📄 solo_cp0.c
字号:
/* * Copyright (C) 1996-1998 by the Board of Trustees * of Leland Stanford Junior University. * * This file is part of the SimOS distribution. * See LICENSE file for terms of the license. * *//**************************************************************** * solo_cp0.c * * $Author: bosch $ * $Date: 1998/02/10 00:33:26 $ *****************************************************************/#include "mipsy.h"#include "cp0.h"#include "sim_error.h"#include "solo_anl.h"#include "solo_interface.h"#include "cpu_interface.h"#include "solo.h"#include "solo_interface.h"#include "solo_page.h"#include "simtypes.h"#include "cpu_stats.h"static int libcOwner = -1;static int libcWaiters = 0;ResultTranslateVirtualNoSideeffect(CPUState *P, VA vAddr, PA *pAddr){ uint flavor = 0; void *bdoorAddr = 0; return TranslateVirtual(P, vAddr, pAddr, &flavor,&bdoorAddr);}/***************************************************************** * TranslateVirtual * * Now that we're in solo mipsy, just return the virtual address *****************************************************************/Result TranslateVirtual(CPUState *P, VA vAddr, PA *pAddr, uint *tlbFlavor, void **bdoorAddr){ int i, p; bool icache; int cpuNum = P->myNum; SoloPA soloPA; icache = (bool) TLB_IS_IFETCH(*tlbFlavor); /* Setting this to 0 means that by this is not a backdoor reference */ *tlbFlavor = 0; if (((void *)vAddr >= (void*)SOLO_STACK_TOP) && ((void *)vAddr < (void*)0x90000000)) { /* WARNING: ALL references above the top of */ /* the application's stack top are backdoor. */ *tlbFlavor = TLB_BDOOR_DATA; *bdoorAddr = (void *)vAddr; *pAddr = (PA)vAddr; } else { if (icache) { /* Make sure that only one processor at a time is allowed to */ /* be executing in the libc code. The start of libc is found */ /* by linking in an object file with a single function in it. */ if ((void *)vAddr >= (void *)CommAreaPtr->libcStart) { if ((libcOwner != P->myNum) && (libcOwner != -1)) { P->cpuStatus = cpu_libc_blocked; STATS_SET(cpuNum, libcWaitStart, MipsyReadTime(cpuNum)); libcWaiters++; return FAILURE; } else { libcOwner = P->myNum; } } else { if (libcOwner == P->myNum) { if (libcWaiters > 0) { libcWaiters--; for (i=1; i < TOTAL_CPUS; i++) { p = (P->myNum + i) % TOTAL_CPUS; if (PE[p].cpuStatus == cpu_libc_blocked) { STATS_ADD_INTERVAL(p, libcWaitTime, libcWaitStart); libcOwner = p; PE[p].cpuStatus = cpu_running; break; } } ASSERT(libcOwner != P->myNum); } else { libcOwner = -1; } } } } if (IS_STACK_REF(vAddr)) { soloPA = SoloV_to_P(P->myNum, vAddr, P->myNum, TRUE, tlbFlavor); } else { soloPA = SoloV_to_P(P->myNum, vAddr, P->myNum, FALSE, tlbFlavor); } if ((*tlbFlavor) == TLB_UNCACHED) { *pAddr = vAddr; /* This will be translated by the memsys command */ } else {#if 0 /* JH: This is the safe, default version that doesn't provide the lock hack. In case the lock code crashes for you badly, this is a saving grace you can use*/ *pAddr = SoloCompressAddr(soloPA);#else/* Check for accesses in the lock space, and remap them into the special range*/ if (SOLO_PA_SPACE(soloPA) == 1) { /* Lock space. Remove space bit, add base in mipsy VA range so */ /* compress maintains hidden notion of this address */#ifdef DEBUG_PAGE_VERBOSE CPUPrint("Lock address detected, pAddr = %llx\n",soloPA); #endif soloPA += soloLockBase;/* soloPA &= ~((unsigned long long) 0xe0000000LL); */ soloPA = SOLO_FORM_PA( SOLO_PA_NODE(soloPA), 0LL, /* Space 0! */ SOLO_PA_OFFSET(soloPA));#ifdef DEBUG_PAGE_VERBOSE CPUPrint("After address munging, pAddr = %llx\n",soloPA); /* Remove the space bit. Not strictly necessary, since compress will */ /* throw it away anyway... */#endif } else if (SOLO_PA_SPACE(soloPA) == 2) { /* Check for accesses in the barrier space, and remap them into the special range*/ /* Lock space. Remove space bit, add base in mipsy VA range so */ /* compress maintains hidden notion of this address */#ifdef DEBUG_PAGE_VERBOSE CPUPrint("Barrier address detected, pAddr = %llx\n",soloPA); #endif soloPA += soloBarrierBase;/* soloPA &= ~((unsigned long long) 0xe0000000LL); */ soloPA = SOLO_FORM_PA( SOLO_PA_NODE(soloPA), 0LL, /* Space 0! */ SOLO_PA_OFFSET(soloPA));#ifdef DEBUG_PAGE_VERBOSE CPUPrint("After address munging, pAddr = %llx\n",soloPA); /* Remove the space bit. Not strictly necessary, since compress will */ /* throw it away anyway... */#endif } *pAddr = SoloCompressAddr(soloPA);#ifdef DEBUG_PAGE_VERBOSE CPUPrint("Before compression, pAddr = %llx\n",soloPA); CPUPrint("After compression, pAddr = %x\n",*pAddr); #endif#endif } } return SUCCESS;}/***************************************************************** * EXCEPTION ****************************************************************/void EXCEPTION(CPUState *P, int code){ CPUError("EXCEPTION %d occurred on cpu %d @ PC 0x%x\n", code, P->myNum, P->PC);}/***************************************************************** * ExceptionReturn ****************************************************************/void ExceptionReturn(int cpuNum){ CPUPrint("RFE - you shouldn't be here\n");}void MipsyCheckForInterrupts(CPUState *P){ /* SOLO doesn't do interrupts */}void UpdateCPUMode(CPUState *P){ CPUWarning("SOLO in UpdateCPUMode\n");}intExecuteC0Instruction(CPUState *P, Inst instr){ CPUWarning("WriteC0Reg - you shouldn't be here\n"); return C0_CONTINUE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -