Debug multiboot, enable apic and ACPI table parsing
This commit is contained in:
parent
657372f1be
commit
7db6db5ae6
17 changed files with 226 additions and 19 deletions
|
@ -109,7 +109,7 @@ mov %eax, %cr0
|
|||
# Now we are in Compatibility mode
|
||||
# Now we need to set CS.L=1 (setting up a 64 bit GDT)
|
||||
lgdt (gdtr)
|
||||
jmp $0x08, $new_cs
|
||||
ljmp $0x08, $new_cs
|
||||
new_cs:
|
||||
|
||||
# Pay attention here!
|
||||
|
|
|
@ -38,7 +38,7 @@ char mb2_find_new_rsdp(u32* mb2_info_addr, u64 *return_addr, u32 *return_size){
|
|||
u32* addr=mb2_find_tag(mb2_info_addr,15);
|
||||
if(addr){
|
||||
*return_size=addr[1];
|
||||
*return_addr=(u64)addr+2;
|
||||
*return_addr=(u64)(addr+2);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -48,7 +48,7 @@ char mb2_find_old_rsdp(u32* mb2_info_addr, u64 *return_addr, u32 *return_size){
|
|||
u32* addr=mb2_find_tag(mb2_info_addr,14);
|
||||
if(addr){
|
||||
*return_size=addr[1];
|
||||
*return_addr=(u64)addr+2;
|
||||
*return_addr=(u64)(addr+2);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#include "core/idt.hpp"
|
||||
#include "boot/multiboot2.hpp"
|
||||
#include "core/paging.hpp"
|
||||
#include "core/apic.hpp"
|
||||
#include "drivers/acpi.hpp"
|
||||
|
||||
extern u32 MB_INFO;
|
||||
|
||||
|
@ -11,11 +13,12 @@ extern "C" void boucane(){
|
|||
idt_enable_interrupt();
|
||||
|
||||
paging_enable();
|
||||
//apic_enable();
|
||||
|
||||
u64 p;
|
||||
u32 size;
|
||||
if(mb2_find_old_rsdp((u32*)MB_INFO,&p,&size)){
|
||||
printk("RSDP Table found!");
|
||||
acpi_load_madt((void*)p);
|
||||
}
|
||||
while(1);
|
||||
}
|
54
src/core/apic.cc
Normal file
54
src/core/apic.cc
Normal file
|
@ -0,0 +1,54 @@
|
|||
#include "apic.hpp"
|
||||
|
||||
#include "paging.hpp"
|
||||
#include "types.hpp"
|
||||
#include "asm.hpp"
|
||||
#include "libs/stdio.hpp"
|
||||
|
||||
extern u64* kpml4;
|
||||
char enable=0;
|
||||
#define APIC_LAPIC_ADDR 0xFEE00000
|
||||
#define APIC_IOAPIC_ADDR 0xFEC00000
|
||||
#define APIC_LAPIC_REG_SPURIOUS 0xF0
|
||||
|
||||
void apic_enable(){
|
||||
// Allocate APIC registers
|
||||
paging_allocate_addr(kpml4, APIC_LAPIC_ADDR, APIC_LAPIC_ADDR,
|
||||
PAGING_OPT_RW|PAGING_OPT_P|PAGING_OPT_PCD);
|
||||
paging_allocate_addr(kpml4, APIC_IOAPIC_ADDR, APIC_IOAPIC_ADDR,
|
||||
PAGING_OPT_RW|PAGING_OPT_P|PAGING_OPT_PCD);
|
||||
|
||||
// Configure APIC register location
|
||||
u32 h=APIC_LAPIC_ADDR>>32;
|
||||
u32 l=(APIC_LAPIC_ADDR&0xFFFFFFFF);
|
||||
l|=0x800; // Enable apic
|
||||
WRITE_MSR(0x1B,h,l);
|
||||
|
||||
// Enable apic 2
|
||||
u8 *c_base=(u8*)APIC_LAPIC_ADDR;
|
||||
c_base+=APIC_LAPIC_REG_SPURIOUS;
|
||||
u32* base=(u32*)c_base;
|
||||
*base=0x100|(*base);
|
||||
|
||||
u8 *c_base2=(u8*)APIC_IOAPIC_ADDR;
|
||||
u32* base2=(u32*)c_base2;
|
||||
*base2=0x12;
|
||||
base2=(u32*)(c_base2+0x10);
|
||||
*base2=(0x0<<12)|0x3C;
|
||||
enable=1;
|
||||
}
|
||||
|
||||
extern "C" void ack(){
|
||||
if(enable){
|
||||
u8 data;
|
||||
do {
|
||||
inb(0x64,data);
|
||||
}
|
||||
while((data&0x01) == 0);
|
||||
inb(0x60,data);
|
||||
|
||||
u8 *c_base=(u8*)(APIC_LAPIC_ADDR|0xB0);
|
||||
u32* base=(u32*)c_base;
|
||||
*base=*base|0;
|
||||
}
|
||||
}
|
6
src/core/apic.hpp
Normal file
6
src/core/apic.hpp
Normal file
|
@ -0,0 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
|
||||
|
||||
|
||||
void apic_enable();
|
23
src/core/asm.hpp
Normal file
23
src/core/asm.hpp
Normal file
|
@ -0,0 +1,23 @@
|
|||
#pragma once
|
||||
|
||||
#define READ_MSR(reg,high,low) \
|
||||
asm volatile( \
|
||||
"mov %2, %%ecx;rdmsr \n\t" \
|
||||
"mov %%edx, %0 \n\t" \
|
||||
"mov %%eax, %1" \
|
||||
: "=m" (high), "=m" (low) :"i" (reg))
|
||||
|
||||
#define WRITE_MSR(reg,high,low) \
|
||||
asm volatile( \
|
||||
"mov %1, %%edx \n\t" \
|
||||
"mov %2, %%eax \n\t" \
|
||||
"mov %0, %%ecx;wrmsr"::"i" (reg), "m" (high), "m" (low))
|
||||
|
||||
#define outb(port,value) \
|
||||
asm volatile ("outb %%al, %%dx" :: "a"(value), "d" (port) )
|
||||
|
||||
#define outbj(port,value) \
|
||||
asm volatile ("outb %%al, %%dx;" :: "a" (value), "d"(port) )
|
||||
|
||||
#define inb(port,dst) \
|
||||
asm volatile ("inb %%dx, %%al": "=a" (dst) : "d" (port))
|
|
@ -6,7 +6,7 @@ IDT_REGISTER IDTR = {
|
|||
IDT_ADDR
|
||||
};
|
||||
|
||||
extern u64 INT_DEFAULT,INT_0,INT_14;
|
||||
extern u64 INT_DEFAULT,INT_0,INT_14,INT_KBD;
|
||||
|
||||
void idt_enable_interrupt(void){
|
||||
IDT_DESCRIPTOR d;
|
||||
|
@ -25,6 +25,10 @@ void idt_enable_interrupt(void){
|
|||
d.offset=(u64)&INT_14;
|
||||
idt_write_descriptor(d, i);
|
||||
}
|
||||
else if(i==60){ // Page fault
|
||||
d.offset=(u64)&INT_KBD;
|
||||
idt_write_descriptor(d, i);
|
||||
}
|
||||
else {
|
||||
d.offset=(u64)&INT_DEFAULT;
|
||||
idt_write_descriptor(d, i);
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "libs/stdio.hpp"
|
||||
|
||||
#define IDT_GATE_SIZE 16
|
||||
#define IDT_MAX_ENTRIES 50
|
||||
#define IDT_MAX_ENTRIES 200
|
||||
#define IDT_ADDR 0x200000
|
||||
|
||||
#define IDT_OPT_P (1 << 15)
|
||||
|
@ -14,8 +14,6 @@
|
|||
#define IDT_OPT_PRVL_2 (2 << 13)
|
||||
#define IDT_OPT_PRVL_3 (3 << 13)
|
||||
|
||||
|
||||
|
||||
typedef struct IDT_REGISTER {
|
||||
u16 limit;
|
||||
u64 base;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
.extern printk
|
||||
.extern ack
|
||||
|
||||
.macro call_printk msg
|
||||
mov \msg, %rdi
|
||||
|
@ -26,8 +27,17 @@ INT_14:
|
|||
jmp INT_14_INFINITE
|
||||
iretq
|
||||
|
||||
.globl INT_KBD
|
||||
INT_KBD:
|
||||
call_printk $MSG_INT_KBD
|
||||
call ack
|
||||
iretq
|
||||
|
||||
MSG_INT_0:
|
||||
.asciz "Zero Division error!"
|
||||
MSG_INT_14:
|
||||
.asciz "Page fault!"
|
||||
MSG_INT_KBD:
|
||||
.asciz "Key press!"
|
||||
MSG:
|
||||
.asciz "Called :)\n"
|
|
@ -4,6 +4,7 @@
|
|||
#include "libs/string.hpp"
|
||||
|
||||
char paging_status[PAGING_MAX_PAGE / 8];
|
||||
u64* kpml4;
|
||||
|
||||
void paging_enable() {
|
||||
// Init status
|
||||
|
@ -16,16 +17,16 @@ void paging_enable() {
|
|||
paging_allocate_contiguous(PAGING_KERNEL_USED_PAGE);
|
||||
|
||||
// Setting up new kernel address space
|
||||
u64* pml4=paging_allocate_table();
|
||||
kpml4=paging_allocate_table();
|
||||
for(int i=0;i<PAGING_KERNEL_SPACE_MAX_PAGE;i++){
|
||||
int addr=i*4096;
|
||||
paging_allocate_addr(pml4,addr,addr, PAGING_OPT_P|PAGING_OPT_RW); // Identity map
|
||||
paging_allocate_addr(kpml4,addr,addr, PAGING_OPT_P|PAGING_OPT_RW); // Identity map
|
||||
}
|
||||
// Load new pml4
|
||||
asm volatile(
|
||||
"movq %0, %%rax \n\t"
|
||||
"movq %%rax, %%cr3 \n\t"
|
||||
:: "r" (pml4));
|
||||
:: "r" (kpml4));
|
||||
}
|
||||
|
||||
u64 paging_as_phy(u64* pml4_table, u64 virt){
|
||||
|
@ -166,8 +167,4 @@ void paging_allocate_addr(u64* pml4_table, u64 virt, u64 phy, u16 options){
|
|||
pt_table[pt]|=options;
|
||||
return;
|
||||
}
|
||||
|
||||
printk("Virtual address %x already in use. Kernel panic!",virt);
|
||||
while(1);
|
||||
|
||||
}
|
|
@ -14,6 +14,7 @@
|
|||
#define PAGING_ALLOCATE() paging_allocate_contiguous(1)
|
||||
#define PAGING_OPT_P 1
|
||||
#define PAGING_OPT_RW (1<<1)
|
||||
#define PAGING_OPT_PCD (1<<3)
|
||||
|
||||
/// @brief Get page address that contain addr
|
||||
#define PAGE(addr) (addr&(~(0xFFF)))
|
||||
|
|
64
src/drivers/acpi.cc
Normal file
64
src/drivers/acpi.cc
Normal file
|
@ -0,0 +1,64 @@
|
|||
#include "acpi.hpp"
|
||||
#include "core/paging.hpp"
|
||||
#include "drivers/framebuffer.hpp"
|
||||
#include "libs/stdio.hpp"
|
||||
#include "libs/string.hpp"
|
||||
|
||||
// TODO: ALL!
|
||||
|
||||
|
||||
char acpi_load_madt(void* rsdp_p){
|
||||
// Load RSDP
|
||||
RSDP rsdp;
|
||||
memcpy(rsdp_p, &rsdp, sizeof(rsdp));
|
||||
if(rsdp.signature!=ACPI_RSDP_SIGNATURE){
|
||||
printk("Invalid RSDP signature\n");
|
||||
return 1;
|
||||
}
|
||||
if(acpi_checksum(rsdp_p, 20)){
|
||||
printk("Wrong RSDP Signature\n\n");
|
||||
return 1;
|
||||
}
|
||||
printk("ACPI Revision %d detected!\n",rsdp.revision);
|
||||
|
||||
// Load RSDT
|
||||
RSDT rsdt;
|
||||
|
||||
paging_allocate_addr(kpml4,(u64)rsdp.rsdt_addr,(u64)rsdp.rsdt_addr,PAGING_OPT_P|PAGING_OPT_RW);
|
||||
memcpy((void*)rsdp.rsdt_addr, &rsdt, sizeof(rsdt));
|
||||
rsdt.first_entry_addr_ptr=rsdp.rsdt_addr+36;
|
||||
|
||||
if(rsdt.header.signature !=ACPI_RSDT_SIGNATURE){
|
||||
printk("Invalid RSDT signature\n");
|
||||
return 1;
|
||||
}
|
||||
if(acpi_checksum((void*)rsdp.rsdt_addr, rsdt.header.length)){
|
||||
printk("Wrong RSDT Signature\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Locate MADT
|
||||
for(int i=0;i<10;i++){
|
||||
u32 *addr=(u32*)(rsdt.first_entry_addr_ptr+i*4);
|
||||
u64 header_p_i=*addr;
|
||||
ACPI_TABLE_HEADER header;
|
||||
paging_allocate_addr(kpml4,header_p_i,header_p_i,PAGING_OPT_P|PAGING_OPT_RW);
|
||||
memcpy((void*)header_p_i, &header, sizeof(header));
|
||||
if(header.signature==ACPI_MADT_SIGNATURE){
|
||||
printk("MADT found!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char acpi_checksum(void* p, char size){
|
||||
char checksum=0;
|
||||
char* data_p=(char*)p;
|
||||
for(int i=0;i<size;i++){
|
||||
checksum+=data_p[i];
|
||||
}
|
||||
return (checksum!=0);
|
||||
}
|
43
src/drivers/acpi.hpp
Normal file
43
src/drivers/acpi.hpp
Normal file
|
@ -0,0 +1,43 @@
|
|||
#pragma once
|
||||
|
||||
#include "include/boucane.hpp"
|
||||
|
||||
#define ACPI_RSDP_SIGNATURE 0x2052545020445352
|
||||
#define ACPI_RSDT_SIGNATURE 0x54445352
|
||||
#define ACPI_MADT_SIGNATURE 0x43495041
|
||||
|
||||
typedef struct RSDP {
|
||||
u64 signature;
|
||||
u8 checksum;
|
||||
u64 oemid:48;
|
||||
u8 revision;
|
||||
u32 rsdt_addr;
|
||||
u32 length;
|
||||
} __attribute__((packed)) RSDP;
|
||||
|
||||
typedef struct ACPI_TABLE_HEADER {
|
||||
u32 signature;
|
||||
u32 length;
|
||||
u8 revision;
|
||||
u8 checksum;
|
||||
u64 oemid:48;
|
||||
u64 oem_table_id;
|
||||
u32 oem_revision;
|
||||
u32 creator_id;
|
||||
u32 creator_revision;
|
||||
} __attribute__((packed)) ACPI_TABLE_HEADER;
|
||||
|
||||
typedef struct RSDT {
|
||||
ACPI_TABLE_HEADER header;
|
||||
u32 first_entry_addr_ptr;
|
||||
} __attribute__((packed)) RSDT;
|
||||
|
||||
typedef struct INT_CTRL_HEADER {
|
||||
u8 type;
|
||||
u8 length;
|
||||
} __attribute__((packed)) INT_CTRL_HEADER;
|
||||
|
||||
|
||||
char acpi_load_madt(void* rsdp_p);
|
||||
char acpi_checksum(void* p, char size);
|
||||
|
|
@ -5,7 +5,9 @@
|
|||
#define VERSION_PATH 0
|
||||
|
||||
#include "core/types.hpp"
|
||||
#include "core/paging.hpp"
|
||||
#include "libs/math.hpp"
|
||||
#include "libs/stdio.hpp"
|
||||
#include "libs/string.hpp"
|
||||
|
||||
extern u64* kpml4;
|
|
@ -92,12 +92,12 @@ void print(char *s){
|
|||
}
|
||||
|
||||
void printi(int i) {
|
||||
char str[12];
|
||||
char str[50];
|
||||
itoa(i, str);
|
||||
print(str);
|
||||
}
|
||||
|
||||
void printh(int h) {
|
||||
void printh(u64 h) {
|
||||
char str[17];
|
||||
itoh(h, str);
|
||||
u8 i=0;
|
||||
|
|
|
@ -23,5 +23,5 @@ void printi(int i);
|
|||
/**
|
||||
* Print an integer as hex using itoh()
|
||||
*/
|
||||
void printh(int h);
|
||||
void printh(u64 h);
|
||||
|
||||
|
|
|
@ -26,9 +26,11 @@ void itoa(u64 i, char *a){
|
|||
|
||||
// Count number of digits
|
||||
u32 len=1;
|
||||
while(i/pow(10,len)>=1)
|
||||
u64 pow_value=i/pow(10,len);
|
||||
while(pow_value>=1)
|
||||
{
|
||||
len++;
|
||||
pow_value=i/pow(10,len);
|
||||
}
|
||||
|
||||
// Build string
|
||||
|
|
Loading…
Add table
Reference in a new issue