Newer
Older
UbixOS / sys / i386 / ap-boot.S
/*
 * Okay, this file contains the code that's going to bootstrap the AP cpus
 */


	.globl	ap_trampoline_start,ap_trampoline_end
	.text
	.code16
ap_trampoline_start:
	cli
	cld

	movw	%cs,%ax		// The CPU knows its CS already, so lets use it for the other segments
	movw	%ax,%ds
	movw	%ax,%es
	movw	%ax,%ss

	// Do some bochs-specific bullshit
	mov	$0x31,%al // '1'
	mov	$0xe9,%dx
	outb	%al,%dx
        //lgdt    ap_gdt;	
	lgdt	ap_trampoline_gdt_limit - ap_trampoline_start
	movl	%cr0,%eax
	orl	$0x1,%eax
	movl	%eax,%cr0	// PMODE!

.code32
	.byte 0x66
	ljmp	$0x08,$(ap_trampoline_32 - ap_trampoline_start)		// 0x08 == KERNEL_CS

ap_trampoline_32:
	mov	$0x32,%al // '2'
	mov	$0xe9,%dx
	outb	%al,%dx

	mov	$0x10,%ax
	mov	%ax,%ds
	mov	%ax,%es
	mov	%ax,%fs
	mov	%ax,%gs
	mov	%ax,%ss

	// Spinlock
	mov	ap_trampoline_spl - ap_trampoline_start,%edi
ap_spl:
	//cmp	$1,(%edi)
	//je	ap_spl

	mov	$1,%eax	     // Value to be set
	xchgl	(%edi),%eax
	cmp	$0,%eax
	je	ap_spl
	// /Spinlock

	mov	$0x30,%al // '0'
	mov	$0xe9,%dx
	outb	%al,%dx
		
	mov	ap_trampoline_stackptr - ap_trampoline_start,%ebx
	mov	%ebx,%esp
	add	$0x1000,%ebx
	mov	%ebx,ap_trampoline_stackptr - ap_trampoline_start

	mov	$0x31,%al // '1'
	mov	$0xe9,%dx
	outb	%al,%dx

	// spinunlock
	mov	$0,%eax
	mov	ap_trampoline_spl - ap_trampoline_start,%edi
	xchgl	(%edi),%eax
	// /spinunlock

	mov	$0x33,%al // '3'
	mov	$0xe9,%dx
	outb	%al,%dx

	mov	ap_trampoline_epoint,%eax
	call	*%eax
1:
	hlt
	jmp	1b		// Halt if we ever get here somehow

	// Stack.. This sucks, since CPU initialization isn't serialized
ap_trampoline_stackptr:
	.long	0x10000		// 256KB
ap_trampoline_epoint:
	.long	c_ap_boot

ap_trampoline_spl:
	.long	0
ap_gdt:
	.long ubixGDT
	
	// GDT
ap_trampoline_gdt:
	.word	0
ap_trampoline_gdt_limit:
	.word	128	// Room for 32 descriptors
ap_trampoline_gdt_base:
	.long	0x20000		// 128KB (move this later)


ap_trampoline_end: