Debug multiboot, enable apic and ACPI table parsing

This commit is contained in:
Loic Guegan 2021-04-25 12:41:24 +02:00
parent 657372f1be
commit 7db6db5ae6
17 changed files with 226 additions and 19 deletions

View file

@ -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!

View file

@ -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;

View file

@ -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
View 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
View file

@ -0,0 +1,6 @@
#pragma once
void apic_enable();

23
src/core/asm.hpp Normal file
View 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))

View file

@ -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);

View file

@ -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;

View file

@ -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"

View file

@ -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);
}

View file

@ -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
View 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
View 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);

View file

@ -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;

View file

@ -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;

View file

@ -23,5 +23,5 @@ void printi(int i);
/**
* Print an integer as hex using itoh()
*/
void printh(int h);
void printh(u64 h);

View file

@ -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