root/arch/i386/i386/mptramp.s

/* [<][>][^][v][top][bottom][index][help] */
    1 /*      $OpenBSD: mptramp.s,v 1.8 2007/02/20 21:15:01 tom Exp $ */
    2 
    3 /*-
    4  * Copyright (c) 2000 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by RedBack Networks Inc.
    9  *
   10  * Author: Bill Sommerfeld
   11  *
   12  * Redistribution and use in source and binary forms, with or without
   13  * modification, are permitted provided that the following conditions
   14  * are met:
   15  * 1. Redistributions of source code must retain the above copyright
   16  *    notice, this list of conditions and the following disclaimer.
   17  * 2. Redistributions in binary form must reproduce the above copyright
   18  *    notice, this list of conditions and the following disclaimer in the
   19  *    documentation and/or other materials provided with the distribution.
   20  * 3. All advertising materials mentioning features or use of this software
   21  *    must display the following acknowledgement:
   22  *        This product includes software developed by the NetBSD
   23  *        Foundation, Inc. and its contributors.
   24  * 4. Neither the name of The NetBSD Foundation nor the names of its
   25  *    contributors may be used to endorse or promote products derived
   26  *    from this software without specific prior written permission.
   27  *
   28  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   29  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   31  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   32  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   38  * POSSIBILITY OF SUCH DAMAGE.
   39  */
   40 
   41 /*
   42  * Copyright (c) 1999 Stefan Grefen
   43  *
   44  * Redistribution and use in source and binary forms, with or without
   45  * modification, are permitted provided that the following conditions
   46  * are met:
   47  * 1. Redistributions of source code must retain the above copyright
   48  *    notice, this list of conditions and the following disclaimer.
   49  * 2. Redistributions in binary form must reproduce the above copyright
   50  *    notice, this list of conditions and the following disclaimer in the
   51  *    documentation and/or other materials provided with the distribution.
   52  * 3. All advertising materials mentioning features or use of this software
   53  *    must display the following acknowledgement:
   54  *      This product includes software developed by the NetBSD
   55  *      Foundation, Inc. and its contributors.
   56  * 4. Neither the name of The NetBSD Foundation nor the names of its
   57  *    contributors may be used to endorse or promote products derived
   58  *    from this software without specific prior written permission.
   59  *
   60  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
   61  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   62  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   63  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR AND CONTRIBUTORS BE LIABLE
   64  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   65  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   66  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   67  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   68  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   69  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   70  * SUCH DAMAGE.
   71  */
   72 /*
   73  * MP startup ...
   74  * the stuff from cpu_spinup_trampoline to mp_startup
   75  * is copied into the first 640 KB
   76  *
   77  * We startup the processors now when the kthreads become ready.
   78  * The steps are:
   79  *      1) Get the processors running kernel-code from a special
   80  *         page-table and stack page, do chip identification.
   81  *      2) halt the processors waiting for them to be enabled
   82  *         by a idle-thread
   83  */
   84 
   85 #include "assym.h"
   86 #include <machine/param.h>
   87 #include <machine/asm.h>
   88 #include <machine/specialreg.h>
   89 #include <machine/segments.h>
   90 #include <machine/gdt.h>
   91 #include <machine/mpbiosvar.h>
   92 #include <machine/i82489reg.h>
   93 
   94 #define GDTE(a,b)       .byte   0xff,0xff,0x0,0x0,0x0,a,b,0x0
   95 #define _RELOC(x)       ((x) - KERNBASE)
   96 #define RELOC(x)        _RELOC(_C_LABEL(x))
   97 
   98 #define _TRMP_LABEL(a)  a = . - _C_LABEL(cpu_spinup_trampoline) + MP_TRAMPOLINE
   99 
  100 /*
  101  * Debug code to stop aux. processors in various stages based on the
  102  * value in cpu_trace.
  103  *
  104  * %edi points at cpu_trace;  cpu_trace[0] is the "hold point";
  105  * cpu_trace[1] is the point which the cpu has reached.
  106  * cpu_trace[2] is the last value stored by HALTT.
  107  */
  108 
  109 
  110 #ifdef MPDEBUG
  111 #define HALT(x) 1: movl (%edi),%ebx;cmpl $ x,%ebx ; jle 1b ; movl $x,4(%edi)
  112 #define HALTT(x,y)      movl y,8(%edi); HALT(x)
  113 #else
  114 #define HALT(x) /**/
  115 #define HALTT(x,y) /**/
  116 #endif
  117 
  118         .globl  _C_LABEL(cpu),_C_LABEL(cpu_id),_C_LABEL(cpu_vendor)
  119         .globl  _C_LABEL(cpuid_level),_C_LABEL(cpu_feature)
  120 
  121         .global _C_LABEL(cpu_spinup_trampoline)
  122         .global _C_LABEL(cpu_spinup_trampoline_end)
  123         .global _C_LABEL(cpu_hatch)
  124         .global _C_LABEL(mp_pdirpa)
  125         .global _C_LABEL(gdt), _C_LABEL(local_apic)
  126 
  127         .text
  128         .align 4,0x0
  129         .code16
  130 _C_LABEL(cpu_spinup_trampoline):
  131         cli
  132         xorw    %ax, %ax
  133         movw    %ax, %ds
  134         movw    %ax, %es
  135         movw    %ax, %ss
  136         data32 addr32 lgdt      (gdt_desc)      # load flat descriptor table
  137         movl    %cr0, %eax      # get cr0
  138         orl     $0x1, %eax      # enable protected mode
  139         movl    %eax, %cr0      # doit
  140         ljmp    $0x8, $mp_startup
  141 
  142 _TRMP_LABEL(mp_startup)
  143         .code32
  144 
  145         movl    $0x10, %eax     # data segment
  146         movw    %ax, %ds
  147         movw    %ax, %ss
  148         movw    %ax, %es
  149         movw    %ax, %fs
  150         movw    %ax, %gs
  151         movl    $(MP_TRAMPOLINE+NBPG-16),%esp   # bootstrap stack end,
  152                                                 # with scratch space..
  153 
  154 #ifdef MPDEBUG
  155         leal    RELOC(cpu_trace),%edi
  156 #endif
  157 
  158         HALT(0x1)
  159         /* First, reset the PSL. */
  160         pushl   $PSL_MBO
  161         popfl
  162 
  163         movl    RELOC(mp_pdirpa),%ecx
  164         HALTT(0x5,%ecx)
  165 
  166         /* Load base of page directory and enable mapping. */
  167         movl    %ecx,%cr3               # load ptd addr into mmu
  168         movl    %cr0,%eax               # get control word
  169                                         # enable paging & NPX emulation
  170         orl     $(CR0_PE|CR0_PG|CR0_NE|CR0_TS|CR0_EM|CR0_MP|CR0_WP),%eax
  171         movl    %eax,%cr0               # and let's page NOW!
  172 
  173 #ifdef MPDEBUG
  174         leal    _C_LABEL(cpu_trace),%edi
  175 #endif
  176         HALT(0x6)
  177 
  178 # ok, we're now running with paging enabled and sharing page tables with cpu0.
  179 # figure out which processor we really are, what stack we should be on, etc.
  180 
  181         movl    _C_LABEL(local_apic)+LAPIC_ID,%ecx
  182         shrl    $LAPIC_ID_SHIFT,%ecx
  183         leal    0(,%ecx,4),%ecx
  184         movl    _C_LABEL(cpu_info)(%ecx),%ecx
  185 
  186         HALTT(0x7, %ecx)
  187 
  188 # %ecx points at our cpu_info structure..
  189 
  190         movw    $((MAXGDTSIZ*8) - 1), 6(%esp)   # prepare segment descriptor
  191         movl    CPU_INFO_GDT(%ecx), %eax        # for real gdt
  192         movl    %eax, 8(%esp)
  193         HALTT(0x8, %eax)
  194         lgdt    6(%esp)
  195         HALT(0x9)
  196         jmp     1f
  197         nop
  198 1:
  199         HALT(0xa)
  200         movl    $GSEL(GDATA_SEL, SEL_KPL),%eax  #switch to new segment
  201         HALTT(0x10, %eax)
  202         movw    %ax,%ds
  203         HALT(0x11)
  204         movw    %ax,%es
  205         HALT(0x12)
  206         movw    %ax,%ss
  207         HALT(0x13)
  208         pushl   $GSEL(GCODE_SEL, SEL_KPL)
  209         pushl   $mp_cont
  210         HALT(0x14)
  211         lret
  212         .align 4,0x0
  213 _TRMP_LABEL(gdt_table)
  214         .word   0x0,0x0,0x0,0x0                 # null GDTE
  215          GDTE(0x9f,0xcf)                        # Kernel text
  216          GDTE(0x93,0xcf)                        # Kernel data
  217 _TRMP_LABEL(gdt_desc)
  218         .word   0x17                            # limit 3 entries
  219         .long   gdt_table                       # where is gdt
  220 
  221 _C_LABEL(cpu_spinup_trampoline_end):    #end of code copied to MP_TRAMPOLINE
  222 mp_cont:
  223 
  224         movl    CPU_INFO_IDLE_PCB(%ecx),%esi
  225 
  226 # %esi now points at our PCB.
  227 
  228         HALTT(0x19, %esi)
  229 
  230         movl    PCB_ESP(%esi),%esp
  231         movl    PCB_EBP(%esi),%ebp
  232 
  233         HALT(0x20)
  234         /* Switch address space. */
  235         movl    PCB_CR3(%esi),%eax
  236         HALTT(0x22, %eax)
  237         movl    %eax,%cr3
  238         HALT(0x25)
  239         /* Load segment registers. */
  240         movl    $GSEL(GCPU_SEL, SEL_KPL),%eax
  241         HALTT(0x26,%eax)
  242         movl    %eax,%fs
  243         xorl    %eax,%eax
  244         HALTT(0x27,%eax)
  245         movl    %eax,%gs
  246         movl    PCB_CR0(%esi),%eax
  247         HALTT(0x28,%eax)
  248         movl    %eax,%cr0
  249         HALTT(0x30,%ecx)
  250         pushl   %ecx
  251         call    _C_LABEL(cpu_hatch)
  252         HALT(0x33)
  253         xorl    %esi,%esi
  254         jmp     _C_LABEL(idle_start)
  255 
  256         .data
  257 _C_LABEL(mp_pdirpa):
  258         .long   0
  259 #ifdef MPDEBUG
  260         .global _C_LABEL(cpu_trace)
  261 _C_LABEL(cpu_trace):
  262         .long   0x40
  263         .long   0xff
  264         .long   0xff
  265 #endif

/* [<][>][^][v][top][bottom][index][help] */