Skip to content

Commit

Permalink
trying to figure out why booting without kvm enabled locks up
Browse files Browse the repository at this point in the history
  • Loading branch information
braindigitalis committed May 6, 2023
1 parent d3d4e55 commit da77095
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 11 deletions.
6 changes: 2 additions & 4 deletions cmake/custom_targets.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,9 @@ function(run TARGETFILE)
add_custom_command(OUTPUT ${OUTNAME}
COMMAND echo "qemu-system-x86_64 \
-s \
-cpu host \
-trace *msi* \
--enable-kvm \
-monitor stdio \
--enable-kvm \
-cpu host \
-smp 8 \
-usb \
-usbdevice mouse \
Expand All @@ -65,7 +64,6 @@ function(run TARGETFILE)
-device ide-hd,drive=disk,bus=ahci.0 \
-drive file=rr.iso,media=cdrom,if=none,id=sata-cdrom \
-device ide-cd,drive=sata-cdrom,bus=ahci.1 \
-no-reboot \
-no-shutdown \
-boot d \
-vnc 0.0.0.0:2 \
Expand Down
81 changes: 80 additions & 1 deletion src/idt.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,75 @@

volatile idt_ptr_t idt64 = { sizeof(idt_entry_t) * 255, NULL };

#define PIC1 0x20 /* IO base address for master PIC */
#define PIC2 0xA0 /* IO base address for slave PIC */
#define PIC1_COMMAND PIC1
#define PIC1_DATA (PIC1+1)
#define PIC2_COMMAND PIC2
#define PIC2_DATA (PIC2+1)

#define ICW1_ICW4 0x01 /* Indicates that ICW4 will be present */
#define ICW1_SINGLE 0x02 /* Single (cascade) mode */
#define ICW1_INTERVAL4 0x04 /* Call address interval 4 (8) */
#define ICW1_LEVEL 0x08 /* Level triggered (edge) mode */
#define ICW1_INIT 0x10 /* Initialization - required! */

#define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */
#define ICW4_AUTO 0x02 /* Auto (normal) EOI */
#define ICW4_BUF_SLAVE 0x08 /* Buffered mode/slave */
#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */
#define ICW4_SFNM 0x10 /* Special fully nested (not) */

void io_wait()
{
outb(0x80, 0);
}

void pic_remap(int offset1, int offset2)
{
uint8_t a1, a2;

a1 = inb(PIC1_DATA); // save masks
a2 = inb(PIC2_DATA);

outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); // starts the initialization sequence (in cascade mode)
io_wait();
outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4);
io_wait();
outb(PIC1_DATA, offset1); // ICW2: Master PIC vector offset
io_wait();
outb(PIC2_DATA, offset2); // ICW2: Slave PIC vector offset
io_wait();
outb(PIC1_DATA, 4); // ICW3: tell Master PIC that there is a slave PIC at IRQ2 (0000 0100)
io_wait();
outb(PIC2_DATA, 2); // ICW3: tell Slave PIC its cascade identity (0000 0010)
io_wait();

outb(PIC1_DATA, ICW4_8086); // ICW4: have the PICs use 8086 mode (and not 8080 mode)
io_wait();
outb(PIC2_DATA, ICW4_8086);
io_wait();

outb(PIC1_DATA, a1); // restore saved masks.
outb(PIC2_DATA, a2);
}

void pic_disable()
{
/* Disable PIC */
uint8_t disable = 0xff;
outb(PIC1_DATA, disable);
outb(PIC2_DATA, disable);
}

void pic_enable()
{
/* Disable PIC */
uint8_t enable = 0;
outb(PIC1_DATA, enable);
outb(PIC2_DATA, enable);
}

void init_idt()
{
/* Allocate memory for IDT */
Expand All @@ -23,11 +92,21 @@ void init_idt()
* 24 pins: http://web.archive.org/web/20161130153145/http://download.intel.com/design/chipsets/datashts/29056601.pdf
*/
for (int in = 0; in < 24; in++) {
/* Unmasked, Active low, level triggered, interrupt mapped to irq + 32 */
// Unmasked, Active low, level triggered, interrupt mapped to irq + 32
dprintf("IOAPIC redirection set %d -> %d\n", in, in + 32);
ioapic_redir_set(in, in + 32, 0, 0, 1, 1, 0);
}

/* PIT timer set to ridiculously low frequency, we don't seem to be able to disable it in qemu so at least
* lets make it less disruptive.
*/
outb(0x43, 0x36);
outb(0x40, 0xFF);
outb(0x40, 0xFF);

pic_remap(0x20, 0x28);
pic_disable();

/* Now we are safe to enable interrupts */
interrupts_on();
dprintf("Interrupts enabled!\n");
Expand Down
3 changes: 0 additions & 3 deletions src/interrupt.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ shared_interrupt_t* shared_interrupt[256] = { 0 };

void register_interrupt_handler(uint8_t n, isr_t handler, pci_dev_t device, void* opaque)
{
interrupts_off();
shared_interrupt_t* si = kmalloc(sizeof(shared_interrupt_t));
si->device = device;
si->interrupt_handler = handler;
Expand All @@ -20,7 +19,6 @@ void register_interrupt_handler(uint8_t n, isr_t handler, pci_dev_t device, void
if (si->next) {
dprintf("NOTE: %s %d is shared!\n", n < 32 ? "ISR" : "IRQ", n < 32 ? n : n - 32);
}
interrupts_on();
}

/**
Expand Down Expand Up @@ -68,7 +66,6 @@ void IRQ(uint64_t isrnumber, uint64_t irqnum)
}
}
}

/* IRQ7 is the APIC spurious interrupt, we never acknowledge it */
if (irqnum != IRQ7) {
local_apic_clear_interrupt();
Expand Down
6 changes: 3 additions & 3 deletions src/ioapic.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ void ioapic_register_write(uint32_t index, uint32_t value, ioapic_t *ioapic)
{
if (ioapic == NULL)
return;
uint32_t *mmio = (uint32_t*)ioapic->paddr;
volatile uint32_t *mmio = (volatile uint32_t*)ioapic->paddr;
mmio[0] = index & 0xFF;
mmio[4] = value;
}
Expand All @@ -18,9 +18,9 @@ uint32_t ioapic_register_read(uint32_t index, ioapic_t* ioapic)
{
if (ioapic == NULL)
return 0;
uint32_t *mmio = (uint32_t*) ioapic->paddr;
volatile uint32_t *mmio = (volatile uint32_t*) ioapic->paddr;
mmio[0] = index & 0xFF;
uint32_t ret = mmio[4];
volatile uint32_t ret = mmio[4];
return ret;
}

Expand Down

0 comments on commit da77095

Please sign in to comment.