📄 kerncontext.cxx
字号:
/* * Copyright (C) 1998, 1999, Jonathan S. Shapiro. * * This file is part of the EROS Operating System. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2, * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include <eros/target.h>#include <kerninc/kernel.hxx>#include <kerninc/Process.hxx>#include <kerninc/Thread.hxx>#include <kerninc/IRQ.hxx>#include "Segment.hxx"#include "lostart.hxx"#if 1/* We need to allow I/O for at least the main() thread so that it can * perform driver initialization */#define KERN_EFLAGS 0x1200; /* allow IO for kernel threads */#else#define KERN_EFLAGS 0x0200; /* disallow IO for kernel threads */#endif/* Initialize a 386 kernel thread: */#if 0KernProcess::KernProcess(const char *myName, Thread& theThread) : Process(){ isUserContext = false; isPinned = true; for (int i = 0; i < 8; i++) name[i] = myName[i]; name[7] = 0; curThread = &theThread; runState = RS_Running; bzero(&fixRegs, sizeof(fixRegs)); hazards = 0; fixRegs.MappingTable = KERNPAGEDIR; /* kern procs run in kernel space */ fixRegs.EFLAGS = KERN_EFLAGS; fixRegs.CS = Selector::KProcCode; fixRegs.DS = Selector::KProcData; fixRegs.ES = Selector::KProcData; fixRegs.FS = Selector::KProcData; fixRegs.GS = Selector::KProcData; fixRegs.SS = Selector::KProcData; fixRegs.EIP = 0; fixRegs.ESP = (uint32_t) stackPtr; saveArea = &fixRegs;#if 0 stackTop = 0; stackBottom = 0;#endif}#endifKernProcess::KernProcess(#ifndef NDEBUG const char *myName,#else const char * /* myName */,#endif Thread& theThread, void (*pc)(), uint32_t * stkBottom, uint32_t * stkTop) : Process(){ /* If you are confused about what's going on here, remember that * the class members grow upwards while the stack grows downwards. * We are constructing a save area by hand. Have a look at the * comments in switch.S to see what that must look like. */#ifdef DBG_WILD_PTR stackTop = stkTop; stackBottom = stkBottom;#endif isUserContext = false; #ifndef NDEBUG for (int i = 0; i < 8; i++) name[i] = myName[i]; name[7] = 0;#endif curThread = &theThread; runState = RS_Running; bzero(&fixRegs, sizeof(fixRegs)); hazards = 0; /* Initialize the per-thread save area so that we can schedule this * thread. When the thread is initiated by resume_process() for the * first time, it will execute the first instruction of it's Start * routine. */ fixRegs.MappingTable = KERNPAGEDIR; /* kern procs run in kernel space */ fixRegs.EFLAGS = KERN_EFLAGS; fixRegs.CS = Selector::KProcCode; fixRegs.DS = Selector::KProcData; fixRegs.ES = Selector::KProcData; fixRegs.FS = Selector::KProcData; fixRegs.GS = Selector::KProcData; fixRegs.SS = Selector::KProcData; fixRegs.EIP = (uint32_t) pc; /* YES the first of these is dead code. It suppresses the unused * argument warning if DBG_WILD_PTR is not enabled. */ fixRegs.ESP = (uint32_t) stkBottom; fixRegs.ESP = (uint32_t) stkTop; saveArea = &fixRegs;}voidKernProcess::InitStack(){ uint32_t *stackPtr = (uint32_t *) fixRegs.ESP; /* Top word on stack */ /* Set up hidden 'this' argument to Thread::Start() routine: */ *(--stackPtr) = (uint32_t) curThread; /* pointer to thread object */ *(--stackPtr) = (uint32_t) 0; /* in case thread returns */ fixRegs.ESP = (uint32_t) stackPtr;}#if 0voidKernContext::DoPrepare(){ fatal("Kernel contexts should never be deprepared\n");}#endifextern "C" { void resume_from_kernel_interrupt(fixregs_t *) NORETURN;};#if 0/* DANGER, WILL ROBINSON!!! Interrupts are disabled when this routine * is called, but the current priority level is such that they ought * to be enabled (and will be when the user thread returns). The * machine also believes itself to be at trapDepth 0, even though it * hasn't quite returned from the last trap. * * Calling printf() will re-enable interrupts. The timer * interrupt is likely to go off halfway through the restore, creating * obscure and unreproducible symptoms. * * If printf is called from here, call splhigh() first, and restore * with setspl() rather than splx. *//* FIX: At some point this should be bolted onto the front of the * appropriate resume path in the assembly code. */voidKernContext::Resume(){#ifndef NDEBUG if ( Thread::CurContext() != this ) fatal("Thread context 0x%08x not me 0x%08x\n", Thread::CurContext(), this); if ( ((uint32_t) saveArea < (uint32_t) stackBottom) || ((uint32_t) saveArea > (uint32_t) stackTop) ) fatal("Bogus save area! 0x%08x stack [0x%08x,0x%08x)\n", saveArea, stackBottom, stackTop);#if 0 /* Kernel threads do not make use of the numerics unit. */ */ if (saveArea->ReloadUnits & CpuUnit::Numeric) fatal("Don't know how to reload numeric coprocessor yet\n");#endif#endif #ifdef OPTION_DDB /* Nested breakpoint trap is okay. */ assert( IRQ::DISABLE_DEPTH() == 1 || saveArea->ExceptionNo == 3);#else assert( IRQ::DISABLE_DEPTH() == 1 );#endif resume_from_kernel_interrupt(saveArea);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -