📄 solo_anl.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. * *//***************************************************************** * * Author: $Author: bosch $ * Date: $Date: 1998/02/10 00:33:21 $ *****************************************************************/#include <stdlib.h>#include <malloc.h>#include <bstring.h>#include <sys/types.h>#include <sys/mman.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <setjmp.h>#include "mipsy.h"#include "cpu_state.h"#include "cpu_stats.h"#include "cp0.h"#include "sim_error.h"#include "solo_anl.h"#include "solo_extras.h"#include "cpu_interface.h"#include "pcache.h"#include "scache.h"#include "../../memsystems/memsys.h"#ifdef USE_FLASHLITE#include "flashtypes.h"#include "flash_interface.h"#endif#include "solo.h"#include "solo_page.h"#include "solo_interface.h"#ifdef FLASHPOINT# include "memspy_simulator.h" /* The undef gets rid of an annoying compiler warning since machine.h redefines SHARED */# undef SHARED# include "mipsy_interface.h" /* from page.c */ extern bool GetPhysicalAddr(VA v_addr, SoloPA *p_addr, uint *flavor); extern SoloPA AllocatePage(int module, VA va); extern void NewMapping(VA v_addr, SoloPA p_addr, uint flavor);#endifSoloState machineState[SIM_MAXCPUS];typedef unsigned int SoloLockType;static CommArea *comm;/* Prototypes for solo calls that come through the comm ptr */static void SoloCreate(Func f);static void SoloResetStats(void);static int SoloActiveProcs(void);static void SoloEndCPU(void);static void SoloPlaceRange(unsigned start, unsigned stop, int node);static int SoloGetCPUNum(void);static unsigned long long SoloGetCurrentTime(void);static int SoloFlush(void *arg);static void SoloIOMap(VA vAddr, long long pAddr);static void *SoloLockInit(void);static int SoloLock(void *);static void SoloUnlock(void *);static void SoloBarEnter(void);static void SoloBarExit(void);#ifdef FLASHPOINT static void SoloFP_Malloc(int, unsigned, void *, char *); static unsigned long long SoloFP_Virtual_To_Physical(unsigned long long v); static unsigned SoloFP_GetNumCpus(void); static char *FetchApplicationString(VA app_addr);# define APP_STRING_SIZE 256 /* max length of application variable name */#endifvoid BDoorStart(void){}void SoloSetupCommArea(void){ comm = (CommArea *)CommAreaPtr; comm->Create = SoloCreate;/* comm->Exit = SoloExit; */ comm->GetCPUNum = SoloGetCPUNum; comm->ActiveProcs = SoloActiveProcs; comm->CurrentTime = SoloGetCurrentTime; comm->ResetStats = SoloResetStats; comm->Flush = SoloFlush; comm->IOMap = SoloIOMap; comm->IOMapGeneral= SoloIOMapGeneral; comm->PlaceRange = SoloPlaceRange; comm->TurnOnCaches = SoloTurnOnCaches; comm->TurnOffCaches = SoloTurnOffCaches; /* These are only needed for fake synchronization */ comm->LockInit = SoloLockInit; comm->Lock = SoloLock; comm->Unlock = SoloUnlock; comm->BarEnter = SoloBarEnter; comm->BarExit = SoloBarExit;#ifdef FLASHPOINT /* Application should call this after every malloc */ comm->FP_Malloc = SoloFP_Malloc; comm->FP_Virtual_To_Physical = SoloFP_Virtual_To_Physical; comm->FP_GetNumCpus = SoloFP_GetNumCpus;#endif}static voidCallSoloEndCPU(int cpuNum){ soloCPUNum = cpuNum; SoloEndCPU();}static voidSoloSyncAndEndCPU(void){ SoloState *P = &machineState[soloCPUNum]; P->syncDoneCallback = CallSoloEndCPU; MipsySoloSync(soloCPUNum); }static void SoloCreate(Func f){ unsigned stackTop; int fd; void *ret; if (soloActiveProcs == TOTAL_CPUS) { CPUError("Application CREATEd too many children: %d\n",soloActiveProcs+1); } stackTop = SOLO_STACK_TOP - (soloActiveProcs * SOLO_STACK_SIZE); SIM_DEBUG(('o', "Mipsy: Mapping application stack for node %d: %8.8x to %8.8x\n", soloActiveProcs, stackTop-SOLO_STACK_SIZE, stackTop)); fd = open("/dev/zero", O_RDWR); if (fd < 0) { perror("Opening /dev/zero"); CPUError("CREATE failed\n"); } ret = (char *) mmap((void *) (stackTop - SOLO_STACK_SIZE), SOLO_STACK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, 0); if (ret != (char *) (stackTop - SOLO_STACK_SIZE)) { perror("Mapping stack for child"); CPUError("CREATE failed\n"); } close(fd); MipsyStartCPU(soloActiveProcs, (VA)f, (VA)SoloSyncAndEndCPU, stackTop); CPUPrint("M: "); CPUPrint("Starting Function on PE %d at %#lld cycles\n", soloActiveProcs, MipsyReadTime(soloActiveProcs)); STATS_SET(soloActiveProcs, haltedTime, MipsyReadTime(soloActiveProcs));#ifdef USE_FLASHLITE FlashliteStartCPU(soloActiveProcs);#endif soloActiveProcs++; soloLowStack = (VA)(stackTop - SOLO_STACK_SIZE);}static voidSoloResetStats(void){ int i; MipsyResetStats();#ifdef USE_FLASHLITE FlashliteResetStats();#endif}static intSoloActiveProcs(void){ return soloActiveProcs;}static void SoloEndCPU(void){ MipsyStopCPU(soloCPUNum); CPUPrint("Killed CPU #%d\n", soloCPUNum);#ifdef USE_FLASHLITE FlashliteStopCPU(soloCPUNum);#endif soloActiveProcs--;}static voidSoloPlaceRange(unsigned start, unsigned stop, int node){ Solosys_place_range((VA)start, (VA)stop, node);}static int SoloGetCPUNum(void){ return soloCPUNum;}static void *SoloLockInit(void){ SoloLockType *intLock; /* Note, this is a simulator malloc, not an application amalloc, so */ /* we're insulated against the application accessing this inadvertantly*/ intLock = (SoloLockType *) malloc(sizeof(SoloLockType)); /* Return a pointer to the lock */ *intLock = 0; /* Initialize the lock itself */ SIM_DEBUG(('o', "M: %d: Lock initialized %#x\n", soloCPUNum, intLock)); return (void *) intLock;}int SoloLock(void *lock) { SoloState *P = &machineState[soloCPUNum]; if (*(SoloLockType *)lock != 0) { return 0; } else { SIM_DEBUG(('o', "M: Lock by %d succeeded on %#x\n", soloCPUNum, lock)); *(SoloLockType *)lock = 1; return 1; }}static void SoloUnlock(void *lock){ SIM_DEBUG(('o', "M: Unlock of %#x by %d\n", lock, soloCPUNum)); * (SoloLockType *) lock= 0;}static voidSoloBarEnter(void){ SoloState *P = &machineState[soloCPUNum]; ASSERT(!(P->inBarrier)); P->inBarrier = TRUE;}static voidSoloBarExit(void){ SoloState *P = &machineState[soloCPUNum]; ASSERT(P->inBarrier); P->inBarrier = FALSE;}/* Return current time in microseconds */static unsigned long longSoloGetCurrentTime(void){ /* cycles/MHz = microseconds */ return (unsigned long long) (mipsyCurrentTime / CPU_CLOCK);}voidSoloBackdoorSyncFinish(int cpuNum){ machineState[cpuNum].syncDoneCallback(cpuNum);}/***************************************************************** * SoloFlush *****************************************************************/static intSoloFlush(void *arg){ VA va = (VA) arg & ~(VA)(SCACHE_LINE_SIZE-1); /* Determine scache line */ return MipsyFlushCacheLine(soloCPUNum, va);}voidSoloIOMap(unsigned va, long long pa){ SIM_DEBUG(('o', "%d: SoloIOMap on va: %8.8x pa:%16.16llx\n",soloCPUNum, va, pa)); SoloEstablishMapping((SoloPA)pa, (VA)va, 0, TLB_UNCACHED);} voidSoloIOMapAccelerated(unsigned va, long long pa){ SIM_DEBUG(('o', "%d: SoloIOMap on va: %8.8x pa:%16.16llx\n",soloCPUNum, va, pa)); SoloEstablishMapping((SoloPA)pa, (VA)va, 0, TLB_UNCACHED|TLB_ACCELERATED);} voidSoloIOMapGeneral(unsigned va, int details, long long pa){ int space; int unc, acc; space = details &~ IO_MAP_ACCELERATED; space = space &~ IO_MAP_UNCACHED; unc = (details & IO_MAP_UNCACHED) != 0; acc = (details & IO_MAP_ACCELERATED) != 0; SIM_DEBUG(('o', "%d: SoloIOMapGeneral on va: %8.8x pa:%16.16llx details: %x \n(space: %d unc: %d acc: %d)\n", soloCPUNum, va, pa, details, space, unc, acc)); SoloEstablishMapping((SoloPA)pa, (VA)va, space, (unc ? TLB_UNCACHED : 0) | (acc ? TLB_ACCELERATED : 0));} void BDoorEnd(void){}/***************************************************************** * Non backdoor calls can go here - namely things that need to be * implemented from within *****************************************************************//***************************************************************** * Routines for timing the various synchronization operations. These * timings will be a little intrusive since there is a jal to * them... annotations can be used eventually. *****************************************************************/voidSoloStartLock(void){}void SoloStopLock(void){}void SoloStartUnlock(void){}void SoloStopUnlock(void){}voidSoloStartBarrier(void){}void SoloStopBarrier(void){}#ifdef FLASHPOINTvoidSoloFP_Malloc(int instance, unsigned size, void *malloc_addr, char *app_name) /* When this function gets called by the application through the CommAreaPtr, it's telling the simulator to work it's magic to set up bins for this malloc. It's autobin's job to replace all calls to malloc() in the application source to a function call that calls malloc, and then calls this. */{ char *name; /* Can't just dereference a string in application space, grab it this way */ name = FetchApplicationString((VA) app_name); CPUPrint("SoloFP_Malloc: instance %d, size %u, name \"%s\" to vaddr %p\n", instance, size, name, malloc_addr); /* Call Memspy to initialize a bin for this malloc */ Memspy_Sim_Malloc(GetSimulatorMemspyGlobals(), (Memspy_VA)malloc_addr, size, name, instance); free(name); /* don't leak - Memspy makes a copy */}unsigned long longSoloFP_Virtual_To_Physical(unsigned long long v){ unsigned long long phys = 0LL; uint flavor = 0; if(GetPhysicalAddr(v, (SoloPA *)(&phys), &flavor)) { return phys; } else { phys = AllocatePage(soloCPUNum, v); NewMapping(v, phys, TLB_CACHED); } return phys;}unsignedSoloFP_GetNumCpus(void){ return TOTAL_CPUS;}char *FetchApplicationString(VA app_addr) { /* Grab a string out of application space. If it's larger than APP_STRING_SIZE, truncate it to APP_STRING_SIZE. */ char *buf = malloc(APP_STRING_SIZE); int i = 0; if(!buf) CPUError("Can't allocate application string\n"); for(i=0; i<APP_STRING_SIZE-1; i++) { if(CPUVec.GetMemory(soloCPUNum, app_addr + i, 1, &(buf[i])) != SUCCESS) { CPUError("GetMemory returned failure tp FetchApplicationString\n"); } if(buf[i] == '\0') { break; } } buf[APP_STRING_SIZE-1] = '\0'; return buf;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -