1c60a3551SFrans Kaashoek#include "asm.h" 2c60a3551SFrans Kaashoek#include "memlayout.h" 3c60a3551SFrans Kaashoek#include "mmu.h" 4c60a3551SFrans Kaashoek 5c60a3551SFrans Kaashoek# Each non-boot CPU ("AP") is started up in response to a STARTUP 6c60a3551SFrans Kaashoek# IPI from the boot CPU. Section B.4.2 of the Multi-Processor 7c60a3551SFrans Kaashoek# Specification says that the AP will start in real mode with CS:IP 8c60a3551SFrans Kaashoek# set to XY00:0000, where XY is an 8-bit value sent with the 9c60a3551SFrans Kaashoek# STARTUP. Thus this code must start at a 4096-byte boundary. 10c60a3551SFrans Kaashoek# 11c60a3551SFrans Kaashoek# Because this code sets DS to zero, it must sit 12c60a3551SFrans Kaashoek# at an address in the low 2^16 bytes. 13c60a3551SFrans Kaashoek# 14310edc99SAustin Clements# Startothers (in main.c) sends the STARTUPs one at a time. 15e25b74caSFrans Kaashoek# It copies this code (start) at 0x7000. It puts the address of 16e25b74caSFrans Kaashoek# a newly allocated per-core stack in start-4,the address of the 17e25b74caSFrans Kaashoek# place to jump to (mpenter) in start-8, and the physical address 18310edc99SAustin Clements# of entrypgdir in start-12. 19c60a3551SFrans Kaashoek# 203431cd49SRobert Morris# This code combines elements of bootasm.S and entry.S. 21c60a3551SFrans Kaashoek 22c60a3551SFrans Kaashoek.code16 23c60a3551SFrans Kaashoek.globl start 24c60a3551SFrans Kaashoekstart: 25c60a3551SFrans Kaashoek cli 26c60a3551SFrans Kaashoek 273431cd49SRobert Morris # Zero data segment registers DS, ES, and SS. 28c60a3551SFrans Kaashoek xorw %ax,%ax 29c60a3551SFrans Kaashoek movw %ax,%ds 30c60a3551SFrans Kaashoek movw %ax,%es 31c60a3551SFrans Kaashoek movw %ax,%ss 32c60a3551SFrans Kaashoek 333431cd49SRobert Morris # Switch from real to protected mode. Use a bootstrap GDT that makes 343431cd49SRobert Morris # virtual addresses map directly to physical addresses so that the 353431cd49SRobert Morris # effective memory map doesn't change during the transition. 36c60a3551SFrans Kaashoek lgdt gdtdesc 37c60a3551SFrans Kaashoek movl %cr0, %eax 38c60a3551SFrans Kaashoek orl $CR0_PE, %eax 39c60a3551SFrans Kaashoek movl %eax, %cr0 40c60a3551SFrans Kaashoek 413431cd49SRobert Morris # Complete the transition to 32-bit protected mode by using a long jmp 423431cd49SRobert Morris # to reload %cs and %eip. The segment descriptors are set up with no 433431cd49SRobert Morris # translation, so that the mapping is still the identity mapping. 44c60a3551SFrans Kaashoek ljmpl $(SEG_KCODE<<3), $(start32) 45c60a3551SFrans Kaashoek 46*24118827SRobert Morris//PAGEBREAK! 473431cd49SRobert Morris.code32 # Tell assembler to generate 32-bit code now. 48c60a3551SFrans Kaashoekstart32: 493431cd49SRobert Morris # Set up the protected-mode data segment registers 503431cd49SRobert Morris movw $(SEG_KDATA<<3), %ax # Our data segment selector 513431cd49SRobert Morris movw %ax, %ds # -> DS: Data Segment 523431cd49SRobert Morris movw %ax, %es # -> ES: Extra Segment 533431cd49SRobert Morris movw %ax, %ss # -> SS: Stack Segment 543431cd49SRobert Morris movw $0, %ax # Zero segments not ready for use 553431cd49SRobert Morris movw %ax, %fs # -> FS 563431cd49SRobert Morris movw %ax, %gs # -> GS 57c60a3551SFrans Kaashoek 5894496468SFrans Kaashoek # Turn on page size extension for 4Mbyte pages 5994496468SFrans Kaashoek movl %cr4, %eax 6094496468SFrans Kaashoek orl $(CR4_PSE), %eax 6194496468SFrans Kaashoek movl %eax, %cr4 620a69dc9bSRobert Morris # Use entrypgdir as our initial page table 63c60a3551SFrans Kaashoek movl (start-12), %eax 64c60a3551SFrans Kaashoek movl %eax, %cr3 65c60a3551SFrans Kaashoek # Turn on paging. 66c60a3551SFrans Kaashoek movl %cr0, %eax 67c60a3551SFrans Kaashoek orl $(CR0_PE|CR0_PG|CR0_WP), %eax 68c60a3551SFrans Kaashoek movl %eax, %cr0 69c60a3551SFrans Kaashoek 70a4b213cfSFrans Kaashoek # Switch to the stack allocated by startothers() 71c60a3551SFrans Kaashoek movl (start-4), %esp 72a4b213cfSFrans Kaashoek # Call mpenter() 73c60a3551SFrans Kaashoek call *(start-8) 74c60a3551SFrans Kaashoek 75c60a3551SFrans Kaashoek movw $0x8a00, %ax 76c60a3551SFrans Kaashoek movw %ax, %dx 77c60a3551SFrans Kaashoek outw %ax, %dx 78c60a3551SFrans Kaashoek movw $0x8ae0, %ax 79c60a3551SFrans Kaashoek outw %ax, %dx 80c60a3551SFrans Kaashoekspin: 81c60a3551SFrans Kaashoek jmp spin 82c60a3551SFrans Kaashoek 83c60a3551SFrans Kaashoek.p2align 2 84c60a3551SFrans Kaashoekgdt: 85c60a3551SFrans Kaashoek SEG_NULLASM 86c60a3551SFrans Kaashoek SEG_ASM(STA_X|STA_R, 0, 0xffffffff) 87c60a3551SFrans Kaashoek SEG_ASM(STA_W, 0, 0xffffffff) 88c60a3551SFrans Kaashoek 89c60a3551SFrans Kaashoek 90c60a3551SFrans Kaashoekgdtdesc: 91c60a3551SFrans Kaashoek .word (gdtdesc - gdt - 1) 92c60a3551SFrans Kaashoek .long gdt 93c60a3551SFrans Kaashoek 94