diff --git a/linux/testvector-generation/EmulateLinux.sh b/linux/testvector-generation/EmulateLinux.sh deleted file mode 100755 index e2b50af4d..000000000 --- a/linux/testvector-generation/EmulateLinux.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/bash - -usage() { echo "Usage: $0 [-h] [-b ] [-d ]" 1>&2; exit 1; } - -help() { - echo "Usage: $0 [OPTIONS] " - echo " -b get images from given buildroot" - echo " -d specify device tree to use" - exit 0; -} - -# defaults -imageDir=$RISCV/buildroot/output/images -DEVICE_TREE=${imageDir}/wally-virt.dtb - -# Process options and arguments. The following code grabs the single -# sdcard device argument no matter where it is in the positional -# parameters list. -ARGS=() -while [ $OPTIND -le "$#" ] ; do - if getopts "hb:d:" arg ; then - case "${arg}" in - h) help - ;; - b) BUILDROOT=${OPTARG} - ;; - d) DEVICE_TREE=${OPTARG} - ;; - esac - else - ARGS+=("${!OPTIND}") - ((OPTIND++)) - fi -done - -# File location variables -imageDir=$BUILDROOT/output/images - -tvDir=$RISCV/linux-testvectors -tcpPort=1239 - -# QEMU Simulation -qemu-system-riscv64 \ --M virt -m 256M -dtb $DEVICE_TREE \ --nographic \ --bios $imageDir/fw_jump.elf -kernel $imageDir/Image -append "root=/dev/vda ro" --singlestep -rtc clock=vm -icount shift=0,align=off,sleep=on diff --git a/linux/testvector-generation/checkpointSweep.sh b/linux/testvector-generation/checkpointSweep.sh deleted file mode 100755 index 075ca253c..000000000 --- a/linux/testvector-generation/checkpointSweep.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -for index in {450..500}; -do - instrs=$(($index*1000000)) - echo "y" | nice -n 5 ./genCheckpoint.sh $instrs -done diff --git a/linux/testvector-generation/debug.sh b/linux/testvector-generation/debug.sh deleted file mode 100755 index 7ca3e9b15..000000000 --- a/linux/testvector-generation/debug.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash -imageDir=$RISCV/buildroot/output/images -tvDir=$RISCV/linux-testvectors -tcpPort=1239 - -# QEMU Simulation -qemu-system-riscv64 \ --M virt -dtb $imageDir/wally-virt.dtb \ --nographic \ --bios $imageDir/fw_jump.elf -kernel $imageDir/Image -append "root=/dev/vda ro" -initrd $imageDir/rootfs.cpio \ --singlestep -rtc clock=vm -icount shift=0,align=off,sleep=on -# > ./qemu-serial \ -# -gdb tcp::$tcpPort -S) \ -# & riscv64-unknown-elf-gdb -quiet \ -# -ex "set pagination off" \ -# -ex "set logging overwrite on" \ -# -ex "set logging redirect on" \ -# -ex "set confirm off" \ -# -ex "target extended-remote :$tcpPort" \ -# -ex "maintenance packet Qqemu.PhyMemMode:1" \ -# -ex "file $imageDir/vmlinux" diff --git a/linux/testvector-generation/disassembleBootTrace.py b/linux/testvector-generation/disassembleBootTrace.py deleted file mode 100755 index ac36fd36e..000000000 --- a/linux/testvector-generation/disassembleBootTrace.py +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env python3 -# -# disassembleBootTrace.py -# David_Harris@hmc.edu 22 November 2023 -# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 -# -# Reads boottrace.log and disassembles the machine code -# - -import csv -import os -import re - -# read a file from sim/logs/boottrace.log and extract the second comma-separated field containing the instruction -print("Reading boottrace.log") -trace = [] -count = 0 -with open('../../sim/logs/boottrace.log') as f: - reader = csv.reader(f, delimiter=',') - for row in reader: - trace.append(row) - count = count + 1 - if count > 50000000: - break -f.close() - -print("Disassembling boottrace.log instructions") -# Write an assembly language file with the machine code -with (open('boottrace.S', 'w')) as f: - f.write('main:\n') - for row in trace: - instr = row[1] - # scrape off leading white space from instr - instr = instr.lstrip() - # check if last character indicates an compressed or uncompressed instruction - lastNibble = instr[-1] - if (lastNibble == '3' or lastNibble == '7' or lastNibble == 'b' or lastNibble == 'f'): - # uncompressed - f.write('.word 0x' + instr + '\n') - else: - # compressed - instr = instr[-4:] - f.write('.hword 0x' + instr + '\n') -f.close() - -# Then assemble and disassemble the file -os.system('riscv64-unknown-elf-gcc -march=rv64gqc_zba_zbb_zbc_zbs_zfh_zicboz_zicbop_zicbom -mabi=lp64d -c boottrace.S') -os.system('riscv64-unknown-elf-objdump -D boottrace.o > boottrace.objdump') - -# Patch disassembly back into boottrace -print("Inserting disassembly into trace") -dumpedLines = [] -with (open('boottrace.objdump', 'r')) as f: - lines = f.readlines() - f.close() -lines = lines[7:] # skip header -p = r'[^:]*:\s*(\S*)\s*(.*)' -for line in lines: - match = re.search(p, line) - if (match): - dump = [match.group(1), match.group(2)] - dumpedLines.append(dump) - -linenum = 0 -for i in range(len(trace)): - row = trace[i] - row.insert(2, dumpedLines[i][1]) - -# write trace back to csv file -print("Writing trace back to boottrace_disasm.log") -with (open('boottrace_disasm.log', 'w')) as f: - writer = csv.writer(f) - writer.writerows(trace) -f.close() diff --git a/linux/testvector-generation/filterTrapsToInterrupts.py b/linux/testvector-generation/filterTrapsToInterrupts.py deleted file mode 100755 index 7476e110f..000000000 --- a/linux/testvector-generation/filterTrapsToInterrupts.py +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env python3 -import sys, os -from functools import reduce - -################ -# Helper Funcs # -################ - -def tokenize(string): - tokens = [] - token = '' - whitespace = 0 - prevWhitespace = 0 - for char in string: - prevWhitespace = whitespace - whitespace = char in ' \t\n' - if (whitespace): - if ((not prevWhitespace) and (token != '')): - tokens.append(token) - token = '' - else: - token = token + char - return tokens - -def strip0x(num): - return num[2:] - -def stripZeroes(num): - num = num.strip('0') - if num=='': - return '0' - else: - return num - -############# -# Main Code # -############# -print("Begin filtering traps down to just external interrupts.") - -# Parse Args -if len(sys.argv) != 2: - sys.exit('Error filterTrapsToInterrupts.py expects 1 arg: ') -tvDir = sys.argv[1]+'/' -trapsFilePath = tvDir+'traps.txt' -if not os.path.exists(trapsFilePath): - sys.exit('Error input file '+trapsFilePath+'not found') - -with open(tvDir+'interrupts.txt', 'w') as interruptsFile: - with open(trapsFilePath, 'r') as trapsFile: - while True: - trap = trapsFile.readline() - if trap == '': - break - trapType = trap.split(' ')[-1] - if ('interrupt' in trap) and (('external' in trapType) or ('m_timer' in trapType)): # no s_timer because that is not controlled by CLINT - interruptsFile.write(trap) # overall line - interruptsFile.write(trapsFile.readline()) # attempted instr count - interruptsFile.write(trapsFile.readline()) # hart # - interruptsFile.write(trapsFile.readline()) # asynchronous - interruptsFile.write(trapsFile.readline()) # cause - interruptsFile.write(trapsFile.readline()) # epc - interruptsFile.write(trapsFile.readline()) # tval - interruptsFile.write(trapsFile.readline()) # description - else: - for i in range(7): - trapsFile.readline() - -print("Finished filtering traps down to just external interrupts.") diff --git a/linux/testvector-generation/genCheckpoint.sh b/linux/testvector-generation/genCheckpoint.sh deleted file mode 100755 index f12223f54..000000000 --- a/linux/testvector-generation/genCheckpoint.sh +++ /dev/null @@ -1,146 +0,0 @@ -#!/bin/bash -tcpPort=1238 -imageDir=$RISCV/buildroot/output/images -tvDir=$RISCV/linux-testvectors -recordFile="$tvDir/all.qemu" -traceFile="$tvDir/all.txt" - -# Parse Commandline Arg -if [ "$#" -ne 1 ]; then - echo "genCheckpoint requires 1 argument: " >&2 - exit 1 -fi -instrs=$1 -if ! [ "$instrs" -eq "$instrs" ] 2> /dev/null -then - echo "Error expected integer number of instructions, got $instrs" >&2 - exit 1 -fi - -checkPtDir="$tvDir/checkpoint$instrs" -outTraceFile="$checkPtDir/all.txt" -rawStateFile="$checkPtDir/stateGDB.txt" -rawUartStateFile="$checkPtDir/uartStateGDB.txt" -uartStateFile="$checkPtDir/checkpoint-UART" -rawPlicStateFile="$checkPtDir/plicStateGDB.txt" -plicStateFile="$checkPtDir/checkpoint-PLIC" -rawRamFile="$checkPtDir/ramGDB.bin" -ramFile="$checkPtDir/ram.bin" - -read -p "This scripts is going to create a checkpoint at $instrs instrs. -Is that what you wanted? (y/n) " -n 1 -r -echo -if [[ $REPLY =~ ^[Yy]$ ]] -then - echo "Creating checkpoint at $instrs instructions!" - if [ ! -d "$tvDir" ]; then - echo "Error: linux testvector directory $tvDir not found!">&2 - echo "Please create it. For example:">&2 - echo " sudo mkdir -p $tvDir">&2 - exit 1 - fi - test -w $tvDir - if [ ! $? -eq 0 ]; then - echo "Error: insuffcient write privileges for linux testvector directory $tvDir !">&2 - echo "Please chmod it. For example:">&2 - echo " sudo chmod -R a+rw $tvDir">&2 - exit 1 - fi - - mkdir -p $checkPtDir - - # Identify instruction in trace - instr=$(sed "${instrs}q;d" "$traceFile") - echo "Found ${instrs}th instr: ${instr}" - pc=$(echo $instr | cut -d " " -f1) - asm=$(echo $instr | cut -d " " -f2) - occurences=$(($(head -$instrs "$traceFile" | grep -c "${pc} ${asm}")-1)) - echo "It occurs ${occurences} times before the ${instrs}th instr." - - # Create GDB script because GDB is terrible at handling arguments / variables - cat > genCheckpoint.gdb <<- end_of_script - set pagination off - set logging overwrite on - set logging redirect on - set confirm off - target extended-remote :$tcpPort - maintenance packet Qqemu.PhyMemMode:1 - file $imageDir/vmlinux - # Step over reset vector into actual code - stepi 100 - shell echo \"GDB proceeding to checkpoint at $instrs instrs, pc $pc\" - b *0x$pc - ignore 1 $occurences - c - shell echo \"Reached checkpoint at $instrs instrs\" - shell echo \"GDB storing CPU state to $rawStateFile\" - set logging file $rawStateFile - set logging on - info all-registers - set logging off - shell echo \"GDB storing UART state to $rawUartStateFile\" - # Save value of LCR - set \$LCR=*0x10000003 & 0xff - set logging file $rawUartStateFile - set logging on - # Change LCR to set DLAB=0 to be able to read RBR and IER - set {char}0x10000003 &= ~0x80 - x/1xb 0x10000000 - x/1xb 0x10000001 - x/1xb 0x10000002 - # But log original value of LCR - printf "0x10000003:\t0x%02x\n", \$LCR - x/1xb 0x10000004 - x/1xb 0x10000005 - x/1xb 0x10000006 - x/1xb 0x10000007 - set logging off - shell echo \"GDB storing PLIC state to $rawPlicStateFile\" - shell echo \"Note: this dumping assumes a maximum of 63 PLIC sources\" - set logging file $rawPlicStateFile - set logging on - # Priority Levels for sources 1 thru 63 - x/63xw 0x0C000004 - # Interrupt Enables for sources 1 thru 63 for contexts 0 and 1 - x/2xw 0x0C002000 - x/2xw 0x0C002080 - # Global Priority Threshold for contexts 0 and 1 - x/1xw 0x0C200000 - x/1xw 0x0C201000 - set logging off - shell echo \"GDB storing RAM to $rawRamFile\" - dump binary memory $rawRamFile 0x80000000 0x87ffffff - kill - q -end_of_script - - # GDB+QEMU - echo "Starting QEMU in replay mode with attached GDB script at $(date +%H:%M:%S)" - (qemu-system-riscv64 \ - -M virt -dtb $imageDir/wally-virt.dtb \ - -nographic \ - -bios $imageDir/fw_jump.elf -kernel $imageDir/Image -append "root=/dev/vda ro" -initrd $imageDir/rootfs.cpio \ - -singlestep -rtc clock=vm -icount shift=0,align=off,sleep=on,rr=replay,rrfile=$recordFile \ - -gdb tcp::$tcpPort -S \ - 1>./qemu-serial) \ - & riscv64-unknown-elf-gdb --quiet -x genCheckpoint.gdb - - echo "Completed GDB script at $(date +%H:%M:%S)" - - # Post-Process GDB outputs - ./parseState.py "$checkPtDir" - ./parseUartState.py "$checkPtDir" - ./parsePlicState.py "$checkPtDir" - echo "Changing Endianness at $(date +%H:%M:%S)" - make fixBinMem - ./fixBinMem "$rawRamFile" "$ramFile" - echo "Copying over a truncated trace" - tail -n+$instrs $traceFile > $outTraceFile - - echo "Checkpoint completed at $(date +%H:%M:%S)" - echo "You may want to restrict write access to $tvDir now and give cad ownership of it." - echo "Run the following:" - echo " sudo chown -R cad:cad $tvDir" - echo " sudo chmod -R go-w $tvDir" -fi - diff --git a/linux/testvector-generation/genRecording.sh b/linux/testvector-generation/genRecording.sh deleted file mode 100755 index 2696253c5..000000000 --- a/linux/testvector-generation/genRecording.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash -imageDir=$RISCV/buildroot/output/images -tvDir=$RISCV/linux-testvectors -recordFile="$tvDir/all.qemu" -DEVICE_TREE=${imageDir}/wally-virt.dtb - -read -p "Warning: running this script will overwrite $recordFile -Would you like to proceed? (y/n) " -n 1 -r -echo -if [[ $REPLY =~ ^[Yy]$ ]] -then - if [ ! -d "$tvDir" ]; then - echo "Error: linux testvector directory $tvDir not found!">&2 - echo "Please create it. For example:">&2 - echo " sudo mkdir -p $tvDir">&2 - exit 1 - fi - test -w $tvDir - if [ ! $? -eq 0 ]; then - echo "Error: insuffcient write privileges for linux testvector directory $tvDir !">&2 - echo "Please chmod it. For example:">&2 - echo " sudo chmod -R a+rw $tvDir">&2 - exit 1 - fi - - echo "Launching QEMU in record mode!" - qemu-system-riscv64 \ - -M virt -m 256M -dtb $DEVICE_TREE \ - -nographic \ - -bios $imageDir/fw_jump.elf -kernel $imageDir/Image -append "root=/dev/vda ro" -initrd $imageDir/rootfs.cpio \ - -singlestep -rtc clock=vm -icount shift=0,align=off,sleep=on,rr=record,rrfile=$recordFile - - echo "genRecording.sh completed!" - echo "You may want to restrict write access to $tvDir now and give cad ownership of it." - echo "Run the following:" - echo " sudo chown -R cad:cad $tvDir" - echo " sudo chmod -R go-w $tvDir" -fi diff --git a/linux/testvector-generation/genTrace.sh b/linux/testvector-generation/genTrace.sh deleted file mode 100755 index 5d04592ce..000000000 --- a/linux/testvector-generation/genTrace.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/bash -tcpPort=1234 -imageDir=$RISCV/buildroot/output/images -tvDir=$RISCV/linux-testvectors -recordFile="$tvDir/all.qemu" -traceFile="$tvDir/all.txt" -trapsFile="$tvDir/traps.txt" -interruptsFile="$tvDir/interrupts.txt" -DEVICE_TREE=${imageDir}/wally-virt.dtb - -read -p "Warning: running this script will overwrite the contents of: - * $traceFile - * $trapsFile - * $interruptsFile -Would you like to proceed? (y/n) " -n 1 -r -echo -if [[ $REPLY =~ ^[Yy]$ ]] -then - if [ ! -d "$tvDir" ]; then - echo "Error: linux testvector directory $tvDir not found!">&2 - echo "Please create it. For example:">&2 - echo " sudo mkdir -p $tvDir">&2 - exit 1 - fi - test -w $tvDir - if [ ! $? -eq 0 ]; then - echo "Error: insuffcient write privileges for linux testvector directory $tvDir !">&2 - echo "Please chmod it. For example:">&2 - echo " sudo chmod -R a+rw $tvDir">&2 - exit 1 - fi - - touch $traceFile - touch $trapsFile - touch $interruptsFile - - # QEMU Simulation - echo "Launching QEMU in replay mode!" - (qemu-system-riscv64 \ - -M virt -m 256M -dtb $DEVICE_TREE \ - -nographic \ - -bios $imageDir/fw_jump.elf -kernel $imageDir/Image -append "root=/dev/vda ro" -initrd $imageDir/rootfs.cpio \ - -singlestep -rtc clock=vm -icount shift=0,align=off,sleep=on,rr=replay,rrfile=$recordFile \ - -d nochain,cpu,in_asm,int \ - 2>&1 >./qemu-serial | ./parseQEMUtoGDB.py | ./parseGDBtoTrace.py $trapsFile > $traceFile) - - ./filterTrapsToInterrupts.py $tvDir - - echo "genTrace.sh completed!" - echo "You may want to restrict write access to $tvDir now and give cad ownership of it." - echo "Run the following:" - echo " sudo chown -R cad:cad $tvDir" - echo " sudo chmod -R go-w $tvDir" -fi diff --git a/linux/testvector-generation/parseGDBtoTrace.py b/linux/testvector-generation/parseGDBtoTrace.py deleted file mode 100755 index 96ad464ed..000000000 --- a/linux/testvector-generation/parseGDBtoTrace.py +++ /dev/null @@ -1,243 +0,0 @@ -#!/usr/bin/env python3 -import sys, fileinput, re - -# Rose 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): - 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): - outString='{:016x} {:08x} {:25s}'.format(instr[0], instr[1], instr[2]) - if(len(GPR) != 0): - outString+=' GPR {}'.format(GPR) - if(instr[3] == 'load' or instr[3] == 'lr'): - outString+=' MemR {:016x} {:016x} {:016x}'.format(instr[5], 0, instr[7]) - if(instr[3] == 'store'): - outString+='\t\t\t MemW {:016x} {:016x} {:016x}'.format(instr[5], instr[6], 0) - if(len(CSR) != 0): - outString+=' CSR {}'.format(CSRStr) - else: - outString='{:x} {:x} {:s}'.format(instr[0], instr[1], instr[2].replace(' ', '_')) - if(len(GPR) != 0): - outString+=' GPR {}'.format(GPR) - if(instr[3] == 'load' or instr[3] == 'lr'): - outString+=' MemR {:x} {:x} {:x}'.format(instr[5], 0, instr[7]) - if(instr[3] == 'store'): - outString+=' MemW {:x} {:x} {:x}'.format(instr[5], instr[6], 0) - if(len(CSR) != 0): - outString+=' CSR {}'.format(CSRStr) - outString+='\n' - return outString - -# ========= -# Main Code -# ========= -# Parse argument for interrupt file -if len(sys.argv) != 2: - sys.exit('Error parseGDBtoTrace.py expects 1 arg:\n >') -interruptFname = sys.argv[1] -# 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, 'mscratch': 46, 'sscratch': 47, 'satp': 48} -# 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, 'mscratch': 0, 'sscratch': 0, 'satp': 0}, {}, None, None, None] - -#with open (InputFile, 'r') as InputFileFP: -#lines = InputFileFP.readlines() -lineNum = 0 -StartLine = 0 -EndLine = 0 -numInstrs = 0 -#instructions = [] -MemAdr = 0 -lines = [] -interrupts=open(interruptFname,'w') -interrupts.close() - -prevInstrOutString='' -currInstrOutString='' -for line in fileinput.input('-'): - if line.startswith('riscv_cpu_do_interrupt'): - with open(interruptFname,'a') as interrupts: - # Write line - # Example line: hart:0, async:0, cause:0000000000000002, epc:0x0000000080008548, tval:0x0000000000000000, desc=illegal_instruction - interrupts.write(line) - # Write instruction count - interrupts.write(str(numInstrs)+'\n') - # Convert line to rows of info for easier Verilog parsing - vals=line.strip('riscv_cpu_do_interrupt: ').strip('\n').split(',') - vals=[val.split(':')[-1].strip(' ') for val in vals] - vals=[val.split('=')[-1].strip(' ') for val in vals] - for val in vals: - interrupts.write(val+'\n') - continue - 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) - - prevInstrOutString = currInstrOutString - currInstrOutString = PrintInstr(MoveInstrToRegWriteLst) - # Remove duplicates - if (PreviousInstr[0] != CurrentInstr[0]) and (currInstrOutString != None): - sys.stdout.write(currInstrOutString) - numInstrs += 1 - if (numInstrs % 1e5 == 0): - sys.stderr.write('GDB trace parser reached '+str(numInstrs/1.0e6)+' million instrs.\n') - sys.stderr.flush() - lineNum += 1 - - -#for instruction in instructions[1::]: - - -#with open(OutputFile, 'w') as OutputFileFP: -# print('opened file') - - - diff --git a/linux/testvector-generation/parsePlicState.py b/linux/testvector-generation/parsePlicState.py deleted file mode 100755 index 5fb2b4eac..000000000 --- a/linux/testvector-generation/parsePlicState.py +++ /dev/null @@ -1,106 +0,0 @@ -#!/usr/bin/env python3 -import sys, os -from functools import reduce - -################ -# Helper Funcs # -################ - -def tokenize(string): - tokens = [] - token = '' - whitespace = 0 - prevWhitespace = 0 - for char in string: - prevWhitespace = whitespace - whitespace = char in ' \t\n' - if (whitespace): - if ((not prevWhitespace) and (token != '')): - tokens.append(token) - token = '' - else: - token = token + char - return tokens - -def strip0x(num): - return num[2:] - -def stripZeroes(num): - num = int(num,16) - return hex(num)[2:] - -############# -# Main Code # -############# -print("Begin parsing PLIC state.") - -# Parse Args -if len(sys.argv) != 2: - sys.exit('Error parsePlicState.py expects 1 arg: ') -outDir = sys.argv[1]+'/' -rawPlicStateFile = outDir+'plicStateGDB.txt' -if not os.path.exists(rawPlicStateFile): - sys.exit('Error input file '+rawPlicStateFile+'not found') - -with open(rawPlicStateFile, 'r') as rawPlicStateFile: - plicIntPriorityArray = [] # iterates over number of different sources - # 0x0C000004 thru 0x0C000010 - plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:] - # 0x0C000014 thru 0x0C000020 - plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:] - # 0x0C000024 thru 0x0C000030 - plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:] - # 0x0C000034 thru 0x0C000040 - plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:] - # 0x0C000044 thru 0x0C000050 - plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:] - # 0x0C000054 thru 0x0C000060 - plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:] - # 0x0C000064 thru 0x0C000070 - plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:] - # 0x0C000074 thru 0x0C000080 - plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:] - # 0x0C000084 thru 0x0C000090 - plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:] - # 0x0C000094 thru 0x0C0000a0 - plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:] - # 0x0C0000a4 thru 0x0C0000b0 - plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:] - # 0x0C0000b4 thru 0x0C0000c0 - plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:] - # 0x0C0000c4 thru 0x0C0000d0 - plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:] - # 0x0C0000d4 thru 0x0C0000e0 - plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:] - # 0x0C0000e4 thru 0x0C0000f0 - plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:] - # 0x0C0000f4 thru 0x0C0000fc - plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:] - - plicIntEnableArray = [] # iterates over number of different contexts - # 0x0C020000 thru 0x0C020004 - plicIntEnable = tokenize(rawPlicStateFile.readline())[1:] - plicIntEnable = map(strip0x,plicIntEnable) - plicIntEnableArray.append(reduce(lambda x,y: y+x,plicIntEnable)) - # 0x0C020080 thru 0x0C020084 - plicIntEnable = tokenize(rawPlicStateFile.readline())[1:] - plicIntEnable = map(strip0x,plicIntEnable) - plicIntEnableArray.append(reduce(lambda x,y: y+x,plicIntEnable)) - - plicIntPriorityThresholdArray = [] # iterates over number of different contexts - # 0x0C200000 - plicIntPriorityThresholdArray += tokenize(rawPlicStateFile.readline())[1:] - # 0x0C201000 - plicIntPriorityThresholdArray += tokenize(rawPlicStateFile.readline())[1:] - -with open(outDir+'checkpoint-PLIC_INT_PRIORITY', 'w') as outFile: - for word in plicIntPriorityArray: - outFile.write(stripZeroes(word[2:])+'\n') -with open(outDir+'checkpoint-PLIC_INT_ENABLE', 'w') as outFile: - for word in plicIntEnableArray: - outFile.write(stripZeroes(word[2:])+'\n') -with open(outDir+'checkpoint-PLIC_THRESHOLD', 'w') as outFile: - for word in plicIntPriorityThresholdArray: - outFile.write(stripZeroes(word[2:])+'\n') - -print("Finished parsing PLIC state!") diff --git a/linux/testvector-generation/parseQEMUtoGDB.py b/linux/testvector-generation/parseQEMUtoGDB.py deleted file mode 100755 index 457085a1b..000000000 --- a/linux/testvector-generation/parseQEMUtoGDB.py +++ /dev/null @@ -1,145 +0,0 @@ -#!/usr/bin/env python3 -import fileinput, sys - -parseState = "idle" -beginPageFault = 0 -inPageFault = 0 -endPageFault = 0 -CSRs = {} -pageFaultCSRs = {} -regs = {} -pageFaultRegs = {} -instrs = {} -instrCount = 0 -returnAdr = 0 -sys.stderr.write("reminder: parse_qemu.py takes input from stdin\n") - -def printPC(l): - global parseState, inPageFault, CSRs, pageFaultCSRs, regs, pageFaultCSRs, instrs, instrCount - if not inPageFault: - inst = l.split() - if len(inst) > 3: - print(f'=> {inst[1]}:\t{inst[2]} {inst[3]}') - else: - print(f'=> {inst[1]}:\t{inst[2]}') - print(f'{inst[0]} 0x{inst[1]}') - instrCount += 1 - if ((instrCount % 100000) == 0): - sys.stderr.write("QEMU parser reached "+str(instrCount)+" instrs\n") - -def printCSRs(): - global parseState, inPageFault, CSRs, pageFaultCSRs, regs, pageFaultCSRs, instrs - global interrupt_line - if not inPageFault: - for (csr,val) in CSRs.items(): - print('{}{}{:#x} {}'.format(csr, ' '*(15-len(csr)), val, val)) - print('-----') # end of current instruction - if len(interrupt_line)>0: # squish interrupts in between instructions - print(interrupt_line) - interrupt_line="" - -def parseCSRs(l): - global parseState, inPageFault, CSRs, pageFaultCSRs, regs, pageFaultCSRs, instrs - if l.strip() and (not l.startswith("Disassembler")) and (not l.startswith("Please")): - # If we've hit the register file - if l.startswith(' x0/zero'): - parseState = "regFile" - if not inPageFault: - instr = instrs[CSRs["pc"]] - printPC(instr) - parseRegs(l) - # If we've hit a CSR - else: - csr = l.split()[0] - val = int(l.split()[1],16) - # Commented out this conditional because the pageFault instrs don't corrupt CSRs - #if inPageFault: - # Not sure if these CSRs should be updated or not during page fault. - #if l.startswith("mstatus") or l.startswith("mepc") or l.startswith("mcause") or l.startswith("mtval") or l.startswith("sepc") or l.startswith("scause") or l.startswith("stval"): - # We do update some CSRs - # CSRs[csr] = val - #else: - # Others we preserve until changed later - # pageFaultCSRs[csr] = val - #elif pageFaultCSRs and (csr in pageFaultCSRs): - # if (val != pageFaultCSRs[csr]): - # del pageFaultCSRs[csr] - # CSRs[csr] = val - #else: - # CSRs[csr] = val - # - # However SEPC and STVAL do get corrupted upon exiting - if endPageFault and ((csr == 'sepc') or (csr == 'stval')): - CSRs[csr] = returnAdr - pageFaultCSRs[csr] = val - elif pageFaultCSRs and (csr in pageFaultCSRs): - if (val != pageFaultCSRs[csr]): - del pageFaultCSRs[csr] - CSRs[csr] = val - else: - CSRs[csr] = val - -def parseRegs(l): - global parseState, inPageFault, CSRs, pageFaultCSRs, regs, pageFaultCSRs, instrs, pageFaultRegs - if "pc" in l: - printCSRs() - # New non-disassembled instruction - parseState = "CSRs" - parseCSRs(l) - elif l.startswith('--------'): - # End of disassembled instruction - printCSRs() - parseState = "idle" - else: - s = l.split() - for i in range(0,len(s),2): - if '/' in s[i]: - reg = s[i].split('/')[1] - val = int(s[i+1], 16) - if inPageFault: - pageFaultRegs[reg] = val - else: - if pageFaultRegs and (reg in pageFaultRegs): - if (val != pageFaultRegs[reg]): - del pageFaultRegs[reg] - regs[reg] = val - else: - regs[reg] = val - val = regs[reg] - print('{}{}{:#x} {}'.format(reg, ' '*(15-len(reg)), val, val)) - else: - sys.stderr.write("Whoops. Expected a list of reg file regs; got:\n"+l) - -############# -# Main Code # -############# -interrupt_line="" -for l in fileinput.input(): - #sys.stderr.write(l) - if l.startswith('riscv_cpu_do_interrupt'): - sys.stderr.write(l) - interrupt_line = l.strip('\n') - elif l.startswith('qemu-system-riscv64: QEMU: Terminated via GDBstub'): - break - elif l.startswith('IN:'): - # New disassembled instr - parseState = "instr" - elif (parseState == "instr") and l.startswith('0x'): - # New instruction - if "out of bounds" in l: - sys.stderr.write("Detected QEMU page fault error\n") - beginPageFault = not inPageFault - if beginPageFault: - returnAdr = int(l.split()[0][2:-1], 16) - sys.stderr.write('Saving SEPC of '+hex(returnAdr)+'\n') - inPageFault = 1 - else: - endPageFault = inPageFault - inPageFault = 0 - adr = int(l.split()[0][2:-1], 16) - instrs[adr] = l - parseState = "CSRs" - elif parseState == "CSRs": - parseCSRs(l) - elif parseState == "regFile": - parseRegs(l) diff --git a/linux/testvector-generation/parseState.py b/linux/testvector-generation/parseState.py deleted file mode 100755 index f54ba0f78..000000000 --- a/linux/testvector-generation/parseState.py +++ /dev/null @@ -1,99 +0,0 @@ -#!/usr/bin/env python3 -import sys, os - -################ -# Helper Funcs # -################ - -def tokenize(string): - tokens = [] - token = '' - whitespace = 0 - prevWhitespace = 0 - for char in string: - prevWhitespace = whitespace - whitespace = char in ' \t\n' - if (whitespace): - if ((not prevWhitespace) and (token != '')): - tokens.append(token) - token = '' - else: - token = token + char - return tokens - -############# -# Main Code # -############# -print("Begin parsing CPU state.") - -# Parse Args -if len(sys.argv) != 2: - sys.exit('Error parseState.py expects 1 arg:\n parseState.py ') -outDir = sys.argv[1]+'/' -stateGDBpath = outDir+'stateGDB.txt' -if not os.path.exists(stateGDBpath): - sys.exit('Error input file '+stateGDBpath+'not found') - -singleCSRs = ['pc','mip','mie','mscratch','mcause','mepc','mtvec','medeleg','mideleg','sscratch','scause','sepc','stvec','sedeleg','sideleg','satp','mstatus','priv','sie','sip','sstatus'] -# priv (current privilege mode) isn't technically a CSR but we can log it with the same machinery -thirtyTwoBitCSRs = ['mcounteren','scounteren'] -listCSRs = ['hpmcounter','pmpaddr'] -pmpcfg = ['pmpcfg'] - -# Initialize List CSR files to empty -# (because later we'll open them in append mode) -for csr in listCSRs+pmpcfg: - outFileName = 'checkpoint-'+csr.upper() - outFile = open(outDir+outFileName, 'w') - outFile.close() - -# Initial State for Main Loop -currState = 'regFile' -regFileIndex = 0 -outFileName = 'checkpoint-RF' -outFile = open(outDir+outFileName, 'w') - -# Main Loop -with open(stateGDBpath, 'r') as stateGDB: - for line in stateGDB: - line = tokenize(line) - name = line[0] - val = line[1][2:] - if (currState == 'regFile'): - if (regFileIndex == 0 and name != 'zero'): - print('Whoops! Expected regFile registers to come first, starting with zero') - exit(1) - if (name != 'zero'): - # Wally doesn't need to know zero=0 - outFile.write(val+'\n') - regFileIndex += 1 - if (regFileIndex == 32): - outFile.close() - currState = 'CSRs' - elif (currState == 'CSRs'): - if name in singleCSRs: - outFileName = 'checkpoint-'+name.upper() - outFile = open(outDir+outFileName, 'w') - outFile.write(val+'\n') - outFile.close() - elif name in thirtyTwoBitCSRs: - outFileName = 'checkpoint-'+name.upper() - outFile = open(outDir+outFileName, 'w') - val = int(val,16) & 0xffffffff - outFile.write(hex(val)[2:]+'\n') - outFile.close() - elif name.strip('0123456789') in listCSRs: - outFileName = 'checkpoint-'+name.upper().strip('0123456789') - outFile = open(outDir+outFileName, 'a') - outFile.write(val+'\n') - outFile.close() - elif name.strip('0123456789') in pmpcfg: - outFileName = 'checkpoint-'+name.upper().strip('0123456789') - outFile = open(outDir+outFileName, 'a') - fourPmp = int(val,16) - for i in range(0,4): - byte = (fourPmp >> 8*i) & 0xff - outFile.write(hex(byte)[2:]+'\n') - outFile.close() - -print("Finished parsing CPU state!") diff --git a/linux/testvector-generation/parseUartState.py b/linux/testvector-generation/parseUartState.py deleted file mode 100755 index 82028d528..000000000 --- a/linux/testvector-generation/parseUartState.py +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env python3 -import sys, os - -################ -# Helper Funcs # -################ - -def tokenize(string): - tokens = [] - token = '' - whitespace = 0 - prevWhitespace = 0 - for char in string: - prevWhitespace = whitespace - whitespace = char in ' \t\n' - if (whitespace): - if ((not prevWhitespace) and (token != '')): - tokens.append(token) - token = '' - else: - token = token + char - return tokens - -############# -# Main Code # -############# -print("Begin parsing UART state.") - -# Parse Args -if len(sys.argv) != 2: - sys.exit('Error parseUartState.py expects 1 arg: ') -outDir = sys.argv[1]+'/' -rawUartStateFile = outDir+'uartStateGDB.txt' -if not os.path.exists(rawUartStateFile): - sys.exit('Error input file '+rawUartStateFile+'not found') - -with open(rawUartStateFile, 'r') as rawUartStateFile: - uartBytes = [] - for i in range(0,8): - uartBytes += tokenize(rawUartStateFile.readline())[1:] -with open(outDir+'checkpoint-UART_IER', 'w') as outFile: - outFile.write(uartBytes[1][2:]) -with open(outDir+'checkpoint-UART_LCR', 'w') as outFile: - outFile.write(uartBytes[3][2:]) -with open(outDir+'checkpoint-UART_MCR', 'w') as outFile: - outFile.write(uartBytes[4][2:]) -with open(outDir+'checkpoint-UART_SCR', 'w') as outFile: - outFile.write(uartBytes[7][2:]) - -print("Finished parsing UART state!")