マイペースなプログラミング日記

DTMやプログラミングにお熱なd-kamiがマイペースに書くブログ

特権レベル0のタスク…

相変わらず特権レベル0のタスクが動かない。bocksだと動くのに、qemuでは無理。どうしたものか

タイマ割り込み時に呼び出されるアセンブラのソース

%macro pushAll 0
        PUSHAD
        PUSH DS
        PUSH ES
%endmacro

%macro popAll 0
        POP ES
        POP DS
        POPAD
%endmacro

asmTimerHandler:
_asmTimerHandler:
	pushAll

	CALL	timerHandler

	popAll
	IRETD

タイマ割り込み時にアセンブラから呼び出されるC++のソース

void timerHandler(){
	int* stack;

	asm volatile("mov %%ebp, %0 \n" : "=g"(stack));

	g_TimerManager->tick();

	taskData[currentTask].eax    = stack[11];
	taskData[currentTask].ecx    = stack[10];
	taskData[currentTask].edx    = stack[9];
	taskData[currentTask].ebx    = stack[8];
	taskData[currentTask].esp2   = stack[7];
	taskData[currentTask].ebp    = stack[6];
	taskData[currentTask].esi    = stack[5];
	taskData[currentTask].edi    = stack[4];
	taskData[currentTask].ds     = stack[3];
	taskData[currentTask].es     = stack[2];

	taskData[currentTask].cs     = stack[13];
	taskData[currentTask].eflags = stack[14];

        //特権レベルが0より大きいときはstackの15番目からESPを取り出し保存する
	if((taskData[currentTask].cs & 3) > 0)
		taskData[currentTask].esp = stack[15];

        //こうするとbochsではうまく動く
        //stack[7]はasmTimerHandlerでpushされたESP
        //g_TSSは現行のTSS
	g_TSS->esp0 = stack[7];

	taskData[currentTask].eip = stack[12];
	currentTask = (currentTask + 1) % taskCount;

	stack[12] = taskData[currentTask].eip;

	stack[11] = taskData[currentTask].eax;
	stack[10] = taskData[currentTask].ecx;
	stack[9] = taskData[currentTask].edx;
	stack[8] = taskData[currentTask].ebx;
	stack[7] = taskData[currentTask].esp2;
	stack[6] = taskData[currentTask].ebp;
	stack[5] = taskData[currentTask].esi;
	stack[4] = taskData[currentTask].edi;
	stack[3] = taskData[currentTask].ds;
	stack[2] = taskData[currentTask].es;

	stack[13] = taskData[currentTask].cs;
	stack[14] = taskData[currentTask].eflags;

	if((taskData[currentTask].cs & 3) > 0){
                //特権レベルが0より大きいときはESPとSSをスタックに入れる
		stack[15] = taskData[currentTask].esp;
		stack[16] = taskData[currentTask].ss;
	}

	IO::writePort8(PIC0_OCW2, 0x60);

	return;
}