help
Support boot from LSI MegaRAID SAS scsi storage.
config FLOPPY
- depends on DRIVES
+ depends on DRIVES && HARDWARE_IRQ
bool "Floppy controller"
default y
help
Support parallel ports. This also enables int 17 parallel port calls.
config RTC_TIMER
bool "Real Time Clock (RTC) scheduling"
+ depends on HARDWARE_IRQ
default y
help
Support MC146818 Real Time Clock chip timer
Disabling this support does not disable access to the RTC
cmos registers.
+ config HARDWARE_IRQ
+ bool "Hardware interrupts"
+ default y
+ help
+ Program and support hardware interrupts using the i8259
+ programmable interrupt controller (PIC). This option must
+ be enabled in order to support most boot loaders. Only
+ disable this option if running on peculiar hardware known
+ not to support irq routing.
+
config USE_SMM
depends on QEMU
bool "System Management Mode (SMM)"
}
}
-// INT 08h System Timer ISR Entry Point
-void VISIBLE16
-handle_08(void)
+// Update main tick counter
+static void
+clock_update(void)
{
- debug_isr(DEBUG_ISR_08);
-
- // Update counter
u32 counter = GET_BDA(timer_counter);
counter++;
// compare to one days worth of timer ticks at 18.2 hz
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;
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
u16
pic_irqmask_read(void)
{
+ if (!CONFIG_HARDWARE_IRQ)
+ return 0;
return inb(PORT_PIC1_DATA) | (inb(PORT_PIC2_DATA) << 8);
}
void
pic_irqmask_write(u16 mask)
{
+ if (!CONFIG_HARDWARE_IRQ)
+ return;
outb(mask, PORT_PIC1_DATA);
outb(mask >> 8, PORT_PIC2_DATA);
}
void
pic_irqmask_mask(u16 off, u16 on)
{
+ if (!CONFIG_HARDWARE_IRQ)
+ return;
u8 pic1off = off, pic1on = on, pic2off = off>>8, pic2on = on>>8;
outb((inb(PORT_PIC1_DATA) & ~pic1off) | pic1on, PORT_PIC1_DATA);
outb((inb(PORT_PIC2_DATA) & ~pic2off) | pic2on, PORT_PIC2_DATA);
void
pic_reset(u8 irq0, u8 irq8)
{
+ if (!CONFIG_HARDWARE_IRQ)
+ return;
// Send ICW1 (select OCW1 + will send ICW4)
outb(0x11, PORT_PIC1_CMD);
outb(0x11, PORT_PIC2_CMD);
void
enable_hwirq(int hwirq, struct segoff_s func)
{
+ if (!CONFIG_HARDWARE_IRQ)
+ return;
pic_irqmask_mask(1 << hwirq, 0);
int vector;
if (hwirq < 8)
static u8
pic_isr1_read(void)
{
+ if (!CONFIG_HARDWARE_IRQ)
+ return 0;
// 0x0b == select OCW1 + read ISR
outb(0x0b, PORT_PIC1_CMD);
return inb(PORT_PIC1_CMD);
static u8
pic_isr2_read(void)
{
+ if (!CONFIG_HARDWARE_IRQ)
+ return 0;
// 0x0b == select OCW1 + read ISR
outb(0x0b, PORT_PIC2_CMD);
return inb(PORT_PIC2_CMD);
static inline void
pic_eoi1(void)
{
+ if (!CONFIG_HARDWARE_IRQ)
+ return;
// Send eoi (select OCW2 + eoi)
outb(0x20, PORT_PIC1_CMD);
}
static inline void
pic_eoi2(void)
{
+ if (!CONFIG_HARDWARE_IRQ)
+ return;
// Send eoi (select OCW2 + eoi)
outb(0x20, PORT_PIC2_CMD);
pic_eoi1();
void
pit_setup(void)
{
+ if (!CONFIG_HARDWARE_IRQ)
+ return;
// timer0: binary count, 16bit count, mode 2
outb(PM_SEL_TIMER0|PM_ACCESS_WORD|PM_MODE2|PM_CNT_BINARY, PORT_PIT_MODE);
// maximum count of 0000H = 18.2Hz
stack_hop_back(0, 0, _cfunc16_check_irqs);
return;
}
+ if (MODE16)
+ clock_poll_irq();
asm volatile("sti ; nop ; rep ; nop ; cli ; cld" : : :"memory");
}
void
yield_toirq(void)
{
- if (!MODESEGMENT && (have_threads() || !CanInterrupt)) {
+ if (!CONFIG_HARDWARE_IRQ
+ || (!MODESEGMENT && (have_threads() || !CanInterrupt))) {
// Threads still active or irqs not available - do a yield instead.
yield();
return;
// clock.c
void clock_setup(void);
void handle_1583(struct bregs *regs);
+void clock_poll_irq(void);
u32 irqtimer_calc_ticks(u32 count);
u32 irqtimer_calc(u32 msecs);
int irqtimer_check(u32 end);