/*
 * setup.S
 *
 * Copyright 2002, Minoru Murashima. All rights reserved.
 * Distributed under the terms of the BSD License.
 *
 * アセンブラメインセットアププログラム
 *
 * このプログラムはbootload.sによりconfig.hで定義されるSTART_ADDRESSにロードされるので、
 * Makefileの-Ttext引数にもSTART_ADDRESS値を設定しなければならない。
 *
 * bootload.sにより
 * 	ebp=MPFloatingPointerStructureアドレス
 * が代入さる。
 *
 * 8cpuに対応させる
 */


#define ASM_FILE


#include"config.h"
#include"segment.h"


#define BOOT_KERNEL_STACK START_ADDRESS		/* BOOT時のカーネルスタックポインタ */
/*
 * BOOT時のカーネルスタックサイズ
 * BIOS DATA AREA を壊さない大きさにする
 */
#define BOOT_KERNEL_STACK_SIZE 0x100


.text

.globl _start
_start:
.code16
/* タイムサービス用に西暦をBIOSから読み出す。 */
	movb	$0x4,%ah
	int		$0x1a
	movb	%cl,year_low		/* 西暦100年未満 */
	movb	%ch,year_high		/* 西暦100年以上 */

/* Application cpuならBIOS初期化コードにjump */
.globl mpstart
mpstart:
	movl	$activ_cpu,%eax
	shrl	$4,%eax
	andw	$0xf000,%ax
	movw	%ax,%ds
	movl	$activ_cpu,%ebx
	movw	(%bx),%ax
	orw		%ax,%ax
	jz		switch_protect_mode
	ljmp	$0xffff,$0

/* プロテクトモード移行16ビットコード */
.globl switch_protect_mode
switch_protect_mode:
	movl	$gdtr,%eax
	shrl	$4,%eax
	andw	$0xf000,%ax
	movw	%ax,%ds
	cli
	lgdt	gdtr
	xorl	%eax,%eax
	orw		$1,%ax
	movl	%eax,%cr0
	wbinvd					/* シリアル化+キャッシュメモリーバック命令 */
	ljmp	$KERNEL_CODE_DES,$start_protect_mode

/* プロテクトモード開始 */
.code32
start_protect_mode:
	movl	$0x10,%eax
	movl	%eax,%ds
	movl	%eax,%ss
	movl	%eax,%es		/* movs命令に対応するためesをセット */
	cld

1:	lock					/* スピンロック入るに */
	btsl	$1,stack_lock
	jc		1b

	movl	kernel_stack,%esp
	subl	$BOOT_KERNEL_STACK_SIZE,kernel_stack

	movl	$0,stack_lock	/* スピンロックから出る */

	xorl	%eax,%eax
	movl	%eax,%fs
	movl	%eax,%gs

/*  IDTをロードするを */
	lidt	idtr

/* Application cpuなら初期化用コードにジャンプ */
	cmpl	$0,activ_cpu
	jz		1f
	jmp		init_application_cpu
1:
/************************************************************************************************************/
	/* テスト用、有効にするとマルチプロセッサでもシングルプロセッサモードになる */
/*	xorl	%ebp,%ebp*/
/************************************************************************************************************/
	movl	%ebp,MFPS_addres	/* MP Floating Pointer Structureアドレスを代入 */

	call	main				/* main setup in C language */

	movl	$KERNEL_ESP_BEG,%esp
	call	init				/* Start init */


.data

.align 4
kernel_stack:
	.4byte	BOOT_KERNEL_STACK

stack_lock:
	.4byte	0
