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  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  *
   26  * mpboot.s:    FreeBSD machine support for the Intel MP Spec
   27  *              multiprocessor systems.
   28  *
   29  * $FreeBSD$
   30  */
   31 
   32 #include "opt_pmap.h"
   33 
   34 #include <machine/asmacros.h>           /* miscellaneous asm macros */
   35 #include <x86/apicreg.h>
   36 #include <machine/specialreg.h>
   37 
   38 #include "assym.inc"
   39 
   40 /*
   41  * this code MUST be enabled here and in mp_machdep.c
   42  * it follows the very early stages of AP boot by placing values in CMOS ram.
   43  * it NORMALLY will never be needed and thus the primitive method for enabling.
   44  *
   45 #define CHECK_POINTS
   46  */
   47 
   48 #if defined(CHECK_POINTS)
   49 
   50 #define CMOS_REG        (0x70)
   51 #define CMOS_DATA       (0x71)
   52 
   53 #define CHECKPOINT(A,D)         \
   54         movb    $(A),%al ;      \
   55         outb    %al,$CMOS_REG ; \
   56         movb    $(D),%al ;      \
   57         outb    %al,$CMOS_DATA
   58 
   59 #else
   60 
   61 #define CHECKPOINT(A,D)
   62 
   63 #endif /* CHECK_POINTS */
   64 
   65 
   66 /*
   67  * the APs enter here from their trampoline code (bootMP, below)
   68  */
   69         .p2align 4
   70 
   71 NON_GPROF_ENTRY(MPentry)
   72         CHECKPOINT(0x36, 3)
   73         /*
   74          * Enable features on this processor.  We don't support SMP on
   75          * CPUs older than a Pentium, so we know that we can use the cpuid
   76          * instruction.
   77          */
   78         movl    $1,%eax
   79         cpuid                                   /* Retrieve features */
   80         movl    %cr4,%eax
   81         testl   $CPUID_PSE,%edx
   82         jz 1f
   83         orl     $CR4_PSE,%eax                   /* Enable PSE  */
   84 1:
   85         testl   $CPUID_PGE,%edx
   86         jz 1f
   87         orl     $CR4_PGE,%eax                   /* Enable PGE  */
   88 1:      
   89         testl   $CPUID_VME,%edx
   90         jz 1f
   91         orl     $CR4_VME,%eax                   /* Enable VME  */
   92 1:
   93         movl    %eax,%cr4
   94 
   95         /* Now enable paging mode */
   96 #if defined(PAE) || defined(PAE_TABLES)
   97         movl    IdlePDPT, %eax
   98         movl    %eax, %cr3
   99         movl    %cr4, %eax
  100         orl     $CR4_PAE, %eax
  101         movl    %eax, %cr4
  102         movl    $0x80000000, %eax
  103         cpuid
  104         movl    $0x80000001, %ebx
  105         cmpl    %ebx, %eax
  106         jb      1f
  107         movl    %ebx, %eax
  108         cpuid
  109         testl   $AMDID_NX, %edx
  110         je      1f
  111         movl    $MSR_EFER, %ecx
  112         rdmsr
  113         orl     $EFER_NXE,%eax
  114         wrmsr
  115 1:
  116 #else
  117         movl    IdlePTD, %eax
  118         movl    %eax,%cr3       
  119 #endif
  120         movl    %cr0,%eax
  121         orl     $CR0_PE|CR0_PG,%eax             /* enable paging */
  122         movl    %eax,%cr0                       /* let the games begin! */
  123         movl    bootSTK,%esp                    /* boot stack end loc. */
  124 
  125         pushl   $mp_begin                       /* jump to high mem */
  126         ret
  127 
  128         /*
  129          * Wait for the booting CPU to signal startup
  130          */
  131 mp_begin:       /* now running relocated at KERNBASE */
  132         CHECKPOINT(0x37, 4)
  133         call    init_secondary                  /* load i386 tables */
  134 
  135 /*
  136  * This is the embedded trampoline or bootstrap that is
  137  * copied into 'real-mode' low memory, it is where the
  138  * secondary processor "wakes up". When it is executed
  139  * the processor will eventually jump into the routine
  140  * MPentry, which resides in normal kernel text above
  141  * 1Meg.                -jackv
  142  */
  143 
  144         .data
  145         ALIGN_DATA                              /* just to be sure */
  146 
  147 BOOTMP1:
  148 
  149 NON_GPROF_ENTRY(bootMP)
  150         .code16         
  151         cli
  152         CHECKPOINT(0x34, 1)
  153         /* First guarantee a 'clean slate' */
  154         xorl    %eax, %eax
  155         movl    %eax, %ebx
  156         movl    %eax, %ecx
  157         movl    %eax, %edx
  158         movl    %eax, %esi
  159         movl    %eax, %edi
  160 
  161         /* set up data segments */
  162         mov     %cs, %ax
  163         mov     %ax, %ds
  164         mov     %ax, %es
  165         mov     %ax, %fs
  166         mov     %ax, %gs
  167         mov     %ax, %ss
  168         mov     $(boot_stk-bootMP), %esp
  169 
  170         /* Now load the global descriptor table */
  171         lgdt    MP_GDTptr-bootMP
  172 
  173         /* Enable protected mode */
  174         movl    %cr0, %eax
  175         orl     $CR0_PE, %eax
  176         movl    %eax, %cr0 
  177 
  178         /*
  179          * make intrasegment jump to flush the processor pipeline and
  180          * reload CS register
  181          */
  182         pushl   $0x18
  183         pushl   $(protmode-bootMP)
  184         lretl
  185 
  186        .code32          
  187 protmode:
  188         CHECKPOINT(0x35, 2)
  189 
  190         /*
  191          * we are NOW running for the first time with %eip
  192          * having the full physical address, BUT we still
  193          * are using a segment descriptor with the origin
  194          * not matching the booting kernel.
  195          *
  196          * SO NOW... for the BIG Jump into kernel's segment
  197          * and physical text above 1 Meg.
  198          */
  199         mov     $0x10, %ebx
  200         movw    %bx, %ds
  201         movw    %bx, %es
  202         movw    %bx, %fs
  203         movw    %bx, %gs
  204         movw    %bx, %ss
  205 
  206         .globl  bigJump
  207 bigJump:
  208         /* this will be modified by mpInstallTramp() */
  209         ljmp    $0x08, $0                       /* far jmp to MPentry() */
  210         
  211 dead:   hlt /* We should never get here */
  212         jmp     dead
  213 
  214 /*
  215  * MP boot strap Global Descriptor Table
  216  */
  217         .p2align 4
  218         .globl  MP_GDT
  219         .globl  bootCodeSeg
  220         .globl  bootDataSeg
  221 MP_GDT:
  222 
  223 nulldesc:               /* offset = 0x0 */
  224 
  225         .word   0x0     
  226         .word   0x0     
  227         .byte   0x0     
  228         .byte   0x0     
  229         .byte   0x0     
  230         .byte   0x0     
  231 
  232 kernelcode:             /* offset = 0x08 */
  233 
  234         .word   0xffff  /* segment limit 0..15 */
  235         .word   0x0000  /* segment base 0..15 */
  236         .byte   0x0     /* segment base 16..23; set for 0K */
  237         .byte   0x9f    /* flags; Type  */
  238         .byte   0xcf    /* flags; Limit */
  239         .byte   0x0     /* segment base 24..32 */
  240 
  241 kerneldata:             /* offset = 0x10 */
  242 
  243         .word   0xffff  /* segment limit 0..15 */
  244         .word   0x0000  /* segment base 0..15 */
  245         .byte   0x0     /* segment base 16..23; set for 0k */
  246         .byte   0x93    /* flags; Type  */
  247         .byte   0xcf    /* flags; Limit */
  248         .byte   0x0     /* segment base 24..32 */
  249 
  250 bootcode:               /* offset = 0x18 */
  251 
  252         .word   0xffff  /* segment limit 0..15 */
  253 bootCodeSeg:            /* this will be modified by mpInstallTramp() */
  254         .word   0x0000  /* segment base 0..15 */
  255         .byte   0x00    /* segment base 16...23; set for 0x000xx000 */
  256         .byte   0x9e    /* flags; Type  */
  257         .byte   0xcf    /* flags; Limit */
  258         .byte   0x0     /*segment base 24..32 */
  259 
  260 bootdata:               /* offset = 0x20 */
  261 
  262         .word   0xffff  
  263 bootDataSeg:            /* this will be modified by mpInstallTramp() */
  264         .word   0x0000  /* segment base 0..15 */
  265         .byte   0x00    /* segment base 16...23; set for 0x000xx000 */
  266         .byte   0x92    
  267         .byte   0xcf    
  268         .byte   0x0             
  269 
  270 /*
  271  * GDT pointer for the lgdt call
  272  */
  273         .globl  mp_gdtbase
  274 
  275 MP_GDTptr:      
  276 mp_gdtlimit:
  277         .word   0x0028          
  278 mp_gdtbase:             /* this will be modified by mpInstallTramp() */
  279         .long   0
  280 
  281         .space  0x100   /* space for boot_stk - 1st temporary stack */
  282 boot_stk:
  283 
  284 BOOTMP2:
  285         .globl  bootMP_size
  286 bootMP_size:
  287         .long   BOOTMP2 - BOOTMP1

Cache object: 181ac6ff852c89d16552f6491035701d


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