| version 1.92, 2010/07/15 18:55:27 |
version 1.93, 2010/07/24 00:45:54 |
| Line 482 try586: /* Use the `cpuid' instruction. |
|
| Line 482 try586: /* Use the `cpuid' instruction. |
|
| movl $_RELOC(tmpstk),%esp # bootstrap stack end location |
movl $_RELOC(tmpstk),%esp # bootstrap stack end location |
| |
|
| /* |
/* |
| * Virtual address space of kernel: |
* Virtual address space of kernel, without PAE. The page dir is 1 page long. |
| * |
* |
| * text | data | bss | [syms] | [blobs] | page dir | proc0 kstack | L1 ptp |
* text | data | bss | [syms] | [blobs] | page dir | proc0 kstack | L1 ptp |
| * 0 1 2 3 |
* 0 1 2 3 |
| |
* |
| |
* Virtual address space of kernel, with PAE. We need 4 pages for the page dir |
| |
* and 1 page for the L3. |
| |
* text | data | bss | [syms] | [blobs] | L3 | page dir | proc0 kstack | L1 ptp |
| |
* 0 1 5 6 7 |
| */ |
*/ |
| |
#ifndef PAE |
| #define PROC0_PDIR_OFF 0 |
#define PROC0_PDIR_OFF 0 |
| #define PROC0_STK_OFF (PROC0_PDIR_OFF + PAGE_SIZE) |
#else |
| |
#define PROC0_L3_OFF 0 |
| |
#define PROC0_PDIR_OFF 1 * PAGE_SIZE |
| |
#endif |
| |
|
| |
#define PROC0_STK_OFF (PROC0_PDIR_OFF + PDP_SIZE * PAGE_SIZE) |
| #define PROC0_PTP1_OFF (PROC0_STK_OFF + UPAGES * PAGE_SIZE) |
#define PROC0_PTP1_OFF (PROC0_STK_OFF + UPAGES * PAGE_SIZE) |
| |
|
| /* |
/* |
| * fillkpt |
* fillkpt - Fill in a kernel page table |
| * eax = pte (page frame | control | status) |
* eax = pte (page frame | control | status) |
| * ebx = page table address |
* ebx = page table address |
| * ecx = number of pages to map |
* ecx = number of pages to map |
| |
* |
| |
* For PAE, each entry is 8 bytes long: we must set the 4 upper bytes to 0. |
| |
* This is done by the first instruction of fillkpt. In the non-PAE case, this |
| |
* instruction just clears the page table entry. |
| */ |
*/ |
| |
|
| #define fillkpt \ |
#define fillkpt \ |
| 1: movl %eax,(%ebx) ; /* store phys addr */ \ |
1: movl $0,(PDE_SIZE-4)(%ebx) ; /* clear bits */ \ |
| addl $4,%ebx ; /* next pte/pde */ \ |
movl %eax,(%ebx) ; /* store phys addr */ \ |
| addl $PAGE_SIZE,%eax ; /* next phys page */ \ |
addl $PDE_SIZE,%ebx ; /* next pte/pde */ \ |
| loop 1b ; \ |
addl $PAGE_SIZE,%eax ; /* next phys page */ \ |
| |
loop 1b ; |
| |
|
| /* Find end of kernel image. */ |
/* Find end of kernel image. */ |
| movl $RELOC(end),%edi |
movl $RELOC(end),%edi |
| Line 538 try586: /* Use the `cpuid' instruction. |
|
| Line 552 try586: /* Use the `cpuid' instruction. |
|
| incl %eax /* one more ptp for VAs stolen by bootstrap */ |
incl %eax /* one more ptp for VAs stolen by bootstrap */ |
| 1: movl %eax,RELOC(nkptp)+1*4 |
1: movl %eax,RELOC(nkptp)+1*4 |
| |
|
| /* tablesize = (1 + UPAGES + nkptp) << PGSHIFT; */ |
/* tablesize = (PDP_SIZE + UPAGES + nkptp) << PGSHIFT; */ |
| addl $(1+UPAGES),%eax |
addl $(PDP_SIZE+UPAGES),%eax |
| |
#ifdef PAE |
| |
incl %eax /* one more page for the L3 PD */ |
| |
shll $PGSHIFT+1,%eax /* PTP tables are twice larger with PAE */ |
| |
#else |
| shll $PGSHIFT,%eax |
shll $PGSHIFT,%eax |
| |
#endif |
| movl %eax,RELOC(tablesize) |
movl %eax,RELOC(tablesize) |
| |
|
| /* ensure that nkptp covers bootstrap tables */ |
/* ensure that nkptp covers bootstrap tables */ |
| Line 578 try586: /* Use the `cpuid' instruction. |
|
| Line 597 try586: /* Use the `cpuid' instruction. |
|
| */ |
*/ |
| movl $_RELOC(KERNTEXTOFF),%eax |
movl $_RELOC(KERNTEXTOFF),%eax |
| movl %eax,%ecx |
movl %eax,%ecx |
| shrl $(PGSHIFT-2),%ecx /* ((n >> PGSHIFT) << 2) for # pdes */ |
shrl $(PGSHIFT-2),%ecx /* ((n >> PGSHIFT) << 2) for # pdes */ |
| |
#ifdef PAE |
| |
shll $1,%ecx /* pdes are twice larger with PAE */ |
| |
#endif |
| addl %ecx,%ebx |
addl %ecx,%ebx |
| |
|
| /* Map the kernel text read-only. */ |
/* Map the kernel text read-only. */ |
| Line 605 try586: /* Use the `cpuid' instruction. |
|
| Line 627 try586: /* Use the `cpuid' instruction. |
|
| * Construct a page table directory. |
* Construct a page table directory. |
| */ |
*/ |
| /* Set up top level entries for identity mapping */ |
/* Set up top level entries for identity mapping */ |
| leal (PROC0_PDIR_OFF)(%esi),%ebx |
leal (PROC0_PDIR_OFF)(%esi),%ebx |
| leal (PROC0_PTP1_OFF)(%esi),%eax |
leal (PROC0_PTP1_OFF)(%esi),%eax |
| orl $(PG_V|PG_KW), %eax |
orl $(PG_V|PG_KW), %eax |
| movl RELOC(nkptp)+1*4,%ecx |
movl RELOC(nkptp)+1*4,%ecx |
| fillkpt |
fillkpt |
| |
|
| /* Set up top level entries for actual kernel mapping */ |
/* Set up top level entries for actual kernel mapping */ |
| leal (PROC0_PDIR_OFF + L2_SLOT_KERNBASE*4)(%esi),%ebx |
leal (PROC0_PDIR_OFF + L2_SLOT_KERNBASE*PDE_SIZE)(%esi),%ebx |
| leal (PROC0_PTP1_OFF)(%esi),%eax |
leal (PROC0_PTP1_OFF)(%esi),%eax |
| orl $(PG_V|PG_KW), %eax |
orl $(PG_V|PG_KW), %eax |
| movl RELOC(nkptp)+1*4,%ecx |
movl RELOC(nkptp)+1*4,%ecx |
| fillkpt |
fillkpt |
| |
|
| /* Install a PDE recursively mapping page directory as a page table! */ |
/* Install a PDE recursively mapping page directory as a page table! */ |
| leal (PROC0_PDIR_OFF + PDIR_SLOT_PTE*4)(%esi),%ebx |
leal (PROC0_PDIR_OFF + PDIR_SLOT_PTE*PDE_SIZE)(%esi),%ebx |
| leal (PROC0_PDIR_OFF)(%esi),%eax |
leal (PROC0_PDIR_OFF)(%esi),%eax |
| orl $(PG_V|PG_KW),%eax |
orl $(PG_V|PG_KW),%eax |
| movl %eax,(%ebx) |
movl $PDP_SIZE,%ecx |
| |
fillkpt |
| |
|
| |
#ifdef PAE |
| |
/* Fill in proc0 L3 page with entries pointing to the page dirs */ |
| |
leal (PROC0_L3_OFF)(%esi),%ebx |
| |
leal (PROC0_PDIR_OFF)(%esi),%eax |
| |
orl $(PG_V),%eax |
| |
movl $PDP_SIZE,%ecx |
| |
fillkpt |
| |
|
| |
/* Enable PAE mode */ |
| |
movl %cr4,%eax |
| |
orl $CR4_PAE,%eax |
| |
movl %eax,%cr4 |
| |
#endif |
| |
|
| /* Save phys. addr of PDP, for libkvm. */ |
/* Save phys. addr of PDP, for libkvm. */ |
| movl %esi,RELOC(PDPpaddr) |
leal (PROC0_PDIR_OFF)(%esi),%eax |
| |
movl %eax,RELOC(PDPpaddr) |
| |
|
| /* |
/* |
| * Startup checklist: |
* Startup checklist: |
| * 1. Load %cr3 with pointer to PDIR. |
* 1. Load %cr3 with pointer to PDIR (or L3 PD page for PAE). |
| */ |
*/ |
| movl %esi,%eax # phys address of ptd in proc 0 |
movl %esi,%eax # phys address of ptd in proc 0 |
| movl %eax,%cr3 # load ptd addr into mmu |
movl %eax,%cr3 # load ptd addr into mmu |
| |
|
| /* |
/* |
| * 2. Enable paging and the rest of it. |
* 2. Enable paging and the rest of it. |
| */ |
*/ |
|
|
| * memory, remove it. |
* memory, remove it. |
| */ |
*/ |
| movl _C_LABEL(nkptp)+1*4,%ecx |
movl _C_LABEL(nkptp)+1*4,%ecx |
| leal (PROC0_PDIR_OFF)(%esi),%ebx # old, phys address of PDIR |
leal (PROC0_PDIR_OFF)(%esi),%ebx # old, phys address of PDIR |
| addl $(KERNBASE), %ebx # new, virtual address of PDIR |
addl $(KERNBASE), %ebx # new, virtual address of PDIR |
| 1: movl $0,(%ebx) |
1: movl $0,(PDE_SIZE-4)(%ebx) # Upper bits (for PAE) |
| addl $4,%ebx |
movl $0,(%ebx) |
| |
addl $PDE_SIZE,%ebx |
| loop 1b |
loop 1b |
| |
|
| /* Relocate atdevbase. */ |
/* Relocate atdevbase. */ |
|
|
| movl _C_LABEL(tablesize),%eax |
movl _C_LABEL(tablesize),%eax |
| addl %esi,%eax # skip past stack and page tables |
addl %esi,%eax # skip past stack and page tables |
| |
|
| |
#ifdef PAE |
| |
pushl $0 # init386() expects a 64 bits paddr_t with PAE |
| |
#endif |
| pushl %eax |
pushl %eax |
| call _C_LABEL(init386) # wire 386 chip for unix operation |
call _C_LABEL(init386) # wire 386 chip for unix operation |
| addl $4+NGDT*8,%esp # pop temporary gdt |
addl $PDE_SIZE,%esp # pop paddr_t |
| |
addl $NGDT*8,%esp # pop temporary gdt |
| |
|
| #ifdef SAFARI_FIFO_HACK |
#ifdef SAFARI_FIFO_HACK |
| movb $5,%al |
movb $5,%al |
|
|
| #endif |
#endif |
| pushl %esi |
pushl %esi |
| call _C_LABEL(init386) # wire 386 chip for unix operation |
call _C_LABEL(init386) # wire 386 chip for unix operation |
| addl $PDE_SIZE,%esp |
addl $PDE_SIZE,%esp # pop paddr_t |
| call _C_LABEL(main) |
call _C_LABEL(main) |
| |
|
| #if defined(XEN) && !defined(XEN_COMPAT_030001) |
#if defined(XEN) && !defined(XEN_COMPAT_030001) |