📄 usercontextipc.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 <kerninc/kernel.hxx>#include <kerninc/Node.hxx>#include <arch-kerninc/KernTune.hxx>#include <kerninc/Thread.hxx>#include <kerninc/util.h>#include <kerninc/ObjectCache.hxx>#include <kerninc/Machine.hxx>#include <kerninc/IRQ.hxx>#include <kerninc/Invocation.hxx>#include <eros/Key.h>#include <kerninc/Process.hxx>#include <arch-kerninc/PTE.hxx>#include "TSS.hxx"#include "GDT.hxx"#include <eros/Invoke.h>#include <eros/ProcessState.h>#include <eros/Registers.h>#include <eros/i486/Registers.h>#include <kerninc/PhysMem.hxx>#include <kerninc/Invocation.hxx>#include <arch-kerninc/Process.hxx>/* #define MSGDEBUG * #define RESUMEDEBUG * #define XLATEDEBUG */extern "C" { void resume_process(Process *) NORETURN;#ifdef V86_SUPPORT void resume_v86_process(Process *) NORETURN;#endif};voidProcess::Resume(){#if 0 printf("Resume user thread 0x%08x\n", thread);#endif #ifndef NDEBUG if ( curThread != Thread::Current() ) fatal("Context 0x%08x (%d) not for current thread 0x%08x (%d)\n", this, this - Process::ContextCache, Thread::Current(), Thread::Current() - Thread::ThreadTable); if ( Thread::CurContext() != this ) fatal("Thread context 0x%08x not me 0x%08x\n", Thread::CurContext(), this);#endif#if 0 if (fixRegs.ReloadUnits) { printf("Don't know how to reload fpu regs yet\n"); printf("ctxt = 0x%08x\n", this); fixRegs.Dump(); halt(); }#endif#if 0 printf("Resume user thread savearea 0x%08x\n", saveArea);#endif /* Need to have a valid directory or the machine reboots. It's * possible that the mapping table entry was nailed by a depend zap, * in which case we will rebuild it next time through. For now, * simply make sure the mapping table value at least maps the kernel */ if (fixRegs.MappingTable == 0) fixRegs.MappingTable = KERNPAGEDIR; assert( IRQ::DISABLE_DEPTH() == 1 ); /* We will be reloading the user segment descriptors on the way out. * Set up here for those to have the proper base and bound. */#ifdef OPTION_SMALL_SPACES if (smallPTE) { assert(bias); GDT::SetupPageSegment(SegEntry::DomainCode, bias, SMALL_SPACE_PAGES-1); GDT::SetupPageSegment(SegEntry::DomainData, bias, SMALL_SPACE_PAGES-1); } else#endif {#ifdef OPTION_SMALL_SPACES assert(bias == 0);#endif GDT::SetupPageSegment(SegEntry::DomainCode, 0, LARGE_SPACE_PAGES-1); GDT::SetupPageSegment(SegEntry::DomainData, 0, LARGE_SPACE_PAGES-1); } #ifdef EROS_HAVE_FPU /* This is the right place to enable, but probably not the right place to *disable*. */ if (fpuOwner == this) { Machine::EnableFPU(); } else if (fpuOwner) { Machine::DisableFPU(); }#endif #ifdef V86_SUPPORT if ((fixRegs.EFLAGS & EFLAGS::Virt8086) == 0) resume_process(this); else resume_v86_process(this);#else resume_process(this);#endif}extern "C" { extern uint32_t cycnt0; extern uint32_t cycnt1; extern uint32_t rdtsr();}/* #define SND_TIMING * #define RCV_TIMING *//* There are three PTE's that must be valid to have a valid mapping: * the address space pointer, the page table pointer, and the page * pointer. It is conceivable that with sufficient bad fortune, the * first two passes through DoPageFault will end up invalidating the * depend entries for one of the other entries. If we can't get it in * 3 tries, however, the depend table design is scrod, and we should * panic. */PTE*proc_BuildMapping(Process *p, ula_t ula, bool writeAccess, bool prompt){ uint32_t retry; for (retry = 0; retry < 4; retry++) { if (proc_DoPageFault(p, ula, writeAccess, prompt) == false) return 0; PTE* pte = proc_TranslatePage(p, ula, PTE_V|PTE_USER, writeAccess);#if 0 dprintf(true, "Resulting PTE* is 0x%08x\n", pte);#endif if (pte) return pte; } fatal("Too many retries\n"); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -