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$
   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 #define R(x)    ((x)-KERNBASE)
   44 
   45 /*
   46  * this code MUST be enabled here and in mp_machdep.c
   47  * it follows the very early stages of AP boot by placing values in CMOS ram.
   48  * it NORMALLY will never be needed and thus the primitive method for enabling.
   49  *
   50 #define CHECK_POINTS
   51  */
   52 
   53 #if defined(CHECK_POINTS) && !defined(PC98)
   54 
   55 #define CMOS_REG        (0x70)
   56 #define CMOS_DATA       (0x71)
   57 
   58 #define CHECKPOINT(A,D)         \
   59         movb    $(A),%al ;      \
   60         outb    %al,$CMOS_REG ; \
   61         movb    $(D),%al ;      \
   62         outb    %al,$CMOS_DATA
   63 
   64 #else
   65 
   66 #define CHECKPOINT(A,D)
   67 
   68 #endif /* CHECK_POINTS */
   69 
   70 
   71 /*
   72  * the APs enter here from their trampoline code (bootMP, below)
   73  */
   74         .p2align 4
   75 
   76 NON_GPROF_ENTRY(MPentry)
   77         CHECKPOINT(0x36, 3)
   78         /* Now enable paging mode */
   79 #ifdef PAE
   80         movl    %cr4,%eax
   81         orl     $CR4_PAE,%eax
   82         movl    %eax,%cr4
   83         movl    $R(_IdlePDPT),%eax
   84 #else
   85         movl    R(_IdlePTD),%eax
   86 #endif
   87         movl    %eax,%cr3       
   88         movl    %cr0,%eax
   89         orl     $CR0_PE|CR0_PG,%eax             /* enable paging */
   90         movl    %eax,%cr0                       /* let the games begin! */
   91         movl    _bootSTK,%esp                   /* boot stack end loc. */
   92 
   93         pushl   $mp_begin                       /* jump to high mem */
   94         ret
   95 
   96         /*
   97          * Wait for the booting CPU to signal startup
   98          */
   99 mp_begin:       /* now running relocated at KERNBASE */
  100         CHECKPOINT(0x37, 4)
  101         call    _init_secondary                 /* load i386 tables */
  102         CHECKPOINT(0x38, 5)
  103 
  104         /*
  105          * If the [BSP] CPU has support for VME, turn it on.
  106          */
  107         testl   $CPUID_VME, _cpu_feature        /* XXX WRONG! BSP! */
  108         jz      1f
  109         movl    %cr4, %eax
  110         orl     $CR4_VME, %eax
  111         movl    %eax, %cr4
  112 1:
  113 
  114         /* disable the APIC, just to be SURE */
  115         movl    lapic_svr, %eax                 /* get spurious vector reg. */
  116         andl    $~APIC_SVR_SWEN, %eax           /* clear software enable bit */
  117         movl    %eax, lapic_svr
  118 
  119         /* signal our startup to the BSP */
  120         movl    lapic_ver, %eax                 /* our version reg contents */
  121         movl    %eax, _cpu_apic_versions        /* into [ 0 ] */
  122         incl    _mp_ncpus                       /* signal BSP */
  123 
  124         CHECKPOINT(0x39, 6)
  125 
  126         /* wait till we can get into the kernel */
  127         call    _boot_get_mplock
  128 
  129         /* Now, let's prepare for some REAL WORK :-) */
  130         call    _ap_init
  131 
  132         call    _rel_mplock
  133         wbinvd                          /* Avoid livelock */
  134 2:      
  135         cmpl    $0, CNAME(smp_started)  /* Wait for last AP to be ready */
  136         jz      2b
  137         call _get_mplock
  138         
  139         /* let her rip! (loads new stack) */
  140         jmp     _cpu_switch
  141 
  142 NON_GPROF_ENTRY(wait_ap)
  143         pushl   %ebp
  144         movl    %esp, %ebp
  145         call    _rel_mplock
  146         wbinvd                          /* Avoid livelock */
  147         movl    %eax, 8(%ebp)
  148 1:              
  149         cmpl    $0, CNAME(smp_started)
  150         jnz     2f
  151         decl    %eax
  152         cmpl    $0, %eax
  153         jge     1b
  154 2:
  155         call    _get_mplock
  156         movl    %ebp, %esp
  157         popl    %ebp
  158         ret
  159         
  160 
  161 /*
  162  * This is the embedded trampoline or bootstrap that is
  163  * copied into 'real-mode' low memory, it is where the
  164  * secondary processor "wakes up". When it is executed
  165  * the processor will eventually jump into the routine
  166  * MPentry, which resides in normal kernel text above
  167  * 1Meg.                -jackv
  168  */
  169 
  170         .data
  171         ALIGN_DATA                              /* just to be sure */
  172 
  173 BOOTMP1:
  174 
  175 NON_GPROF_ENTRY(bootMP)
  176         .code16         
  177         cli
  178         CHECKPOINT(0x34, 1)
  179         /* First guarantee a 'clean slate' */
  180         xorl    %eax, %eax
  181         movl    %eax, %ebx
  182         movl    %eax, %ecx
  183         movl    %eax, %edx
  184         movl    %eax, %esi
  185         movl    %eax, %edi
  186 
  187         /* set up data segments */
  188         mov     %cs, %ax
  189         mov     %ax, %ds
  190         mov     %ax, %es
  191         mov     %ax, %fs
  192         mov     %ax, %gs
  193         mov     %ax, %ss
  194         mov     $(boot_stk-_bootMP), %esp
  195 
  196         /* Now load the global descriptor table */
  197         lgdt    MP_GDTptr-_bootMP
  198 
  199         /* Enable protected mode */
  200         movl    %cr0, %eax
  201         orl     $CR0_PE, %eax
  202         movl    %eax, %cr0 
  203 
  204         /*
  205          * make intrasegment jump to flush the processor pipeline and
  206          * reload CS register
  207          */
  208         pushl   $0x18
  209         pushl   $(protmode-_bootMP)
  210         lretl
  211 
  212        .code32          
  213 protmode:
  214         CHECKPOINT(0x35, 2)
  215 
  216         /*
  217          * we are NOW running for the first time with %eip
  218          * having the full physical address, BUT we still
  219          * are using a segment descriptor with the origin
  220          * not matching the booting kernel.
  221          *
  222          * SO NOW... for the BIG Jump into kernel's segment
  223          * and physical text above 1 Meg.
  224          */
  225         mov     $0x10, %ebx
  226         movw    %bx, %ds
  227         movw    %bx, %es
  228         movw    %bx, %fs
  229         movw    %bx, %gs
  230         movw    %bx, %ss
  231 
  232         .globl  _bigJump
  233 _bigJump:
  234         /* this will be modified by mpInstallTramp() */
  235         ljmp    $0x08, $0                       /* far jmp to MPentry() */
  236         
  237 dead:   hlt /* We should never get here */
  238         jmp     dead
  239 
  240 /*
  241  * MP boot strap Global Descriptor Table
  242  */
  243         .p2align 4
  244         .globl  _MP_GDT
  245         .globl  _bootCodeSeg
  246         .globl  _bootDataSeg
  247 _MP_GDT:
  248 
  249 nulldesc:               /* offset = 0x0 */
  250 
  251         .word   0x0     
  252         .word   0x0     
  253         .byte   0x0     
  254         .byte   0x0     
  255         .byte   0x0     
  256         .byte   0x0     
  257 
  258 kernelcode:             /* offset = 0x08 */
  259 
  260         .word   0xffff  /* segment limit 0..15 */
  261         .word   0x0000  /* segment base 0..15 */
  262         .byte   0x0     /* segment base 16..23; set for 0K */
  263         .byte   0x9f    /* flags; Type  */
  264         .byte   0xcf    /* flags; Limit */
  265         .byte   0x0     /* segment base 24..32 */
  266 
  267 kerneldata:             /* offset = 0x10 */
  268 
  269         .word   0xffff  /* segment limit 0..15 */
  270         .word   0x0000  /* segment base 0..15 */
  271         .byte   0x0     /* segment base 16..23; set for 0k */
  272         .byte   0x93    /* flags; Type  */
  273         .byte   0xcf    /* flags; Limit */
  274         .byte   0x0     /* segment base 24..32 */
  275 
  276 bootcode:               /* offset = 0x18 */
  277 
  278         .word   0xffff  /* segment limit 0..15 */
  279 _bootCodeSeg:           /* this will be modified by mpInstallTramp() */
  280         .word   0x0000  /* segment base 0..15 */
  281         .byte   0x00    /* segment base 16...23; set for 0x000xx000 */
  282         .byte   0x9e    /* flags; Type  */
  283         .byte   0xcf    /* flags; Limit */
  284         .byte   0x0     /*segment base 24..32 */
  285 
  286 bootdata:               /* offset = 0x20 */
  287 
  288         .word   0xffff  
  289 _bootDataSeg:           /* this will be modified by mpInstallTramp() */
  290         .word   0x0000  /* segment base 0..15 */
  291         .byte   0x00    /* segment base 16...23; set for 0x000xx000 */
  292         .byte   0x92    
  293         .byte   0xcf    
  294         .byte   0x0             
  295 
  296 /*
  297  * GDT pointer for the lgdt call
  298  */
  299         .globl  _mp_gdtbase
  300 
  301 MP_GDTptr:      
  302 _mp_gdtlimit:
  303         .word   0x0028          
  304 _mp_gdtbase:            /* this will be modified by mpInstallTramp() */
  305         .long   0
  306 
  307         .space  0x100   /* space for boot_stk - 1st temporary stack */
  308 boot_stk:
  309 
  310 BOOTMP2:
  311         .globl  _bootMP_size
  312 _bootMP_size:
  313         .long   BOOTMP2 - BOOTMP1

Cache object: 9cb5cb2974326afcf7755936315de4ec


[ 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.