Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/arch/i386/i386/locore.S,v rcsdiff: /ftp/cvs/cvsroot/src/sys/arch/i386/i386/locore.S,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.36 retrieving revision 1.43.4.7 diff -u -p -r1.36 -r1.43.4.7 --- src/sys/arch/i386/i386/locore.S 2005/12/11 12:17:41 1.36 +++ src/sys/arch/i386/i386/locore.S 2007/01/19 20:07:55 1.43.4.7 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.36 2005/12/11 12:17:41 christos Exp $ */ +/* $NetBSD: locore.S,v 1.43.4.7 2007/01/19 20:07:55 ad Exp $ */ /*- * Copyright (c) 1998, 2000, 2004 The NetBSD Foundation, Inc. @@ -83,7 +83,6 @@ #include "npx.h" #include "assym.h" -#include "apm.h" #include "lapic.h" #include "ioapic.h" #include "ksyms.h" @@ -95,12 +94,13 @@ #include #include #include -#include #if NLAPIC > 0 #include #endif +#include + /* LINTSTUB: include */ /* LINTSTUB: include */ /* LINTSTUB: include */ @@ -156,13 +156,9 @@ .data .globl _C_LABEL(cpu) - .globl _C_LABEL(esym),_C_LABEL(boothowto) - .globl _C_LABEL(bootinfo),_C_LABEL(atdevbase) -#ifdef COMPAT_OLDBOOT - .globl _C_LABEL(bootdev) -#endif - .globl _C_LABEL(proc0paddr),_C_LABEL(PDPpaddr) - .globl _C_LABEL(biosbasemem),_C_LABEL(biosextmem) + .globl _C_LABEL(esym) + .globl _C_LABEL(atdevbase) + .globl _C_LABEL(proc0uarea),_C_LABEL(PDPpaddr) .globl _C_LABEL(gdt) #ifdef I586_CPU .globl _C_LABEL(idt) @@ -195,20 +191,9 @@ _C_LABEL(lapic_tpr): _C_LABEL(cpu): .long 0 # are we 386, 386sx, or 486, # 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(proc0paddr): .long 0 +_C_LABEL(proc0uarea): .long 0 _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 tmpstk: @@ -224,66 +209,47 @@ tmpstk: .globl start start: movw $0x1234,0x472 # warm boot - /* - * Load parameters from stack - * (howto, [bootdev], bootinfo, esym, basemem, extmem). - */ - movl 4(%esp),%eax - movl %eax,RELOC(boothowto) -#ifdef COMPAT_OLDBOOT - movl 8(%esp),%eax - movl %eax,RELOC(bootdev) -#endif - movl 12(%esp),%eax +#if defined(MULTIBOOT) + jmp 1f + + .align 4 + .globl Multiboot_Header +_C_LABEL(Multiboot_Header): +#define MULTIBOOT_HEADER_FLAGS (MULTIBOOT_HEADER_WANT_MEMORY) + .long MULTIBOOT_HEADER_MAGIC + .long MULTIBOOT_HEADER_FLAGS + .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) - testl %eax, %eax - jz 1f - movl (%eax), %ebx /* number of entries */ - movl $RELOC(bootinfo), %edi - movl %ebx, (%edi) - addl $4, %edi -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: + /* Check if we are being executed by a Multiboot-compliant boot + * loader. */ + cmpl $MULTIBOOT_INFO_MAGIC,%eax + jne 1f - movl 16(%esp),%eax - testl %eax,%eax - jz 1f - addl $KERNBASE,%eax -1: movl %eax,RELOC(esym) + /* + * Indeed, a multiboot-compliant boot loader executed us. We copy + * the received Multiboot information structure into kernel's data + * space to process it later -- after we are relocated. It will + * be safer to run complex C code than doing it at this point. + */ + pushl %ebx # Address of Multiboot information + call _C_LABEL(multiboot_pre_reloc) + addl $4,%esp + jmp 2f +#endif - 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: + /* + * At this point, we know that a NetBSD-specific boot loader + * booted this kernel. The stack carries the following parameters: + * (boothowto, [bootdev], bootinfo, esym, biosextmem, biosbasemem), + * 4 bytes each. + */ + addl $4,%esp # Discard return address to boot loader + call _C_LABEL(native_loader) + addl $24,%esp +2: /* First, reset the PSL. */ pushl $PSL_MBO popfl @@ -628,11 +594,19 @@ begin: /* Set up bootstrap stack. */ leal (PROC0STACK+KERNBASE)(%esi),%eax - movl %eax,_C_LABEL(proc0paddr) - leal (USPACE-FRAMESIZE)(%eax),%esp - movl %esi,PCB_CR3(%eax) # pcb->pcb_cr3 + movl %eax,_C_LABEL(proc0uarea) + leal (KSTACK_SIZE-FRAMESIZE)(%eax),%esp + movl %esi,(KSTACK_SIZE+PCB_CR3)(%eax) # pcb->pcb_cr3 xorl %ebp,%ebp # mark end of frames +#if defined(MULTIBOOT) + /* It is now safe to parse the Multiboot information structure + * we saved before from C code. Note that we cannot delay its + * parsing any more because initgdt (called below) needs to make + * use of this information. */ + call _C_LABEL(multiboot_post_reloc) +#endif + subl $NGDT*8, %esp # space for temporary gdt pushl %esp call _C_LABEL(initgdt) @@ -794,8 +768,8 @@ NENTRY(switch_error) /* * void cpu_switch(struct lwp *) - * Find a runnable process 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 + * Find a runnable lwp and switch to it. Wait if necessary. If the new + * lwp is the same as the old one, we short-circuit the context save and * restore. * * Note that the stack frame layout is known to "struct switchframe" @@ -905,7 +879,7 @@ ENTRY(cpu_switch) xorl %esi,%esi sti idle_unlock: -#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG) +#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG) || defined(DIAGNOSTIC) call _C_LABEL(sched_unlock_idle) #endif /* Interrupts are okay again. */ @@ -934,7 +908,7 @@ idle_start: idle_exit: movl $IPL_HIGH,CPUVAR(ILEVEL) # splhigh sti -#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG) +#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG) || defined(DIAGNOSTIC) call _C_LABEL(sched_lock_idle) #endif movl _C_LABEL(sched_whichqs),%ecx @@ -1088,7 +1062,7 @@ switch_restored: movl $1,%ebx switch_return: -#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG) +#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG) || defined(DIAGNOSTIC) call _C_LABEL(sched_unlock_idle) #endif cmpl $0,CPUVAR(IPENDING) @@ -1181,8 +1155,6 @@ ENTRY(cpu_exit) movl CPUVAR(IDLE_PCB),%esi movl CPUVAR(IDLE_TSS_SEL),%edx #endif - /* In case we fault... */ - movl $0,CPUVAR(CURLWP) /* Restore the idle context. */ cli @@ -1213,19 +1185,14 @@ ENTRY(cpu_exit) /* Record new pcb. */ SET_CURPCB(%esi) + /* Now off the CPU. */ + movl $0,CPUVAR(CURLWP) + /* Interrupts are okay again. */ 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. */ xorl %esi,%esi - movl %esi,CPUVAR(CURLWP) jmp idle_start /*