mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 08:24:32 -08:00
Split gdt.* from interrupts.*
This commit is contained in:
259
src/kernel/gdt.cpp
Normal file
259
src/kernel/gdt.cpp
Normal file
@@ -0,0 +1,259 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "kutil/assert.h"
|
||||
#include "kutil/enum_bitfields.h"
|
||||
#include "kutil/memory.h"
|
||||
#include "console.h"
|
||||
#include "log.h"
|
||||
|
||||
|
||||
enum class gdt_type : uint8_t
|
||||
{
|
||||
accessed = 0x01,
|
||||
read_write = 0x02,
|
||||
conforming = 0x04,
|
||||
execute = 0x08,
|
||||
system = 0x10,
|
||||
ring1 = 0x20,
|
||||
ring2 = 0x40,
|
||||
ring3 = 0x60,
|
||||
present = 0x80
|
||||
};
|
||||
IS_BITFIELD(gdt_type);
|
||||
|
||||
struct gdt_descriptor
|
||||
{
|
||||
uint16_t limit_low;
|
||||
uint16_t base_low;
|
||||
uint8_t base_mid;
|
||||
gdt_type type;
|
||||
uint8_t size;
|
||||
uint8_t base_high;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct tss_descriptor
|
||||
{
|
||||
uint16_t limit_low;
|
||||
uint16_t base_00;
|
||||
uint8_t base_16;
|
||||
gdt_type type;
|
||||
uint8_t size;
|
||||
uint8_t base_24;
|
||||
uint32_t base_32;
|
||||
uint32_t reserved;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct tss_entry
|
||||
{
|
||||
uint32_t reserved0;
|
||||
|
||||
uint64_t rsp[3]; // stack pointers for CPL 0-2
|
||||
uint64_t ist[8]; // ist[0] is reserved
|
||||
|
||||
uint64_t reserved1;
|
||||
uint16_t reserved2;
|
||||
uint16_t iomap_offset;
|
||||
};
|
||||
|
||||
struct idt_descriptor
|
||||
{
|
||||
uint16_t base_low;
|
||||
uint16_t selector;
|
||||
uint8_t ist;
|
||||
uint8_t flags;
|
||||
uint16_t base_mid;
|
||||
uint32_t base_high;
|
||||
uint32_t reserved; // must be zero
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct table_ptr
|
||||
{
|
||||
uint16_t limit;
|
||||
uint64_t base;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
gdt_descriptor g_gdt_table[10];
|
||||
idt_descriptor g_idt_table[256];
|
||||
table_ptr g_gdtr;
|
||||
table_ptr g_idtr;
|
||||
tss_entry g_tss;
|
||||
|
||||
|
||||
extern "C" {
|
||||
void idt_write();
|
||||
void idt_load();
|
||||
|
||||
void gdt_write(uint16_t cs, uint16_t ds, uint16_t tr);
|
||||
void gdt_load();
|
||||
}
|
||||
|
||||
void
|
||||
gdt_set_entry(uint8_t i, uint32_t base, uint64_t limit, bool is64, gdt_type type)
|
||||
{
|
||||
g_gdt_table[i].limit_low = limit & 0xffff;
|
||||
g_gdt_table[i].size = (limit >> 16) & 0xf;
|
||||
g_gdt_table[i].size |= (is64 ? 0xa0 : 0xc0);
|
||||
|
||||
g_gdt_table[i].base_low = base & 0xffff;
|
||||
g_gdt_table[i].base_mid = (base >> 16) & 0xff;
|
||||
g_gdt_table[i].base_high = (base >> 24) & 0xff;
|
||||
|
||||
g_gdt_table[i].type = type | gdt_type::system | gdt_type::present;
|
||||
}
|
||||
|
||||
void
|
||||
tss_set_entry(uint8_t i, uint64_t base, uint64_t limit)
|
||||
{
|
||||
tss_descriptor tssd;
|
||||
tssd.limit_low = limit & 0xffff;
|
||||
tssd.size = (limit >> 16) & 0xf;
|
||||
|
||||
tssd.base_00 = base & 0xffff;
|
||||
tssd.base_16 = (base >> 16) & 0xff;
|
||||
tssd.base_24 = (base >> 24) & 0xff;
|
||||
tssd.base_32 = (base >> 32) & 0xffffffff;
|
||||
|
||||
tssd.type =
|
||||
gdt_type::accessed |
|
||||
gdt_type::execute |
|
||||
gdt_type::ring3 |
|
||||
gdt_type::present;
|
||||
kutil::memcpy(&g_gdt_table[i], &tssd, sizeof(tss_descriptor));
|
||||
}
|
||||
|
||||
void
|
||||
idt_set_entry(uint8_t i, uint64_t addr, uint16_t selector, uint8_t flags)
|
||||
{
|
||||
g_idt_table[i].base_low = addr & 0xffff;
|
||||
g_idt_table[i].base_mid = (addr >> 16) & 0xffff;
|
||||
g_idt_table[i].base_high = (addr >> 32) & 0xffffffff;
|
||||
g_idt_table[i].selector = selector;
|
||||
g_idt_table[i].flags = flags;
|
||||
g_idt_table[i].ist = 0;
|
||||
g_idt_table[i].reserved = 0;
|
||||
}
|
||||
|
||||
void
|
||||
tss_set_stack(int ring, addr_t rsp)
|
||||
{
|
||||
kassert(ring < 3, "Bad ring passed to set_tss_stack.");
|
||||
g_tss.rsp[ring] = rsp;
|
||||
}
|
||||
|
||||
void
|
||||
gdt_init()
|
||||
{
|
||||
kutil::memset(&g_gdt_table, 0, sizeof(g_gdt_table));
|
||||
kutil::memset(&g_idt_table, 0, sizeof(g_idt_table));
|
||||
|
||||
g_gdtr.limit = sizeof(g_gdt_table) - 1;
|
||||
g_gdtr.base = reinterpret_cast<uint64_t>(&g_gdt_table);
|
||||
|
||||
gdt_set_entry(1, 0, 0xfffff, true, gdt_type::read_write | gdt_type::execute);
|
||||
gdt_set_entry(2, 0, 0xfffff, true, gdt_type::read_write);
|
||||
gdt_set_entry(3, 0, 0xfffff, true, gdt_type::ring3 | gdt_type::read_write | gdt_type::execute);
|
||||
gdt_set_entry(4, 0, 0xfffff, true, gdt_type::ring3 | gdt_type::read_write);
|
||||
|
||||
kutil::memset(&g_tss, 0, sizeof(tss_entry));
|
||||
addr_t tss_base = reinterpret_cast<addr_t>(&g_tss);
|
||||
|
||||
// Note that this takes TWO GDT entries
|
||||
tss_set_entry(6, tss_base, sizeof(tss_entry));
|
||||
|
||||
gdt_write(1 << 3, 2 << 3, 6 << 3);
|
||||
|
||||
g_idtr.limit = sizeof(g_idt_table) - 1;
|
||||
g_idtr.base = reinterpret_cast<uint64_t>(&g_idt_table);
|
||||
|
||||
idt_write();
|
||||
}
|
||||
|
||||
void
|
||||
gdt_dump()
|
||||
{
|
||||
const table_ptr &table = g_gdtr;
|
||||
|
||||
console *cons = console::get();
|
||||
cons->printf(" GDT: loc:%lx size:%d\n", table.base, table.limit+1);
|
||||
|
||||
int count = (table.limit + 1) / sizeof(gdt_descriptor);
|
||||
const gdt_descriptor *gdt =
|
||||
reinterpret_cast<const gdt_descriptor *>(table.base);
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
uint32_t base =
|
||||
(gdt[i].base_high << 24) |
|
||||
(gdt[i].base_mid << 16) |
|
||||
gdt[i].base_low;
|
||||
|
||||
uint32_t limit =
|
||||
static_cast<uint32_t>(gdt[i].size & 0x0f) << 16 |
|
||||
gdt[i].limit_low;
|
||||
|
||||
cons->printf(" %02d:", i);
|
||||
if (! bitfield_has(gdt[i].type, gdt_type::present)) {
|
||||
cons->puts(" Not Present\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
cons->printf(" Base %08x limit %05x ", base, limit);
|
||||
|
||||
switch (gdt[i].type & gdt_type::ring3) {
|
||||
case gdt_type::ring3: cons->puts("ring3"); break;
|
||||
case gdt_type::ring2: cons->puts("ring2"); break;
|
||||
case gdt_type::ring1: cons->puts("ring1"); break;
|
||||
default: cons->puts("ring0"); break;
|
||||
}
|
||||
|
||||
cons->printf(" %s %s %s %s %s %s %s\n",
|
||||
bitfield_has(gdt[i].type, gdt_type::accessed) ? "A" : " ",
|
||||
bitfield_has(gdt[i].type, gdt_type::read_write) ? "RW" : " ",
|
||||
bitfield_has(gdt[i].type, gdt_type::conforming) ? "C" : " ",
|
||||
bitfield_has(gdt[i].type, gdt_type::execute) ? "EX" : " ",
|
||||
bitfield_has(gdt[i].type, gdt_type::system) ? "S" : " ",
|
||||
(gdt[i].size & 0x80) ? "KB" : " B",
|
||||
(gdt[i].size & 0x60) == 0x20 ? "64" :
|
||||
(gdt[i].size & 0x60) == 0x40 ? "32" : "16");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
idt_dump()
|
||||
{
|
||||
const table_ptr &table = g_idtr;
|
||||
|
||||
log::info(logs::boot, "Loaded IDT at: %lx size: %d bytes", table.base, table.limit+1);
|
||||
|
||||
int count = (table.limit + 1) / sizeof(idt_descriptor);
|
||||
const idt_descriptor *idt =
|
||||
reinterpret_cast<const idt_descriptor *>(table.base);
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
uint64_t base =
|
||||
(static_cast<uint64_t>(idt[i].base_high) << 32) |
|
||||
(static_cast<uint64_t>(idt[i].base_mid) << 16) |
|
||||
idt[i].base_low;
|
||||
|
||||
char const *type;
|
||||
switch (idt[i].flags & 0xf) {
|
||||
case 0x5: type = " 32tsk "; break;
|
||||
case 0x6: type = " 16int "; break;
|
||||
case 0x7: type = " 16trp "; break;
|
||||
case 0xe: type = " 32int "; break;
|
||||
case 0xf: type = " 32trp "; break;
|
||||
default: type = " ????? "; break;
|
||||
}
|
||||
|
||||
if (idt[i].flags & 0x80) {
|
||||
log::debug(logs::boot,
|
||||
" Entry %3d: Base:%lx Sel(rpl %d, ti %d, %3d) IST:%d %s DPL:%d", i, base,
|
||||
(idt[i].selector & 0x3),
|
||||
((idt[i].selector & 0x4) >> 2),
|
||||
(idt[i].selector >> 3),
|
||||
idt[i].ist,
|
||||
type,
|
||||
((idt[i].flags >> 5) & 0x3));
|
||||
}
|
||||
}
|
||||
}
|
||||
27
src/kernel/gdt.h
Normal file
27
src/kernel/gdt.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
/// \file gdt.h
|
||||
/// Definitions relating to system descriptor tables: GDT, IDT, TSS
|
||||
#include <stdint.h>
|
||||
#include "kutil/memory.h"
|
||||
|
||||
/// Set up the GDT and TSS, and switch segment registers to point
|
||||
/// to them.
|
||||
void gdt_init();
|
||||
|
||||
/// Set an entry in the IDT
|
||||
/// \arg i Index in the IDT (vector of the interrupt this handles)
|
||||
/// \arg addr Address of the handler
|
||||
/// \arg selector GDT selector to set when invoking this handler
|
||||
/// \arg flags Descriptor flags to set
|
||||
void idt_set_entry(uint8_t i, uint64_t addr, uint16_t selector, uint8_t flags);
|
||||
|
||||
/// Set the stack pointer for a given ring in the TSS
|
||||
/// \arg ring Ring to set for (0-2)
|
||||
/// \arg rsp Stack pointer to set
|
||||
void tss_set_stack(int ring, addr_t rsp);
|
||||
|
||||
/// Dump information about the current GDT to the screen
|
||||
void gdt_dump();
|
||||
|
||||
/// Dump information about the current IDT to the screen
|
||||
void idt_dump();
|
||||
@@ -1,94 +1,15 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "kutil/enum_bitfields.h"
|
||||
#include "kutil/memory.h"
|
||||
#include "console.h"
|
||||
#include "device_manager.h"
|
||||
#include "gdt.h"
|
||||
#include "interrupts.h"
|
||||
#include "io.h"
|
||||
#include "log.h"
|
||||
|
||||
enum class gdt_type : uint8_t
|
||||
{
|
||||
accessed = 0x01,
|
||||
read_write = 0x02,
|
||||
conforming = 0x04,
|
||||
execute = 0x08,
|
||||
system = 0x10,
|
||||
ring1 = 0x20,
|
||||
ring2 = 0x40,
|
||||
ring3 = 0x60,
|
||||
present = 0x80
|
||||
};
|
||||
IS_BITFIELD(gdt_type);
|
||||
|
||||
struct gdt_descriptor
|
||||
{
|
||||
uint16_t limit_low;
|
||||
uint16_t base_low;
|
||||
uint8_t base_mid;
|
||||
gdt_type type;
|
||||
uint8_t size;
|
||||
uint8_t base_high;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct idt_descriptor
|
||||
{
|
||||
uint16_t base_low;
|
||||
uint16_t selector;
|
||||
uint8_t ist;
|
||||
uint8_t flags;
|
||||
uint16_t base_mid;
|
||||
uint32_t base_high;
|
||||
uint32_t reserved; // must be zero
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct tss_descriptor
|
||||
{
|
||||
uint16_t limit_low;
|
||||
uint16_t base_00;
|
||||
uint8_t base_16;
|
||||
gdt_type type;
|
||||
uint8_t size;
|
||||
uint8_t base_24;
|
||||
uint32_t base_32;
|
||||
uint32_t reserved;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct tss_entry
|
||||
{
|
||||
uint32_t reserved0;
|
||||
|
||||
uint64_t rsp[3]; // stack pointers for CPL 0-2
|
||||
uint64_t ist[8]; // ist[0] is reserved
|
||||
|
||||
uint64_t reserved1;
|
||||
uint16_t reserved2;
|
||||
uint16_t iomap_offset;
|
||||
};
|
||||
|
||||
struct table_ptr
|
||||
{
|
||||
uint16_t limit;
|
||||
uint64_t base;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
gdt_descriptor g_gdt_table[10];
|
||||
idt_descriptor g_idt_table[256];
|
||||
table_ptr g_gdtr;
|
||||
table_ptr g_idtr;
|
||||
tss_entry g_tss;
|
||||
|
||||
struct registers;
|
||||
|
||||
extern "C" {
|
||||
void idt_write();
|
||||
void idt_load();
|
||||
|
||||
void gdt_write(uint16_t cs, uint16_t ds, uint16_t tr);
|
||||
void gdt_load();
|
||||
|
||||
void isr_handler(registers);
|
||||
void irq_handler(registers);
|
||||
|
||||
@@ -101,9 +22,6 @@ extern "C" {
|
||||
#undef ISR
|
||||
}
|
||||
|
||||
void idt_dump(const table_ptr &table);
|
||||
void gdt_dump(const table_ptr &table);
|
||||
|
||||
isr
|
||||
operator+(const isr &lhs, int rhs)
|
||||
{
|
||||
@@ -127,52 +45,6 @@ get_irq(unsigned vector)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
set_gdt_entry(uint8_t i, uint32_t base, uint64_t limit, bool is64, gdt_type type)
|
||||
{
|
||||
g_gdt_table[i].limit_low = limit & 0xffff;
|
||||
g_gdt_table[i].size = (limit >> 16) & 0xf;
|
||||
g_gdt_table[i].size |= (is64 ? 0xa0 : 0xc0);
|
||||
|
||||
g_gdt_table[i].base_low = base & 0xffff;
|
||||
g_gdt_table[i].base_mid = (base >> 16) & 0xff;
|
||||
g_gdt_table[i].base_high = (base >> 24) & 0xff;
|
||||
|
||||
g_gdt_table[i].type = type | gdt_type::system | gdt_type::present;
|
||||
}
|
||||
|
||||
void
|
||||
set_tss_entry(uint8_t i, uint64_t base, uint64_t limit)
|
||||
{
|
||||
tss_descriptor tssd;
|
||||
tssd.limit_low = limit & 0xffff;
|
||||
tssd.size = (limit >> 16) & 0xf;
|
||||
|
||||
tssd.base_00 = base & 0xffff;
|
||||
tssd.base_16 = (base >> 16) & 0xff;
|
||||
tssd.base_24 = (base >> 24) & 0xff;
|
||||
tssd.base_32 = (base >> 32) & 0xffffffff;
|
||||
|
||||
tssd.type =
|
||||
gdt_type::accessed |
|
||||
gdt_type::execute |
|
||||
gdt_type::ring3 |
|
||||
gdt_type::present;
|
||||
kutil::memcpy(&g_gdt_table[i], &tssd, sizeof(tss_descriptor));
|
||||
}
|
||||
|
||||
void
|
||||
set_idt_entry(uint8_t i, uint64_t addr, uint16_t selector, uint8_t flags)
|
||||
{
|
||||
g_idt_table[i].base_low = addr & 0xffff;
|
||||
g_idt_table[i].base_mid = (addr >> 16) & 0xffff;
|
||||
g_idt_table[i].base_high = (addr >> 32) & 0xffffffff;
|
||||
g_idt_table[i].selector = selector;
|
||||
g_idt_table[i].flags = flags;
|
||||
g_idt_table[i].ist = 0;
|
||||
g_idt_table[i].reserved = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
disable_legacy_pic()
|
||||
{
|
||||
@@ -207,39 +79,14 @@ enable_serial_interrupts()
|
||||
void
|
||||
interrupts_init()
|
||||
{
|
||||
kutil::memset(&g_gdt_table, 0, sizeof(g_gdt_table));
|
||||
kutil::memset(&g_idt_table, 0, sizeof(g_idt_table));
|
||||
|
||||
g_gdtr.limit = sizeof(g_gdt_table) - 1;
|
||||
g_gdtr.base = reinterpret_cast<uint64_t>(&g_gdt_table);
|
||||
|
||||
set_gdt_entry(1, 0, 0xfffff, true, gdt_type::read_write | gdt_type::execute);
|
||||
set_gdt_entry(2, 0, 0xfffff, true, 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, true, gdt_type::ring3 | gdt_type::read_write);
|
||||
|
||||
kutil::memset(&g_tss, 0, sizeof(tss_entry));
|
||||
addr_t tss_base = reinterpret_cast<addr_t>(&g_tss);
|
||||
|
||||
// Note that this takes TWO GDT entries
|
||||
set_tss_entry(6, tss_base, sizeof(tss_entry));
|
||||
// TODO: Set up TSS stack pointers!
|
||||
|
||||
gdt_write(1 << 3, 2 << 3, 6 << 3);
|
||||
|
||||
g_idtr.limit = sizeof(g_idt_table) - 1;
|
||||
g_idtr.base = reinterpret_cast<uint64_t>(&g_idt_table);
|
||||
|
||||
#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), 0x08, 0x8e);
|
||||
#define IRQ(i, q, name) set_idt_entry(i, reinterpret_cast<uint64_t>(& name), 0x08, 0x8e);
|
||||
#define ISR(i, name) idt_set_entry(i, reinterpret_cast<uint64_t>(& name), 0x08, 0x8e);
|
||||
#define EISR(i, name) idt_set_entry(i, reinterpret_cast<uint64_t>(& name), 0x08, 0x8e);
|
||||
#define IRQ(i, q, name) idt_set_entry(i, reinterpret_cast<uint64_t>(& name), 0x08, 0x8e);
|
||||
#include "interrupt_isrs.inc"
|
||||
#undef IRQ
|
||||
#undef EISR
|
||||
#undef ISR
|
||||
|
||||
idt_write();
|
||||
|
||||
disable_legacy_pic();
|
||||
enable_serial_interrupts();
|
||||
|
||||
@@ -316,13 +163,13 @@ isr_handler(registers regs)
|
||||
switch (regs.errorcode & 0x06) {
|
||||
case 0:
|
||||
cons->printf(" GDT[%d]\n", index);
|
||||
gdt_dump(g_gdtr);
|
||||
gdt_dump();
|
||||
break;
|
||||
|
||||
case 1:
|
||||
case 3:
|
||||
cons->printf(" IDT[%d]\n", index);
|
||||
idt_dump(g_idtr);
|
||||
idt_dump();
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -479,88 +326,3 @@ irq_handler(registers regs)
|
||||
*reinterpret_cast<uint32_t *>(0xffffff80fee000b0) = 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gdt_dump(const table_ptr &table)
|
||||
{
|
||||
console *cons = console::get();
|
||||
cons->printf(" GDT: loc:%lx size:%d\n", table.base, table.limit+1);
|
||||
|
||||
int count = (table.limit + 1) / sizeof(gdt_descriptor);
|
||||
const gdt_descriptor *gdt =
|
||||
reinterpret_cast<const gdt_descriptor *>(table.base);
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
uint32_t base =
|
||||
(gdt[i].base_high << 24) |
|
||||
(gdt[i].base_mid << 16) |
|
||||
gdt[i].base_low;
|
||||
|
||||
uint32_t limit =
|
||||
static_cast<uint32_t>(gdt[i].size & 0x0f) << 16 |
|
||||
gdt[i].limit_low;
|
||||
|
||||
cons->printf(" %02d:", i);
|
||||
if (! bitfield_has(gdt[i].type, gdt_type::present)) {
|
||||
cons->puts(" Not Present\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
cons->printf(" Base %08x limit %05x ", base, limit);
|
||||
|
||||
switch (gdt[i].type & gdt_type::ring3) {
|
||||
case gdt_type::ring3: cons->puts("ring3"); break;
|
||||
case gdt_type::ring2: cons->puts("ring2"); break;
|
||||
case gdt_type::ring1: cons->puts("ring1"); break;
|
||||
default: cons->puts("ring0"); break;
|
||||
}
|
||||
|
||||
cons->printf(" %s %s %s %s %s %s %s\n",
|
||||
bitfield_has(gdt[i].type, gdt_type::accessed) ? "A" : " ",
|
||||
bitfield_has(gdt[i].type, gdt_type::read_write) ? "RW" : " ",
|
||||
bitfield_has(gdt[i].type, gdt_type::conforming) ? "C" : " ",
|
||||
bitfield_has(gdt[i].type, gdt_type::execute) ? "EX" : " ",
|
||||
bitfield_has(gdt[i].type, gdt_type::system) ? "S" : " ",
|
||||
(gdt[i].size & 0x80) ? "KB" : " B",
|
||||
(gdt[i].size & 0x60) == 0x20 ? "64" :
|
||||
(gdt[i].size & 0x60) == 0x40 ? "32" : "16");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
idt_dump(const table_ptr &table)
|
||||
{
|
||||
log::info(logs::boot, "Loaded IDT at: %lx size: %d bytes", table.base, table.limit+1);
|
||||
|
||||
int count = (table.limit + 1) / sizeof(idt_descriptor);
|
||||
const idt_descriptor *idt =
|
||||
reinterpret_cast<const idt_descriptor *>(table.base);
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
uint64_t base =
|
||||
(static_cast<uint64_t>(idt[i].base_high) << 32) |
|
||||
(static_cast<uint64_t>(idt[i].base_mid) << 16) |
|
||||
idt[i].base_low;
|
||||
|
||||
char const *type;
|
||||
switch (idt[i].flags & 0xf) {
|
||||
case 0x5: type = " 32tsk "; break;
|
||||
case 0x6: type = " 16int "; break;
|
||||
case 0x7: type = " 16trp "; break;
|
||||
case 0xe: type = " 32int "; break;
|
||||
case 0xf: type = " 32trp "; break;
|
||||
default: type = " ????? "; break;
|
||||
}
|
||||
|
||||
if (idt[i].flags & 0x80) {
|
||||
log::debug(logs::boot,
|
||||
" Entry %3d: Base:%lx Sel(rpl %d, ti %d, %3d) IST:%d %s DPL:%d", i, base,
|
||||
(idt[i].selector & 0x3),
|
||||
((idt[i].selector & 0x4) >> 2),
|
||||
(idt[i].selector >> 3),
|
||||
idt[i].ist,
|
||||
type,
|
||||
((idt[i].flags >> 5) & 0x3));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,11 +17,17 @@ enum class isr : uint8_t
|
||||
_zero = 0
|
||||
};
|
||||
|
||||
/// Helper operator to add an offset to an isr vector
|
||||
isr operator+(const isr &lhs, int rhs);
|
||||
|
||||
extern "C" {
|
||||
/// Set the CPU interrupt enable flag (sti)
|
||||
void interrupts_enable();
|
||||
|
||||
/// Set the CPU interrupt disable flag (cli)
|
||||
void interrupts_disable();
|
||||
}
|
||||
|
||||
/// Fill the IDT with our ISRs, and disable the legacy
|
||||
/// PIC interrupts.
|
||||
void interrupts_init();
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "cpu.h"
|
||||
#include "device_manager.h"
|
||||
#include "font.h"
|
||||
#include "gdt.h"
|
||||
#include "interrupts.h"
|
||||
#include "io.h"
|
||||
#include "kernel_data.h"
|
||||
@@ -66,6 +67,9 @@ kernel_main(popcorn_data *header)
|
||||
{
|
||||
kutil::assert_set_callback(__kernel_assert);
|
||||
|
||||
gdt_init();
|
||||
interrupts_init();
|
||||
|
||||
page_manager *pager = new (&g_page_manager) page_manager;
|
||||
|
||||
memory_initialize(
|
||||
@@ -80,7 +84,6 @@ kernel_main(popcorn_data *header)
|
||||
init_console(header);
|
||||
// pager->dump_blocks();
|
||||
|
||||
interrupts_init();
|
||||
|
||||
device_manager *devices =
|
||||
new (&device_manager::get()) device_manager(header->acpi_table);
|
||||
|
||||
Reference in New Issue
Block a user