still not sure if QEMU workaround is correct, but here is all linux progress so far

This commit is contained in:
bbracker 2021-06-17 00:50:02 -04:00
parent e41a87be23
commit 6625f74a85
4 changed files with 81 additions and 78 deletions

4
.gitignore vendored
View File

@ -16,8 +16,8 @@ wlft*
/imperas-riscv-tests/FunctionRadix.addr /imperas-riscv-tests/FunctionRadix.addr
/imperas-riscv-tests/ProgramMap.txt /imperas-riscv-tests/ProgramMap.txt
/imperas-riscv-tests/logs /imperas-riscv-tests/logs
/wally-pipelined/busybear-testgen/gdbcombined.txt /wally-pipelined/linux-testgen/qemu_output.txt
/wally-pipelined/busybear-testgen/first10.txt /wally-pipelined/linux-testgen/qemu_in_gdb_format.txt
*.o *.o
*.d *.d
testsBP/*/*/*.elf* testsBP/*/*/*.elf*

View File

@ -2,25 +2,26 @@
# Uncomment this version for GDB/QEMU debugging # Uncomment this version for GDB/QEMU debugging
# - Opens up GDB interactively # - Opens up GDB interactively
# - Logs raw QEMU output to qemu_output.txt # - 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 # Uncomment this version to generate qemu_output.txt
# - Uses GDB script # - Uses GDB script
# - Logs raw QEMU output to qemu_output.txt # - 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 # Uncomment this version for parse_qemu.py debugging
# - Uses qemu_output.txt # - Uses qemu_output.txt
# - Makes qemu_in_gdb_format.txt # - Makes qemu_in_gdb_format.txt
# - Logs parse_qemu.py's simulated gdb output to 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 # Uncomment this version for parse_gdb_output.py debugging
# - Uses qemu_in_gdb_format.txt # - Uses qemu_in_gdb_format.txt
# - Logs info needed by buildroot testbench # - 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 ========== # =========== 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 # - 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

View File

