diff options
Diffstat (limited to 'vmem.c')
-rw-r--r-- | vmem.c | 229 |
1 files changed, 117 insertions, 112 deletions
@@ -14,141 +14,146 @@ extern struct cpu_ident cpu_id; static unsigned long mapped_win = 1; void paging_off(void) { - if (!cpu_id.fid.bits.pae) - return; - __asm__ __volatile__ ( - /* Disable paging */ - "movl %%cr0, %%eax\n\t" - "andl $0x7FFFFFFF, %%eax\n\t" - "movl %%eax, %%cr0\n\t" - : : - : "ax" - ); + if (!cpu_id.fid.bits.pae) + return; + __asm__ __volatile__ + ( + /* Disable paging */ + "movl %%cr0, %%eax\n\t" + "andl $0x7FFFFFFF, %%eax\n\t" + "movl %%eax, %%cr0\n\t" + : : + : "ax" + ); } static void paging_on(void *pdp) { - if (!cpu_id.fid.bits.pae) - return; - __asm__ __volatile__( - /* Load the page table address */ - "movl %0, %%cr3\n\t" - /* Enable paging */ - "movl %%cr0, %%eax\n\t" - "orl $0x80000000, %%eax\n\t" - "movl %%eax, %%cr0\n\t" - : - : "r" (pdp) - : "ax" - ); + if (!cpu_id.fid.bits.pae) + return; + __asm__ __volatile__ + ( + /* Load the page table address */ + "movl %0, %%cr3\n\t" + /* Enable paging */ + "movl %%cr0, %%eax\n\t" + "orl $0x80000000, %%eax\n\t" + "movl %%eax, %%cr0\n\t" + : + : "r" (pdp) + : "ax" + ); } static void paging_on_lm(void *pml) { - if (!cpu_id.fid.bits.pae) - return; - __asm__ __volatile__( - /* Load the page table address */ - "movl %0, %%cr3\n\t" - /* Enable paging */ - "movl %%cr0, %%eax\n\t" - "orl $0x80000000, %%eax\n\t" - "movl %%eax, %%cr0\n\t" - : - : "r" (pml) - : "ax" - ); + if (!cpu_id.fid.bits.pae) + return; + __asm__ __volatile__ + ( + /* Load the page table address */ + "movl %0, %%cr3\n\t" + /* Enable paging */ + "movl %%cr0, %%eax\n\t" + "orl $0x80000000, %%eax\n\t" + "movl %%eax, %%cr0\n\t" + : + : "r" (pml) + : "ax" + ); } int map_page(unsigned long page) { - unsigned long i; - struct pde { - unsigned long addr_lo; - unsigned long addr_hi; - }; - extern unsigned char pdp[]; - extern unsigned char pml4[]; - extern struct pde pd2[]; - unsigned long win = page >> 19; + unsigned long i; + struct pde { + unsigned long addr_lo; + unsigned long addr_hi; + }; + extern unsigned char pdp[]; + extern unsigned char pml4[]; + extern struct pde pd2[]; + unsigned long win = page >> 19; - /* Less than 2 GB so no mapping is required */ - if (win == 0) { - return 0; - } - if (cpu_id.fid.bits.pae == 0) { - /* Fail, we don't have PAE */ - return -1; - } - if (cpu_id.fid.bits.lm == 0 && (page > 0x1000000)) { - /* Fail, we want an address that is out of bounds (> 64GB) - * for PAE and no long mode (ie. 32 bit CPU). - */ - return -1; - } - /* Compute the page table entries... */ - for(i = 0; i < 1024; i++) { - /*-----------------10/30/2004 12:37PM--------------- - * 0xE3 -- - * Bit 0 = Present bit. 1 = PDE is present - * Bit 1 = Read/Write. 1 = memory is writable - * Bit 2 = Supervisor/User. 0 = Supervisor only (CPL 0-2) - * Bit 3 = Writethrough. 0 = writeback cache policy - * Bit 4 = Cache Disable. 0 = page level cache enabled - * Bit 5 = Accessed. 1 = memory has been accessed. - * Bit 6 = Dirty. 1 = memory has been written to. - * Bit 7 = Page Size. 1 = page size is 2 MBytes - * --------------------------------------------------*/ - pd2[i].addr_lo = ((win & 1) << 31) + ((i & 0x3ff) << 21) + 0xE3; - pd2[i].addr_hi = (win >> 1); - } - paging_off(); - if (cpu_id.fid.bits.lm == 1) { - paging_on_lm(pml4); - } else { - paging_on(pdp); - } - mapped_win = win; - return 0; + /* Less than 2 GB so no mapping is required */ + if (win == 0) { + return 0; + } + if (cpu_id.fid.bits.pae == 0) { + /* Fail, we don't have PAE */ + return -1; + } + if (cpu_id.fid.bits.lm == 0 && (page > 0x1000000)) { + /* Fail, we want an address that is out of bounds (> 64GB) + * for PAE and no long mode (ie. 32 bit CPU). + */ + return -1; + } + /* Compute the page table entries... */ + for(i = 0; i < 1024; i++) { + /*-----------------10/30/2004 12:37PM--------------- + * 0xE3 -- + * Bit 0 = Present bit. 1 = PDE is present + * Bit 1 = Read/Write. 1 = memory is writable + * Bit 2 = Supervisor/User. 0 = Supervisor only (CPL 0-2) + * Bit 3 = Writethrough. 0 = writeback cache policy + * Bit 4 = Cache Disable. 0 = page level cache enabled + * Bit 5 = Accessed. 1 = memory has been accessed. + * Bit 6 = Dirty. 1 = memory has been written to. + * Bit 7 = Page Size. 1 = page size is 2 MBytes + * --------------------------------------------------*/ + pd2[i].addr_lo = ((win & 1) << 31) + ((i & 0x3ff) << 21) + 0xE3; + pd2[i].addr_hi = (win >> 1); + } + paging_off(); + if (cpu_id.fid.bits.lm == 1) { + paging_on_lm(pml4); + } else { + paging_on(pdp); + } + mapped_win = win; + return 0; } -void *mapping(unsigned long page_addr) +void *mapping(unsigned long phys_page) { - void *result; - if (page_addr < 0x80000) { - /* If the address is less than 1GB directly use the address */ - result = (void *)(page_addr << 12); - } - else { - unsigned long alias; - alias = page_addr & 0x7FFFF; - alias += 0x80000; - result = (void *)(alias << 12); - } - return result; + void *result; + if (phys_page < WIN_SZ_PAGES) { + /* If the page is below 2GB, address it directly */ + result = (void *)(phys_page << 12); + } + else { + // Higher physical pages map to a virtual address + // in the 2G-4G range. + unsigned long alias; + alias = phys_page & 0x7FFFF; + alias += 0x80000; + result = (void *)(alias << 12); + } + return result; } -void *emapping(unsigned long page_addr) +void *emapping(unsigned long phys_page) { - void *result; - result = mapping(page_addr -1); - /* Fill in the low address bits */ - result = ((unsigned char *)result) + 0xffc; - return result; + void *result; + result = mapping(phys_page - 1); + /* Fill in the low address bits */ + result = ((unsigned char *)result) + 0xffc; + return result; } unsigned long page_of(void *addr) { - unsigned long page; - page = ((unsigned long)addr) >> 12; - if (page >= 0x80000) { - page &= 0x7FFFF; - page += mapped_win << 19; - } + unsigned long page; + page = ((unsigned long)addr) >> 12; + if (page >= 0x80000) { + page &= 0x7FFFF; + page += mapped_win << 19; + } #if 0 - cprint(LINE_SCROLL -2, 0, "page_of( )-> "); - hprint(LINE_SCROLL -2, 8, ((unsigned long)addr)); - hprint(LINE_SCROLL -2, 20, page); + cprint(LINE_SCROLL -2, 0, "page_of( )-> "); + hprint(LINE_SCROLL -2, 8, ((unsigned long)addr)); + hprint(LINE_SCROLL -2, 20, page); #endif - return page; + return page; } |