The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/i386/i386/mpboot.s

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 1995, Jack F. Vogel
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  * 3. All advertising materials mentioning features or use of this software
   14  *    must display the following acknowledgement:
   15  *      This product includes software developed by Jack F. Vogel
   16  * 4. The name of the developer may be used to endorse or promote products
   17  *    derived from this software without specific prior written permission.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29  * SUCH DAMAGE.
   30  *
   31  * mpboot.s:    FreeBSD machine support for the Intel MP Spec
   32  *              multiprocessor systems.
   33  *
   34  * $FreeBSD: releng/5.0/sys/i386/i386/mpboot.s 73011 2001-02-25 06:29:04Z jake $
   35  */
   36 
   37 #include <machine/asmacros.h>           /* miscellaneous asm macros */
   38 #include <machine/apic.h>
   39 #include <machine/specialreg.h>
   40 
   41 #include "assym.s"
   42 
   43 /*
   44  * this code MUST be enabled here and in mp_machdep.c
   45  * it follows the very early stages of AP boot by placing values in CMOS ram.
   46  * it NORMALLY will never be needed and thus the primitive method for enabling.
   47  *
   48 #define CHECK_POINTS
   49  */
   50 
   51 #if defined(CHECK_POINTS) && !defined(PC98)
   52 
   53 #define CMOS_REG        (0x70)
   54 #define CMOS_DATA       (0x71)
   55 
   56 #define CHECKPOINT(A,D)         \
   57         movb    $(A),%al ;      \
   58         outb    %al,$CMOS_REG ; \
   59         movb    $(D),%al ;      \
   60         outb    %al,$CMOS_DATA
   61 
   62 #else
   63 
   64 #define CHECKPOINT(A,D)
   65 
   66 #endif /* CHECK_POINTS */
   67 
   68 
   69 /*
   70  * the APs enter here from their trampoline code (bootMP, below)
   71  */
   72         .p2align 4
   73 
   74 NON_GPROF_ENTRY(MPentry)
   75         CHECKPOINT(0x36, 3)
   76         /* Now enable paging mode */
   77         movl    IdlePTD-KERNBASE, %eax
   78         movl    %eax,%cr3       
   79         movl    %cr0,%eax
   80         orl     $CR0_PE|CR0_PG,%eax             /* enable paging */
   81         movl    %eax,%cr0                       /* let the games begin! */
   82         movl    bootSTK,%esp                    /* boot stack end loc. */
   83 
   84         pushl   $mp_begin                       /* jump to high mem */
   85         ret
   86 
   87         /*
   88          * Wait for the booting CPU to signal startup
   89          */
   90 mp_begin:       /* now running relocated at KERNBASE */
   91         CHECKPOINT(0x37, 4)
   92         call    init_secondary                  /* load i386 tables */
   93         CHECKPOINT(0x38, 5)
   94 
   95         /*
   96          * If the [BSP] CPU has support for VME, turn it on.
   97          */
   98         testl   $CPUID_VME, cpu_feature         /* XXX WRONG! BSP! */
   99         jz      1f
  100         movl    %cr4, %eax
  101         orl     $CR4_VME, %eax
  102         movl    %eax, %cr4
  103 1:
  104 
  105         /* disable the APIC, just to be SURE */
  106         movl    lapic+LA_SVR, %eax              /* get spurious vector reg. */
  107         andl    $~APIC_SVR_SWEN, %eax           /* clear software enable bit */
  108         movl    %eax, lapic+LA_SVR
  109 
  110         /* signal our startup to the BSP */
  111         movl    lapic+LA_VER, %eax              /* our version reg contents */
  112         movl    %eax, cpu_apic_versions         /* into [ 0 ] */
  113         incl    mp_ncpus                        /* signal BSP */
  114 
  115         CHECKPOINT(0x39, 6)
  116 
  117         /* Now, let's prepare for some REAL WORK :-)  This doesn't return. */
  118         call    ap_init
  119 
  120 /*
  121  * This is the embedded trampoline or bootstrap that is
  122  * copied into 'real-mode' low memory, it is where the
  123  * secondary processor "wakes up". When it is executed
  124  * the processor will eventually jump into the routine
  125  * MPentry, which resides in normal kernel text above
  126  * 1Meg.                -jackv
  127  */
  128 
  129         .data
  130         ALIGN_DATA                              /* just to be sure */
  131 
  132 BOOTMP1:
  133 
  134 NON_GPROF_ENTRY(bootMP)
  135         .code16         
  136         cli
  137         CHECKPOINT(0x34, 1)
  138         /* First guarantee a 'clean slate' */
  139         xorl    %eax, %eax
  140         movl    %eax, %ebx
  141         movl    %eax, %ecx
  142         movl    %eax, %edx
  143         movl    %eax, %esi
  144         movl    %eax, %edi
  145 
  146         /* set up data segments */
  147         mov     %cs, %ax
  148         mov     %ax, %ds
  149         mov     %ax, %es
  150         mov     %ax, %fs
  151         mov     %ax, %gs
  152         mov     %ax, %ss
  153         mov     $(boot_stk-bootMP), %esp
  154 
  155         /* Now load the global descriptor table */
  156         lgdt    MP_GDTptr-bootMP
  157 
  158         /* Enable protected mode */
  159         movl    %cr0, %eax
  160         orl     $CR0_PE, %eax
  161         movl    %eax, %cr0 
  162 
  163         /*
  164          * make intrasegment jump to flush the processor pipeline and
  165          * reload CS register
  166          */
  167         pushl   $0x18
  168         pushl   $(protmode-bootMP)
  169         lretl
  170 
  171        .code32          
  172 protmode:
  173         CHECKPOINT(0x35, 2)
  174 
  175         /*
  176          * we are NOW running for the first time with %eip
  177          * having the full physical address, BUT we still
  178          * are using a segment descriptor with the origin
  179          * not matching the booting kernel.
  180          *
  181          * SO NOW... for the BIG Jump into kernel's segment
  182          * and physical text above 1 Meg.
  183          */
  184         mov     $0x10, %ebx
  185         movw    %bx, %ds
  186         movw    %bx, %es
  187         movw    %bx, %fs
  188         movw    %bx, %gs
  189         movw    %bx, %ss
  190 
  191         .globl  bigJump
  192 bigJump:
  193         /* this will be modified by mpInstallTramp() */
  194         ljmp    $0x08, $0                       /* far jmp to MPentry() */
  195         
  196 dead:   hlt /* We should never get here */
  197         jmp     dead
  198 
  199 /*
  200  * MP boot strap Global Descriptor Table
  201  */
  202         .p2align 4
  203         .globl  MP_GDT
  204         .globl  bootCodeSeg
  205         .globl  bootDataSeg
  206 MP_GDT:
  207 
  208 nulldesc:               /* offset = 0x0 */
  209 
  210         .word   0x0     
  211         .word   0x0     
  212         .byte   0x0     
  213         .byte   0x0     
  214         .byte   0x0     
  215         .byte   0x0     
  216 
  217 kernelcode:             /* offset = 0x08 */
  218 
  219         .word   0xffff  /* segment limit 0..15 */
  220         .word   0x0000  /* segment base 0..15 */
  221         .byte   0x0     /* segment base 16..23; set for 0K */
  222         .byte   0x9f    /* flags; Type  */
  223         .byte   0xcf    /* flags; Limit */
  224         .byte   0x0     /* segment base 24..32 */
  225 
  226 kerneldata:             /* offset = 0x10 */
  227 
  228         .word   0xffff  /* segment limit 0..15 */
  229         .word   0x0000  /* segment base 0..15 */
  230         .byte   0x0     /* segment base 16..23; set for 0k */
  231         .byte   0x93    /* flags; Type  */
  232         .byte   0xcf    /* flags; Limit */
  233         .byte   0x0     /* segment base 24..32 */
  234 
  235 bootcode:               /* offset = 0x18 */
  236 
  237         .word   0xffff  /* segment limit 0..15 */
  238 bootCodeSeg:            /* this will be modified by mpInstallTramp() */
  239         .word   0x0000  /* segment base 0..15 */
  240         .byte   0x00    /* segment base 16...23; set for 0x000xx000 */
  241         .byte   0x9e    /* flags; Type  */
  242         .byte   0xcf    /* flags; Limit */
  243         .byte   0x0     /*segment base 24..32 */
  244 
  245 bootdata:               /* offset = 0x20 */
  246 
  247         .word   0xffff  
  248 bootDataSeg:            /* this will be modified by mpInstallTramp() */
  249         .word   0x0000  /* segment base 0..15 */
  250         .byte   0x00    /* segment base 16...23; set for 0x000xx000 */
  251         .byte   0x92    
  252         .byte   0xcf    
  253         .byte   0x0             
  254 
  255 /*
  256  * GDT pointer for the lgdt call
  257  */
  258         .globl  mp_gdtbase
  259 
  260 MP_GDTptr:      
  261 mp_gdtlimit:
  262         .word   0x0028          
  263 mp_gdtbase:             /* this will be modified by mpInstallTramp() */
  264         .long   0
  265 
  266         .space  0x100   /* space for boot_stk - 1st temporary stack */
  267 boot_stk:
  268 
  269 BOOTMP2:
  270         .globl  bootMP_size
  271 bootMP_size:
  272         .long   BOOTMP2 - BOOTMP1

Cache object: 49122907ebd99eb45d25ef801ef56600


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.