mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 08:24:32 -08:00
Change GDT code to enforce correct CS
This commit is contained in:
@@ -61,7 +61,7 @@ extern "C" {
|
|||||||
void idt_write();
|
void idt_write();
|
||||||
void idt_load();
|
void idt_load();
|
||||||
|
|
||||||
void gdt_write();
|
void gdt_write(uint16_t cs, uint16_t ds);
|
||||||
void gdt_load();
|
void gdt_load();
|
||||||
|
|
||||||
void isr_handler(registers);
|
void isr_handler(registers);
|
||||||
@@ -168,28 +168,26 @@ interrupts_init()
|
|||||||
g_gdtr.limit = sizeof(g_gdt_table) - 1;
|
g_gdtr.limit = sizeof(g_gdt_table) - 1;
|
||||||
g_gdtr.base = reinterpret_cast<uint64_t>(&g_gdt_table);
|
g_gdtr.base = reinterpret_cast<uint64_t>(&g_gdt_table);
|
||||||
|
|
||||||
set_gdt_entry(1, 0, 0xfffff, false, gdt_type::read_write);
|
set_gdt_entry(1, 0, 0xfffff, true, gdt_type::read_write | gdt_type::execute);
|
||||||
set_gdt_entry(2, 0, 0xfffff, false, gdt_type::read_write | gdt_type::execute | gdt_type::conforming);
|
set_gdt_entry(2, 0, 0xfffff, true, gdt_type::read_write);
|
||||||
set_gdt_entry(3, 0, 0xfffff, false, gdt_type::read_write);
|
set_gdt_entry(3, 0, 0xfffff, true, gdt_type::ring3 | gdt_type::read_write | gdt_type::execute);
|
||||||
set_gdt_entry(4, 0, 0xfffff, false, gdt_type::read_write | gdt_type::execute);
|
set_gdt_entry(4, 0, 0xfffff, true, gdt_type::ring3 | gdt_type::read_write);
|
||||||
|
|
||||||
set_gdt_entry(6, 0, 0xfffff, false, gdt_type::read_write);
|
gdt_write(1 << 3, 2 << 3);
|
||||||
set_gdt_entry(7, 0, 0xfffff, true, gdt_type::read_write | gdt_type::execute);
|
|
||||||
|
|
||||||
gdt_write();
|
|
||||||
|
|
||||||
g_idtr.limit = sizeof(g_idt_table) - 1;
|
g_idtr.limit = sizeof(g_idt_table) - 1;
|
||||||
g_idtr.base = reinterpret_cast<uint64_t>(&g_idt_table);
|
g_idtr.base = reinterpret_cast<uint64_t>(&g_idt_table);
|
||||||
|
|
||||||
#define ISR(i, name) set_idt_entry(i, reinterpret_cast<uint64_t>(& name), 0x38, 0x8e);
|
#define ISR(i, name) set_idt_entry(i, reinterpret_cast<uint64_t>(& name), 0x08, 0x8e);
|
||||||
#define EISR(i, name) set_idt_entry(i, reinterpret_cast<uint64_t>(& name), 0x38, 0x8e);
|
#define EISR(i, name) set_idt_entry(i, reinterpret_cast<uint64_t>(& name), 0x08, 0x8e);
|
||||||
#define IRQ(i, q, name) set_idt_entry(i, reinterpret_cast<uint64_t>(& name), 0x38, 0x8e);
|
#define IRQ(i, q, name) set_idt_entry(i, reinterpret_cast<uint64_t>(& name), 0x08, 0x8e);
|
||||||
#include "interrupt_isrs.inc"
|
#include "interrupt_isrs.inc"
|
||||||
#undef IRQ
|
#undef IRQ
|
||||||
#undef EISR
|
#undef EISR
|
||||||
#undef ISR
|
#undef ISR
|
||||||
|
|
||||||
idt_write();
|
idt_write();
|
||||||
|
|
||||||
disable_legacy_pic();
|
disable_legacy_pic();
|
||||||
enable_serial_interrupts();
|
enable_serial_interrupts();
|
||||||
|
|
||||||
@@ -284,9 +282,34 @@ isr_handler(registers regs)
|
|||||||
cons->putc('\n');
|
cons->putc('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cons->puts("\n");
|
||||||
|
print_reg(" ds", regs.ds);
|
||||||
|
print_reg(" cs", regs.cs);
|
||||||
|
print_reg(" ss", regs.ss);
|
||||||
|
|
||||||
|
|
||||||
|
cons->puts("\n");
|
||||||
|
print_reg("rax", regs.rax);
|
||||||
|
print_reg("rbx", regs.rbx);
|
||||||
|
print_reg("rcx", regs.rcx);
|
||||||
|
print_reg("rdx", regs.rdx);
|
||||||
|
print_reg("rdi", regs.rdi);
|
||||||
|
print_reg("rsi", regs.rsi);
|
||||||
|
|
||||||
|
cons->puts("\n");
|
||||||
|
print_reg("rbp", regs.rbp);
|
||||||
|
print_reg("rsp", regs.rsp);
|
||||||
|
|
||||||
cons->puts("\n");
|
cons->puts("\n");
|
||||||
print_reg("rip", regs.rip);
|
print_reg("rip", regs.rip);
|
||||||
print_stacktrace(2);
|
print_stacktrace(2);
|
||||||
|
|
||||||
|
cons->puts("\nStack:\n");
|
||||||
|
uint64_t sp = regs.rsp;
|
||||||
|
while (sp <= regs.rbp) {
|
||||||
|
cons->printf("%016x: %016x\n", sp, *reinterpret_cast<uint64_t *>(sp));
|
||||||
|
sp += sizeof(uint64_t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
while(1) asm("hlt");
|
while(1) asm("hlt");
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -14,6 +14,17 @@ idt_load:
|
|||||||
global gdt_write
|
global gdt_write
|
||||||
gdt_write:
|
gdt_write:
|
||||||
lgdt [rel g_gdtr]
|
lgdt [rel g_gdtr]
|
||||||
|
mov ax, si ; second arg is data segment
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
mov fs, ax
|
||||||
|
mov gs, ax
|
||||||
|
mov ss, ax
|
||||||
|
push qword rdi ; first arg is code segment
|
||||||
|
lea rax, [rel .next]
|
||||||
|
push rax
|
||||||
|
o64 retf
|
||||||
|
.next:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
global gdt_load
|
global gdt_load
|
||||||
|
|||||||
@@ -3,20 +3,29 @@
|
|||||||
#include "interrupts.h"
|
#include "interrupts.h"
|
||||||
#include "pci.h"
|
#include "pci.h"
|
||||||
|
|
||||||
struct pci_cap_msi :
|
struct pci_cap_msi
|
||||||
public pci_cap
|
|
||||||
{
|
{
|
||||||
|
pci_cap::type id;
|
||||||
|
uint8_t next;
|
||||||
uint16_t control;
|
uint16_t control;
|
||||||
uint64_t address;
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct pci_cap_msi32
|
||||||
|
{
|
||||||
|
pci_cap::type id;
|
||||||
|
uint8_t next;
|
||||||
|
uint16_t control;
|
||||||
|
uint32_t address;
|
||||||
uint16_t data;
|
uint16_t data;
|
||||||
uint16_t reserved;
|
uint16_t reserved;
|
||||||
uint32_t mask;
|
uint32_t mask;
|
||||||
uint32_t pending;
|
uint32_t pending;
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
struct pci_cap_msix :
|
struct pci_cap_msi64
|
||||||
public pci_cap
|
|
||||||
{
|
{
|
||||||
|
pci_cap::type id;
|
||||||
|
uint8_t next;
|
||||||
uint16_t control;
|
uint16_t control;
|
||||||
uint64_t address;
|
uint64_t address;
|
||||||
uint16_t data;
|
uint16_t data;
|
||||||
@@ -68,11 +77,13 @@ pci_device::pci_device(pci_group &group, uint8_t bus, uint8_t device, uint8_t fu
|
|||||||
while (next) {
|
while (next) {
|
||||||
pci_cap *cap = reinterpret_cast<pci_cap *>(kutil::offset_pointer(m_base, next));
|
pci_cap *cap = reinterpret_cast<pci_cap *>(kutil::offset_pointer(m_base, next));
|
||||||
next = cap->next;
|
next = cap->next;
|
||||||
|
log::debug(logs::device, " - found PCI cap type %02x", cap->id);
|
||||||
|
|
||||||
if (cap->id == pci_cap::type::msi) {
|
if (cap->id == pci_cap::type::msi) {
|
||||||
m_msi = cap;
|
m_msi = cap;
|
||||||
pci_cap_msi *mcap = reinterpret_cast<pci_cap_msi *>(cap);
|
pci_cap_msi *mcap = reinterpret_cast<pci_cap_msi *>(cap);
|
||||||
mcap->control |= ~0x1; // Mask interrupts
|
mcap->control |= ~0x1; // Mask interrupts
|
||||||
|
log::debug(logs::device, " - MSI control %08x", mcap->control);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -111,9 +122,24 @@ pci_device::write_msi_regs(addr_t address, uint16_t data)
|
|||||||
kassert(m_msi, "Tried to write MSI for a device without that cap");
|
kassert(m_msi, "Tried to write MSI for a device without that cap");
|
||||||
if (m_msi->id == pci_cap::type::msi) {
|
if (m_msi->id == pci_cap::type::msi) {
|
||||||
pci_cap_msi *mcap = reinterpret_cast<pci_cap_msi *>(m_msi);
|
pci_cap_msi *mcap = reinterpret_cast<pci_cap_msi *>(m_msi);
|
||||||
mcap->address = address;
|
if (mcap->control & 0x0080) {
|
||||||
mcap->data = data;
|
pci_cap_msi64 *mcap64 = reinterpret_cast<pci_cap_msi64 *>(m_msi);
|
||||||
mcap->control |= 1;
|
mcap64->address = address;
|
||||||
|
mcap64->data = data;
|
||||||
|
if (mcap64->control & 0x0100)
|
||||||
|
log::debug(logs::device, " - MSI mask %08x pending %08x", mcap64->mask, mcap64->pending);
|
||||||
|
} else {
|
||||||
|
pci_cap_msi32 *mcap32 = reinterpret_cast<pci_cap_msi32 *>(m_msi);
|
||||||
|
mcap32->address = address;
|
||||||
|
mcap32->data = data;
|
||||||
|
if (mcap32->control & 0x0100)
|
||||||
|
log::debug(logs::device, " - MSI mask %08x pending %08x", mcap32->mask, mcap32->pending);
|
||||||
|
}
|
||||||
|
uint16_t control = mcap->control;
|
||||||
|
control &= 0xff8f; // We're allocating one vector, clear 6::4
|
||||||
|
control |= 0x0001; // Enable MSI
|
||||||
|
mcap->control = control;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
kassert(0, "MIS-X is NYI");
|
kassert(0, "MIS-X is NYI");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user