-#define PAGE_P 0x0
-#define PAGE_WR 0x1
-#define PAGE_US 0x2
+#define PAGE_P 0x1
+#define PAGE_WR 0x2
+#define PAGE_US 0x4
#define PAGE_SHIFT (12)
#define PAGE_SIZE (1UL << PAGE_SHIFT)
#ifndef ASM
#include <types.h>
#include <bits.h>
-#define get_npd(vaddr) (((u32)(vaddr))>>22)
-#define get_npt(vaddr) ((((u32)(vaddr))>>12) & 0x3FF)
+#define get_npd(addr) (((u32)(addr))>>22)
+#define get_npt(addr) ((((u32)(addr))>>12) & 0x3FF)
#include <list.h>
void init_paging()
{
- unsigned long di, ti;
- unsigned long *pde, *pte;
-
- unsigned long max_pfn = bootmem_data.max_pfn;
- unsigned long min_pfn = BOOT_INIT_PAGETBL_CNT*1024;
-
- unsigned long pde_end = (pfn2pa(bootmem_data.max_pfn) >> 22);
- if(1) // need to fix.
- pde_end++;
- for(di=BOOT_INIT_PAGETBL_CNT; di<pde_end; ++di)
+ unsigned int i;
+ unsigned long pfn = 0;
+ pte_t *pte = 0;
+ unsigned long pgtb_addr = 0;
+ for(pfn=pa2pfn(BOOT_INIT_PAGETBL_CNT<<22); pfn<bootmem_data.max_pfn; ++pfn)
{
- pde = init_pgd + di;
-
- if(di >= pde_end)
+ unsigned long ti = pfn % PAGE_PTE_CNT;
+ unsigned long page_addr = pfn2pa(pfn);
+ if(ti == 0)
{
- *pde = 0;
- continue;
- }
+ pgtb_addr = (unsigned long) va2pa(bootmem_alloc_pages(1));
+ if(0 == pgtb_addr)
+ panic("No Pages for Paging...");
- unsigned long pt_addr = (unsigned long) va2pa(bootmem_alloc_pages(1));
+ memset((void *)pgtb_addr, 0, PAGE_SIZE);
- *pde = pt_addr | 7;
- *(pde + (PAGE_OFFSET>>22)) = *pde; // for kernel paging
+ init_pgd[get_npd(page_addr)] = (pde_t)(pgtb_addr | PAGE_P | PAGE_WR | PAGE_US);
+ }
- for(ti=0; ti<PTECNT_PER_PAGE; ++ti)
- {
- unsigned long page = (di << 22) | (ti << 12);
+ pte = ((pte_t *) pa2va(pgtb_addr)) + ti;
+ *pte = (pte_t) (page_addr | PAGE_P | PAGE_WR | PAGE_US);
+ }
- pte = ((pte_t *) pa2va(pt_addr)) + ti;
- *pte = page | 7;
- //printk("pde %08x pte %08x pt_addr %08x page %08x\n", pde, pte, pt_addr, page);
- }
+ // paging for kernel space
+ unsigned long delta = get_npd(PAGE_OFFSET);
+ for(i=delta; i<PDECNT_PER_PAGE; ++i)
+ {
+ init_pgd[i] = init_pgd[i-delta];
}
LOAD_CR3(init_pgd);