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) |