summaryrefslogtreecommitdiffstats
path: root/qemu/roms/seabios/src/clock.c
diff options
context:
space:
mode:
authorRajithaY <rajithax.yerrumsetty@intel.com>2017-04-25 03:31:15 -0700
committerRajitha Yerrumchetty <rajithax.yerrumsetty@intel.com>2017-05-22 06:48:08 +0000
commitbb756eebdac6fd24e8919e2c43f7d2c8c4091f59 (patch)
treeca11e03542edf2d8f631efeca5e1626d211107e3 /qemu/roms/seabios/src/clock.c
parenta14b48d18a9ed03ec191cf16b162206998a895ce (diff)
Adding qemu as a submodule of KVMFORNFV
This Patch includes the changes to add qemu as a submodule to kvmfornfv repo and make use of the updated latest qemu for the execution of all testcase Change-Id: I1280af507a857675c7f81d30c95255635667bdd7 Signed-off-by:RajithaY<rajithax.yerrumsetty@intel.com>
Diffstat (limited to 'qemu/roms/seabios/src/clock.c')
-rw-r--r--qemu/roms/seabios/src/clock.c505
1 files changed, 0 insertions, 505 deletions
diff --git a/qemu/roms/seabios/src/clock.c b/qemu/roms/seabios/src/clock.c
deleted file mode 100644
index e83e0f338..000000000
--- a/qemu/roms/seabios/src/clock.c
+++ /dev/null
@@ -1,505 +0,0 @@
-// 16bit code to handle system clocks.
-//
-// Copyright (C) 2008-2010 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" // SET_BDA
-#include "bregs.h" // struct bregs
-#include "hw/pic.h" // pic_eoi1
-#include "hw/ps2port.h" // ps2_check_event
-#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
-
-
-/****************************************************************
- * Init
- ****************************************************************/
-
-static u32
-bcd2bin(u8 val)
-{
- return (val & 0xf) + ((val >> 4) * 10);
-}
-
-u8 Century VARLOW;
-
-void
-clock_setup(void)
-{
- dprintf(3, "init timer\n");
- pit_setup();
-
- rtc_setup();
- rtc_updating();
- 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 = rtc_read(CMOS_CENTURY);
- } else {
- // Infer current century from the year.
- u8 year = rtc_read(CMOS_RTC_YEAR);
- if (year > 0x80)
- Century = 0x19;
- else
- Century = 0x20;
- }
-
- enable_hwirq(0, FUNC16(entry_08));
- if (CONFIG_RTC_TIMER)
- enable_hwirq(8, FUNC16(entry_70));
-}
-
-
-/****************************************************************
- * Standard clock functions
- ****************************************************************/
-
-// get current clock count
-static void
-handle_1a00(struct bregs *regs)
-{
- yield();
- u32 ticks = GET_BDA(timer_counter);
- regs->cx = ticks >> 16;
- regs->dx = ticks;
- regs->al = GET_BDA(timer_rollover);
- SET_BDA(timer_rollover, 0); // reset flag
- set_success(regs);
-}
-
-// Set Current Clock Count
-static void
-handle_1a01(struct bregs *regs)
-{
- u32 ticks = (regs->cx << 16) | regs->dx;
- SET_BDA(timer_counter, ticks);
- SET_BDA(timer_rollover, 0); // reset flag
- // XXX - should use set_code_success()?
- regs->ah = 0;
- set_success(regs);
-}
-
-// Read CMOS Time
-static void
-handle_1a02(struct bregs *regs)
-{
- if (rtc_updating()) {
- set_invalid(regs);
- return;
- }
-
- 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);
-}
-
-// Set CMOS Time
-static void
-handle_1a03(struct bregs *regs)
-{
- // Using a debugger, I notice the following masking/setting
- // of bits in Status Register B, by setting Reg B to
- // a few values and getting its value after INT 1A was called.
- //
- // try#1 try#2 try#3
- // before 1111 1101 0111 1101 0000 0000
- // after 0110 0010 0110 0010 0000 0010
- //
- // Bit4 in try#1 flipped in hardware (forced low) due to bit7=1
- // My assumption: RegB = ((RegB & 01100000b) | 00000010b)
- if (rtc_updating()) {
- rtc_setup();
- // fall through as if an update were not in progress
- }
- 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 = ((rtc_read(CMOS_STATUS_B) & (RTC_B_PIE|RTC_B_AIE))
- | RTC_B_24HR | (regs->dl & RTC_B_DSE));
- rtc_write(CMOS_STATUS_B, val8);
- regs->ah = 0;
- regs->al = val8; // val last written to Reg B
- set_success(regs);
-}
-
-// Read CMOS Date
-static void
-handle_1a04(struct bregs *regs)
-{
- regs->ah = 0;
- if (rtc_updating()) {
- set_invalid(regs);
- return;
- }
- 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);
-}
-
-// Set CMOS Date
-static void
-handle_1a05(struct bregs *regs)
-{
- // Using a debugger, I notice the following masking/setting
- // of bits in Status Register B, by setting Reg B to
- // a few values and getting its value after INT 1A was called.
- //
- // try#1 try#2 try#3 try#4
- // before 1111 1101 0111 1101 0000 0010 0000 0000
- // after 0110 1101 0111 1101 0000 0010 0000 0000
- //
- // Bit4 in try#1 flipped in hardware (forced low) due to bit7=1
- // My assumption: RegB = (RegB & 01111111b)
- if (rtc_updating()) {
- rtc_setup();
- set_invalid(regs);
- return;
- }
- 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 = 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);
-}
-
-// Set Alarm Time in CMOS
-static void
-handle_1a06(struct bregs *regs)
-{
- // Using a debugger, I notice the following masking/setting
- // of bits in Status Register B, by setting Reg B to
- // a few values and getting its value after INT 1A was called.
- //
- // try#1 try#2 try#3
- // before 1101 1111 0101 1111 0000 0000
- // after 0110 1111 0111 1111 0010 0000
- //
- // Bit4 in try#1 flipped in hardware (forced low) due to bit7=1
- // My assumption: RegB = ((RegB & 01111111b) | 00100000b)
- u8 val8 = rtc_read(CMOS_STATUS_B); // Get Status Reg B
- regs->ax = 0;
- if (val8 & RTC_B_AIE) {
- // Alarm interrupt enabled already
- set_invalid(regs);
- return;
- }
- if (rtc_updating()) {
- rtc_setup();
- // fall through as if an update were not in progress
- }
- 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
- rtc_write(CMOS_STATUS_B, (val8 & ~RTC_B_SET) | RTC_B_AIE);
- set_success(regs);
-}
-
-// Turn off Alarm
-static void
-handle_1a07(struct bregs *regs)
-{
- // Using a debugger, I notice the following masking/setting
- // of bits in Status Register B, by setting Reg B to
- // a few values and getting its value after INT 1A was called.
- //
- // try#1 try#2 try#3 try#4
- // before 1111 1101 0111 1101 0010 0000 0010 0010
- // after 0100 0101 0101 0101 0000 0000 0000 0010
- //
- // Bit4 in try#1 flipped in hardware (forced low) due to bit7=1
- // My assumption: RegB = (RegB & 01010111b)
- u8 val8 = rtc_read(CMOS_STATUS_B); // Get Status Reg B
- // clear clock-halt bit, disable alarm bit
- 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);
-}
-
-static void
-handle_1abb(struct bregs *regs)
-{
- if (!CONFIG_TCGBIOS)
- return;
-
- dprintf(DEBUG_tcg, "16: Calling tpm_interrupt_handler\n");
- call32(tpm_interrupt_handler32, MAKE_FLATPTR(GET_SEG(SS), regs), 0);
-}
-
-// Unsupported
-static void
-handle_1aXX(struct bregs *regs)
-{
- set_unimplemented(regs);
-}
-
-// INT 1Ah Time-of-day Service Entry Point
-void VISIBLE16
-handle_1a(struct bregs *regs)
-{
- debug_enter(regs, DEBUG_HDL_1a);
- switch (regs->ah) {
- case 0x00: handle_1a00(regs); break;
- case 0x01: handle_1a01(regs); break;
- case 0x02: handle_1a02(regs); break;
- case 0x03: handle_1a03(regs); break;
- case 0x04: handle_1a04(regs); break;
- case 0x05: handle_1a05(regs); break;
- case 0x06: handle_1a06(regs); break;
- case 0x07: handle_1a07(regs); break;
- case 0xbb: handle_1abb(regs); break;
- default: handle_1aXX(regs); break;
- }
-}
-
-// Update main tick counter
-static void
-clock_update(void)
-{
- u32 counter = GET_BDA(timer_counter);
- counter++;
- // compare to one days worth of timer ticks at 18.2 hz
- if (counter >= TICKS_PER_DAY) {
- // there has been a midnight rollover at this point
- counter = 0;
- SET_BDA(timer_rollover, GET_BDA(timer_rollover) + 1);
- }
- SET_BDA(timer_counter, counter);
-
- // Check for internal events.
- floppy_tick();
- usb_check_event();
- ps2_check_event();
-}
-
-// INT 08h System Timer ISR Entry Point
-void VISIBLE16
-handle_08(void)
-{
- debug_isr(DEBUG_ISR_08);
- clock_update();
-
- // chain to user timer tick INT #0x1c
- struct bregs br;
- memset(&br, 0, sizeof(br));
- br.flags = F_IF;
- call16_int(0x1c, &br);
-
- pic_eoi1();
-}
-
-u32 last_timer_check VARLOW;
-
-// Simulate timer irq on machines without hardware irqs
-void
-clock_poll_irq(void)
-{
- if (CONFIG_HARDWARE_IRQ)
- return;
- if (!timer_check(GET_LOW(last_timer_check)))
- return;
- SET_LOW(last_timer_check, timer_calc(ticks_to_ms(1)));
- clock_update();
-}
-
-
-/****************************************************************
- * IRQ based timer
- ****************************************************************/
-
-// Calculate the timer value at 'count' number of full timer ticks in
-// the future.
-u32
-irqtimer_calc_ticks(u32 count)
-{
- return (GET_BDA(timer_counter) + count + 1) % TICKS_PER_DAY;
-}
-
-// Return the timer value that is 'msecs' time in the future.
-u32
-irqtimer_calc(u32 msecs)
-{
- if (!msecs)
- return GET_BDA(timer_counter);
- return irqtimer_calc_ticks(ticks_from_ms(msecs));
-}
-
-// Check if the given timer value has passed.
-int
-irqtimer_check(u32 end)
-{
- return (((GET_BDA(timer_counter) + TICKS_PER_DAY - end) % TICKS_PER_DAY)
- < (TICKS_PER_DAY/2));
-}
-
-
-/****************************************************************
- * Periodic timer
- ****************************************************************/
-
-static int
-set_usertimer(u32 usecs, u16 seg, u16 offset)
-{
- if (GET_BDA(rtc_wait_flag) & RWS_WAIT_PENDING)
- return -1;
-
- // Interval not already set.
- 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);
- rtc_use();
- return 0;
-}
-
-static void
-clear_usertimer(void)
-{
- if (!(GET_BDA(rtc_wait_flag) & RWS_WAIT_PENDING))
- return;
- // Turn off status byte.
- SET_BDA(rtc_wait_flag, 0);
- rtc_release();
-}
-
-#define RET_ECLOCKINUSE 0x83
-
-// Wait for CX:DX microseconds
-void
-handle_1586(struct bregs *regs)
-{
- if (!CONFIG_RTC_TIMER) {
- set_code_unimplemented(regs, RET_EUNSUPPORTED);
- return;
- }
- // Use the rtc to wait for the specified time.
- u8 statusflag = 0;
- u32 count = (regs->cx << 16) | regs->dx;
- int ret = set_usertimer(count, GET_SEG(SS), (u32)&statusflag);
- if (ret) {
- set_code_invalid(regs, RET_ECLOCKINUSE);
- return;
- }
- while (!statusflag)
- yield_toirq();
- set_success(regs);
-}
-
-// Set Interval requested.
-static void
-handle_158300(struct bregs *regs)
-{
- int ret = set_usertimer((regs->cx << 16) | regs->dx, regs->es, regs->bx);
- if (ret)
- // Interval already set.
- set_code_invalid(regs, RET_EUNSUPPORTED);
- else
- set_success(regs);
-}
-
-// Clear interval requested
-static void
-handle_158301(struct bregs *regs)
-{
- clear_usertimer();
- set_success(regs);
-}
-
-static void
-handle_1583XX(struct bregs *regs)
-{
- set_code_unimplemented(regs, RET_EUNSUPPORTED);
- regs->al--;
-}
-
-void
-handle_1583(struct bregs *regs)
-{
- if (!CONFIG_RTC_TIMER) {
- handle_1583XX(regs);
- return;
- }
- switch (regs->al) {
- case 0x00: handle_158300(regs); break;
- case 0x01: handle_158301(regs); break;
- default: handle_1583XX(regs); break;
- }
-}
-
-#define USEC_PER_RTC DIV_ROUND_CLOSEST(1000000, 1024)
-
-// int70h: IRQ8 - CMOS RTC
-void VISIBLE16
-handle_70(void)
-{
- if (!CONFIG_RTC_TIMER)
- return;
- debug_isr(DEBUG_ISR_70);
-
- // Check which modes are enabled and have occurred.
- u8 registerB = rtc_read(CMOS_STATUS_B);
- u8 registerC = rtc_read(CMOS_STATUS_C);
-
- if (!(registerB & (RTC_B_PIE|RTC_B_AIE)))
- goto done;
- if (registerC & RTC_B_AIE) {
- // Handle Alarm Interrupt.
- struct bregs br;
- memset(&br, 0, sizeof(br));
- br.flags = F_IF;
- call16_int(0x4a, &br);
- }
- if (!(registerC & RTC_B_PIE))
- goto done;
-
- // Handle Periodic Interrupt.
-
- check_preempt();
-
- if (!GET_BDA(rtc_wait_flag))
- goto done;
-
- // Wait Interval (Int 15, AH=83) active.
- u32 time = GET_BDA(user_wait_timeout); // Time left in microseconds.
- if (time < USEC_PER_RTC) {
- // Done waiting - write to specified flag byte.
- struct segoff_s segoff = GET_BDA(user_wait_complete_flag);
- u16 ptr_seg = segoff.seg;
- u8 *ptr_far = (u8*)(segoff.offset+0);
- u8 oldval = GET_FARVAR(ptr_seg, *ptr_far);
- SET_FARVAR(ptr_seg, *ptr_far, oldval | 0x80);
-
- clear_usertimer();
- } else {
- // Continue waiting.
- time -= USEC_PER_RTC;
- SET_BDA(user_wait_timeout, time);
- }
-
-done:
- pic_eoi2();
-}