changeset 2:da946b5ff948

implement page table init.
author taiki
date Sat, 16 Feb 2013 05:47:59 +0900
parents 1b2326947b0d
children 593205c4e5fc
files x86_64/elilo_kernel.c
diffstat 1 files changed, 82 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/x86_64/elilo_kernel.c	Fri Feb 15 04:22:42 2013 +0900
+++ b/x86_64/elilo_kernel.c	Sat Feb 16 05:47:59 2013 +0900
@@ -2,14 +2,7 @@
 #include <efilib.h>
 
 #include "elilo.h"
-
-#define PAGETABLE_SIZE 1024
-#define PAGEDIRECTORY_SIZE 1024
-
-extern UINT64 *pte;
-
-#define X86_CR4_PAE 0x00000020
-#define X86_CR4_PSE 0x00000010
+#include "pgtable_flags.h"
 
 VOID
 MemCpy(UINT8 *t, UINT8 *f, UINTN n)
@@ -37,39 +30,109 @@
     }
 }
 
+#define EFER_LME 8
+#define EFER_NXE 0x00000400
+#define MSR_EFER 0xc0000080
+
+/*
+VOID
+operate_efer()
+{
+    UINT32 msr_efer = MSR_EFER;
+    UINT32 efer_flg = EFER_LME;
+    asm volatile ("movl %0, %%ecx \n\t rdmsr \n\t btsl %1, %%eax\n\t wrmsr " :: "m"(msr_efer) ,"m"(efer_flg));
+}
+*/
+
+
+extern pml4_t *pml4;
+extern pdpte_t *pdpte;
+
+#define X86_CR4_PAE 0x00000020
+#define X86_CR4_PSE 0x00000010
+
 INTN
 enable_cr4_pae()
 {
+    UINT32 cr4_flag = X86_CR4_PAE;
+    asm volatile("movq %%rax, %%cr4"::"a"(cr4_flag));
     return 0;
 }
 
+
 UINTN
 insert_addr_to_cr3(UINT64 addr)
 {
     asm volatile ("movq %0, %%rax \n\tmovq %%rax, %%cr3" :: "m"(addr) );
-    //asm volatile ("movq %0, %%rax movq %rax, %cr3": :"a"(addr) :"%rax" );
+    return 0;
+}
+
+
+#define X86_CR0_PG 0x80000000
+
+INTN
+enable_paging_cr0()
+{
+    UINT32 cr0_flag = X86_CR0_PG;
+    asm volatile("movl %0, %%eax \n\t movq %%rax, %%cr0"::"m"(cr0_flag));
     return 0;
 }
 
-INTN
-pgtable_init()
+VOID
+init_pgtable_value(UINT64 *addr, UINT32 size, UINT64 value)
+{
+    if (addr == NULL) {
+        Print(L"addr is not using.\n");
+        return;
+    }
+
+    while(size--) {
+        *addr++ = value;
+    }
+}
+
+
+/* init_pgtable()
+ * init pagetable. use IA-32e page table 
+ * This function initialize PML4 and PDPTE 
+ */
+UINT64
+init_pgtable()
 {
-    UINTN size = PAGETABLE_SIZE * PAGEDIRECTORY_SIZE * sizeof(UINT64);
-    pte = (UINT64 *)alloc_pages(size, EfiLoaderData, AllocateAddress, pte);
-    if (pte != NULL) return -1;
-    Print(L"allocate page :%p", pte);
+    pml4 = (pml4_t *)alloc_pages(PML4_SIZE, EfiLoaderData, AllocateAddress, pml4);
+    pdpte = (pdpte_t *)alloc_pages(PDPTE_SIZE * PML4_SIZE * sizeof(pdpte_t), EfiLoaderData, AllocateAddress, pdpte);
+
+    if ((pml4 != NULL)&&(pdpte != NULL)) return -1;
+    Print(L"allocate page :%lx", pdpte);
+
+    init_pgtable_value((UINT64*)pml4, PML4_SIZE, 0);
+    init_pgtable_value((UINT64*)pdpte, PDPTE_SIZE * PML4_SIZE, 0);
 
-    return 0;
+    UINTN i = 0;
+    for (; i<PML4_SIZE ;i++) {
+        pml4[i].paddr = (UINT64 *)&pdpte[(PDPTE_SIZE * i) + PDPTE_SIZE];
+        pml4[i].p = ENABLE;
+        UINTN j = 0;
+        for (;j < PDPTE_SIZE; j++) {
+            pdpte[(PDPTE_SIZE*i) + j].p = ENABLE;
+            pdpte[(PDPTE_SIZE * i) + j].ps = ENABLE;
+        }
+    }
+
+    return (UINT64)pdpte + PML4_SIZE;
 }
 
+
+
 EFI_STATUS
 start_elilo_kernel()
 {
-    pgtable_init();
+    init_pgtable();
+    UINT64 addr = enable_paging_cr0();
+    insert_addr_to_cr3(addr);
     UINT64 i=0;
     asm volatile ("cli" : : );
-    for (;i < 100000000; i++)
-    {
+    for (;i < 100000000; i++) {
     }
     Print(L"finish internal kernel\n");
     return EFI_SUCCESS;