version 1.120, 2016/05/14 08:39:41 |
version 1.129, 2016/06/04 10:02:12 |
|
|
*/ |
*/ |
|
|
/* |
/* |
|
* Copyright (c) 1998, 2000, 2004, 2006, 2007, 2009, 2016 |
|
* The NetBSD Foundation, Inc., All rights reserved. |
|
* |
|
* This code is derived from software contributed to The NetBSD Foundation |
|
* by Charles M. Hannum, by Andrew Doran and by Maxime Villard. |
|
* |
|
* Redistribution and use in source and binary forms, with or without |
|
* modification, are permitted provided that the following conditions |
|
* are met: |
|
* 1. Redistributions of source code must retain the above copyright |
|
* notice, this list of conditions and the following disclaimer. |
|
* 2. Redistributions in binary form must reproduce the above copyright |
|
* notice, this list of conditions and the following disclaimer in the |
|
* documentation and/or other materials provided with the distribution. |
|
* |
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
* POSSIBILITY OF SUCH DAMAGE. |
|
*/ |
|
|
|
/* |
* Copyright (c) 2006 Manuel Bouyer. |
* Copyright (c) 2006 Manuel Bouyer. |
* |
* |
* Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without |
|
|
*/ |
*/ |
|
|
/*- |
/*- |
* Copyright (c) 1998, 2000, 2004, 2006, 2007, 2009 The NetBSD Foundation, Inc. |
|
* All rights reserved. |
|
* |
|
* This code is derived from software contributed to The NetBSD Foundation |
|
* by Charles M. Hannum, and by Andrew Doran. |
|
* |
|
* Redistribution and use in source and binary forms, with or without |
|
* modification, are permitted provided that the following conditions |
|
* are met: |
|
* 1. Redistributions of source code must retain the above copyright |
|
* notice, this list of conditions and the following disclaimer. |
|
* 2. Redistributions in binary form must reproduce the above copyright |
|
* notice, this list of conditions and the following disclaimer in the |
|
* documentation and/or other materials provided with the distribution. |
|
* |
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
* POSSIBILITY OF SUCH DAMAGE. |
|
*/ |
|
|
|
/*- |
|
* Copyright (c) 1990 The Regents of the University of California. |
* Copyright (c) 1990 The Regents of the University of California. |
* All rights reserved. |
* All rights reserved. |
* |
* |
Line 147 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 147 __KERNEL_RCSID(0, "$NetBSD$"); |
|
#include <sys/errno.h> |
#include <sys/errno.h> |
#include <sys/syscall.h> |
#include <sys/syscall.h> |
|
|
#include <machine/cputypes.h> |
|
#include <machine/segments.h> |
#include <machine/segments.h> |
#include <machine/specialreg.h> |
#include <machine/specialreg.h> |
#include <machine/trap.h> |
#include <machine/trap.h> |
#include <machine/i82489reg.h> |
#include <machine/i82489reg.h> |
#include <machine/frameasm.h> |
#include <machine/frameasm.h> |
#include <machine/i82489reg.h> |
#include <machine/i82489reg.h> |
|
#include <machine/cputypes.h> |
|
|
#ifndef XEN |
#ifndef XEN |
#include <machine/multiboot.h> |
#include <machine/multiboot.h> |
#endif |
#endif |
Line 191 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 192 __KERNEL_RCSID(0, "$NetBSD$"); |
|
* This is done by the first instruction of fillkpt. In the non-PAE case, this |
* This is done by the first instruction of fillkpt. In the non-PAE case, this |
* instruction just clears the page table entry. |
* instruction just clears the page table entry. |
*/ |
*/ |
|
|
#define fillkpt \ |
#define fillkpt \ |
|
cmpl $0,%ecx ; /* zero-sized? */ \ |
|
je 2f ; \ |
1: movl $0,(PDE_SIZE-4)(%ebx) ; /* upper 32 bits: 0 */ \ |
1: movl $0,(PDE_SIZE-4)(%ebx) ; /* upper 32 bits: 0 */ \ |
movl %eax,(%ebx) ; /* store phys addr */ \ |
movl %eax,(%ebx) ; /* store phys addr */ \ |
addl $PDE_SIZE,%ebx ; /* next PTE/PDE */ \ |
addl $PDE_SIZE,%ebx ; /* next PTE/PDE */ \ |
addl $PAGE_SIZE,%eax ; /* next phys page */ \ |
addl $PAGE_SIZE,%eax ; /* next phys page */ \ |
loop 1b ; |
loop 1b ; \ |
|
2: ; |
|
|
/* |
/* |
* fillkpt_nox - Same as fillkpt, but sets the NX/XD bit. |
* fillkpt_nox - Same as fillkpt, but sets the NX/XD bit. |
*/ |
*/ |
#define fillkpt_nox \ |
#define fillkpt_nox \ |
|
cmpl $0,%ecx ; /* zero-sized? */ \ |
|
je 2f ; \ |
pushl %ebp ; \ |
pushl %ebp ; \ |
movl RELOC(nox_flag),%ebp ; \ |
movl RELOC(nox_flag),%ebp ; \ |
1: movl %ebp,(PDE_SIZE-4)(%ebx) ; /* upper 32 bits: NX */ \ |
1: movl %ebp,(PDE_SIZE-4)(%ebx) ; /* upper 32 bits: NX */ \ |
Line 210 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 215 __KERNEL_RCSID(0, "$NetBSD$"); |
|
addl $PDE_SIZE,%ebx ; /* next PTE/PDE */ \ |
addl $PDE_SIZE,%ebx ; /* next PTE/PDE */ \ |
addl $PAGE_SIZE,%eax ; /* next phys page */ \ |
addl $PAGE_SIZE,%eax ; /* next phys page */ \ |
loop 1b ; \ |
loop 1b ; \ |
popl %ebp ; |
popl %ebp ; \ |
|
2: ; |
|
|
|
/* |
|
* fillkpt_blank - Fill in a kernel page table with blank entries |
|
* ebx = page table address |
|
* ecx = number of pages to map |
|
*/ |
|
#define fillkpt_blank \ |
|
cmpl $0,%ecx ; /* zero-sized? */ \ |
|
je 2f ; \ |
|
1: movl $0,(PDE_SIZE-4)(%ebx) ; /* upper 32 bits: 0 */ \ |
|
movl $0,(%ebx) ; /* lower 32 bits: 0 */ \ |
|
addl $PDE_SIZE,%ebx ; /* next PTE/PDE */ \ |
|
loop 1b ; \ |
|
2: ; |
|
|
/* |
/* |
* killkpt - Destroy a kernel page table |
* killkpt - Destroy a kernel page table |
Line 250 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 270 __KERNEL_RCSID(0, "$NetBSD$"); |
|
*/ |
*/ |
.data |
.data |
|
|
.globl _C_LABEL(nox_flag) |
|
.globl _C_LABEL(cputype) |
|
.globl _C_LABEL(cpuid_level) |
|
.globl _C_LABEL(esym) |
|
.globl _C_LABEL(eblob) |
|
.globl _C_LABEL(atdevbase) |
|
.globl _C_LABEL(lwp0uarea) |
|
.globl _C_LABEL(PDPpaddr) |
|
.globl _C_LABEL(gdt) |
|
.globl _C_LABEL(idt) |
|
.globl _C_LABEL(lapic_tpr) |
.globl _C_LABEL(lapic_tpr) |
|
|
#if NLAPIC > 0 |
#if NLAPIC > 0 |
Line 268 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 278 __KERNEL_RCSID(0, "$NetBSD$"); |
|
#else |
#else |
.align 12 |
.align 12 |
#endif |
#endif |
.globl _C_LABEL(local_apic), _C_LABEL(lapic_id) |
.globl _C_LABEL(local_apic) |
|
.globl _C_LABEL(lapic_id) |
|
|
.type _C_LABEL(local_apic), @object |
.type _C_LABEL(local_apic), @object |
LABEL(local_apic) |
LABEL(local_apic) |
.space LAPIC_ID |
.space LAPIC_ID |
Line 297 LABEL(lapic_tpr) |
|
Line 309 LABEL(lapic_tpr) |
|
END(lapic_tpr) |
END(lapic_tpr) |
#endif |
#endif |
|
|
|
.globl _C_LABEL(tablesize) |
|
.globl _C_LABEL(nox_flag) |
|
.globl _C_LABEL(cputype) |
|
.globl _C_LABEL(cpuid_level) |
|
.globl _C_LABEL(esym) |
|
.globl _C_LABEL(eblob) |
|
.globl _C_LABEL(atdevbase) |
|
.globl _C_LABEL(PDPpaddr) |
|
.globl _C_LABEL(lwp0uarea) |
|
.globl _C_LABEL(gdt) |
|
.globl _C_LABEL(idt) |
|
|
|
.type _C_LABEL(tablesize), @object |
|
_C_LABEL(tablesize): .long 0 |
|
END(tablesize) |
.type _C_LABEL(nox_flag), @object |
.type _C_LABEL(nox_flag), @object |
LABEL(nox_flag) .long 0 /* 32bit NOX flag, set if supported */ |
LABEL(nox_flag) .long 0 /* 32bit NOX flag, set if supported */ |
END(nox_flag) |
END(nox_flag) |
|
|
LABEL(cputype) .long 0 /* are we 80486, Pentium, or.. */ |
LABEL(cputype) .long 0 /* are we 80486, Pentium, or.. */ |
END(cputype) |
END(cputype) |
.type _C_LABEL(cpuid_level), @object |
.type _C_LABEL(cpuid_level), @object |
LABEL(cpuid_level) .long 0 |
LABEL(cpuid_level) .long -1 /* max. level accepted by cpuid instr */ |
END(cpuid_level) |
END(cpuid_level) |
.type _C_LABEL(atdevbase), @object |
.type _C_LABEL(atdevbase), @object |
LABEL(atdevbase) .long 0 /* location of start of iomem in virt */ |
LABEL(atdevbase) .long 0 /* location of start of iomem in virt */ |
|
|
.type _C_LABEL(PDPpaddr), @object |
.type _C_LABEL(PDPpaddr), @object |
LABEL(PDPpaddr) .long 0 /* paddr of PDP, for libkvm */ |
LABEL(PDPpaddr) .long 0 /* paddr of PDP, for libkvm */ |
END(PDPpaddr) |
END(PDPpaddr) |
.type _C_LABEL(tablesize), @object |
|
_C_LABEL(tablesize): .long 0 |
|
END(tablesize) |
|
|
|
/* Space for the temporary stack */ |
/* Space for the temporary stack */ |
.size tmpstk, tmpstk - . |
.size tmpstk, tmpstk - . |
Line 392 _C_LABEL(Multiboot_Header): |
|
Line 416 _C_LABEL(Multiboot_Header): |
|
xorl %eax,%eax |
xorl %eax,%eax |
movw %ax,%fs |
movw %ax,%fs |
movw %ax,%gs |
movw %ax,%gs |
decl %eax |
|
movl %eax,RELOC(cpuid_level) |
|
|
|
/* Find out our CPU type. */ |
/* Find out our CPU type. */ |
|
|
Line 555 try586: /* Use the `cpuid' instruction. |
|
Line 577 try586: /* Use the `cpuid' instruction. |
|
cpuid |
cpuid |
movl %eax,RELOC(cpuid_level) |
movl %eax,RELOC(cpuid_level) |
|
|
|
/* |
|
* Retrieve the NX/XD flag. We use the 32bit version of PG_NX. |
|
*/ |
|
movl $0x80000001,%eax |
|
cpuid |
|
andl $CPUID_NOX,%edx |
|
jz no_NOX |
|
movl $PG_NX32,RELOC(nox_flag) |
|
no_NOX: |
|
|
2: |
2: |
/* |
/* |
* Finished with old stack; load new %esp now instead of later so we |
* Finished with old stack; load new %esp now instead of later so we |
Line 571 try586: /* Use the `cpuid' instruction. |
|
Line 603 try586: /* Use the `cpuid' instruction. |
|
*/ |
*/ |
movl $_RELOC(tmpstk),%esp |
movl $_RELOC(tmpstk),%esp |
|
|
/* |
|
* Retrieve the NX/XD flag. We use the 32bit version of PG_NX. |
|
*/ |
|
movl $0x80000001,%eax |
|
cpuid |
|
andl $CPUID_NOX,%edx |
|
jz no_NOX |
|
movl $PG_NX32,RELOC(nox_flag) |
|
no_NOX: |
|
|
|
/* |
/* |
* There are two different layouts possible, depending on whether PAE is |
* There are two different layouts possible, depending on whether PAE is |
* enabled or not. |
* enabled or not. |
|
|
* |
* |
* PROC0 STK is obviously not linked as a page level. It just happens to be |
* PROC0 STK is obviously not linked as a page level. It just happens to be |
* caught between L2 and L1. |
* caught between L2 and L1. |
|
* |
|
* Important note: the kernel segments are properly 4k-aligned |
|
* (see kern.ldscript), so there's no need to enforce alignment. |
*/ |
*/ |
|
|
/* Find end of kernel image; brings us on (1). */ |
/* Find end of kernel image; brings us on (1). */ |
|
|
*/ |
*/ |
leal (PROC0_PTP1_OFF)(%esi),%ebx |
leal (PROC0_PTP1_OFF)(%esi),%ebx |
|
|
/* Compute &__rodata_start - KERNBASE. */ |
|
movl $RELOC(__rodata_start),%edx |
|
andl $~PGOFSET,%edx |
|
|
|
/* Skip the first MB. */ |
/* Skip the first MB. */ |
movl $(KERNTEXTOFF - KERNBASE),%eax |
movl $(KERNTEXTOFF - KERNBASE),%ecx |
movl %eax,%ecx |
shrl $PGSHIFT,%ecx |
shrl $(PGSHIFT-2),%ecx /* ((n >> PGSHIFT) << 2) for # PDEs */ |
fillkpt_blank |
#ifdef PAE |
|
shll $1,%ecx /* PDEs are twice larger with PAE */ |
|
#endif |
|
addl %ecx,%ebx |
|
|
|
/* Map the kernel text read-only. */ |
/* Map the kernel text RX. */ |
movl %edx,%ecx |
movl $(KERNTEXTOFF - KERNBASE),%eax /* start of TEXT */ |
|
movl $RELOC(__rodata_start),%ecx |
subl %eax,%ecx |
subl %eax,%ecx |
shrl $PGSHIFT,%ecx |
shrl $PGSHIFT,%ecx |
orl $(PG_V|PG_KR),%eax |
orl $(PG_V|PG_KR),%eax |
fillkpt |
fillkpt |
|
|
/* Map the data, BSS, and bootstrap tables read-write. */ |
/* Map the kernel rodata R. */ |
leal (PG_V|PG_KW)(%edx),%eax |
movl $RELOC(__rodata_start),%eax |
movl RELOC(tablesize),%ecx |
movl $RELOC(__data_start),%ecx |
addl %esi,%ecx /* end of tables */ |
subl %eax,%ecx |
subl %edx,%ecx /* subtract end of text */ |
shrl $PGSHIFT,%ecx |
|
orl $(PG_V|PG_KR),%eax |
|
fillkpt_nox |
|
|
|
/* Map the kernel data+bss RW. */ |
|
movl $RELOC(__data_start),%eax |
|
movl $RELOC(__kernel_end),%ecx |
|
subl %eax,%ecx |
shrl $PGSHIFT,%ecx |
shrl $PGSHIFT,%ecx |
|
orl $(PG_V|PG_KW),%eax |
|
fillkpt_nox |
|
|
|
/* Map [SYMS]+[PRELOADED MODULES] RWX. */ |
|
movl $RELOC(__kernel_end),%eax |
|
movl %esi,%ecx /* start of BOOTSTRAP TABLES */ |
|
subl %eax,%ecx |
|
shrl $PGSHIFT,%ecx |
|
orl $(PG_V|PG_KW),%eax |
fillkpt |
fillkpt |
|
|
/* Map ISA I/O mem (later atdevbase) */ |
/* Map the BOOTSTRAP TABLES RW. */ |
|
movl %esi,%eax /* start of BOOTSTRAP TABLES */ |
|
movl RELOC(tablesize),%ecx /* length of BOOTSTRAP TABLES */ |
|
shrl $PGSHIFT,%ecx |
|
orl $(PG_V|PG_KW),%eax |
|
fillkpt_nox |
|
|
|
/* We are on (4). Map ISA I/O mem (later atdevbase) RWX. */ |
movl $(IOM_BEGIN|PG_V|PG_KW/*|PG_N*/),%eax |
movl $(IOM_BEGIN|PG_V|PG_KW/*|PG_N*/),%eax |
movl $(IOM_SIZE>>PGSHIFT),%ecx |
movl $(IOM_SIZE>>PGSHIFT),%ecx |
fillkpt |
fillkpt |