aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/boot/boot.S2
-rw-r--r--src/boot/multiboot2.cc4
-rw-r--r--src/boucane.cc5
-rw-r--r--src/core/apic.cc54
-rw-r--r--src/core/apic.hpp6
-rw-r--r--src/core/asm.hpp23
-rw-r--r--src/core/idt.cc6
-rw-r--r--src/core/idt.hpp4
-rw-r--r--src/core/int.S10
-rw-r--r--src/core/paging.cc11
-rw-r--r--src/core/paging.hpp1
-rw-r--r--src/drivers/acpi.cc64
-rw-r--r--src/drivers/acpi.hpp43
-rw-r--r--src/include/boucane.hpp2
-rw-r--r--src/libs/stdio.cc4
-rw-r--r--src/libs/stdio.hpp2
-rw-r--r--src/libs/string.cc4
17 files changed, 226 insertions, 19 deletions
diff --git a/src/boot/boot.S b/src/boot/boot.S
index 5e4d82c..029a67e 100644
--- a/src/boot/boot.S
+++ b/src/boot/boot.S
@@ -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!
diff --git a/src/boot/multiboot2.cc b/src/boot/multiboot2.cc
index b0e8c14..1b661b8 100644
--- a/src/boot/multiboot2.cc
+++ b/src/boot/multiboot2.cc
@@ -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;
diff --git a/src/boucane.cc b/src/boucane.cc
index aa06152..6541902 100644
--- a/src/boucane.cc
+++ b/src/boucane.cc
@@ -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);
} \ No newline at end of file
diff --git a/src/core/apic.cc b/src/core/apic.cc
new file mode 100644
index 0000000..a93e54e
--- /dev/null
+++ b/src/core/apic.cc
@@ -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;
+ }
+} \ No newline at end of file
diff --git a/src/core/apic.hpp b/src/core/apic.hpp
new file mode 100644
index 0000000..edfeaa3
--- /dev/null
+++ b/src/core/apic.hpp
@@ -0,0 +1,6 @@
+#pragma once
+
+
+
+
+void apic_enable(); \ No newline at end of file
diff --git a/src/core/asm.hpp b/src/core/asm.hpp
new file mode 100644
index 0000000..8a931f6
--- /dev/null
+++ b/src/core/asm.hpp
@@ -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))
diff --git a/src/core/idt.cc b/src/core/idt.cc
index b808625..a73d92c 100644
--- a/src/core/idt.cc
+++ b/src/core/idt.cc
@@ -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);
diff --git a/src/core/idt.hpp b/src/core/idt.hpp
index f2aca43..2f2050d 100644
--- a/src/core/idt.hpp
+++ b/src/core/idt.hpp
@@ -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;
diff --git a/src/core/int.S b/src/core/int.S
index d5ad643..1c8d7bb 100644
--- a/src/core/int.S
+++ b/src/core/int.S
@@ -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" \ No newline at end of file
diff --git a/src/core/paging.cc b/src/core/paging.cc
index b9ab94e..8e58511 100644
--- a/src/core/paging.cc
+++ b/src/core/paging.cc
@@ -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);
-
} \ No newline at end of file
diff --git a/src/core/paging.hpp b/src/core/paging.hpp
index 1457d10..15d04ad 100644
--- a/src/core/paging.hpp
+++ b/src/core/paging.hpp
@@ -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)))
diff --git a/src/drivers/acpi.cc b/src/drivers/acpi.cc
new file mode 100644
index 0000000..bb48ba4
--- /dev/null
+++ b/src/drivers/acpi.cc
@@ -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);
+} \ No newline at end of file
diff --git a/src/drivers/acpi.hpp b/src/drivers/acpi.hpp
new file mode 100644
index 0000000..7bbcdb0
--- /dev/null
+++ b/src/drivers/acpi.hpp
@@ -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);
+
diff --git a/src/include/boucane.hpp b/src/include/boucane.hpp
index d78db60..8df2e59 100644
--- a/src/include/boucane.hpp
+++ b/src/include/boucane.hpp
@@ -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; \ No newline at end of file
diff --git a/src/libs/stdio.cc b/src/libs/stdio.cc
index c7007c2..8dcb1f6 100644
--- a/src/libs/stdio.cc
+++ b/src/libs/stdio.cc
@@ -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;
diff --git a/src/libs/stdio.hpp b/src/libs/stdio.hpp
index 804796b..2d252b6 100644
--- a/src/libs/stdio.hpp
+++ b/src/libs/stdio.hpp
@@ -23,5 +23,5 @@ void printi(int i);
/**
* Print an integer as hex using itoh()
*/
-void printh(int h);
+void printh(u64 h);
diff --git a/src/libs/string.cc b/src/libs/string.cc
index 3966407..8253526 100644
--- a/src/libs/string.cc
+++ b/src/libs/string.cc
@@ -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