version 1.37, 2006/02/03 11:08:24 |
version 1.47, 2007/02/19 11:46:10 |
|
|
|
|
#include "npx.h" |
#include "npx.h" |
#include "assym.h" |
#include "assym.h" |
#include "apm.h" |
|
#include "lapic.h" |
#include "lapic.h" |
#include "ioapic.h" |
#include "ioapic.h" |
#include "ksyms.h" |
#include "ksyms.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/bootinfo.h> |
|
|
|
#if NLAPIC > 0 |
#if NLAPIC > 0 |
#include <machine/i82489reg.h> |
#include <machine/i82489reg.h> |
|
|
.data |
.data |
|
|
.globl _C_LABEL(cpu) |
.globl _C_LABEL(cpu) |
.globl _C_LABEL(esym),_C_LABEL(boothowto) |
.globl _C_LABEL(esym) |
.globl _C_LABEL(bootinfo),_C_LABEL(atdevbase) |
.globl _C_LABEL(atdevbase) |
#ifdef COMPAT_OLDBOOT |
.globl _C_LABEL(proc0uarea),_C_LABEL(PDPpaddr) |
.globl _C_LABEL(bootdev) |
|
#endif |
|
.globl _C_LABEL(proc0paddr),_C_LABEL(PDPpaddr) |
|
.globl _C_LABEL(biosbasemem),_C_LABEL(biosextmem) |
|
.globl _C_LABEL(gdt) |
.globl _C_LABEL(gdt) |
#ifdef I586_CPU |
#ifdef I586_CPU |
.globl _C_LABEL(idt) |
.globl _C_LABEL(idt) |
Line 197 _C_LABEL(lapic_tpr): |
|
Line 191 _C_LABEL(lapic_tpr): |
|
|
|
_C_LABEL(cpu): .long 0 # are we 386, 386sx, or 486, |
_C_LABEL(cpu): .long 0 # are we 386, 386sx, or 486, |
# or Pentium, or.. |
# or Pentium, or.. |
_C_LABEL(esym): .long 0 # ptr to end of syms |
|
_C_LABEL(atdevbase): .long 0 # location of start of iomem in virtual |
_C_LABEL(atdevbase): .long 0 # location of start of iomem in virtual |
_C_LABEL(proc0paddr): .long 0 |
_C_LABEL(proc0uarea): .long 0 |
_C_LABEL(PDPpaddr): .long 0 # paddr of PDP, for libkvm |
_C_LABEL(PDPpaddr): .long 0 # paddr of PDP, for libkvm |
#ifndef REALBASEMEM |
|
_C_LABEL(biosbasemem): .long 0 # base memory reported by BIOS |
|
#else |
|
_C_LABEL(biosbasemem): .long REALBASEMEM |
|
#endif |
|
#ifndef REALEXTMEM |
|
_C_LABEL(biosextmem): .long 0 # extended memory reported by BIOS |
|
#else |
|
_C_LABEL(biosextmem): .long REALEXTMEM |
|
#endif |
|
|
|
.space 512 |
.space 512 |
tmpstk: |
tmpstk: |
Line 232 start: movw $0x1234,0x472 # warm boot |
|
Line 215 start: movw $0x1234,0x472 # warm boot |
|
.align 4 |
.align 4 |
.globl Multiboot_Header |
.globl Multiboot_Header |
_C_LABEL(Multiboot_Header): |
_C_LABEL(Multiboot_Header): |
#define MULTIBOOT_HEADER_FLAGS (MULTIBOOT_HEADER_WANT_MEMORY | \ |
#define MULTIBOOT_HEADER_FLAGS (MULTIBOOT_HEADER_WANT_MEMORY) |
MULTIBOOT_HEADER_HAS_ADDR) |
|
.long MULTIBOOT_HEADER_MAGIC |
.long MULTIBOOT_HEADER_MAGIC |
.long MULTIBOOT_HEADER_FLAGS |
.long MULTIBOOT_HEADER_FLAGS |
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) |
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) |
.long RELOC(Multiboot_Header) |
|
.long RELOC(start) |
|
.long RELOC(_edata) |
|
.long RELOC(_end) + MULTIBOOT_SYMTAB_SPACE |
|
.long RELOC(start) |
|
|
|
1: |
1: |
/* Check if we are being executed by a Multiboot-compliant boot |
/* Check if we are being executed by a Multiboot-compliant boot |
Line 249 _C_LABEL(Multiboot_Header): |
|
Line 226 _C_LABEL(Multiboot_Header): |
|
cmpl $MULTIBOOT_INFO_MAGIC,%eax |
cmpl $MULTIBOOT_INFO_MAGIC,%eax |
jne 1f |
jne 1f |
|
|
/* Indeed, a multiboot-compliat boot loader executed us. We copy |
/* |
|
* Indeed, a multiboot-compliant boot loader executed us. We copy |
* the received Multiboot information structure into kernel's data |
* the received Multiboot information structure into kernel's data |
* space to process it later -- after we are relocated. It will |
* space to process it later -- after we are relocated. It will |
* be safer to run complex C code than doing it at this point. */ |
* be safer to run complex C code than doing it at this point. |
|
*/ |
pushl %ebx # Address of Multiboot information |
pushl %ebx # Address of Multiboot information |
call _C_LABEL(multiboot_pre_reloc) |
call _C_LABEL(multiboot_pre_reloc) |
addl $4,%esp |
addl $4,%esp |
jmp 3f |
jmp 2f |
#endif |
#endif |
|
|
1: |
1: |
/* |
/* |
* Load parameters from stack |
* At this point, we know that a NetBSD-specific boot loader |
* (howto, [bootdev], bootinfo, esym, basemem, extmem). |
* booted this kernel. The stack carries the following parameters: |
|
* (boothowto, [bootdev], bootinfo, esym, biosextmem, biosbasemem), |
|
* 4 bytes each. |
*/ |
*/ |
movl 4(%esp),%eax |
addl $4,%esp # Discard return address to boot loader |
movl %eax,RELOC(boothowto) |
call _C_LABEL(native_loader) |
#ifdef COMPAT_OLDBOOT |
addl $24,%esp |
movl 8(%esp),%eax |
|
movl %eax,RELOC(bootdev) |
|
#endif |
|
movl 12(%esp),%eax |
|
|
|
testl %eax, %eax |
|
jz 1f |
|
movl (%eax), %ebx /* number of entries */ |
|
movl $RELOC(bootinfo), %edi |
|
movl %ebx, (%edi) |
|
addl $4, %edi |
|
2: |
2: |
testl %ebx, %ebx |
|
jz 1f |
|
addl $4, %eax |
|
movl (%eax), %ecx /* address of entry */ |
|
pushl %eax |
|
pushl (%ecx) /* len */ |
|
pushl %ecx |
|
pushl %edi |
|
addl (%ecx), %edi /* update dest pointer */ |
|
cmpl $_RELOC(_C_LABEL(bootinfo) + BOOTINFO_MAXSIZE), %edi |
|
jg 2f |
|
call _C_LABEL(memcpy) |
|
addl $12, %esp |
|
popl %eax |
|
subl $1, %ebx |
|
jmp 2b |
|
2: /* cleanup for overflow case */ |
|
addl $16, %esp |
|
movl $RELOC(bootinfo), %edi |
|
subl %ebx, (%edi) /* correct number of entries */ |
|
1: |
|
|
|
movl 16(%esp),%eax |
|
testl %eax,%eax |
|
jz 1f |
|
addl $KERNBASE,%eax |
|
1: movl %eax,RELOC(esym) |
|
|
|
movl RELOC(biosextmem),%eax |
|
testl %eax,%eax |
|
jnz 1f |
|
movl 20(%esp),%eax |
|
movl %eax,RELOC(biosextmem) |
|
1: |
|
movl RELOC(biosbasemem),%eax |
|
testl %eax,%eax |
|
jnz 1f |
|
movl 24(%esp),%eax |
|
movl %eax,RELOC(biosbasemem) |
|
1: |
|
|
|
3: |
|
/* First, reset the PSL. */ |
/* First, reset the PSL. */ |
pushl $PSL_MBO |
pushl $PSL_MBO |
popfl |
popfl |
|
|
|
|
/* Set up bootstrap stack. */ |
/* Set up bootstrap stack. */ |
leal (PROC0STACK+KERNBASE)(%esi),%eax |
leal (PROC0STACK+KERNBASE)(%esi),%eax |
movl %eax,_C_LABEL(proc0paddr) |
movl %eax,_C_LABEL(proc0uarea) |
leal (USPACE-FRAMESIZE)(%eax),%esp |
leal (KSTACK_SIZE-FRAMESIZE)(%eax),%esp |
movl %esi,PCB_CR3(%eax) # pcb->pcb_cr3 |
movl %esi,(KSTACK_SIZE+PCB_CR3)(%eax) # pcb->pcb_cr3 |
xorl %ebp,%ebp # mark end of frames |
xorl %ebp,%ebp # mark end of frames |
|
|
#if defined(MULTIBOOT) |
#if defined(MULTIBOOT) |
|
|
pushl %eax |
pushl %eax |
lret |
lret |
|
|
|
NENTRY(x86_flush) |
|
/* Reload code selector by doing intersegment return. */ |
|
popl %eax |
|
pushl $GSEL(GCODE_SEL, SEL_KPL) |
|
pushl %eax |
|
lret |
|
|
/*****************************************************************************/ |
/*****************************************************************************/ |
|
|
/* |
/* |
Line 839 NENTRY(switch_error) |
|
Line 775 NENTRY(switch_error) |
|
|
|
/* |
/* |
* void cpu_switch(struct lwp *) |
* void cpu_switch(struct lwp *) |
* Find a runnable process and switch to it. Wait if necessary. If the new |
* Find a runnable lwp and switch to it. Wait if necessary. If the new |
* process is the same as the old one, we short-circuit the context save and |
* lwp is the same as the old one, we short-circuit the context save and |
* restore. |
* restore. |
* |
* |
* Note that the stack frame layout is known to "struct switchframe" |
* Note that the stack frame layout is known to "struct switchframe" |
Line 950 ENTRY(cpu_switch) |
|
Line 886 ENTRY(cpu_switch) |
|
xorl %esi,%esi |
xorl %esi,%esi |
sti |
sti |
idle_unlock: |
idle_unlock: |
#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG) |
|
call _C_LABEL(sched_unlock_idle) |
call _C_LABEL(sched_unlock_idle) |
#endif |
|
/* Interrupts are okay again. */ |
/* Interrupts are okay again. */ |
pushl $IPL_NONE # spl0() |
pushl $IPL_NONE # spl0() |
call _C_LABEL(Xspllower) # process pending interrupts |
call _C_LABEL(spllower) # process pending interrupts |
addl $4,%esp |
addl $4,%esp |
jmp idle_start |
jmp idle_start |
idle_zero: |
idle_zero: |
|
|
idle_exit: |
idle_exit: |
movl $IPL_HIGH,CPUVAR(ILEVEL) # splhigh |
movl $IPL_HIGH,CPUVAR(ILEVEL) # splhigh |
sti |
sti |
#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG) |
|
call _C_LABEL(sched_lock_idle) |
call _C_LABEL(sched_lock_idle) |
#endif |
|
movl _C_LABEL(sched_whichqs),%ecx |
movl _C_LABEL(sched_whichqs),%ecx |
bsfl %ecx,%ebx |
bsfl %ecx,%ebx |
jz idle_unlock |
jz idle_unlock |
|
|
|
|
#if 0 |
#if 0 |
/* Don't bother with the rest if switching to a system process. */ |
/* Don't bother with the rest if switching to a system process. */ |
testl $P_SYSTEM,L_FLAG(%edi); XXX NJWLWP lwp's don't have P_SYSTEM! |
testl $PK_SYSTEM,L_FLAG(%edi); XXX NJWLWP lwp's don't have PK_SYSTEM! |
jnz switch_restored |
jnz switch_restored |
#endif |
#endif |
|
|
Line 1133 switch_restored: |
|
Line 1065 switch_restored: |
|
movl $1,%ebx |
movl $1,%ebx |
|
|
switch_return: |
switch_return: |
#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG) |
|
call _C_LABEL(sched_unlock_idle) |
call _C_LABEL(sched_unlock_idle) |
#endif |
|
cmpl $0,CPUVAR(IPENDING) |
cmpl $0,CPUVAR(IPENDING) |
jz 3f |
jz 3f |
pushl $IPL_NONE # spl0() |
pushl $IPL_NONE # spl0() |
call _C_LABEL(Xspllower) # process pending interrupts |
call _C_LABEL(spllower) # process pending interrupts |
addl $4,%esp |
addl $4,%esp |
3: |
3: |
movl $IPL_HIGH,CPUVAR(ILEVEL) # splhigh() |
movl $IPL_HIGH,CPUVAR(ILEVEL) # splhigh() |
Line 1226 ENTRY(cpu_exit) |
|
Line 1156 ENTRY(cpu_exit) |
|
movl CPUVAR(IDLE_PCB),%esi |
movl CPUVAR(IDLE_PCB),%esi |
movl CPUVAR(IDLE_TSS_SEL),%edx |
movl CPUVAR(IDLE_TSS_SEL),%edx |
#endif |
#endif |
/* In case we fault... */ |
|
movl $0,CPUVAR(CURLWP) |
|
|
|
/* Restore the idle context. */ |
/* Restore the idle context. */ |
cli |
cli |
Line 1258 ENTRY(cpu_exit) |
|
Line 1186 ENTRY(cpu_exit) |
|
/* Record new pcb. */ |
/* Record new pcb. */ |
SET_CURPCB(%esi) |
SET_CURPCB(%esi) |
|
|
|
/* Now off the CPU. */ |
|
movl $0,CPUVAR(CURLWP) |
|
|
/* Interrupts are okay again. */ |
/* Interrupts are okay again. */ |
sti |
sti |
|
|
/* |
|
* Schedule the dead LWP's stack to be freed. |
|
*/ |
|
pushl %edi |
|
call _C_LABEL(lwp_exit2) |
|
addl $4,%esp |
|
|
|
/* Jump into cpu_switch() with the right state. */ |
/* Jump into cpu_switch() with the right state. */ |
xorl %esi,%esi |
xorl %esi,%esi |
movl %esi,CPUVAR(CURLWP) |
|
jmp idle_start |
jmp idle_start |
|
|
/* |
/* |
Line 1279 ENTRY(cpu_exit) |
|
Line 1202 ENTRY(cpu_exit) |
|
*/ |
*/ |
/* LINTSTUB: Func: void savectx(struct pcb *pcb) */ |
/* LINTSTUB: Func: void savectx(struct pcb *pcb) */ |
ENTRY(savectx) |
ENTRY(savectx) |
movl 4(%esp),%edx # edx = p->p_addr |
movl 4(%esp),%edx # edx = pcb |
|
|
/* Save stack pointers. */ |
/* Save stack pointers. */ |
movl %esp,PCB_ESP(%edx) |
movl %esp,PCB_ESP(%edx) |