mirror of
https://github.com/openhwgroup/cvw
synced 2025-01-26 22:44:28 +00:00
b6e2710f5d
When a timer interrupt occurs it should be routed to the machine interrupt pending MTIP even if MIDELEG[5] = 1 when the current privilege mode is Machine. This is true for all the interrupts. The interrupt should not be masked even though it is delegated to a lower privilege. Since the CPU is currently in machine mode the interrupt must be taken if MIE. Additionally added a new qemu script which pipes together all the parsing and post processing scripts to produce the singular all.txt trace without the massivie intermediate files.
209 lines
7.6 KiB
Python
Executable File
209 lines
7.6 KiB
Python
Executable File
#! /usr/bin/python3
|
|
import sys, fileinput, re
|
|
|
|
# Ross Thompson
|
|
# July 27, 2021
|
|
# Rewrite of the linux trace parser.
|
|
|
|
|
|
InstrStartDelim = '=>'
|
|
InstrEndDelim = '-----'
|
|
|
|
#InputFile = 'noparse.txt'
|
|
#InputFile = sys.stdin
|
|
#InputFile = 'temp.txt'
|
|
#OutputFile = 'parsedAll.txt'
|
|
|
|
HUMAN_READABLE = False
|
|
|
|
def toDict(lst):
|
|
'Converts the list of register values to a dictionary'
|
|
dct= {}
|
|
for item in lst:
|
|
regTup = item.split()
|
|
dct[regTup[0]] = int(regTup[2], 10)
|
|
del dct['pc']
|
|
return dct
|
|
|
|
def whichClass(text, Regs):
|
|
'Which instruction class?'
|
|
#print(text, Regs)
|
|
if text[0:2] == 'ld' or text[0:2] == 'lw' or text[0:2] == 'lh' or text[0:2] == 'lb':
|
|
return ('load', WhatAddr(text, Regs), None, WhatMemDestSource(text))
|
|
elif text[0:2] == 'sd' or text[0:2] == 'sw' or text[0:2] == 'sh' or text[0:2] == 'sb':
|
|
return ('store', WhatAddr(text, Regs), WhatMemDestSource(text), None)
|
|
elif text[0:3] == 'amo':
|
|
return ('amo', WhatAddrAMO(text, Regs), WhatMemDestSource(text), WhatMemDestSource(text))
|
|
elif text[0:2] == 'lr':
|
|
return ('lr', WhatAddrLR(text, Regs), None, WhatMemDestSource(text))
|
|
elif text[0:2] == 'sc':
|
|
return ('sc', WhatAddrSC(text, Regs), WhatMemDestSource(text), None)
|
|
else:
|
|
return ('other', None, None, None)
|
|
|
|
def whatChanged(dct0, dct1):
|
|
'Compares two dictionaries of instrution registers and indicates which registers changed'
|
|
dct = {}
|
|
for key in dct0:
|
|
if (dct1[key] != dct0[key]):
|
|
dct[key] = dct1[key]
|
|
return dct
|
|
|
|
def WhatMemDestSource(text):
|
|
''''What is the destination register. Used to compute where the read data is
|
|
on a load or the write data on a store.'''
|
|
return text.split()[1].split(',')[0]
|
|
|
|
def WhatAddr(text, Regs):
|
|
'What is the data memory address?'
|
|
Imm = text.split(',')[1]
|
|
(Imm, Src) = Imm.split('(')
|
|
Imm = int(Imm.strip(), 10)
|
|
Src = Src.strip(')').strip()
|
|
RegVal = Regs[Src]
|
|
return Imm + RegVal
|
|
|
|
def WhatAddrAMO(text, Regs):
|
|
'What is the data memory address?'
|
|
Src = text.split('(')[1]
|
|
Src = Src.strip(')').strip()
|
|
return Regs[Src]
|
|
|
|
def WhatAddrLR(text, Regs):
|
|
'What is the data memory address?'
|
|
Src = text.split('(')[1]
|
|
Src = Src.strip(')').strip()
|
|
return Regs[Src]
|
|
|
|
def WhatAddrSC(text, Regs):
|
|
'What is the data memory address?'
|
|
Src = text.split('(')[1]
|
|
Src = Src.strip(')').strip()
|
|
return Regs[Src]
|
|
|
|
def PrintInstr(instr, fp):
|
|
if instr[2] == None:
|
|
return
|
|
ChangedRegisters = instr[4]
|
|
GPR = ''
|
|
CSR = []
|
|
for key in ChangedRegisters:
|
|
# filter out csr which are not checked.
|
|
if(key in RegNumber):
|
|
if(RegNumber[key] < 32):
|
|
# GPR
|
|
if(HUMAN_READABLE):
|
|
GPR = '{:-2d} {:016x}'.format(RegNumber[key], ChangedRegisters[key])
|
|
else:
|
|
GPR = '{:d} {:x}'.format(RegNumber[key], ChangedRegisters[key])
|
|
else:
|
|
if(HUMAN_READABLE):
|
|
CSR.extend([key, '{:016x}'.format(ChangedRegisters[key])])
|
|
else:
|
|
CSR.extend([key, '{:x}'.format(ChangedRegisters[key])])
|
|
|
|
CSRStr = ' '.join(CSR)
|
|
|
|
#print(instr)
|
|
|
|
if (HUMAN_READABLE == True):
|
|
fp.write('{:016x} {:08x} {:25s}'.format(instr[0], instr[1], instr[2]))
|
|
if(len(GPR) != 0):
|
|
fp.write(' GPR {}'.format(GPR))
|
|
if(instr[3] == 'load' or instr[3] == 'lr'):
|
|
fp.write(' MemR {:016x} {:016x} {:016x}'.format(instr[5], 0, instr[7]))
|
|
if(instr[3] == 'store'):
|
|
fp.write('\t\t\t MemW {:016x} {:016x} {:016x}'.format(instr[5], instr[6], 0))
|
|
|
|
if(len(CSR) != 0):
|
|
fp.write(' CSR {}'.format(CSRStr))
|
|
else:
|
|
fp.write('{:x} {:x} {:s}'.format(instr[0], instr[1], instr[2].replace(' ', '_')))
|
|
if(len(GPR) != 0):
|
|
fp.write(' GPR {}'.format(GPR))
|
|
if(instr[3] == 'load' or instr[3] == 'lr'):
|
|
fp.write(' MemR {:x} {:x} {:x}'.format(instr[5], 0, instr[7]))
|
|
if(instr[3] == 'store'):
|
|
fp.write(' MemW {:x} {:x} {:x}'.format(instr[5], instr[6], 0))
|
|
|
|
if(len(CSR) != 0):
|
|
fp.write(' CSR {}'.format(CSRStr))
|
|
fp.write('\n')
|
|
|
|
# reg number
|
|
RegNumber = {'zero': 0, 'ra': 1, 'sp': 2, 'gp': 3, 'tp': 4, 't0': 5, 't1': 6, 't2': 7, 's0': 8, 's1': 9, 'a0': 10, 'a1': 11, 'a2': 12, 'a3': 13, 'a4': 14, 'a5': 15, 'a6': 16, 'a7': 17, 's2': 18, 's3': 19, 's4': 20, 's5': 21, 's6': 22, 's7': 23, 's8': 24, 's9': 25, 's10': 26, 's11': 27, 't3': 28, 't4': 29, 't5': 30, 't6': 31, 'mhartid': 32, 'mstatus': 33, 'mip': 34, 'mie': 35, 'mideleg': 36, 'medeleg': 37, 'mtvec': 38, 'stvec': 39, 'mepc': 40, 'sepc': 41, 'mcause': 42, 'scause': 43, 'mtval': 44, 'stval': 45}
|
|
# initial state
|
|
CurrentInstr = ['0', '0', None, 'other', {'zero': 0, 'ra': 0, 'sp': 0, 'gp': 0, 'tp': 0, 't0': 0, 't1': 0, 't2': 0, 's0': 0, 's1': 0, 'a0': 0, 'a1': 0, 'a2': 0, 'a3': 0, 'a4': 0, 'a5': 0, 'a6': 0, 'a7': 0, 's2': 0, 's3': 0, 's4': 0, 's5': 0, 's6': 0, 's7': 0, 's8': 0, 's9': 0, 's10': 0, 's11': 0, 't3': 0, 't4': 0, 't5': 0, 't6': 0, 'mhartid': 0, 'mstatus': 0, 'mip': 0, 'mie': 0, 'mideleg': 0, 'medeleg': 0, 'mtvec': 0, 'stvec': 0, 'mepc': 0, 'sepc': 0, 'mcause': 0, 'scause': 0, 'mtval': 0, 'stval': 0}, {}, None, None, None]
|
|
|
|
#with open (InputFile, 'r') as InputFileFP:
|
|
#lines = InputFileFP.readlines()
|
|
lineNum = 0
|
|
StartLine = 0
|
|
EndLine = 0
|
|
#instructions = []
|
|
MemAdr = 0
|
|
lines = []
|
|
for line in fileinput.input('-'):
|
|
lines.insert(lineNum, line)
|
|
if InstrStartDelim in line:
|
|
lineNum = 0
|
|
StartLine = lineNum
|
|
elif InstrEndDelim in line:
|
|
EndLine = lineNum
|
|
(InstrBits, text) = lines[StartLine].split(':')
|
|
InstrBits = int(InstrBits.strip('=> '), 16)
|
|
text = text.strip()
|
|
PC = int(lines[StartLine+1].split(':')[0][2:], 16)
|
|
Regs = toDict(lines[StartLine+2:EndLine])
|
|
(Class, Addr, WriteReg, ReadReg) = whichClass(text, Regs)
|
|
#print("CWR", Class, WriteReg, ReadReg)
|
|
PreviousInstr = CurrentInstr
|
|
|
|
Changed = whatChanged(PreviousInstr[4], Regs)
|
|
|
|
if (ReadReg !=None): ReadData = ReadReg
|
|
else: ReadData = None
|
|
|
|
if (WriteReg !=None): WriteData = WriteReg
|
|
else: WriteData = None
|
|
|
|
CurrentInstr = [PC, InstrBits, text, Class, Regs, Changed, Addr, WriteData, ReadData]
|
|
|
|
#print(CurrentInstr[0:4], PreviousInstr[5], CurrentInstr[6:7], PreviousInstr[8])
|
|
|
|
# pc, instrbits, text and class come from the last line.
|
|
MoveInstrToRegWriteLst = PreviousInstr[0:4]
|
|
# updated registers come from the current line.
|
|
MoveInstrToRegWriteLst.append(CurrentInstr[5]) # destination regs
|
|
# memory address if present comes from the last line.
|
|
MoveInstrToRegWriteLst.append(PreviousInstr[6]) # MemAdrM
|
|
# write data from the previous line
|
|
#MoveInstrToRegWriteLst.append(PreviousInstr[7]) # WriteDataM
|
|
|
|
if (PreviousInstr[7] != None):
|
|
MoveInstrToRegWriteLst.append(Regs[PreviousInstr[7]]) # WriteDataM
|
|
else:
|
|
MoveInstrToRegWriteLst.append(None)
|
|
|
|
# read data from the current line
|
|
#MoveInstrToRegWriteLst.append(PreviousInstr[8]) # ReadDataM
|
|
if (PreviousInstr[8] != None):
|
|
MoveInstrToRegWriteLst.append(Regs[PreviousInstr[8]]) # ReadDataM
|
|
else:
|
|
MoveInstrToRegWriteLst.append(None)
|
|
|
|
lines.clear()
|
|
#instructions.append(MoveInstrToRegWriteLst)
|
|
PrintInstr(MoveInstrToRegWriteLst, sys.stdout)
|
|
lineNum += 1
|
|
|
|
|
|
#for instruction in instructions[1::]:
|
|
|
|
|
|
#with open(OutputFile, 'w') as OutputFileFP:
|
|
# print('opened file')
|
|
|
|
|
|
|