@ -27,7 +27,7 @@ try:
readType = '' readType = ''
lastReadType = '' lastReadType = ''
readLoc = '' readLoc = ''
instrStart = -1 lineOffset = -1
lastRegs = '' lastRegs = ''
curRegs = '' curRegs = ''
storeReg = '' storeReg = ''
@ -40,10 +40,12 @@ try:
for l in fileinput.input('-'): for l in fileinput.input('-'):
l = l.split("#")[0].rstrip() l = l.split("#")[0].rstrip()
if l.startswith('=>'): if l.startswith('=>'):
# Begin new instruction
instrs += 1 instrs += 1
storeAMO = '' storeAMO = ''
if instrs % 10000 == 0: if instrs % 10000 == 0:
print(instrs) print(instrs)
# Instr in human assembly
wPC.write('{} ***\n'.format(' '.join(l.split(':')[1].split()[0:2]))) 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: if '\tld' in l or '\tlw' in l or '\tlh' in l or '\tlb' in l:
currentRead = l.split()[-1].split(',')[0] currentRead = l.split()[-1].split(',')[0]
@ -53,7 +55,6 @@ try:
readLoc = l.split()[-1].split(',')[1].split('(')[1][:-1] readLoc = l.split()[-1].split(',')[1].split('(')[1][:-1]
readType = l.split()[-2] readType = l.split()[-2]
if 'amo' in l: if 'amo' in l:
#print(l)
currentRead = l.split()[-1].split(',')[0] currentRead = l.split()[-1].split(',')[0]
readOffset = "0" readOffset = "0"
readLoc = l.split()[-1].split('(')[1][:-1] readLoc = l.split()[-1].split('(')[1][:-1]
@ -63,7 +64,6 @@ try:
storeReg = l.split()[-1].split(',')[1] storeReg = l.split()[-1].split(',')[1]
storeAMO = l.split()[-2] storeAMO = l.split()[-2]
if '\tsd' in l or '\tsw' in l or '\tsh' in l or '\tsb' in l: if '\tsd' in l or '\tsw' in l or '\tsh' in l or '\tsb' in l:
#print(l)
s = l.split('#')[0].split()[-1] s = l.split('#')[0].split()[-1]
storeReg = s.split(',')[0] storeReg = s.split(',')[0]
if len(s.split(',')) < 2: if len(s.split(',')) < 2:
@ -74,17 +74,19 @@ try:
print(l) print(l)
storeOffset = s.split(',')[1].split('(')[0] storeOffset = s.split(',')[1].split('(')[0]
storeLoc = s.split(',')[1].split('(')[1][:-1] storeLoc = s.split(',')[1].split('(')[1][:-1]
instrStart = 0 lineOffset = 0
elif instrStart != -1: elif lineOffset != -1:
instrStart += 1 lineOffset += 1
if instrStart == 1: if lineOffset == 1:
# Instr in hex comes one line after the instruction
wPC.write('{}\n'.format(l.split()[-1][2:])) 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]: if lastRead == l.split()[0]:
readData = int(l.split()[1][2:], 16) readData = int(l.split()[1][2:], 16)
readData <<= (8 * (lastReadLoc % 8)) readData <<= (8 * (lastReadLoc % 8))
#if(lastReadLoc % 8 != 0 and ('lw' in lastReadType or 'lb' in lastReadType)):
# readData <<= 32
wMem.write('{:x}\n'.format(readData)) wMem.write('{:x}\n'.format(readData))
if readLoc == l.split()[0]: if readLoc == l.split()[0]:
readLoc = l.split()[1][2:] readLoc = l.split()[1][2:]
@ -92,16 +94,12 @@ try:
storeReg = l.split()[1] storeReg = l.split()[1]
if storeLoc == l.split()[0]: if storeLoc == l.split()[0]:
storeLoc = l.split()[1][2:] storeLoc = l.split()[1][2:]
if instrStart > 2: if lineOffset > (1+1):
#print(l) # Start logging x1 onwards (we don't care about x0)
#print(instrStart)
curRegs += '{}\n'.format(l.split()[1][2:]) curRegs += '{}\n'.format(l.split()[1][2:])
elif instrStart < 35: #elif "pc" in l:
#print("----------") # wPC.write('{}\n'.format(l.split()[1][2:]))
#print(l.split()[1][2:]) if any([csr == l.split()[0] for csr in csrs]):
wPC.write('{}\n'.format(l.split()[1][2:]))
#print(l.split()[1][2:])
if any([c == l.split()[0] for c in csrs]):
if l.split()[0] in curCSRs: if l.split()[0] in curCSRs:
if curCSRs[l.split()[0]] != l.split()[1]: if curCSRs[l.split()[0]] != l.split()[1]:
if firstCSR: if firstCSR:
@ -112,51 +110,53 @@ try:
wCSRs.write('{}\n{}\n'.format(l.split()[0], l.split()[1][2:])) wCSRs.write('{}\n{}\n'.format(l.split()[0], l.split()[1][2:]))
curCSRs[l.split()[0]] = l.split()[1] curCSRs[l.split()[0]] = l.split()[1]
if '-----' in l: # end of each cycle if '-----' in l: # end of each cycle
if curRegs != lastRegs: if curRegs != lastRegs:
if lastRegs == '': if lastRegs == '':
wReg.write(curRegs) wReg.write(curRegs)
else: else:
for i in range(32): for i in range(32):
if curRegs.split('\n')[i] != lastRegs.split('\n')[i]: if curRegs.split('\n')[i] != lastRegs.split('\n')[i]:
wReg.write('{}\n'.format(i+1)) wReg.write('{}\n'.format(i+1))
wReg.write('{}\n'.format(curRegs.split('\n')[i])) wReg.write('{}\n'.format(curRegs.split('\n')[i]))
break break
lastRegs = curRegs lastRegs = curRegs
if lastAMO != '': if lastAMO != '':
if 'amoadd' in lastAMO: if 'amoadd' in lastAMO:
lastStoreReg = hex(int(lastStoreReg[2:], 16) + readData)[2:] lastStoreReg = hex(int(lastStoreReg[2:], 16) + readData)[2:]
elif 'amoand' in lastAMO: elif 'amoand' in lastAMO:
lastStoreReg = hex(int(lastStoreReg[2:], 16) & readData)[2:] lastStoreReg = hex(int(lastStoreReg[2:], 16) & readData)[2:]
elif 'amoor' in lastAMO: elif 'amoor' in lastAMO:
lastStoreReg = hex(int(lastStoreReg[2:], 16) | readData)[2:] lastStoreReg = hex(int(lastStoreReg[2:], 16) | readData)[2:]
elif 'amoswap' in lastAMO: elif 'amoswap' in lastAMO:
lastStoreReg = hex(int(lastStoreReg[2:], 16))[2:] lastStoreReg = hex(int(lastStoreReg[2:], 16))[2:]
else: else:
print(lastAMO) print(lastAMO)
exit() exit()
wMemW.write('{}\n'.format(lastStoreReg)) #print('lastStoreReg {}\n'.format(lastStoreReg))
wMemW.write('{:x}\n'.format(int(lastStoreLoc, 16))) #print('lastStoreLoc '+str(lastStoreLoc))
if storeReg != '' and storeOffset != '' and storeLoc != '' and storeAMO == '': wMemW.write('{}\n'.format(lastStoreReg))
storeLocOffset = int(storeOffset,10) + int(storeLoc, 16) wMemW.write('{:x}\n'.format(int(lastStoreLoc, 16)))
#wMemW.write('{:x}\n'.format(int(storeReg, 16) << (8 * (storeLocOffset % 8)))) if storeReg != '' and storeOffset != '' and storeLoc != '' and storeAMO == '':
wMemW.write('{}\n'.format(storeReg[2:])) storeLocOffset = int(storeOffset,10) + int(storeLoc, 16)
wMemW.write('{:x}\n'.format(storeLocOffset)) #wMemW.write('{:x}\n'.format(int(storeReg, 16) << (8 * (storeLocOffset % 8))))
if readOffset != '' and readLoc != '': wMemW.write('{}\n'.format(storeReg[2:]))
wMem.write('{:x}\n'.format(int(readOffset,10) + int(readLoc, 16))) wMemW.write('{:x}\n'.format(storeLocOffset))
lastReadLoc = int(readOffset,10) + int(readLoc, 16) if readOffset != '' and readLoc != '':
lastReadType = readType wMem.write('{:x}\n'.format(int(readOffset,10) + int(readLoc, 16)))
readOffset = '' lastReadLoc = int(readOffset,10) + int(readLoc, 16)
readLoc = '' lastReadType = readType
curRegs = '' readOffset = ''
instrStart = -1 readLoc = ''
lastRead = currentRead curRegs = ''
currentRead = '' lineOffset = -1
lastStoreReg = storeReg lastRead = currentRead
lastStoreLoc = storeLoc currentRead = ''
storeReg = '' lastStoreReg = storeReg
storeOffset = '' lastStoreLoc = storeLoc
storeLoc = '' storeReg = ''
lastAMO = storeAMO storeOffset = ''
storeLoc = ''
lastAMO = storeAMO
except (FileNotFoundError): except (FileNotFoundError):

View File

@ -39,12 +39,14 @@ def parseCSRs(l):
csr = l.split()[0] csr = l.split()[0]
val = int(l.split()[1],16) val = int(l.split()[1],16)
if inPageFault: 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"): # Not sure if these CSRs should be updated or not during page fault.
# We do update some CSRs #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"):
CSRs[csr] = val # # We do update some CSRs
else: # CSRs[csr] = val
# Others we preserve until changed later #else:
pageFaultCSRs[csr] = val # # Others we preserve until changed later
# pageFaultCSRs[csr] = val
pageFaultCSRs[csr] = val
elif pageFaultCSRs and (csr in pageFaultCSRs): elif pageFaultCSRs and (csr in pageFaultCSRs):
if (val != pageFaultCSRs[csr]): if (val != pageFaultCSRs[csr]):
del pageFaultCSRs[csr] del pageFaultCSRs[csr]