summaryrefslogtreecommitdiff
path: root/src/arch/amd64
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/arch/amd64/boot.S112
-rw-r--r--src/arch/amd64/shim.c77
2 files changed, 129 insertions, 60 deletions
diff --git a/src/arch/amd64/boot.S b/src/arch/amd64/boot.S
index fc580fb..9771fe2 100644
--- a/src/arch/amd64/boot.S
+++ b/src/arch/amd64/boot.S
@@ -3,18 +3,6 @@ extern kmain
extern amd64_shim
bits 32
-; base, limit, access, flags
-%macro gdt_entry 4
- db %2 & 0xff
- db (%2 >> 8) & 0xff
- db %1 & 0xff
- db (%1 >> 8) & 0xff
- db (%1 >> 16) & 0xff
- db %3
- db ((%2 >> 16) & 0x0f) | (%4 << 4)
- db (%1 >> 24) & 0xff
-%endmacro
-
section .multiboot
align 8
mb_start:
@@ -38,33 +26,97 @@ stack_end:
section .rodata
align 16
-gdt_start:
-gdt_entry 0, 0, 0, 0
-gdt_entry 0, 0xFFFFF, 0x9A, 0xC
-gdt_entry 0, 0xFFFFF, 0x92, 0xC
-gdt_end:
-gdt_descriptor:
- dw gdt_end - gdt_start - 1
- dd gdt_start
-
+; Access bits
+PRESENT equ 1 << 7
+NOT_SYS equ 1 << 4
+EXEC equ 1 << 3
+DC equ 1 << 2
+RW equ 1 << 1
+ACCESSED equ 1 << 0
+
+; Flags bits
+GRAN_4K equ 1 << 7
+SZ_32 equ 1 << 6
+LONG_MODE equ 1 << 5
+
+GDT:
+ .Null: equ $ - GDT
+ dq 0
+ .Code: equ $ - GDT
+ dd 0xFFFF ; Limit & Base (low, bits 0-15)
+ db 0 ; Base (mid, bits 16-23)
+ db PRESENT | NOT_SYS | EXEC | RW ; Access
+ db GRAN_4K | LONG_MODE | 0xF ; Flags & Limit (high, bits 16-19)
+ db 0 ; Base (high, bits 24-31)
+ .Data: equ $ - GDT
+ dd 0xFFFF ; Limit & Base (low, bits 0-15)
+ db 0 ; Base (mid, bits 16-23)
+ db PRESENT | NOT_SYS | RW ; Access
+ db GRAN_4K | SZ_32 | 0xF ; Flags & Limit (high, bits 16-19)
+ db 0 ; Base (high, bits 24-31)
+ .TSS: equ $ - GDT
+ dd 0x00000068
+ dd 0x00CF8900
+ .Pointer:
+ dw $ - GDT - 1
+ dq GDT
section .text
align 8
start:
cli
- lgdt [gdt_descriptor]
- jmp 0x08:after_lgdt
-after_lgdt:
- mov ax, 0x10
- mov ds, ax
- mov ss, ax
- mov es, ax
- mov fs, ax
- mov gs, ax
mov esp, stack_end
mov ebp, stack_end
+
push ebx
+
+ mov edi, 0x1000
+ mov cr3, edi
+ xor eax, eax
+ mov ecx, 4096
+ rep stosd
+ mov edi, cr3
+
+ mov DWORD [edi], 0x2003 ; Set the uint32_t at the destination index to 0x2003.
+ add edi, 0x1000 ; Add 0x1000 to the destination index.
+ mov DWORD [edi], 0x3003 ; Set the uint32_t at the destination index to 0x3003.
+ add edi, 0x1000 ; Add 0x1000 to the destination index.
+ mov DWORD [edi], 0x4003 ; Set the uint32_t at the destination index to 0x4003.
+ add edi, 0x1000 ; Add 0x1000 to the destination index.
+
+ mov ebx, 0x00000003 ; Set the B-register to 0x00000003.
+ mov ecx, 512 ; Set the C-register to 512.
+
+.SetEntry:
+ mov DWORD [edi], ebx ; Set the uint32_t at the destination index to the B-register.
+ add ebx, 0x1000 ; Add 0x1000 to the B-register.
+ add edi, 8 ; Add eight to the destination index.
+ loop .SetEntry ; Set the next entry.
+
+ ;push ebx ; Call our function to set up basic paging
+ ;call amd64_shim
+
+
+ mov eax, cr4 ; Enable the PAE bit
+ or eax, 1 << 5
+ mov cr4, eax
+
+ mov ecx, 0xC0000080 ; Enable long mode
+ rdmsr
+ or eax, 1 << 8
+ wrmsr
+
+ mov eax, cr0 ; Enable paging
+ or eax, 1 << 31
+ mov cr0, eax
+
+ lgdt [GDT.Pointer]
+ jmp GDT.Code:code64
+
+ bits 64
+code64:
call amd64_shim
+ push rax
call kmain
cli
halt:
diff --git a/src/arch/amd64/shim.c b/src/arch/amd64/shim.c
index 0c2d418..3e9cfd7 100644
--- a/src/arch/amd64/shim.c
+++ b/src/arch/amd64/shim.c
@@ -1,4 +1,5 @@
#include <stdint.h>
+#include <cpuid.h>
#define PG_PRESENT 0x0000'0000'0000'0001
#define PG_READ_WRITE 0x0000'0000'0000'0002
@@ -8,14 +9,19 @@
#define PG_ACCESSED 0x0000'0000'0000'0020
#define PG_EXECUTE_DISABLE 0x8000'0000'0000'0000
+#define F_PRESENT 0b1
+#define F_WRITEABLE 0b10
+#define F_UNPRIVILEGED 0b100
+#define F_WRITETHROUGH 0b1000
+#define F_CACHEDISABLE 0b10000
+#define F_ACCESSED 0b100000
+#define F_DIRTY 0b1000000
+#define F_MEGABYTE 0b10000000
+#define F_GLOBAL 0b100000000
+
// PAGE MAP LEVEL 4 ENTRY
-struct pml4 {
- uint64_t present : 1;
- uint64_t rw : 1;
- uint64_t user_supervisor : 1;
- uint64_t write_through : 1;
- uint64_t cache_disable : 1;
- uint64_t accessed : 1;
+struct pml4e {
+ uint64_t flags : 6;
uint64_t _reserved : 6;
uint64_t address : 40;
uint64_t _reserved_2 : 11;
@@ -24,12 +30,7 @@ struct pml4 {
// PAGE DIRECTORY POINTER TABLE ENTRY
struct pdpte {
- uint64_t present : 1;
- uint64_t rw : 1;
- uint64_t user_supervisor : 1;
- uint64_t write_through : 1;
- uint64_t cache_disable : 1;
- uint64_t accessed : 1;
+ uint64_t flags : 6;
uint64_t _reserved : 1;
uint64_t page_size : 1;
uint64_t _reserved_2 : 2;
@@ -40,12 +41,7 @@ struct pdpte {
// PAGE DIRECTORY ENTRY
struct pde {
- uint64_t present : 1;
- uint64_t rw : 1;
- uint64_t user_supervisor : 1;
- uint64_t write_through : 1;
- uint64_t cache_disable : 1;
- uint64_t accessed : 1;
+ uint64_t flags : 6;
uint64_t _reserved : 1;
uint64_t page_size : 1;
uint64_t _reserved_2 : 2;
@@ -56,15 +52,7 @@ struct pde {
// PAGE TABLE ENTRY
struct pte {
- uint64_t present : 1;
- uint64_t rw : 1;
- uint64_t user_supervisor : 1;
- uint64_t write_through : 1;
- uint64_t cache_disable : 1;
- uint64_t accessed : 1;
- uint64_t dirty : 1;
- uint64_t mem_type : 1;
- uint64_t global : 1;
+ uint64_t flags : 9;
uint64_t _reserved : 3;
uint64_t address : 40;
uint64_t _reserved_2 : 7;
@@ -72,7 +60,36 @@ struct pte {
uint64_t execute_disable : 1;
};
+struct pml4e pml4[512];
+struct pdpte pdpt[512];
+struct pde pd[512];
+struct pte pt[512];
+
+static int get_maxphysaddr() {
+ uint32_t eax, ebx, ecx, edx;
+ __cpuid(0x80000008, eax, ebx, ecx, edx);
+ return eax & 0xFF;
+}
+
// entry point for amd64
-void amd64_shim(void *boot_info) {
-
+void* amd64_shim(void *boot_info) {
+ for (int i = 0; i < 512; i++) {
+ pml4[i].flags = 0;
+ }
+ for (int i = 0; i < 512; i++) {
+ pdpt[i].flags = 0;
+ }
+ for (int i = 0; i < 512; i++) {
+ pd[i].flags = 0;
+ }
+ pml4[0].flags = F_PRESENT | F_WRITEABLE;
+ pml4[0].address = (uint64_t)&pdpt;
+ pdpt[0].flags = F_PRESENT | F_WRITEABLE;
+ pdpt[0].address = (uint64_t)&pd;
+ pd[0].flags = F_PRESENT | F_WRITEABLE;
+ pd[0].address = (uint64_t)&pt;
+ for (int i = 0; i < 512; i++) {
+ pt[i].flags = F_PRESENT | F_WRITEABLE;
+ pt[i].address = i * 4096;
+ }
}