Created
July 12, 2020 18:16
-
-
Save RiscInside/43ec03b296922bd6f7e5f7fcc1becf4a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <amd64/gdt.h> | |
#include <amd64/tss.h> | |
#include <memory/bdalloc.h> | |
#include <smp/percpu.h> | |
#define GDT_ENTRIES 7 | |
struct gdt { | |
uint64_t entries[GDT_ENTRIES]; | |
struct gdt_pointer { | |
uint16_t limit; | |
uint64_t base; | |
} PACKED pointer; | |
}; | |
extern void gdt_load(struct gdt_pointer *pointer); | |
void gdt_init(void) { | |
struct gdt *gdt = bdalloc_new(sizeof(struct gdt)); | |
assert(gdt != NULL, "[gdt] Panic: Failed to allocated GDT\n"); | |
gdt->entries[0] = 0; | |
gdt->entries[1] = (1LLU << 44) | (1LLU << 47) | (1LLU << 41LLU) | | |
(1LLU << 43) | (1LLU << 53); | |
gdt->entries[2] = (1LLU << 44) | (1LLU << 47) | (1LLU << 41LLU); | |
gdt->entries[3] = (1LLU << 44) | (1LLU << 47) | (1LLU << 41LLU) | | |
(1LLU << 43) | (1LLU << 53) | (1LLU << 46) | | |
(1LLU << 45); | |
gdt->entries[4] = (1LLU << 44) | (1LLU << 47) | (1LLU << 41LLU) | | |
(1LLU << 46) | (1LLU << 45); | |
uint64_t tss_base = (uint64_t)(percpu_get()->tss); | |
gdt->entries[5] = ((sizeof(struct tss_layout) - 1) & 0xffff) | | |
((tss_base & 0xffffff) << 16) | (0b1001LLU << 40) | | |
(1LLU << 47) | (((tss_base >> 24) & 0xff) << 56); | |
gdt->entries[6] = tss_base >> 32; | |
gdt->pointer.base = (uint64_t)(&(gdt->entries)); | |
gdt->pointer.limit = 8 * GDT_ENTRIES - 1; | |
gdt_load(&(gdt->pointer)); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef __GDT_H_INCLUDED__ | |
#define __GDT_H_INCLUDED__ | |
#include <utils.h> | |
void gdt_init(void); | |
#endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <amd64/idt.h> | |
#include <memory/bdalloc.h> | |
#include <smp/percpu.h> | |
struct idt_entry { | |
uint16_t addr_low; | |
uint16_t selector; | |
uint8_t ist : 3; | |
uint8_t zeroed1 : 5; | |
bool ints_enabled : 1; | |
uint8_t ones1 : 3; | |
uint8_t zeroed2 : 1; | |
uint8_t dpl : 2; | |
uint8_t present : 1; | |
uint16_t addr_middle; | |
uint32_t addr_high; | |
uint32_t zeroed3; | |
} PACKED; | |
struct idt_pointer { | |
uint16_t limit; | |
uint64_t base; | |
} PACKED; | |
struct idt { | |
struct idt_entry entries[256]; | |
struct idt_pointer pointer; | |
}; | |
extern void idt_load(struct idt_pointer *pointer); | |
void idt_handler(void) { | |
panic("Panic: Unhandled interrupt!!!"); | |
} | |
void idt_init(void) { | |
struct idt *idt = (struct idt *)bdalloc_new(sizeof(struct idt)); | |
assert(idt != NULL, "[idt] Panic: Failed to allocate IDT\n"); | |
memset(&(idt->entries), sizeof(idt->entries), 0); | |
idt->pointer.base = (uint64_t)(&idt); | |
idt->pointer.limit = 0x1000; | |
idt_load(&(idt->pointer)); | |
printf("IDT at %p\n", &(idt->pointer)); | |
percpu_get()->idt = idt; | |
for (uint64_t i = 0; i < 256; ++i) { | |
idt_set_gate(i, (uint64_t)idt_handler, 0, false); | |
} | |
} | |
void idt_set_gate(uint8_t index, uint64_t addr, uint8_t dpl, bool enable_ints) { | |
struct idt *idt = percpu_get()->idt; | |
struct idt_entry *entries = idt->entries; | |
entries[index].addr_low = (uint16_t)addr; | |
entries[index].addr_middle = (uint16_t)(addr >> 16); | |
entries[index].addr_high = (uint64_t)(addr >> 32); | |
entries[index].zeroed1 = 0; | |
entries[index].zeroed2 = 0; | |
entries[index].zeroed3 = 0; | |
entries[index].ints_enabled = enable_ints; | |
entries[index].ist = 0; | |
entries[index].dpl = dpl; | |
entries[index].ones1 = 0b111; | |
entries[index].selector = 0x8; | |
entries[index].present = true; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef __IDT_H_INCLUDED__ | |
#define __IDT_H_INLCUDED__ | |
#include <utils.h> | |
void idt_init(void); | |
void idt_set_gate(uint8_t vec, uint64_t addr, uint8_t dpl, bool enable_ints); | |
#endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <amd64/gdt.h> | |
#include <amd64/idt.h> | |
#include <amd64/tss.h> | |
#include <drivers/lapic.h> | |
#include <smp/percpu.h> | |
#include <smp/smp.h> | |
#include <spinlock.h> | |
#include <utils.h> | |
atomic_ulong cpu_count; | |
void smpmain() { | |
lapic_core_init(); | |
atomic_fetch_add(&cpu_count, 1); | |
while (atomic_load(&cpu_count) != smp_get_cpu_count()) { | |
asm("pause"); | |
} | |
percpu_storage_init(); | |
idt_init(); | |
tss_init(); | |
gdt_init(); | |
tss_load(); | |
printf("Started CPU %llu\n", percpu_get()->id); | |
asm("int $80"); | |
while (true) | |
; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <amd64/tss.h> | |
#include <memory/bdalloc.h> | |
#include <smp/percpu.h> | |
#include <utils.h> | |
void tss_init() { | |
struct tss_layout *tss = bdalloc_new(sizeof(struct tss_layout)); | |
assert(tss != NULL, "[tss] Panic: Failed to allocate TSS\n"); | |
memset(tss, sizeof(struct tss_layout), 0); | |
tss->iopb = sizeof(struct tss_layout); | |
// hack to get stack used by cpu | |
int val; | |
tss->rsp[0] = ALIGN_UP((uint64_t)(&val), 0x10000); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef __TSS_H_INCLUDED__ | |
#define __TSS_H_INCLUDED__ | |
#include <utils.h> | |
struct tss_layout { | |
uint32_t : 32; | |
uint64_t rsp[3]; | |
uint64_t : 64; | |
uint64_t ist[7]; | |
uint64_t : 64; | |
uint16_t : 16; | |
uint16_t iopb; | |
} PACKED; | |
void tss_init(void); | |
void tss_load(void); | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment