root/entryother.S

/* [previous][next][first][last][top][bottom][index][help]  */
   1 #include "asm.h"
   2 #include "memlayout.h"
   3 #include "mmu.h"
   4         
   5 # Each non-boot CPU ("AP") is started up in response to a STARTUP
   6 # IPI from the boot CPU.  Section B.4.2 of the Multi-Processor
   7 # Specification says that the AP will start in real mode with CS:IP
   8 # set to XY00:0000, where XY is an 8-bit value sent with the
   9 # STARTUP. Thus this code must start at a 4096-byte boundary.
  10 #
  11 # Because this code sets DS to zero, it must sit
  12 # at an address in the low 2^16 bytes.
  13 #
  14 # Startothers (in main.c) sends the STARTUPs one at a time.
  15 # It copies this code (start) at 0x7000.  It puts the address of
  16 # a newly allocated per-core stack in start-4,the address of the
  17 # place to jump to (mpenter) in start-8, and the physical address
  18 # of entrypgdir in start-12.
  19 #
  20 # This code combines elements of bootasm.S and entry.S.
  21 
  22 .code16           
  23 .globl start
  24 start:
  25   cli            
  26 
  27   # Zero data segment registers DS, ES, and SS.
  28   xorw    %ax,%ax
  29   movw    %ax,%ds
  30   movw    %ax,%es
  31   movw    %ax,%ss
  32 
  33   # Switch from real to protected mode.  Use a bootstrap GDT that makes
  34   # virtual addresses map directly to physical addresses so that the
  35   # effective memory map doesn't change during the transition.
  36   lgdt    gdtdesc
  37   movl    %cr0, %eax
  38   orl     $CR0_PE, %eax
  39   movl    %eax, %cr0
  40 
  41   # Complete the transition to 32-bit protected mode by using a long jmp
  42   # to reload %cs and %eip.  The segment descriptors are set up with no
  43   # translation, so that the mapping is still the identity mapping.
  44   ljmpl    $(SEG_KCODE<<3), $(start32)
  45 
  46 //PAGEBREAK!
  47 .code32  # Tell assembler to generate 32-bit code now.
  48 start32:
  49   # Set up the protected-mode data segment registers
  50   movw    $(SEG_KDATA<<3), %ax    # Our data segment selector
  51   movw    %ax, %ds                # -> DS: Data Segment
  52   movw    %ax, %es                # -> ES: Extra Segment
  53   movw    %ax, %ss                # -> SS: Stack Segment
  54   movw    $0, %ax                 # Zero segments not ready for use
  55   movw    %ax, %fs                # -> FS
  56   movw    %ax, %gs                # -> GS
  57 
  58   # Turn on page size extension for 4Mbyte pages
  59   movl    %cr4, %eax
  60   orl     $(CR4_PSE), %eax
  61   movl    %eax, %cr4
  62   # Use entrypgdir as our initial page table
  63   movl    (start-12), %eax
  64   movl    %eax, %cr3
  65   # Turn on paging.
  66   movl    %cr0, %eax
  67   orl     $(CR0_PE|CR0_PG|CR0_WP), %eax
  68   movl    %eax, %cr0
  69 
  70   # Switch to the stack allocated by startothers()
  71   movl    (start-4), %esp
  72   # Call mpenter()
  73   call   *(start-8)
  74 
  75   movw    $0x8a00, %ax
  76   movw    %ax, %dx
  77   outw    %ax, %dx
  78   movw    $0x8ae0, %ax
  79   outw    %ax, %dx
  80 spin:
  81   jmp     spin
  82 
  83 .p2align 2
  84 gdt:
  85   SEG_NULLASM
  86   SEG_ASM(STA_X|STA_R, 0, 0xffffffff)
  87   SEG_ASM(STA_W, 0, 0xffffffff)
  88 
  89 
  90 gdtdesc:
  91   .word   (gdtdesc - gdt - 1)
  92   .long   gdt
  93 

/* [previous][next][first][last][top][bottom][index][help]  */