Remove buildroot and testvector to avoid duplicate files.

This commit is contained in:
Kunlin Han 2024-04-15 10:30:14 -07:00
parent 6234db81a0
commit 2fd0a724f2
24 changed files with 23 additions and 7589 deletions

4
.gitignore vendored
View file

@ -186,3 +186,7 @@ sim/branch/*
sim/obj_dir
examples/verilog/fulladder/obj_dir
config/deriv
# docs/docker
docs/docker/buildroot-config-src
docs/docker/testvector-generation

View file

@ -22,15 +22,17 @@ If you have any other questions, please read the [troubleshooting]() first.
- [x] Regression Script
- [x] Configure the license for Questa
- [ ] Change the condition from empty string to 1
- [ ] Add linux testvector-generation
- [ ] Estimate the useless building intermediate files
- [x] Add linux testvector-generation
- [x] Estimate the useless building intermediate files
## TL;DR
Steps:
1. Install either Docker Engine or Podman for container support
2. Run start-up script `docs/docker/start.sh` to start a stateless container to run the toolchains and EDA tool
2. (If you want to build image your own) Run `get_buildroot_testvector.py` to get the buildroot and testvector configuration from relative path.
- `python get_buildroot_testvector.py` is the command to run.
3. Run start-up script `docs/docker/start.sh` to start a stateless container to run the toolchains and EDA tool
### Docker Engine or Podman
@ -169,6 +171,7 @@ Because we are going to use the whole environment of ubuntu to get both executab
There are four scripts:
- `get_buildroot_testvector.py`: copy buildroot and testvector configuration required by building
- `start.sh` (most often used): start running the container
- if you don't care about toolchains and running regression automatically, this script is only thing you need to know
- `get_images.sh`: get docker image `wallysoc/ubuntu_wally` or `wallysoc/toolchains_wally`

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,29 +0,0 @@
echo "Hello this ~/.profile is meant to demonstrate running some basic commands on Wally."
echo "I am $(whoami)"
echo "And I am on $(hostname)"
touch myFile.txt
echo "Hello World!" > myFile.txt
echo "And farewell!" >> myFile.txt
mkdir myDir
mv myFile.txt myDir
echo "Created myFile.txt and moved it to myDir. It contains:"
cat myDir/myFile.txt
touch myScript.sh
echo "echo \"Hello this is another example script\"" > myScript.sh
chmod +x myScript.sh
echo "Created myScript.sh. Running it yields:"
./myScript.sh
cd myDir
ln -s ../myScript.sh symLinkToMyScript.sh
echo "Created symLinkToMyScript.sh. Running it yields:"
./symLinkToMyScript.sh
echo "Now let's remove all these example files and scripts"
cd /
rm -r myDir
rm myScript.sh
echo "Here is disk usage:"
df -h
echo "And here are the current processes:"
ps
echo "And finally a login prompt."
login

View file

@ -1,41 +0,0 @@
# /etc/inittab
#
# Copyright (C) 2001 Erik Andersen <andersen@codepoet.org>
#
# Note: BusyBox init doesn't support runlevels. The runlevels field is
# completely ignored by BusyBox init. If you want runlevels, use
# sysvinit.
#
# Format for each entry: <id>:<runlevels>:<action>:<process>
#
# id == tty to run on, or empty for /dev/console
# runlevels == ignored
# action == one of sysinit, respawn, askfirst, wait, and once
# process == program to run
# Startup the system
::sysinit:/bin/mount -t proc proc /proc
::sysinit:/bin/mount -o remount,rw /
::sysinit:/bin/mkdir -p /dev/pts /dev/shm
::sysinit:/bin/mount -a
::sysinit:/sbin/swapon -a
null::sysinit:/bin/ln -sf /proc/self/fd /dev/fd
null::sysinit:/bin/ln -sf /proc/self/fd/0 /dev/stdin
null::sysinit:/bin/ln -sf /proc/self/fd/1 /dev/stdout
null::sysinit:/bin/ln -sf /proc/self/fd/2 /dev/stderr
::sysinit:/bin/hostname -F /etc/hostname
# now run any rc scripts
::sysinit:/etc/init.d/rcS
# (commented out) Put a getty on the serial port
#console::respawn:/sbin/getty -L console 0 vt100 # GENERIC_SERIAL
# Actually no, let's automatically login
console::respawn:-/bin/sh
# Stuff to do for the 3-finger salute
#::ctrlaltdel:/sbin/reboot
# Stuff to do before rebooting
::shutdown:/etc/init.d/rcK
::shutdown:/sbin/swapoff -a
::shutdown:/bin/umount -a -r

View file

@ -0,0 +1,13 @@
import shutil, os
# if WALLY is defined, then get it
WALLY_HOME = os.getenv("WALLY")
if WALLY_HOME is None or WALLY_HOME == "":
# otherwise, it is assumed as ../../
WALLY_HOME = "../../"
BUILDROOT_SRC = "linux/buildroot-config-src/wally"
TESTVECTOR_SRC = "linux/testvector-generation"
shutil.copytree(os.path.join(WALLY_HOME, BUILDROOT_SRC), "./buildroot-config-src")
shutil.copytree(os.path.join(WALLY_HOME, TESTVECTOR_SRC), "./testvector-generation")

View file

@ -1,47 +0,0 @@
#!/bin/bash
usage() { echo "Usage: $0 [-h] [-b <path/to/buildroot>] [-d <path/to/device tree>]" 1>&2; exit 1; }
help() {
echo "Usage: $0 [OPTIONS] <device>"
echo " -b <path/to/buildroot> get images from given buildroot"
echo " -d <device tree name> 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

View file

@ -1,13 +0,0 @@
SHELL = /bin/sh
CFLAG = -Wall -g
CC = gcc
all: fixBinMem
fixBinMem: fixBinMem.c
${CC} ${CFLAGS} fixBinMem.c -o fixBinMem
chmod +x fixBinMem
clean:
-rm -f fixBinMem

View file

@ -1,6 +0,0 @@
#!/bin/bash
for index in {450..500};
do
instrs=$(($index*1000000))
echo "y" | nice -n 5 ./genCheckpoint.sh $instrs
done

View file

@ -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"

View file

@ -1,74 +0,0 @@
#!/usr/bin/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()

View file

@ -1,68 +0,0 @@
#! /usr/bin/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: <path_to_testvector_dir>')
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.")

View file

@ -1,33 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int main(int argc, char *argv[]) {
if (argc < 3){
fprintf(stderr, "Expected 2 arguments: <raw GDB dump> <output binary>\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;
}

View file

@ -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: <num instrs>" >&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

View file

@ -1,63 +0,0 @@
#!/bin/bash
tcpPort=1235
imageDir=$RISCV/buildroot/output/images
tvDir=$RISCV/linux-testvectors
rawRamFile="$tvDir/ramGDB.bin"
ramFile="$tvDir/ram.bin"
rawBootmemFile="$tvDir/bootmemGDB.bin"
bootmemFile="$tvDir/bootmem.bin"
rawUntrimmedBootmemFile="$tvDir/untrimmedBootmemFileGDB.bin"
untrimmedBootmemFile="$tvDir/untrimmedBootmemFile.bin"
DEVICE_TREE=${imageDir}/wally-virt.dtb
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 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 \
-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 "printf \"Creating $rawBootmemFile\n\"" \
-ex "dump binary memory $rawBootmemFile 0x1000 0x1fff" \
-ex "printf \"Creating $rawRamFile\n\"" \
-ex "dump binary memory $rawRamFile 0x80000000 0x8fffffff" \
-ex "kill" \
-ex "q"
#-ex "printf \"Warning - please verify that the second half of $rawUntrimmedBootmemFile is all 0s\n\"" \
#-ex "printf \"Creating $rawUntrimmedBootmemFile\n\"" \
#-ex "dump binary memory $rawUntrimmedBootmemFile 0x1000 0x2fff" \
echo "Changing Endianness"
make fixBinMem
./fixBinMem "$rawRamFile" "$ramFile"
./fixBinMem "$rawBootmemFile" "$bootmemFile"
#./fixBinMem "$rawUntrimmedBootmemFile" "$untrimmedBootmemFile" # doesn't seem to be used for anything
rm -f "$rawRamFile" "$rawBootmemFile" "$rawUntrimmedBootmemFile"
echo "genInitMem.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"

View file

@ -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

View file

@ -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

View file

@ -1,243 +0,0 @@
#! /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):
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 <interrupt filename>>')
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')

View file

@ -1,106 +0,0 @@
#! /usr/bin/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: <path_to_checkpoint_dir>')
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!")

View file

@ -1,145 +0,0 @@
#! /usr/bin/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)

View file

@ -1,99 +0,0 @@
#! /usr/bin/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 <path_to_checkpoint_dir>')
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!")

View file

@ -1,50 +0,0 @@
#! /usr/bin/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: <path_to_checkpoint_dir>')
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!")