changeset 3:593205c4e5fc

finish paging
author taiki
date Sat, 16 Feb 2013 16:06:09 +0900
parents da946b5ff948
children 1623c50369a2
files x86_64/elilo_kernel.c
diffstat 1 files changed, 106 insertions(+), 47 deletions(-) [+]
line wrap: on
line diff
--- a/x86_64/elilo_kernel.c	Sat Feb 16 05:47:59 2013 +0900
+++ b/x86_64/elilo_kernel.c	Sat Feb 16 16:06:09 2013 +0900
@@ -3,33 +3,37 @@
 
 #include "elilo.h"
 #include "pgtable_flags.h"
+#include "sysdeps.h"
 
-VOID
-MemCpy(UINT8 *t, UINT8 *f, UINTN n)
-{
-    if (t && f && n && (t<f)) {
-        while (n--) {
-            *t++ = *f++;
-        }
-    } else if (t && f && n && (t>f)) {
-        t +=n;
-        f +=n;
-        while (n--) {
-            *t-- = *f--;
-        }
-    }
+#define MEMCPY(to, from, cnt) { \
+        UINT8 *t = (UINT8 *)(to); \
+        UINT8 *f = (UINT8 *)(from); \
+        UINTN n = cnt; \
+        if (t && f && n && (t<f)) { \
+                    while (n--) { \
+                                    *t++ = *f++; \
+                                } \
+                } else if (t && f && n && (t>f)) { \
+                            t += n; \
+                            f += n; \
+                            while (n--) { \
+                                            *t-- = *f--; \
+                                        } \
+                        } \
 }
 
-VOID
-MemSet(UINT8 *p, UINTN *n, UINTN v)
-{
-    if (p && n) {
-        while (n--) {
-            *p++ = v;
-        }
-    }
+#define MEMSET(ptr, size, val) { \
+        UINT8 *p = (UINT8 *)(ptr); \
+        UINTN n = (UINTN)(size); \
+        UINT8 v = (UINT8)(val); \
+        if (p && n) { \
+                    while (n--) { \
+                                    *p++ = v; \
+                                } \
+                } \
 }
 
+
 #define EFER_LME 8
 #define EFER_NXE 0x00000400
 #define MSR_EFER 0xc0000080
@@ -54,43 +58,61 @@
 INTN
 enable_cr4_pae()
 {
-    UINT32 cr4_flag = X86_CR4_PAE;
-    asm volatile("movq %%rax, %%cr4"::"a"(cr4_flag));
+    UINT64 __force_order;
+    UINT64 val;
+    asm volatile("mov %%cr4,%0\n\t" : "=r" (val), "=m" (__force_order));
+    val |= X86_CR4_PAE;
+    asm volatile("mov %0,%%cr4": : "r" (val), "m" (__force_order));
+    //asm volatile("movq %%rax, %%cr4"::"a"(cr4_flag));
     return 0;
 }
 
 
 UINTN
-insert_addr_to_cr3(UINT64 addr)
+insert_addr_to_cr3(UINT64 val)
 {
-    asm volatile ("movq %0, %%rax \n\tmovq %%rax, %%cr3" :: "m"(addr) );
+    UINT64 __force_order;
+    // asm volatile ("movq %0, %%rax \n\tmovq %%rax, %%cr3" :: "m"(addr) );
+    /* write cr3 */
+    asm volatile("mov %0,%%cr3": : "r" (val), "m" (__force_order));
     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));
+{   
+    UINT64 __force_order;
+    UINT64 val;
+    asm volatile("mov %%cr0,%0\n\t" : "=r" (val), "=m" (__force_order));
+    val |= X86_CR0_PG;
+    asm volatile("mov %0,%%cr0": : "r" (val), "m" (__force_order));
+    // asm volatile("movl %0, %%eax \n\t movq %%rax, %%cr0"::"m"(cr0_flag));
     return 0;
 }
 
 VOID
-init_pgtable_value(UINT64 *addr, UINT32 size, UINT64 value)
+init_pgtable_value(VOID *addr, UINT32 size, UINT64 value)
 {
     if (addr == NULL) {
         Print(L"addr is not using.\n");
         return;
     }
 
+    UINT64 *tmp = (UINT64 *)addr;
+
     while(size--) {
-        *addr++ = value;
+        *tmp++ = value;
     }
 }
 
+#define PML4_START 0x00270000
+#define PDPTE_START PML4_START + (PML4_SIZE + 1) * PDPTE_SIZE
+
+/* alloc pages use how many pages for 4KiB */
+#define PGCNT_BYTE 1024
+
 
 /* init_pgtable()
  * init pagetable. use IA-32e page table 
@@ -99,41 +121,78 @@
 UINT64
 init_pgtable()
 {
-    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);
+    pml4 = (pml4_t *)PML4_START;
+    UINTN pml4_size = PML4_SIZE * sizeof(pml4_t) / PGCNT_BYTE;
+    Print(L"allocate pml4 ::%lx \n", pml4);
+    pml4 = (pml4_t *)alloc_pages(pml4_size, EfiLoaderData, AllocateAddress, pml4);
+    Print(L"pml4 :%lx\n", pml4);
+    if (pml4 == NULL) {
+        Print(L"can not allocate pml4.\n");
+        return -1;
+    }
 
-    if ((pml4 != NULL)&&(pdpte != NULL)) return -1;
-    Print(L"allocate page :%lx", pdpte);
+    pdpte = (pdpte_t *)PDPTE_START;
+    Print(L"allocate pdpte ::%lx\n", pdpte);
+    UINTN pdpte_size = PDPTE_SIZE * PML4_SIZE * sizeof(pdpte_t) / PGCNT_BYTE;
+    pdpte = (pdpte_t *)alloc_pages(pdpte_size , EfiLoaderData, AllocateAddress, pdpte);
+    Print(L"pdpte :%lx\n", pdpte);
 
-    init_pgtable_value((UINT64*)pml4, PML4_SIZE, 0);
-    init_pgtable_value((UINT64*)pdpte, PDPTE_SIZE * PML4_SIZE, 0);
+    if (pdpte == NULL) {
+        Print(L"can not allocate pdpte.\n");
+        return -1;
+    }
+
+    init_pgtable_value((VOID *)pml4, PML4_SIZE * sizeof(pml4_t), 0);
+    init_pgtable_value((VOID *)pdpte, PDPTE_SIZE * PML4_SIZE * sizeof(pdpte_t), 0);
 
     UINTN i = 0;
     for (; i<PML4_SIZE ;i++) {
-        pml4[i].paddr = (UINT64 *)&pdpte[(PDPTE_SIZE * i) + PDPTE_SIZE];
+        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].p = ENABLE;
             pdpte[(PDPTE_SIZE * i) + j].ps = ENABLE;
         }
     }
 
-    return (UINT64)pdpte + PML4_SIZE;
+    return (UINT64)pml4 + PML4_SIZE;
 }
 
+VOID 
+stop_kernel()
+{
+    Print(L"stop\n");
+    while(1) {
+    }
+}
 
 
 EFI_STATUS
 start_elilo_kernel()
 {
-    init_pgtable();
-    UINT64 addr = enable_paging_cr0();
+    MEMSET(gdt_addr.base, gdt_addr.limit, 0);
+    MEMCPY(gdt_addr.base, init_gdt, sizeof_init_gdt);
+
+    asm volatile ( "lidt %0" : : "m" (idt_addr) );
+    asm volatile ( "lgdt %0" : : "m" (gdt_addr) );
+
+    Print(L"enable cr4 pae...\n");
+    enable_cr4_pae(); 
+
+    Print(L"init pagetable...\n");
+    UINT64 addr = init_pgtable();
+
+    Print(L"insert addr %lx to cr3...\n", addr);
+    while(1) { }
     insert_addr_to_cr3(addr);
-    UINT64 i=0;
-    asm volatile ("cli" : : );
-    for (;i < 100000000; i++) {
-    }
+
+    Print(L"enable paging cr0...\n");
+    enable_paging_cr0();
+
+    Print(L"finish to initialize...\n");
+
+    asm volatile ("hlt" : : );
     Print(L"finish internal kernel\n");
     return EFI_SUCCESS;
 }