[SeaBIOS] [PATCH 2/4] Rename hw/cmos.h to hw/rtc.h and copy RTC code from clock.c to hw/rtc.c.
Kevin O'Connor
kevin at koconnor.net
Thu Sep 19 03:58:52 CEST 2013
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 at 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 at 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 at 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;
--
1.8.3.1
More information about the SeaBIOS
mailing list