diff --git a/tests/linux-testgen/testvector-generation/Makefile b/tests/linux-testgen/testvector-generation/Makefile new file mode 100644 index 00000000..8f9bff4b --- /dev/null +++ b/tests/linux-testgen/testvector-generation/Makefile @@ -0,0 +1,13 @@ +SHELL = /bin/sh + +CFLAG = -Wall -g +CC = clang + +all: fixBinMem + +fixBinMem: fixBinMem.c + ${CC} ${CFLAGS} fixBinMem.c -o fixBinMem + chmod +x fixBinMem + +clean: + -rm -f fixBinMem diff --git a/tests/linux-testgen/testvector-generation/fixBinMem b/tests/linux-testgen/testvector-generation/fixBinMem new file mode 100755 index 00000000..563ed988 Binary files /dev/null and b/tests/linux-testgen/testvector-generation/fixBinMem differ diff --git a/tests/linux-testgen/testvector-generation/fixBinMem.c b/tests/linux-testgen/testvector-generation/fixBinMem.c new file mode 100644 index 00000000..fe071008 --- /dev/null +++ b/tests/linux-testgen/testvector-generation/fixBinMem.c @@ -0,0 +1,33 @@ +#include +#include +#include +int main(int argc, char *argv[]) { + if (argc < 3){ + fprintf(stderr, "Expected 2 arguments: \n"); + exit(1); + } + char* rawGDBfilePath = argv[1]; + FILE* rawGDBfile; + if ((rawGDBfile = fopen(rawGDBfilePath,"rb"))==NULL) { + fprintf(stderr, "File not found: %s\n",rawGDBfilePath); + exit(1); + } + char* outFilePath = argv[2]; + FILE* outFile = fopen(outFilePath,"w"); + uint64_t qemuWord; + uint64_t verilogWord; + int bytesReturned=0; + do { + bytesReturned=fread(&qemuWord, 8, 1, rawGDBfile); + verilogWord = (((qemuWord>>0 )&0xff)<<56 | + ((qemuWord>>8 )&0xff)<<48 | + ((qemuWord>>16)&0xff)<<40 | + ((qemuWord>>24)&0xff)<<32 | + ((qemuWord>>32)&0xff)<<24 | + ((qemuWord>>40)&0xff)<<16 | + ((qemuWord>>48)&0xff)<<8 | + ((qemuWord>>56)&0xff)<<0); + fwrite(&verilogWord, 8, 1, outFile); + } while(bytesReturned!=0); + return 0; +} diff --git a/tests/linux-testgen/testvector-generation/fix_mem.py b/tests/linux-testgen/testvector-generation/fixTxtMem.py similarity index 100% rename from tests/linux-testgen/testvector-generation/fix_mem.py rename to tests/linux-testgen/testvector-generation/fixTxtMem.py diff --git a/tests/linux-testgen/testvector-generation/genCheckpoint.gdb b/tests/linux-testgen/testvector-generation/genCheckpoint.gdb index 92630698..a7744139 100755 --- a/tests/linux-testgen/testvector-generation/genCheckpoint.gdb +++ b/tests/linux-testgen/testvector-generation/genCheckpoint.gdb @@ -13,7 +13,7 @@ define genCheckpoint set $checkPC=$arg3 set $checkPCoccurences=$arg4 eval "set $statePath = \"%s/stateGDB.txt\"", $statePath - eval "set $ramPath = \"%s/ramGDB.txt\"", $ramPath + eval "set $ramPath = \"%s/ramGDB.bin\"", $ramPath # Connect to QEMU session eval "target extended-remote :%d",$tcpPort @@ -46,10 +46,7 @@ define genCheckpoint # Log main memory to a file printf "GDB storing RAM to %s\n", $ramPath - eval "set logging file %s", $ramPath - set logging on - x/134217728xb 0x80000000 - set logging off + eval "dump binary memory %s 0x80000000 0xffffffff", $ramPath kill q diff --git a/tests/linux-testgen/testvector-generation/genCheckpoint.sh b/tests/linux-testgen/testvector-generation/genCheckpoint.sh index cca7486e..ca4bcf49 100755 --- a/tests/linux-testgen/testvector-generation/genCheckpoint.sh +++ b/tests/linux-testgen/testvector-generation/genCheckpoint.sh @@ -3,7 +3,7 @@ source genSettings.sh tcpPort=1236 -instrs=450000000 +instrs=8500000 checkOutDir="$outDir/checkpoint$instrs" checkIntermedDir="$checkOutDir/intermediate-outputs" @@ -15,24 +15,35 @@ if [[ $REPLY =~ ^[Yy]$ ]] then mkdir -p $checkOutDir mkdir -p $checkIntermedDir + + # Identify instruction in trace instr=$(sed "${instrs}q;d" "../linux-testvectors/all.txt") - echo "Found ${instrs}th instr: ${instr}." + echo "Found ${instrs}th instr: ${instr}" pc=$(echo $instr | cut -d " " -f1) asm=$(echo $instr | cut -d " " -f2) occurences=$(($(head -$instrs "../linux-testvectors/all.txt" | grep -c "${pc} ${asm}")-1)) echo "It occurs ${occurences} times before the ${instrs}th instr." - # Simulate QEMU, parse QEMU trace, run GDB script which logs a bunch of data at the checkpoint + + # GDB+QEMU + echo "Starting QEMU with attached GDB script at $(date +%H:%M:%S)" ($customQemu \ -M virt \ -nographic \ -bios $imageDir/fw_jump.elf -kernel $imageDir/Image -append "root=/dev/vda ro" -initrd $imageDir/rootfs.cpio \ -singlestep -rtc clock=vm -icount shift=1,align=off,sleep=on,rr=replay,rrfile="$intermedDir/$recordFile" \ -gdb tcp::$tcpPort -S) \ - & riscv64-unknown-elf-gdb -x genCheckpoint.gdb -ex "genCheckpoint $tcpPort $instrs \"$checkIntermedDir\" \"$pc\" $occurences" + & riscv64-unknown-elf-gdb --quiet \ + -x genCheckpoint.gdb -ex "genCheckpoint $tcpPort $instrs \"$checkIntermedDir\" \"$pc\" $occurences" + echo "Completed GDB script completed at $(date +%H:%M:%S)" + # Post-Process GDB outputs ./parseState.py "$checkOutDir" - ./fix_mem.py "$checkIntermedDir/ramGDB.txt" "$checkOutDir/ram.txt" - tail -n+$(($instrs+1)) "$outDir/$traceFile" > "$checkOutDir/$traceFile" + echo "Changing Endianness at $(date +%H:%M:%S)" + make + ./fixBinMem "$checkIntermedDir/ramGDB.bin" "$checkOutDir/ram.bin" + echo "Creating truncated trace at $(date +%H:%M:%S)" + tail -n+$instrs "$outDir/$traceFile" > "$checkOutDir/$traceFile" + echo "Checkpoint completed at $(date +%H:%M:%S)" else echo "You can change the number of instructions by editing the \"instrs\" variable in this script." echo "Have a nice day!" diff --git a/tests/linux-testgen/testvector-generation/genInitMem.sh b/tests/linux-testgen/testvector-generation/genInitMem.sh index 56b30a45..f82556f5 100755 --- a/tests/linux-testgen/testvector-generation/genInitMem.sh +++ b/tests/linux-testgen/testvector-generation/genInitMem.sh @@ -16,8 +16,8 @@ then & riscv64-unknown-elf-gdb -quiet -x genInitMem.gdb -ex "genInitMem $tcpPort \"$intermedDir\"" echo "Translating Mem from GDB to Questa format" - ./fix_mem.py "$intermedDir/bootmemGDB.txt" "$outDir/bootmem.txt" - ./fix_mem.py "$intermedDir/ramGDB.txt" "$outDir/ram.txt" + ./fixTxtMem.py "$intermedDir/bootmemGDB.txt" "$outDir/bootmem.txt" + ./fixTxtMem.py "$intermedDir/ramGDB.txt" "$outDir/ram.txt" echo "Done" echo "Creating debugging objdump of linux image" diff --git a/tests/linux-testgen/testvector-generation/genSettings.sh b/tests/linux-testgen/testvector-generation/genSettings.sh index 57bd7765..59490e35 100755 --- a/tests/linux-testgen/testvector-generation/genSettings.sh +++ b/tests/linux-testgen/testvector-generation/genSettings.sh @@ -4,7 +4,7 @@ # *** on the long term we'll want to include QEMU in the addins folder export customQemu="/courses/e190ax/qemu_sim/rv64_initrd/qemu_experimental/qemu/build/qemu-system-riscv64" export imageDir="../buildroot-image-output" -export outDir="../linux-testvectors-experimental" +export outDir="../linux-testvectors" export intermedDir="$outDir/intermediate-outputs" export traceFile="all.txt" export recordFile="all.qemu" diff --git a/wally-pipelined/testbench/testbench-linux.sv b/wally-pipelined/testbench/testbench-linux.sv index 72adf589..68bf64ad 100644 --- a/wally-pipelined/testbench/testbench-linux.sv +++ b/wally-pipelined/testbench/testbench-linux.sv @@ -280,7 +280,9 @@ module testbench(); `INIT_CHECKPOINT_VAL(SATP, [`XLEN-1:0]); `MAKE_CHECKPOINT_INIT_SIGNAL(MSTATUS, [`XLEN-1:0],0,0); - assign initPriv = (initPC[0][`XLEN-1]) ? 2'h2 : 2'h3; // *** a hacky way to detect initial privilege level + integer ramFile; + integer readResult; + assign initPriv = (initPC[0][`XLEN-1]) ? 2'h1 : 2'h3; // *** a hacky way to detect initial privilege level initial begin force dut.hart.priv.SwIntM = 0; force dut.hart.priv.TimerIntM = 0; @@ -297,7 +299,10 @@ module testbench(); end else begin // checkpoint $sformat(checkpointDir,"checkpoint%0d/",CHECKPOINT); checkpointDir = {`LINUX_TEST_VECTORS,checkpointDir}; - $readmemh({checkpointDir,"ram.txt"}, dut.uncore.dtim.RAM); + //$readmemh({checkpointDir,"ram.txt"}, dut.uncore.dtim.RAM); + ramFile = $fopen({checkpointDir,"ram.bin"}, "rb"); + readResult = $fread(dut.uncore.dtim.RAM,ramFile); + $fclose(ramFile); data_file_all = $fopen({checkpointDir,"all.txt"}, "r"); InstrCountW = CHECKPOINT; // manual checkpoint initializations that don't neatly fit into MACRO