📄 trace.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. * *//***************************************************************** * * trace.c * * ISSUES - * Exception: cause, epc (check branch delay slot issue), badVaddr * Don't send asid with each subtype * send uncached too ****************************************************************/#include "sim_error.h"#include "machine_params.h"#include "cpu_state.h"#include "simtypes.h"#include "TraceDef.h"#include "tcl_init.h"#define MAX_CPUS 128void *packetManager;TracePacket_t *packet;int asid[MAX_CPUS];int tracingActive = 1;struct { Boolean active; VA dataVA; PA dataPA; VA dataInstPC;} dataEvent[MAX_CPUS];char traceDumpMask[MAX_CPUS];extern CPUState *PE;/***************************************************************** * TraceInit *****************************************************************/voidTraceInit(){ int i; packetManager = (void *)InitTrace("trace.out", TRUE); packet = (TracePacket_t *)InitPacket(); for (i=0; i< TOTAL_CPUS; i++) { asid[i] = GET_ASID(PE[i].CP0[C0_TLBHI]); dataEvent[i].active = FALSE; traceDumpMask[i] = 0; }}/***************************************************************** * TraceInstruction *****************************************************************/void TraceInstruction(CPUState *P, Inst instr){ int cpuNum = P->myNum; if (!traceDumpMask[cpuNum]) return; packet->Id = Instr_e; packet->processorId = cpuNum; packet->instWord = instr; packet->instVAddr = P->PC; packet->instPAddr = P->pcPaddrcache + PAGE_OFFSET(P->PC); packet->instASID = asid[cpuNum]; if (P->branchStatus == BranchStatus_taken) { packet->Id = JumpBranchTaken_e; } else if (dataEvent[cpuNum].active) { ASSERT(P->PC == dataEvent[cpuNum].dataInstPC); packet->Id = MemRef_e; packet->packetValue.memRef.dataVAddr = dataEvent[cpuNum].dataVA; packet->packetValue.memRef.dataPAddr = dataEvent[cpuNum].dataPA; packet->packetValue.memRef.dataASID = asid[cpuNum]; dataEvent[cpuNum].active = FALSE; } SendPacket(packet, packetManager);}/***************************************************************** * TraceDataRef *****************************************************************/void TraceDataRef(CPUState *P, VA vAddr, PA pAddr){ int cpuNum = P->myNum; if (!traceDumpMask[cpuNum]) return; if (dataEvent[cpuNum].active != FALSE) { /* The implementation of sdl and sdr cause two memory references */ ASSERT(dataEvent[cpuNum].dataInstPC == P->PC); } dataEvent[cpuNum].active = TRUE; dataEvent[cpuNum].dataVA = vAddr; dataEvent[cpuNum].dataPA = pAddr; dataEvent[cpuNum].dataInstPC = P->PC;}void TraceUncachedDataRef(CPUState *P, VA vAddr, PA pAddr){ int cpuNum = P->myNum; if (!traceDumpMask[cpuNum]) return; if (dataEvent[cpuNum].active != FALSE) { /* The implementation of sdl and sdr cause two memory references */ ASSERT(dataEvent[cpuNum].dataInstPC == P->PC); } dataEvent[cpuNum].active = TRUE; dataEvent[cpuNum].dataVA = vAddr; dataEvent[cpuNum].dataPA = pAddr; dataEvent[cpuNum].dataInstPC = P->PC;}voidTraceCheckASID(CPUState *P){ int cpuNum = P->myNum; int newASID = GET_ASID(P->CP0[C0_TLBHI]); asid[cpuNum] = GET_ASID(P->CP0[C0_TLBHI]); if (!traceDumpMask[cpuNum]) return; if (asid[cpuNum] != newASID) { CPUWarning("ASID[%d]:\t %d to %d at %#x\n", P->myNum, asid[P->myNum], GET_ASID(P->CP0[C0_TLBHI]), P->PC); }}voidTraceException(CPUState *P, int code){ int cpuNum = 0; if (!traceDumpMask[cpuNum]) return; packet->Id = Event_e; packet->processorId = cpuNum; /* PROBLEM -> hard to get this field again*/ packet->instWord = 0; packet->instVAddr = P->PC; /* this might not be right for interrupts */ packet->instPAddr = P->pcPaddrcache + PAGE_OFFSET(P->PC); packet->instASID = asid[cpuNum]; /* Treat interrupts differently? */ packet->packetValue.event.event = code >> 2; /* Clear cached load or store address */ dataEvent[cpuNum].active = FALSE; SendPacket(packet, packetManager);} int TraceDumpTclCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){#ifndef TRACING Tcl_AppendResult(interp, "traceDump not supported unless mipsy compiled -DTRACING", NULL); return TCL_ERROR;#else int i;#ifndef SOLO if (simosCPUType != MIPSY) { Tcl_AppendResult(interp, "traceDump only supported in mipsy", NULL); return TCL_ERROR; }#endif if (argc < 2) { Tcl_AppendResult(interp, "Usage: traceDump <all|off|list of cpunumbers>", NULL); return TCL_ERROR; } if (!strcmp(argv[1], "off")) { CPUWarning("traceDump: Turning trace dumping OFF\n"); for (i = 0; i < MAX_CPUS; i++) { traceDumpMask[i] = 0; } } else if (!strcmp(argv[1], "all")) { CPUWarning("traceDump: Turning trace dumping on for ALL cpus\n"); for (i = 0; i < MAX_CPUS; i++) { traceDumpMask[i] = 1; } } else { for (i=1; i<argc; i++) { int cpuNum; if ((Tcl_GetInt(interp, argv[i], &cpuNum) != TCL_OK) || cpuNum >= MAX_CPUS ) { Tcl_AppendResult(interp, "Bad cpu num to traceDump command", NULL); return TCL_ERROR; } traceDumpMask[cpuNum] = 1; CPUWarning("traceDump: Enabling trace dumping for cpu %d\n", cpuNum); } } return TCL_OK;#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -