Mercurial > hg > Members > taiki > elilo
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;