Group the Real Time Clock code into hw/rtc.[ch].
Also, use rtc_read/write/mask function naming (instead of inb/outb_cmos) to be more consistent with other register accessors.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- Makefile | 2 +- src/block.c | 4 +- src/boot.c | 8 +-- src/clock.c | 139 ++++++++++++----------------------------------- src/fw/paravirt.c | 16 +++--- src/fw/smp.c | 4 +- src/hw/ata.c | 1 - src/hw/floppy.c | 4 +- src/hw/rtc.c | 93 +++++++++++++++++++++++++++++++ src/hw/{cmos.h => rtc.h} | 53 ++++++++---------- src/post.c | 4 +- src/resume.c | 6 +- src/romlayout.S | 2 +- src/stacks.c | 5 +- src/util.h | 2 - 15 files changed, 177 insertions(+), 166 deletions(-) create mode 100644 src/hw/rtc.c rename src/hw/{cmos.h => rtc.h} (67%)
diff --git a/Makefile b/Makefile index 70ba8d9..0cdb6d3 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ OUT=out/ SRCBOTH=misc.c stacks.c output.c string.c x86.c block.c cdrom.c mouse.c kbd.c \ serial.c clock.c resume.c pnpbios.c vgahooks.c pcibios.c apm.c \ fw/smp.c \ - hw/pci.c hw/timer.c hw/pic.c hw/ps2port.c \ + hw/pci.c hw/timer.c hw/rtc.c hw/pic.c hw/ps2port.c \ hw/usb.c hw/usb-uhci.c hw/usb-ohci.c hw/usb-ehci.c \ hw/usb-hid.c hw/usb-msc.c hw/usb-uas.c \ hw/blockcmd.c hw/floppy.c hw/ata.c hw/ahci.c hw/ramdisk.c \ diff --git a/src/block.c b/src/block.c index 4560b24..cbcf9e1 100644 --- a/src/block.c +++ b/src/block.c @@ -10,8 +10,8 @@ #include "bregs.h" // struct bregs #include "hw/ata.h" // process_ata_op #include "hw/ahci.h" // process_ahci_op -#include "hw/cmos.h" // inb_cmos #include "hw/blockcmd.h" // cdb_* +#include "hw/rtc.h" // rtc_read #include "hw/virtio-blk.h" // process_virtio_blk_op #include "malloc.h" // malloc_low #include "output.h" // dprintf @@ -72,7 +72,7 @@ get_translation(struct drive_s *drive_g) // Emulators pass in the translation info via nvram. u8 ataid = GET_GLOBAL(drive_g->cntl_id); u8 channel = ataid / 2; - u8 translation = inb_cmos(CMOS_BIOS_DISKTRANSFLAG + channel/2); + u8 translation = rtc_read(CMOS_BIOS_DISKTRANSFLAG + channel/2); translation >>= 2 * (ataid % 4); translation &= 0x03; return translation; diff --git a/src/boot.c b/src/boot.c index a2851b2..b14ced9 100644 --- a/src/boot.c +++ b/src/boot.c @@ -9,8 +9,8 @@ #include "bregs.h" // struct bregs #include "config.h" // CONFIG_* #include "fw/paravirt.h" // qemu_cfg_show_boot_menu -#include "hw/cmos.h" // inb_cmos #include "hw/pci.h" // pci_bdf_to_* +#include "hw/rtc.h" // rtc_read #include "hw/usb.h" // struct usbdevice_s #include "list.h" // hlist_node #include "malloc.h" // free @@ -257,10 +257,10 @@ boot_init(void)
if (CONFIG_QEMU) { // On emulators, get boot order from nvram. - if (inb_cmos(CMOS_BIOS_BOOTFLAG1) & 1) + if (rtc_read(CMOS_BIOS_BOOTFLAG1) & 1) CheckFloppySig = 0; - u32 bootorder = (inb_cmos(CMOS_BIOS_BOOTFLAG2) - | ((inb_cmos(CMOS_BIOS_BOOTFLAG1) & 0xf0) << 4)); + u32 bootorder = (rtc_read(CMOS_BIOS_BOOTFLAG2) + | ((rtc_read(CMOS_BIOS_BOOTFLAG1) & 0xf0) << 4)); DefaultFloppyPrio = DefaultCDPrio = DefaultHDPrio = DefaultBEVPrio = DEFAULT_PRIO; int i; diff --git a/src/clock.c b/src/clock.c index e54944b..9ab0ac0 100644 --- a/src/clock.c +++ b/src/clock.c @@ -7,64 +7,19 @@
#include "biosvar.h" // SET_BDA #include "bregs.h" // struct bregs -#include "hw/cmos.h" // inb_cmos #include "hw/pic.h" // pic_eoi1 +#include "hw/rtc.h" // rtc_read #include "hw/usb-hid.h" // usb_check_event #include "output.h" // debug_enter #include "stacks.h" // yield #include "string.h" // memset #include "util.h" // clock_setup
-// RTC register flags -#define RTC_A_UIP 0x80 - -#define RTC_B_SET 0x80 -#define RTC_B_PIE 0x40 -#define RTC_B_AIE 0x20 -#define RTC_B_UIE 0x10 -#define RTC_B_BIN 0x04 -#define RTC_B_24HR 0x02 -#define RTC_B_DSE 0x01 -
/**************************************************************** * Init ****************************************************************/
-static int -rtc_updating(void) -{ - // This function checks to see if the update-in-progress bit - // is set in CMOS Status Register A. If not, it returns 0. - // If it is set, it tries to wait until there is a transition - // to 0, and will return 0 if such a transition occurs. A -1 - // is returned only after timing out. The maximum period - // that this bit should be set is constrained to (1984+244) - // useconds, but we wait for longer just to be sure. - - if ((inb_cmos(CMOS_STATUS_A) & RTC_A_UIP) == 0) - return 0; - u32 end = timer_calc(15); - for (;;) { - if ((inb_cmos(CMOS_STATUS_A) & RTC_A_UIP) == 0) - return 0; - if (timer_check(end)) - // update-in-progress never transitioned to 0 - return -1; - yield(); - } -} - -static void -rtc_setup(void) -{ - outb_cmos(0x26, CMOS_STATUS_A); // 32,768Khz src, 976.5625us updates - u8 regB = inb_cmos(CMOS_STATUS_B); - outb_cmos((regB & RTC_B_DSE) | RTC_B_24HR, CMOS_STATUS_B); - inb_cmos(CMOS_STATUS_C); - inb_cmos(CMOS_STATUS_D); -} - static u32 bcd2bin(u8 val) { @@ -81,18 +36,18 @@ clock_setup(void)
rtc_setup(); rtc_updating(); - u32 seconds = bcd2bin(inb_cmos(CMOS_RTC_SECONDS)); - u32 minutes = bcd2bin(inb_cmos(CMOS_RTC_MINUTES)); - u32 hours = bcd2bin(inb_cmos(CMOS_RTC_HOURS)); + u32 seconds = bcd2bin(rtc_read(CMOS_RTC_SECONDS)); + u32 minutes = bcd2bin(rtc_read(CMOS_RTC_MINUTES)); + u32 hours = bcd2bin(rtc_read(CMOS_RTC_HOURS)); u32 ticks = ticks_from_ms(((hours * 60 + minutes) * 60 + seconds) * 1000); SET_BDA(timer_counter, ticks % TICKS_PER_DAY);
// Setup Century storage if (CONFIG_QEMU) { - Century = inb_cmos(CMOS_CENTURY); + Century = rtc_read(CMOS_CENTURY); } else { // Infer current century from the year. - u8 year = inb_cmos(CMOS_RTC_YEAR); + u8 year = rtc_read(CMOS_RTC_YEAR); if (year > 0x80) Century = 0x19; else @@ -142,10 +97,10 @@ handle_1a02(struct bregs *regs) return; }
- regs->dh = inb_cmos(CMOS_RTC_SECONDS); - regs->cl = inb_cmos(CMOS_RTC_MINUTES); - regs->ch = inb_cmos(CMOS_RTC_HOURS); - regs->dl = inb_cmos(CMOS_STATUS_B) & RTC_B_DSE; + regs->dh = rtc_read(CMOS_RTC_SECONDS); + regs->cl = rtc_read(CMOS_RTC_MINUTES); + regs->ch = rtc_read(CMOS_RTC_HOURS); + regs->dl = rtc_read(CMOS_STATUS_B) & RTC_B_DSE; regs->ah = 0; regs->al = regs->ch; set_success(regs); @@ -169,13 +124,13 @@ handle_1a03(struct bregs *regs) rtc_setup(); // fall through as if an update were not in progress } - outb_cmos(regs->dh, CMOS_RTC_SECONDS); - outb_cmos(regs->cl, CMOS_RTC_MINUTES); - outb_cmos(regs->ch, CMOS_RTC_HOURS); + rtc_write(CMOS_RTC_SECONDS, regs->dh); + rtc_write(CMOS_RTC_MINUTES, regs->cl); + rtc_write(CMOS_RTC_HOURS, regs->ch); // Set Daylight Savings time enabled bit to requested value - u8 val8 = ((inb_cmos(CMOS_STATUS_B) & (RTC_B_PIE|RTC_B_AIE)) + u8 val8 = ((rtc_read(CMOS_STATUS_B) & (RTC_B_PIE|RTC_B_AIE)) | RTC_B_24HR | (regs->dl & RTC_B_DSE)); - outb_cmos(val8, CMOS_STATUS_B); + rtc_write(CMOS_STATUS_B, val8); regs->ah = 0; regs->al = val8; // val last written to Reg B set_success(regs); @@ -190,9 +145,9 @@ handle_1a04(struct bregs *regs) set_invalid(regs); return; } - regs->cl = inb_cmos(CMOS_RTC_YEAR); - regs->dh = inb_cmos(CMOS_RTC_MONTH); - regs->dl = inb_cmos(CMOS_RTC_DAY_MONTH); + regs->cl = rtc_read(CMOS_RTC_YEAR); + regs->dh = rtc_read(CMOS_RTC_MONTH); + regs->dl = rtc_read(CMOS_RTC_DAY_MONTH); regs->ch = GET_LOW(Century); regs->al = regs->ch; set_success(regs); @@ -217,13 +172,13 @@ handle_1a05(struct bregs *regs) set_invalid(regs); return; } - outb_cmos(regs->cl, CMOS_RTC_YEAR); - outb_cmos(regs->dh, CMOS_RTC_MONTH); - outb_cmos(regs->dl, CMOS_RTC_DAY_MONTH); + rtc_write(CMOS_RTC_YEAR, regs->cl); + rtc_write(CMOS_RTC_MONTH, regs->dh); + rtc_write(CMOS_RTC_DAY_MONTH, regs->dl); SET_LOW(Century, regs->ch); // clear halt-clock bit - u8 val8 = inb_cmos(CMOS_STATUS_B) & ~RTC_B_SET; - outb_cmos(val8, CMOS_STATUS_B); + u8 val8 = rtc_read(CMOS_STATUS_B) & ~RTC_B_SET; + rtc_write(CMOS_STATUS_B, val8); regs->ah = 0; regs->al = val8; // AL = val last written to Reg B set_success(regs); @@ -243,7 +198,7 @@ handle_1a06(struct bregs *regs) // // Bit4 in try#1 flipped in hardware (forced low) due to bit7=1 // My assumption: RegB = ((RegB & 01111111b) | 00100000b) - u8 val8 = inb_cmos(CMOS_STATUS_B); // Get Status Reg B + u8 val8 = rtc_read(CMOS_STATUS_B); // Get Status Reg B regs->ax = 0; if (val8 & RTC_B_AIE) { // Alarm interrupt enabled already @@ -254,11 +209,11 @@ handle_1a06(struct bregs *regs) rtc_setup(); // fall through as if an update were not in progress } - outb_cmos(regs->dh, CMOS_RTC_SECONDS_ALARM); - outb_cmos(regs->cl, CMOS_RTC_MINUTES_ALARM); - outb_cmos(regs->ch, CMOS_RTC_HOURS_ALARM); + rtc_write(CMOS_RTC_SECONDS_ALARM, regs->dh); + rtc_write(CMOS_RTC_MINUTES_ALARM, regs->cl); + rtc_write(CMOS_RTC_HOURS_ALARM, regs->ch); // enable Status Reg B alarm bit, clear halt clock bit - outb_cmos((val8 & ~RTC_B_SET) | RTC_B_AIE, CMOS_STATUS_B); + rtc_write(CMOS_STATUS_B, (val8 & ~RTC_B_SET) | RTC_B_AIE); set_success(regs); }
@@ -276,9 +231,9 @@ handle_1a07(struct bregs *regs) // // Bit4 in try#1 flipped in hardware (forced low) due to bit7=1 // My assumption: RegB = (RegB & 01010111b) - u8 val8 = inb_cmos(CMOS_STATUS_B); // Get Status Reg B + u8 val8 = rtc_read(CMOS_STATUS_B); // Get Status Reg B // clear clock-halt bit, disable alarm bit - outb_cmos(val8 & ~(RTC_B_SET|RTC_B_AIE), CMOS_STATUS_B); + rtc_write(CMOS_STATUS_B, val8 & ~(RTC_B_SET|RTC_B_AIE)); regs->ah = 0; regs->al = val8; // val last written to Reg B set_success(regs); @@ -374,32 +329,6 @@ irqtimer_check(u32 end) * Periodic timer ****************************************************************/
-int RTCusers VARLOW; - -void -useRTC(void) -{ - int count = GET_LOW(RTCusers); - SET_LOW(RTCusers, count+1); - if (count) - return; - // Turn on the Periodic Interrupt timer - u8 bRegister = inb_cmos(CMOS_STATUS_B); - outb_cmos(bRegister | RTC_B_PIE, CMOS_STATUS_B); -} - -void -releaseRTC(void) -{ - int count = GET_LOW(RTCusers); - SET_LOW(RTCusers, count-1); - if (count != 1) - return; - // Clear the Periodic Interrupt. - u8 bRegister = inb_cmos(CMOS_STATUS_B); - outb_cmos(bRegister & ~RTC_B_PIE, CMOS_STATUS_B); -} - static int set_usertimer(u32 usecs, u16 seg, u16 offset) { @@ -410,7 +339,7 @@ set_usertimer(u32 usecs, u16 seg, u16 offset) SET_BDA(rtc_wait_flag, RWS_WAIT_PENDING); // Set status byte. SET_BDA(user_wait_complete_flag, SEGOFF(seg, offset)); SET_BDA(user_wait_timeout, usecs); - useRTC(); + rtc_use(); return 0; }
@@ -421,7 +350,7 @@ clear_usertimer(void) return; // Turn off status byte. SET_BDA(rtc_wait_flag, 0); - releaseRTC(); + rtc_release(); }
#define RET_ECLOCKINUSE 0x83 @@ -489,8 +418,8 @@ handle_70(void) debug_isr(DEBUG_ISR_70);
// Check which modes are enabled and have occurred. - u8 registerB = inb_cmos(CMOS_STATUS_B); - u8 registerC = inb_cmos(CMOS_STATUS_C); + u8 registerB = rtc_read(CMOS_STATUS_B); + u8 registerC = rtc_read(CMOS_STATUS_C);
if (!(registerB & (RTC_B_PIE|RTC_B_AIE))) goto done; diff --git a/src/fw/paravirt.c b/src/fw/paravirt.c index 2524b7b..f8d44d7 100644 --- a/src/fw/paravirt.c +++ b/src/fw/paravirt.c @@ -10,8 +10,8 @@
#include "byteorder.h" // be32_to_cpu #include "config.h" // CONFIG_QEMU -#include "hw/cmos.h" // CMOS_* #include "hw/pci.h" // create_pirtable +#include "hw/rtc.h" // CMOS_* #include "ioport.h" // outw #include "malloc.h" // malloc_tmp #include "memmap.h" // add_e820 @@ -69,21 +69,21 @@ qemu_preinit(void) kvm_preinit();
// On emulators, get memory size from nvram. - u32 rs = ((inb_cmos(CMOS_MEM_EXTMEM2_LOW) << 16) - | (inb_cmos(CMOS_MEM_EXTMEM2_HIGH) << 24)); + u32 rs = ((rtc_read(CMOS_MEM_EXTMEM2_LOW) << 16) + | (rtc_read(CMOS_MEM_EXTMEM2_HIGH) << 24)); if (rs) rs += 16 * 1024 * 1024; else - rs = (((inb_cmos(CMOS_MEM_EXTMEM_LOW) << 10) - | (inb_cmos(CMOS_MEM_EXTMEM_HIGH) << 18)) + rs = (((rtc_read(CMOS_MEM_EXTMEM_LOW) << 10) + | (rtc_read(CMOS_MEM_EXTMEM_HIGH) << 18)) + 1 * 1024 * 1024); RamSize = rs; add_e820(0, rs, E820_RAM);
// Check for memory over 4Gig - u64 high = ((inb_cmos(CMOS_MEM_HIGHMEM_LOW) << 16) - | ((u32)inb_cmos(CMOS_MEM_HIGHMEM_MID) << 24) - | ((u64)inb_cmos(CMOS_MEM_HIGHMEM_HIGH) << 32)); + u64 high = ((rtc_read(CMOS_MEM_HIGHMEM_LOW) << 16) + | ((u32)rtc_read(CMOS_MEM_HIGHMEM_MID) << 24) + | ((u64)rtc_read(CMOS_MEM_HIGHMEM_HIGH) << 32)); RamSizeOver4G = high; add_e820(0x100000000ull, high, E820_RAM);
diff --git a/src/fw/smp.c b/src/fw/smp.c index b96bcfd..38fe383 100644 --- a/src/fw/smp.c +++ b/src/fw/smp.c @@ -6,7 +6,7 @@ // This file may be distributed under the terms of the GNU LGPLv3 license.
#include "config.h" // CONFIG_* -#include "hw/cmos.h" // CMOS_BIOS_SMP_COUNT +#include "hw/rtc.h" // CMOS_BIOS_SMP_COUNT #include "output.h" // dprintf #include "romfile.h" // romfile_loadint #include "stacks.h" // yield @@ -132,7 +132,7 @@ smp_setup(void) writel(APIC_ICR_LOW, 0x000C4600 | sipi_vector);
// Wait for other CPUs to process the SIPI. - u8 cmos_smp_count = inb_cmos(CMOS_BIOS_SMP_COUNT); + u8 cmos_smp_count = rtc_read(CMOS_BIOS_SMP_COUNT); while (cmos_smp_count + 1 != readl(&CountCPUs)) yield();
diff --git a/src/hw/ata.c b/src/hw/ata.c index 34ba119..8165e50 100644 --- a/src/hw/ata.c +++ b/src/hw/ata.c @@ -10,7 +10,6 @@ #include "block.h" // struct drive_s #include "blockcmd.h" // CDB_CMD_READ_10 #include "byteorder.h" // be16_to_cpu -#include "cmos.h" // inb_cmos #include "ioport.h" // inb #include "malloc.h" // malloc_fseg #include "output.h" // dprintf diff --git a/src/hw/floppy.c b/src/hw/floppy.c index 39efaad..cf1ab87 100644 --- a/src/hw/floppy.c +++ b/src/hw/floppy.c @@ -8,7 +8,6 @@ #include "biosvar.h" // SET_BDA #include "block.h" // struct drive_s #include "bregs.h" // struct bregs -#include "cmos.h" // inb_cmos #include "config.h" // CONFIG_FLOPPY #include "malloc.h" // malloc_fseg #include "output.h" // dprintf @@ -16,6 +15,7 @@ #include "pci_ids.h" // PCI_CLASS_BRIDGE_ISA #include "pic.h" // pic_eoi1 #include "romfile.h" // romfile_loadint +#include "rtc.h" // rtc_read #include "stacks.h" // yield #include "std/disk.h" // DISK_RET_SUCCESS #include "string.h" // memset @@ -139,7 +139,7 @@ floppy_setup(void) dprintf(3, "init floppy drives\n");
if (CONFIG_QEMU) { - u8 type = inb_cmos(CMOS_FLOPPY_DRIVE_TYPE); + u8 type = rtc_read(CMOS_FLOPPY_DRIVE_TYPE); if (type & 0xf0) addFloppy(0, type >> 4); if (type & 0x0f) diff --git a/src/hw/rtc.c b/src/hw/rtc.c new file mode 100644 index 0000000..9886aa5 --- /dev/null +++ b/src/hw/rtc.c @@ -0,0 +1,93 @@ +// Support for MC146818 Real Time Clock chip. +// +// Copyright (C) 2008-2013 Kevin O'Connor kevin@koconnor.net +// Copyright (C) 2002 MandrakeSoft S.A. +// +// This file may be distributed under the terms of the GNU LGPLv3 license. + +#include "biosvar.h" // GET_LOW +#include "ioport.h" // inb +#include "rtc.h" // rtc_read +#include "stacks.h" // yield +#include "util.h" // timer_calc + +u8 +rtc_read(u8 index) +{ + index |= NMI_DISABLE_BIT; + outb(index, PORT_CMOS_INDEX); + return inb(PORT_CMOS_DATA); +} + +void +rtc_write(u8 index, u8 val) +{ + index |= NMI_DISABLE_BIT; + outb(index, PORT_CMOS_INDEX); + outb(val, PORT_CMOS_DATA); +} + +void +rtc_mask(u8 index, u8 off, u8 on) +{ + outb(index, PORT_CMOS_INDEX); + u8 val = inb(PORT_CMOS_DATA); + outb((val & ~off) | on, PORT_CMOS_DATA); +} + +int +rtc_updating(void) +{ + // This function checks to see if the update-in-progress bit + // is set in CMOS Status Register A. If not, it returns 0. + // If it is set, it tries to wait until there is a transition + // to 0, and will return 0 if such a transition occurs. A -1 + // is returned only after timing out. The maximum period + // that this bit should be set is constrained to (1984+244) + // useconds, but we wait for longer just to be sure. + + if ((rtc_read(CMOS_STATUS_A) & RTC_A_UIP) == 0) + return 0; + u32 end = timer_calc(15); + for (;;) { + if ((rtc_read(CMOS_STATUS_A) & RTC_A_UIP) == 0) + return 0; + if (timer_check(end)) + // update-in-progress never transitioned to 0 + return -1; + yield(); + } +} + +void +rtc_setup(void) +{ + rtc_write(CMOS_STATUS_A, 0x26); // 32,768Khz src, 976.5625us updates + rtc_mask(CMOS_STATUS_B, ~RTC_B_DSE, RTC_B_24HR); + rtc_read(CMOS_STATUS_C); + rtc_read(CMOS_STATUS_D); +} + +int RTCusers VARLOW; + +void +rtc_use(void) +{ + int count = GET_LOW(RTCusers); + SET_LOW(RTCusers, count+1); + if (count) + return; + // Turn on the Periodic Interrupt timer + rtc_mask(CMOS_STATUS_B, 0, RTC_B_PIE); +} + +void +rtc_release(void) +{ + int count = GET_LOW(RTCusers); + SET_LOW(RTCusers, count-1); + if (count != 1) + return; + // Clear the Periodic Interrupt. + rtc_mask(CMOS_STATUS_B, RTC_B_PIE, 0); +} diff --git a/src/hw/cmos.h b/src/hw/rtc.h similarity index 67% rename from src/hw/cmos.h rename to src/hw/rtc.h index 067c7fa..d975f6b 100644 --- a/src/hw/cmos.h +++ b/src/hw/rtc.h @@ -1,10 +1,5 @@ -// Definitions for X86 CMOS non-volatile memory access. -// -// Copyright (C) 2008 Kevin O'Connor kevin@koconnor.net -// -// This file may be distributed under the terms of the GNU LGPLv3 license. -#ifndef __CMOS_H -#define __CMOS_H +#ifndef __RTC_H +#define __RTC_H
// Standard BIOS RTC chip entries #define CMOS_RTC_SECONDS 0x00 @@ -45,34 +40,30 @@ #define CMOS_MEM_HIGHMEM_HIGH 0x5d #define CMOS_BIOS_SMP_COUNT 0x5f
-// CMOS_FLOPPY_DRIVE_TYPE bitdefs -#define CFD_NO_DRIVE 0 -#define CFD_360KB 1 -#define CFD_12MB 2 -#define CFD_720KB 3 -#define CFD_144MB 4 -#define CFD_288MB 5 +// RTC register flags +#define RTC_A_UIP 0x80
-#ifndef __ASSEMBLY__ +#define RTC_B_SET 0x80 +#define RTC_B_PIE 0x40 +#define RTC_B_AIE 0x20 +#define RTC_B_UIE 0x10 +#define RTC_B_BIN 0x04 +#define RTC_B_24HR 0x02 +#define RTC_B_DSE 0x01
-#include "ioport.h" // inb, outb +#ifndef __ASSEMBLY__
-static inline u8 -inb_cmos(u8 reg) -{ - reg |= NMI_DISABLE_BIT; - outb(reg, PORT_CMOS_INDEX); - return inb(PORT_CMOS_DATA); -} +#include "types.h" // u8
-static inline void -outb_cmos(u8 val, u8 reg) -{ - reg |= NMI_DISABLE_BIT; - outb(reg, PORT_CMOS_INDEX); - outb(val, PORT_CMOS_DATA); -} +// rtc.c +u8 rtc_read(u8 index); +void rtc_write(u8 index, u8 val); +void rtc_mask(u8 index, u8 off, u8 on); +int rtc_updating(void); +void rtc_setup(void); +void rtc_use(void); +void rtc_release(void);
#endif // !__ASSEMBLY__
-#endif // cmos.h +#endif // rtc.h diff --git a/src/post.c b/src/post.c index 592176d..acd2362 100644 --- a/src/post.c +++ b/src/post.c @@ -12,12 +12,12 @@ #include "fw/xen.h" // xen_preinit #include "hw/ahci.h" // ahci_setup #include "hw/ata.h" // ata_setup -#include "hw/cmos.h" // CMOS_* #include "hw/esp-scsi.h" // esp_scsi_setup #include "hw/lsi-scsi.h" // lsi_scsi_setup #include "hw/megasas.h" // megasas_setup #include "hw/pic.h" // pic_setup #include "hw/ps2port.h" // ps2port_setup +#include "hw/rtc.h" // rtc_write #include "hw/usb.h" // usb_setup #include "hw/virtio-blk.h" // virtio_blk_setup #include "hw/virtio-scsi.h" // virtio_scsi_setup @@ -39,7 +39,7 @@ ivt_init(void)
// Setup reset-vector entry point (controls legacy reboots). HaveRunPost = 1; - outb_cmos(0, CMOS_RESET_CODE); + rtc_write(CMOS_RESET_CODE, 0);
// Initialize all vectors to the default handler. int i; diff --git a/src/resume.c b/src/resume.c index af39a1d..12daf0f 100644 --- a/src/resume.c +++ b/src/resume.c @@ -7,10 +7,10 @@ #include "bregs.h" // struct bregs #include "config.h" // CONFIG_* #include "farptr.h" // FLATPTR_TO_SEGOFF -#include "hw/cmos.h" // inb_cmos #include "hw/pci.h" // pci_reboot #include "hw/pic.h" // pic_eoi2 #include "hw/ps2port.h" // i8042_reboot +#include "hw/rtc.h" // rtc_read #include "ioport.h" // outb #include "output.h" // dprintf #include "stacks.h" // farcall16big @@ -40,8 +40,8 @@ handle_resume(void) { ASSERT16(); debug_serial_preinit(); - int status = inb_cmos(CMOS_RESET_CODE); - outb_cmos(0, CMOS_RESET_CODE); + int status = rtc_read(CMOS_RESET_CODE); + rtc_write(CMOS_RESET_CODE, 0); dprintf(1, "In resume (status=%d)\n", status);
dma_setup(); diff --git a/src/romlayout.S b/src/romlayout.S index 17904ae..3307f76 100644 --- a/src/romlayout.S +++ b/src/romlayout.S @@ -8,7 +8,7 @@ #include "config.h" // CONFIG_* #include "ioport.h" // PORT_A20 #include "x86.h" // CR0_* -#include "hw/cmos.h" // CMOS_RESET_CODE +#include "hw/rtc.h" // CMOS_RESET_CODE #include "asm-offsets.h" // BREGS_* #include "entryfuncs.S" // ENTRY_*
diff --git a/src/stacks.c b/src/stacks.c index cc597c6..d8aaca8 100644 --- a/src/stacks.c +++ b/src/stacks.c @@ -6,6 +6,7 @@
#include "biosvar.h" // GET_GLOBAL #include "bregs.h" // CR0_PE +#include "hw/rtc.h" // rtc_use #include "list.h" // hlist_node #include "malloc.h" // free #include "output.h" // dprintf @@ -446,7 +447,7 @@ start_preempt(void) return; CanPreempt = 1; PreemptCount = 0; - useRTC(); + rtc_use(); }
// Turn off RTC irqs / stop checking for thread execution. @@ -458,7 +459,7 @@ finish_preempt(void) return; } CanPreempt = 0; - releaseRTC(); + rtc_release(); dprintf(9, "Done preempt - %d checks\n", PreemptCount); yield(); } diff --git a/src/util.h b/src/util.h index 57c3ae9..9c45925 100644 --- a/src/util.h +++ b/src/util.h @@ -59,8 +59,6 @@ u32 irqtimer_calc_ticks(u32 count); u32 irqtimer_calc(u32 msecs); int irqtimer_check(u32 end); void handle_1586(struct bregs *regs); -void useRTC(void); -void releaseRTC(void);
// fw/acpi.c extern struct rsdp_descriptor *RsdpAddr;