From 6625f74a8510d0bcc114b741811717da9c653ec6 Mon Sep 17 00:00:00 2001 From: bbracker Date: Thu, 17 Jun 2021 00:50:02 -0400 Subject: [PATCH] still not sure if QEMU workaround is correct, but here is all linux progress so far --- .gitignore | 4 +- .../linux-testgen/logAllBuildroot.sh | 13 +- .../linux-testgen/parse_gdb_output.py | 128 +++++++++--------- wally-pipelined/linux-testgen/parse_qemu.py | 14 +- 4 files changed, 81 insertions(+), 78 deletions(-) diff --git a/.gitignore b/.gitignore index 7f65a18a..1b19857d 100644 --- a/.gitignore +++ b/.gitignore @@ -16,8 +16,8 @@ wlft* /imperas-riscv-tests/FunctionRadix.addr /imperas-riscv-tests/ProgramMap.txt /imperas-riscv-tests/logs -/wally-pipelined/busybear-testgen/gdbcombined.txt -/wally-pipelined/busybear-testgen/first10.txt +/wally-pipelined/linux-testgen/qemu_output.txt +/wally-pipelined/linux-testgen/qemu_in_gdb_format.txt *.o *.d testsBP/*/*/*.elf* diff --git a/wally-pipelined/linux-testgen/logAllBuildroot.sh b/wally-pipelined/linux-testgen/logAllBuildroot.sh index dfb5205a..df8b506a 100755 --- a/wally-pipelined/linux-testgen/logAllBuildroot.sh +++ b/wally-pipelined/linux-testgen/logAllBuildroot.sh @@ -2,25 +2,26 @@ # Uncomment this version for GDB/QEMU debugging # - Opens up GDB interactively # - Logs raw QEMU output to qemu_output.txt -#(qemu-system-riscv64 -M virt -nographic -bios /courses/e190ax/qemu_sim/rv64_initrd/buildroot_experimental/output/images/fw_jump.elf -kernel /courses/e190ax/qemu_sim/rv64_initrd/buildroot_experimental/output/images/Image -append "root=/dev/vda ro" -initrd /courses/e190ax/qemu_sim/rv64_initrd/buildroot_experimental/output/images/rootfs.cpio -d nochain,cpu,in_asm -serial /dev/null -singlestep -s -S 2> /mnt/scratch/wally_linux_output/qemu_output.txt) & riscv64-unknown-elf-gdb +#(qemu-system-riscv64 -M virt -nographic -bios /courses/e190ax/qemu_sim/rv64_initrd/buildroot_experimental/output/images/fw_jump.elf -kernel /courses/e190ax/qemu_sim/rv64_initrd/buildroot_experimental/output/images/Image -append "root=/dev/vda ro" -initrd /courses/e190ax/qemu_sim/rv64_initrd/buildroot_experimental/output/images/rootfs.cpio -d nochain,cpu,in_asm -serial /dev/null -singlestep -s -S 2> qemu_output.txt) & riscv64-unknown-elf-gdb # Uncomment this version to generate qemu_output.txt # - Uses GDB script # - Logs raw QEMU output to qemu_output.txt -#(qemu-system-riscv64 -M virt -nographic -bios /courses/e190ax/qemu_sim/rv64_initrd/buildroot_experimental/output/images/fw_jump.elf -kernel /courses/e190ax/qemu_sim/rv64_initrd/buildroot_experimental/output/images/Image -append "root=/dev/vda ro" -initrd /courses/e190ax/qemu_sim/rv64_initrd/buildroot_experimental/output/images/rootfs.cpio -d nochain,cpu,in_asm -serial /dev/null -singlestep -s -S 2>/mnt/scratch/wally_linux_output/qemu_output.txt) & riscv64-unknown-elf-gdb -x gdbinit_qemulog +#(qemu-system-riscv64 -M virt -nographic -bios /courses/e190ax/qemu_sim/rv64_initrd/buildroot_experimental/output/images/fw_jump.elf -kernel /courses/e190ax/qemu_sim/rv64_initrd/buildroot_experimental/output/images/Image -append "root=/dev/vda ro" -initrd /courses/e190ax/qemu_sim/rv64_initrd/buildroot_experimental/output/images/rootfs.cpio -d nochain,cpu,in_asm -serial /dev/null -singlestep -s -S 2>qemu_output.txt) & riscv64-unknown-elf-gdb -x gdbinit_qemulog_debug # Uncomment this version for parse_qemu.py debugging # - Uses qemu_output.txt # - Makes qemu_in_gdb_format.txt # - Logs parse_qemu.py's simulated gdb output to qemu_in_gdb_format.txt -#cat /mnt/scratch/wally_linux_output/qemu_output.txt | ./parse_qemu.py >/mnt/scratch/wally_linux_output/qemu_in_gdb_format.txt +#cat qemu_output.txt | ./parse_qemu.py >qemu_in_gdb_format.txt +#cat qemu_output.txt | ./parse_qemu.py | ./parse_gdb_output.py "/courses/e190ax/buildroot_boot/" # Uncomment this version for parse_gdb_output.py debugging # - Uses qemu_in_gdb_format.txt # - Logs info needed by buildroot testbench -cat /mnt/scratch/wally_linux_output/qemu_in_gdb_format.txt | ./parse_gdb_output.py "/courses/e190ax/buildroot_boot/" +#cat qemu_in_gdb_format.txt | ./parse_gdb_output.py "/courses/e190ax/buildroot_boot/" # =========== Just Do the Thing ========== -# Uncomment this version for the whole thing (if it works ha ha_ +# Uncomment this version for the whole thing # - Logs info needed by buildroot testbench -#(qemu-system-riscv64 -M virt -nographic -bios /courses/e190ax/qemu_sim/rv64_initrd/buildroot_experimental/output/images/fw_jump.elf -kernel /courses/e190ax/qemu_sim/rv64_initrd/buildroot_experimental/output/images/Image -append "root=/dev/vda ro" -initrd /courses/e190ax/qemu_sim/rv64_initrd/buildroot_experimental/output/images/rootfs.cpio -d nochain,cpu,in_asm -serial /dev/null -singlestep -s -S 2>&1 >/dev/null | pv -l | ./parse_qemu.py | ./parse_gdb_output.py "/courses/e190ax/buildroot_boot/") & riscv64-unknown-elf-gdb -x gdbinit_qemulog +(qemu-system-riscv64 -M virt -nographic -bios /courses/e190ax/qemu_sim/rv64_initrd/buildroot_experimental/output/images/fw_jump.elf -kernel /courses/e190ax/qemu_sim/rv64_initrd/buildroot_experimental/output/images/Image -append "root=/dev/vda ro" -initrd /courses/e190ax/qemu_sim/rv64_initrd/buildroot_experimental/output/images/rootfs.cpio -d nochain,cpu,in_asm -serial /dev/null -singlestep -s -S 2>&1 >/dev/null | pv -l | ./parse_qemu.py | ./parse_gdb_output.py "/courses/e190ax/buildroot_boot/") & riscv64-unknown-elf-gdb -x gdbinit_qemulog diff --git a/wally-pipelined/linux-testgen/parse_gdb_output.py b/wally-pipelined/linux-testgen/parse_gdb_output.py index 5ae62b32..739a97e3 100755 --- a/wally-pipelined/linux-testgen/parse_gdb_output.py +++ b/wally-pipelined/linux-testgen/parse_gdb_output.py @@ -27,7 +27,7 @@ try: readType = '' lastReadType = '' readLoc = '' - instrStart = -1 + lineOffset = -1 lastRegs = '' curRegs = '' storeReg = '' @@ -40,10 +40,12 @@ try: for l in fileinput.input('-'): l = l.split("#")[0].rstrip() if l.startswith('=>'): + # Begin new instruction instrs += 1 storeAMO = '' if instrs % 10000 == 0: print(instrs) + # Instr in human assembly wPC.write('{} ***\n'.format(' '.join(l.split(':')[1].split()[0:2]))) if '\tld' in l or '\tlw' in l or '\tlh' in l or '\tlb' in l: currentRead = l.split()[-1].split(',')[0] @@ -53,7 +55,6 @@ try: readLoc = l.split()[-1].split(',')[1].split('(')[1][:-1] readType = l.split()[-2] if 'amo' in l: - #print(l) currentRead = l.split()[-1].split(',')[0] readOffset = "0" readLoc = l.split()[-1].split('(')[1][:-1] @@ -63,7 +64,6 @@ try: storeReg = l.split()[-1].split(',')[1] storeAMO = l.split()[-2] if '\tsd' in l or '\tsw' in l or '\tsh' in l or '\tsb' in l: - #print(l) s = l.split('#')[0].split()[-1] storeReg = s.split(',')[0] if len(s.split(',')) < 2: @@ -74,17 +74,19 @@ try: print(l) storeOffset = s.split(',')[1].split('(')[0] storeLoc = s.split(',')[1].split('(')[1][:-1] - instrStart = 0 - elif instrStart != -1: - instrStart += 1 - if instrStart == 1: + lineOffset = 0 + elif lineOffset != -1: + lineOffset += 1 + if lineOffset == 1: + # Instr in hex comes one line after the instruction wPC.write('{}\n'.format(l.split()[-1][2:])) - elif instrStart < 34: + # As well as instr address + wPC.write('{}\n'.format(l.split()[0][2:].strip(":"))) + elif lineOffset <= (1+32): + # Next 32 lines are the Register File if lastRead == l.split()[0]: readData = int(l.split()[1][2:], 16) readData <<= (8 * (lastReadLoc % 8)) - #if(lastReadLoc % 8 != 0 and ('lw' in lastReadType or 'lb' in lastReadType)): - # readData <<= 32 wMem.write('{:x}\n'.format(readData)) if readLoc == l.split()[0]: readLoc = l.split()[1][2:] @@ -92,16 +94,12 @@ try: storeReg = l.split()[1] if storeLoc == l.split()[0]: storeLoc = l.split()[1][2:] - if instrStart > 2: - #print(l) - #print(instrStart) + if lineOffset > (1+1): + # Start logging x1 onwards (we don't care about x0) curRegs += '{}\n'.format(l.split()[1][2:]) - elif instrStart < 35: - #print("----------") - #print(l.split()[1][2:]) - wPC.write('{}\n'.format(l.split()[1][2:])) - #print(l.split()[1][2:]) - if any([c == l.split()[0] for c in csrs]): + #elif "pc" in l: + # wPC.write('{}\n'.format(l.split()[1][2:])) + if any([csr == l.split()[0] for csr in csrs]): if l.split()[0] in curCSRs: if curCSRs[l.split()[0]] != l.split()[1]: if firstCSR: @@ -112,51 +110,53 @@ try: wCSRs.write('{}\n{}\n'.format(l.split()[0], l.split()[1][2:])) curCSRs[l.split()[0]] = l.split()[1] if '-----' in l: # end of each cycle - if curRegs != lastRegs: - if lastRegs == '': - wReg.write(curRegs) - else: - for i in range(32): - if curRegs.split('\n')[i] != lastRegs.split('\n')[i]: - wReg.write('{}\n'.format(i+1)) - wReg.write('{}\n'.format(curRegs.split('\n')[i])) - break - lastRegs = curRegs - if lastAMO != '': - if 'amoadd' in lastAMO: - lastStoreReg = hex(int(lastStoreReg[2:], 16) + readData)[2:] - elif 'amoand' in lastAMO: - lastStoreReg = hex(int(lastStoreReg[2:], 16) & readData)[2:] - elif 'amoor' in lastAMO: - lastStoreReg = hex(int(lastStoreReg[2:], 16) | readData)[2:] - elif 'amoswap' in lastAMO: - lastStoreReg = hex(int(lastStoreReg[2:], 16))[2:] - else: - print(lastAMO) - exit() - wMemW.write('{}\n'.format(lastStoreReg)) - wMemW.write('{:x}\n'.format(int(lastStoreLoc, 16))) - if storeReg != '' and storeOffset != '' and storeLoc != '' and storeAMO == '': - storeLocOffset = int(storeOffset,10) + int(storeLoc, 16) - #wMemW.write('{:x}\n'.format(int(storeReg, 16) << (8 * (storeLocOffset % 8)))) - wMemW.write('{}\n'.format(storeReg[2:])) - wMemW.write('{:x}\n'.format(storeLocOffset)) - if readOffset != '' and readLoc != '': - wMem.write('{:x}\n'.format(int(readOffset,10) + int(readLoc, 16))) - lastReadLoc = int(readOffset,10) + int(readLoc, 16) - lastReadType = readType - readOffset = '' - readLoc = '' - curRegs = '' - instrStart = -1 - lastRead = currentRead - currentRead = '' - lastStoreReg = storeReg - lastStoreLoc = storeLoc - storeReg = '' - storeOffset = '' - storeLoc = '' - lastAMO = storeAMO + if curRegs != lastRegs: + if lastRegs == '': + wReg.write(curRegs) + else: + for i in range(32): + if curRegs.split('\n')[i] != lastRegs.split('\n')[i]: + wReg.write('{}\n'.format(i+1)) + wReg.write('{}\n'.format(curRegs.split('\n')[i])) + break + lastRegs = curRegs + if lastAMO != '': + if 'amoadd' in lastAMO: + lastStoreReg = hex(int(lastStoreReg[2:], 16) + readData)[2:] + elif 'amoand' in lastAMO: + lastStoreReg = hex(int(lastStoreReg[2:], 16) & readData)[2:] + elif 'amoor' in lastAMO: + lastStoreReg = hex(int(lastStoreReg[2:], 16) | readData)[2:] + elif 'amoswap' in lastAMO: + lastStoreReg = hex(int(lastStoreReg[2:], 16))[2:] + else: + print(lastAMO) + exit() + #print('lastStoreReg {}\n'.format(lastStoreReg)) + #print('lastStoreLoc '+str(lastStoreLoc)) + wMemW.write('{}\n'.format(lastStoreReg)) + wMemW.write('{:x}\n'.format(int(lastStoreLoc, 16))) + if storeReg != '' and storeOffset != '' and storeLoc != '' and storeAMO == '': + storeLocOffset = int(storeOffset,10) + int(storeLoc, 16) + #wMemW.write('{:x}\n'.format(int(storeReg, 16) << (8 * (storeLocOffset % 8)))) + wMemW.write('{}\n'.format(storeReg[2:])) + wMemW.write('{:x}\n'.format(storeLocOffset)) + if readOffset != '' and readLoc != '': + wMem.write('{:x}\n'.format(int(readOffset,10) + int(readLoc, 16))) + lastReadLoc = int(readOffset,10) + int(readLoc, 16) + lastReadType = readType + readOffset = '' + readLoc = '' + curRegs = '' + lineOffset = -1 + lastRead = currentRead + currentRead = '' + lastStoreReg = storeReg + lastStoreLoc = storeLoc + storeReg = '' + storeOffset = '' + storeLoc = '' + lastAMO = storeAMO except (FileNotFoundError): diff --git a/wally-pipelined/linux-testgen/parse_qemu.py b/wally-pipelined/linux-testgen/parse_qemu.py index 91d45800..c7f31fb2 100755 --- a/wally-pipelined/linux-testgen/parse_qemu.py +++ b/wally-pipelined/linux-testgen/parse_qemu.py @@ -39,12 +39,14 @@ def parseCSRs(l): csr = l.split()[0] val = int(l.split()[1],16) if inPageFault: - 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 + # 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 + pageFaultCSRs[csr] = val elif pageFaultCSRs and (csr in pageFaultCSRs): if (val != pageFaultCSRs[csr]): del pageFaultCSRs[csr]