aboutsummaryrefslogtreecommitdiff
path: root/src/clock.c
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2009-12-13 11:25:25 -0500
committerKevin O'Connor <kevin@koconnor.net>2009-12-13 11:25:25 -0500
commitad901592515cf7eaddfb86f610919fd9479dd3da (patch)
tree7eda29fec6389e6a9e71c1f62257d3688ca7d56d /src/clock.c
parent2edace134c323e47c3ad23f4635deb3d14a556b3 (diff)
downloadseabios-hppa-ad901592515cf7eaddfb86f610919fd9479dd3da.zip
seabios-hppa-ad901592515cf7eaddfb86f610919fd9479dd3da.tar.gz
seabios-hppa-ad901592515cf7eaddfb86f610919fd9479dd3da.tar.bz2
Enhance experimental option rom "threading" - enable preemption.
When experimental support for parallelizing option roms and hardware init (default disabled) is selected, add support for checking on hardware init progress from the RTC irq handler. Enable ability for RTC to be turned on for additional users. Allow regular option roms (not just vga option roms) to run in parallel with hardware init. Don't use stack in transition32 / transition16 until new mode is entered. Also, cleanup leaking of data handlers in usb code. Also, decrease frequency of iomemcpy checks (every 2K instead of 1K).
Diffstat (limited to 'src/clock.c')
-rw-r--r--src/clock.c40
1 files changed, 32 insertions, 8 deletions
diff --git a/src/clock.c b/src/clock.c
index 7077631..6706e5c 100644
--- a/src/clock.c
+++ b/src/clock.c
@@ -466,6 +466,32 @@ handle_08()
* Periodic timer
****************************************************************/
+void
+useRTC()
+{
+ u16 ebda_seg = get_ebda_seg();
+ int count = GET_EBDA2(ebda_seg, RTCusers);
+ SET_EBDA2(ebda_seg, 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()
+{
+ u16 ebda_seg = get_ebda_seg();
+ int count = GET_EBDA2(ebda_seg, RTCusers);
+ SET_EBDA2(ebda_seg, 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)
{
@@ -476,22 +502,18 @@ 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);
-
- // Turn on the Periodic Interrupt timer
- u8 bRegister = inb_cmos(CMOS_STATUS_B);
- outb_cmos(bRegister | RTC_B_PIE, CMOS_STATUS_B);
-
+ useRTC();
return 0;
}
static void
clear_usertimer()
{
+ if (!(GET_BDA(rtc_wait_flag) & RWS_WAIT_PENDING))
+ return;
// Turn off status byte.
SET_BDA(rtc_wait_flag, 0);
- // Clear the Periodic Interrupt.
- u8 bRegister = inb_cmos(CMOS_STATUS_B);
- outb_cmos(bRegister & ~RTC_B_PIE, CMOS_STATUS_B);
+ releaseRTC();
}
#define RET_ECLOCKINUSE 0x83
@@ -574,6 +596,8 @@ handle_70()
// Handle Periodic Interrupt.
+ check_preempt();
+
if (!GET_BDA(rtc_wait_flag))
goto done;