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: releng/12.0/sys/i386/i386/mpboot.s 332489 2018-04-13 20:30:49Z kib $
   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 #else
  103         movl    IdlePTD, %eax
  104         movl    %eax,%cr3       
  105 #endif
  106         movl    %cr0,%eax
  107         orl     $CR0_PE|CR0_PG,%eax             /* enable paging */
  108         movl    %eax,%cr0                       /* let the games begin! */
  109         movl    bootSTK,%esp                    /* boot stack end loc. */
  110 
  111         pushl   $mp_begin                       /* jump to high mem */
  112         ret
  113 
  114         /*
  115          * Wait for the booting CPU to signal startup
  116          */
  117 mp_begin:       /* now running relocated at KERNBASE */
  118         CHECKPOINT(0x37, 4)
  119         call    init_secondary                  /* load i386 tables */
  120 
  121 /*
  122  * This is the embedded trampoline or bootstrap that is
  123  * copied into 'real-mode' low memory, it is where the
  124  * secondary processor "wakes up". When it is executed
  125  * the processor will eventually jump into the routine
  126  * MPentry, which resides in normal kernel text above
  127  * 1Meg.                -jackv
  128  */
  129 
  130         .data
  131         ALIGN_DATA                              /* just to be sure */
  132 
  133 BOOTMP1:
  134 
  135 NON_GPROF_ENTRY(bootMP)
  136         .code16         
  137         cli
  138         CHECKPOINT(0x34, 1)
  139         /* First guarantee a 'clean slate' */
  140         xorl    %eax, %eax
  141         movl    %eax, %ebx
  142         movl    %eax, %ecx
  143         movl    %eax, %edx
  144         movl    %eax, %esi
  145         movl    %eax, %edi
  146 
  147         /* set up data segments */
  148         mov     %cs, %ax
  149         mov     %ax, %ds
  150         mov     %ax, %es
  151         mov     %ax, %fs
  152         mov     %ax, %gs
  153         mov     %ax, %ss
  154         mov     $(boot_stk-bootMP), %esp
  155 
  156         /* Now load the global descriptor table */
  157         lgdt    MP_GDTptr-bootMP
  158 
  159         /* Enable protected mode */
  160         movl    %cr0, %eax
  161         orl     $CR0_PE, %eax
  162         movl    %eax, %cr0 
  163 
  164         /*
  165          * make intrasegment jump to flush the processor pipeline and
  166          * reload CS register
  167          */
  168         pushl   $0x18
  169         pushl   $(protmode-bootMP)
  170         lretl
  171 
  172        .code32          
  173 protmode:
  174         CHECKPOINT(0x35, 2)
  175 
  176         /*
  177          * we are NOW running for the first time with %eip
  178          * having the full physical address, BUT we still
  179          * are using a segment descriptor with the origin
  180          * not matching the booting kernel.
  181          *
  182          * SO NOW... for the BIG Jump into kernel's segment
  183          * and physical text above 1 Meg.
  184          */
  185         mov     $0x10, %ebx
  186         movw    %bx, %ds
  187         movw    %bx, %es
  188         movw    %bx, %fs
  189         movw    %bx, %gs
  190         movw    %bx, %ss
  191 
  192         .globl  bigJump
  193 bigJump:
  194         /* this will be modified by mpInstallTramp() */
  195         ljmp    $0x08, $0                       /* far jmp to MPentry() */
  196         
  197 dead:   hlt /* We should never get here */
  198         jmp     dead
  199 
  200 /*
  201  * MP boot strap Global Descriptor Table
  202  */
  203         .p2align 4
  204         .globl  MP_GDT
  205         .globl  bootCodeSeg
  206         .globl  bootDataSeg
  207 MP_GDT:
  208 
  209 nulldesc:               /* offset = 0x0 */
  210 
  211         .word   0x0     
  212         .word   0x0     
  213         .byte   0x0     
  214         .byte   0x0     
  215         .byte   0x0     
  216         .byte   0x0     
  217 
  218 kernelcode:             /* offset = 0x08 */
  219 
  220         .word   0xffff  /* segment limit 0..15 */
  221         .word   0x0000  /* segment base 0..15 */
  222         .byte   0x0     /* segment base 16..23; set for 0K */
  223         .byte   0x9f    /* flags; Type  */
  224         .byte   0xcf    /* flags; Limit */
  225         .byte   0x0     /* segment base 24..32 */
  226 
  227 kerneldata:             /* offset = 0x10 */
  228 
  229         .word   0xffff  /* segment limit 0..15 */
  230         .word   0x0000  /* segment base 0..15 */
  231         .byte   0x0     /* segment base 16..23; set for 0k */
  232         .byte   0x93    /* flags; Type  */
  233         .byte   0xcf    /* flags; Limit */
  234         .byte   0x0     /* segment base 24..32 */
  235 
  236 bootcode:               /* offset = 0x18 */
  237 
  238         .word   0xffff  /* segment limit 0..15 */
  239 bootCodeSeg:            /* this will be modified by mpInstallTramp() */
  240         .word   0x0000  /* segment base 0..15 */
  241         .byte   0x00    /* segment base 16...23; set for 0x000xx000 */
  242         .byte   0x9e    /* flags; Type  */
  243         .byte   0xcf    /* flags; Limit */
  244         .byte   0x0     /*segment base 24..32 */
  245 
  246 bootdata:               /* offset = 0x20 */
  247 
  248         .word   0xffff  
  249 bootDataSeg:            /* this will be modified by mpInstallTramp() */
  250         .word   0x0000  /* segment base 0..15 */
  251         .byte   0x00    /* segment base 16...23; set for 0x000xx000 */
  252         .byte   0x92    
  253         .byte   0xcf    
  254         .byte   0x0             
  255 
  256 /*
  257  * GDT pointer for the lgdt call
  258  */
  259         .globl  mp_gdtbase
  260 
  261 MP_GDTptr:      
  262 mp_gdtlimit:
  263         .word   0x0028          
  264 mp_gdtbase:             /* this will be modified by mpInstallTramp() */
  265         .long   0
  266 
  267         .space  0x100   /* space for boot_stk - 1st temporary stack */
  268 boot_stk:
  269 
  270 BOOTMP2:
  271         .globl  bootMP_size
  272 bootMP_size:
  273         .long   BOOTMP2 - BOOTMP1

Cache object: 09d90355588e5d1f0b3b183925c40d0a


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