forked from Github_Repos/cvw
		
	Merge branch 'main' of github.com:davidharrishmc/riscv-wally into main
This commit is contained in:
		
						commit
						22279a29ab
					
				
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -70,3 +70,4 @@ synthDC/*.svf
 | 
				
			|||||||
synthDC/runs/
 | 
					synthDC/runs/
 | 
				
			||||||
synthDC/hdl
 | 
					synthDC/hdl
 | 
				
			||||||
/pipelined/regression/power.saif
 | 
					/pipelined/regression/power.saif
 | 
				
			||||||
 | 
					tests/fp/vectors/*.tv
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										12
									
								
								linux/bootmem.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								linux/bootmem.txt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					00001000: 00000297		auipc t0, 0		# t0 = 0x00001000
 | 
				
			||||||
 | 
					00001004: 02828613		addi a2, t0,0x28	# a2 = 0x00001028
 | 
				
			||||||
 | 
					00001008: f1402573		csrr a0, mhartid	# a0 = mhartid
 | 
				
			||||||
 | 
					0000100c: 0202b583		ld a1, 32(t0) 		# a1 = 87000000 - device tree address
 | 
				
			||||||
 | 
					00001010: 0182b283		ld t0, 24(t0)		# t0 = 80000000 - start of firmware
 | 
				
			||||||
 | 
					00001014: 00028067		jr t0			# jump to firmware
 | 
				
			||||||
 | 
					00001018: 0000000080000000			# firmware start address
 | 
				
			||||||
 | 
					00001020: 0000000087000000			# flattened device tree load address
 | 
				
			||||||
 | 
					00001028: 000000004942534f			# a2 points to this 8 dword data structure
 | 
				
			||||||
 | 
					00001030: 0000000000000002
 | 
				
			||||||
 | 
					00001038: 0000000080200000
 | 
				
			||||||
 | 
					00001040: 0000000000000001
 | 
				
			||||||
@ -28,7 +28,7 @@ ${DIS}/vmlinux.objdump.addr: ${DIS}/vmlinux.objdump
 | 
				
			|||||||
	-cd ${DIS}; extractFunctionRadix.sh vmlinux.objdump
 | 
						-cd ${DIS}; extractFunctionRadix.sh vmlinux.objdump
 | 
				
			||||||
 | 
					
 | 
				
			||||||
${DIS}/busybox.objdump: ${DIS}/rootfs/bin/busybox
 | 
					${DIS}/busybox.objdump: ${DIS}/rootfs/bin/busybox
 | 
				
			||||||
	riscv64-unknown-elf-objdump -D ${DIS}/rootfs/bin/busybox >> ${DIS}/busybox.objdump
 | 
						riscv64-unknown-elf-objdump -S ${DIS}/rootfs/bin/busybox >> ${DIS}/busybox.objdump
 | 
				
			||||||
 | 
					
 | 
				
			||||||
${DIS}/rootfs/bin/busybox:
 | 
					${DIS}/rootfs/bin/busybox:
 | 
				
			||||||
	mkdir -p ${DIS}/rootfs
 | 
						mkdir -p ${DIS}/rootfs
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										68
									
								
								linux/testvector-generation/filterTrapsToInterrupts.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										68
									
								
								linux/testvector-generation/filterTrapsToInterrupts.py
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,68 @@
 | 
				
			|||||||
 | 
					#! /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.")
 | 
				
			||||||
@ -53,7 +53,7 @@ then
 | 
				
			|||||||
    -ex "printf \"Warning - please verify that the second half of $rawUntrimmedBootmemFile is all 0s\n\"" \
 | 
					    -ex "printf \"Warning - please verify that the second half of $rawUntrimmedBootmemFile is all 0s\n\"" \
 | 
				
			||||||
    -ex "dump binary memory $rawUntrimmedBootmemFile 0x1000 0x2fff" \
 | 
					    -ex "dump binary memory $rawUntrimmedBootmemFile 0x1000 0x2fff" \
 | 
				
			||||||
    -ex "printf \"Creating $rawRamFile\n\"" \
 | 
					    -ex "printf \"Creating $rawRamFile\n\"" \
 | 
				
			||||||
    -ex "dump binary memory $rawRamFile 0x80000000 0xffffffff" \
 | 
					    -ex "dump binary memory $rawRamFile 0x80000000 0x87ffffff" \
 | 
				
			||||||
    -ex "kill" \
 | 
					    -ex "kill" \
 | 
				
			||||||
    -ex "q"
 | 
					    -ex "q"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -4,10 +4,12 @@ imageDir=$RISCV/buildroot/output/images
 | 
				
			|||||||
tvDir=$RISCV/linux-testvectors
 | 
					tvDir=$RISCV/linux-testvectors
 | 
				
			||||||
recordFile="$tvDir/all.qemu"
 | 
					recordFile="$tvDir/all.qemu"
 | 
				
			||||||
traceFile="$tvDir/all.txt"
 | 
					traceFile="$tvDir/all.txt"
 | 
				
			||||||
 | 
					trapsFile="$tvDir/traps.txt"
 | 
				
			||||||
interruptsFile="$tvDir/interrupts.txt"
 | 
					interruptsFile="$tvDir/interrupts.txt"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
read -p "Warning: running this script will overwrite the contents of:
 | 
					read -p "Warning: running this script will overwrite the contents of:
 | 
				
			||||||
  * $traceFile
 | 
					  * $traceFile
 | 
				
			||||||
 | 
					  * $trapsFile
 | 
				
			||||||
  * $interruptsFile
 | 
					  * $interruptsFile
 | 
				
			||||||
Would you like to proceed? (y/n) " -n 1 -r
 | 
					Would you like to proceed? (y/n) " -n 1 -r
 | 
				
			||||||
echo
 | 
					echo
 | 
				
			||||||
@ -28,6 +30,7 @@ then
 | 
				
			|||||||
    fi
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    touch $traceFile 
 | 
					    touch $traceFile 
 | 
				
			||||||
 | 
					    touch $trapsFile 
 | 
				
			||||||
    touch $interruptsFile 
 | 
					    touch $interruptsFile 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # QEMU Simulation
 | 
					    # QEMU Simulation
 | 
				
			||||||
@ -38,7 +41,9 @@ then
 | 
				
			|||||||
    -bios $imageDir/fw_jump.elf -kernel $imageDir/Image -append "root=/dev/vda ro" -initrd $imageDir/rootfs.cpio \
 | 
					    -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 \
 | 
					    -singlestep -rtc clock=vm -icount shift=0,align=off,sleep=on,rr=replay,rrfile=$recordFile \
 | 
				
			||||||
    -d nochain,cpu,in_asm,int \
 | 
					    -d nochain,cpu,in_asm,int \
 | 
				
			||||||
    2>&1 >./qemu-serial | ./parseQEMUtoGDB.py | ./parseGDBtoTrace.py $interruptsFile | ./remove_dup.awk > $traceFile)
 | 
					    2>&1 >./qemu-serial | ./parseQEMUtoGDB.py | ./parseGDBtoTrace.py $trapsFile | ./remove_dup.awk > $traceFile)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ./filterTrapsToInterrupts.py $tvDir
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    echo "genTrace.sh completed!"
 | 
					    echo "genTrace.sh completed!"
 | 
				
			||||||
    echo "You may want to restrict write access to $tvDir now and give cad ownership of it."
 | 
					    echo "You may want to restrict write access to $tvDir now and give cad ownership of it."
 | 
				
			||||||
 | 
				
			|||||||
@ -29,10 +29,14 @@ def printPC(l):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
def printCSRs():
 | 
					def printCSRs():
 | 
				
			||||||
    global parseState, inPageFault, CSRs, pageFaultCSRs, regs, pageFaultCSRs, instrs
 | 
					    global parseState, inPageFault, CSRs, pageFaultCSRs, regs, pageFaultCSRs, instrs
 | 
				
			||||||
 | 
					    global interrupt_line
 | 
				
			||||||
    if not inPageFault:
 | 
					    if not inPageFault:
 | 
				
			||||||
        for (csr,val) in CSRs.items():
 | 
					        for (csr,val) in CSRs.items():
 | 
				
			||||||
            print('{}{}{:#x}  {}'.format(csr, ' '*(15-len(csr)), val, val))
 | 
					            print('{}{}{:#x}  {}'.format(csr, ' '*(15-len(csr)), val, val))
 | 
				
			||||||
        print('-----')
 | 
					        print('-----') # end of current instruction
 | 
				
			||||||
 | 
					        if len(interrupt_line)>0: # squish interrupts in between instructions
 | 
				
			||||||
 | 
					            print(interrupt_line)
 | 
				
			||||||
 | 
					            interrupt_line=""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def parseCSRs(l):
 | 
					def parseCSRs(l):
 | 
				
			||||||
    global parseState, inPageFault, CSRs, pageFaultCSRs, regs, pageFaultCSRs, instrs
 | 
					    global parseState, inPageFault, CSRs, pageFaultCSRs, regs, pageFaultCSRs, instrs
 | 
				
			||||||
@ -119,15 +123,9 @@ for l in fileinput.input():
 | 
				
			|||||||
        break
 | 
					        break
 | 
				
			||||||
    elif l.startswith('IN:'):
 | 
					    elif l.startswith('IN:'):
 | 
				
			||||||
        # New disassembled instr
 | 
					        # New disassembled instr
 | 
				
			||||||
        if len(interrupt_line)>0:
 | 
					 | 
				
			||||||
            print(interrupt_line)
 | 
					 | 
				
			||||||
            interrupt_line=""
 | 
					 | 
				
			||||||
        parseState = "instr"
 | 
					        parseState = "instr"
 | 
				
			||||||
    elif (parseState == "instr") and l.startswith('0x'):
 | 
					    elif (parseState == "instr") and l.startswith('0x'):
 | 
				
			||||||
        # New instruction
 | 
					        # New instruction
 | 
				
			||||||
        if len(interrupt_line)>0:
 | 
					 | 
				
			||||||
            print(interrupt_line)
 | 
					 | 
				
			||||||
            interrupt_line=""
 | 
					 | 
				
			||||||
        if "out of bounds" in l:
 | 
					        if "out of bounds" in l:
 | 
				
			||||||
            sys.stderr.write("Detected QEMU page fault error\n")
 | 
					            sys.stderr.write("Detected QEMU page fault error\n")
 | 
				
			||||||
            beginPageFault = not inPageFault
 | 
					            beginPageFault = not inPageFault
 | 
				
			||||||
 | 
				
			|||||||
@ -43,6 +43,7 @@
 | 
				
			|||||||
`define ZIFENCEI_SUPPORTED 1
 | 
					`define ZIFENCEI_SUPPORTED 1
 | 
				
			||||||
`define COUNTERS 32
 | 
					`define COUNTERS 32
 | 
				
			||||||
`define ZICOUNTERS_SUPPORTED 1
 | 
					`define ZICOUNTERS_SUPPORTED 1
 | 
				
			||||||
 | 
					`define ZFH_SUPPORTED 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Microarchitectural Features
 | 
					// Microarchitectural Features
 | 
				
			||||||
`define UARCH_PIPELINED 1
 | 
					`define UARCH_PIPELINED 1
 | 
				
			||||||
 | 
				
			|||||||
@ -43,6 +43,7 @@
 | 
				
			|||||||
`define ZIFENCEI_SUPPORTED 1
 | 
					`define ZIFENCEI_SUPPORTED 1
 | 
				
			||||||
`define COUNTERS 32
 | 
					`define COUNTERS 32
 | 
				
			||||||
`define ZICOUNTERS_SUPPORTED 1
 | 
					`define ZICOUNTERS_SUPPORTED 1
 | 
				
			||||||
 | 
					`define ZFH_SUPPORTED 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Microarchitectural Features
 | 
					/// Microarchitectural Features
 | 
				
			||||||
`define UARCH_PIPELINED 1
 | 
					`define UARCH_PIPELINED 1
 | 
				
			||||||
 | 
				
			|||||||
@ -41,7 +41,6 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
 | 
				
			|||||||
    run -all
 | 
					    run -all
 | 
				
			||||||
    run -all
 | 
					    run -all
 | 
				
			||||||
    exec ./slack-notifier/slack-notifier.py
 | 
					    exec ./slack-notifier/slack-notifier.py
 | 
				
			||||||
    quit 
 | 
					 | 
				
			||||||
} else {
 | 
					} else {
 | 
				
			||||||
    vlog -lint -work wkdir/work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench.sv ../testbench/common/*.sv   ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 -suppress 7063
 | 
					    vlog -lint -work wkdir/work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench.sv ../testbench/common/*.sv   ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 -suppress 7063
 | 
				
			||||||
    # start and run simulation
 | 
					    # start and run simulation
 | 
				
			||||||
@ -52,11 +51,15 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
 | 
				
			|||||||
    #vopt work_$2.testbench -work work_$2 -o workopt_$2 +cover=sbectf
 | 
					    #vopt work_$2.testbench -work work_$2 -o workopt_$2 +cover=sbectf
 | 
				
			||||||
    #vsim -coverage -lib work_$2 workopt_$2
 | 
					    #vsim -coverage -lib work_$2 workopt_$2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # power add generates the logging necessary for saif generation.
 | 
				
			||||||
 | 
					    power add -r /dut/core/*
 | 
				
			||||||
    run -all
 | 
					    run -all
 | 
				
			||||||
    quit
 | 
					    power off -r /dut/core/*
 | 
				
			||||||
} 
 | 
					} 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#coverage report -file wally-pipelined-coverage.txt
 | 
					#coverage report -file wally-pipelined-coverage.txt
 | 
				
			||||||
# These aren't doing anything helpful
 | 
					# These aren't doing anything helpful
 | 
				
			||||||
#coverage report -memory 
 | 
					#coverage report -memory 
 | 
				
			||||||
#profile report -calltree -file wally-pipelined-calltree.rpt -cutoff 2
 | 
					#profile report -calltree -file wally-pipelined-calltree.rpt -cutoff 2
 | 
				
			||||||
 | 
					power report -all -bsaif power.saif
 | 
				
			||||||
 | 
					quit
 | 
				
			||||||
 | 
				
			|||||||
@ -57,12 +57,12 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
 | 
				
			|||||||
    do wave.do
 | 
					    do wave.do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # power add generates the logging necessary for saif generation.
 | 
					    # power add generates the logging necessary for saif generation.
 | 
				
			||||||
    #power add -r /dut/core/*
 | 
					    power add -r /dut/core/*
 | 
				
			||||||
    #-- Run the Simulation 
 | 
					    #-- Run the Simulation 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    run -all
 | 
					    run -all
 | 
				
			||||||
    #power off -r /dut/core/*
 | 
					    power off -r /dut/core/*
 | 
				
			||||||
    #power report -all -bsaif power.saif
 | 
					    power report -all -bsaif power.saif
 | 
				
			||||||
    noview ../testbench/testbench.sv
 | 
					    noview ../testbench/testbench.sv
 | 
				
			||||||
    view wave
 | 
					    view wave
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -193,7 +193,7 @@ module expadd(
 | 
				
			|||||||
            endcase
 | 
					            endcase
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    end else begin
 | 
					    end else if (`FPSIZES == 4) begin
 | 
				
			||||||
        always_comb begin
 | 
					        always_comb begin
 | 
				
			||||||
            case (FmtE)
 | 
					            case (FmtE)
 | 
				
			||||||
                2'h3: Denorm = 1;
 | 
					                2'h3: Denorm = 1;
 | 
				
			||||||
@ -619,7 +619,7 @@ module normalize(
 | 
				
			|||||||
            endcase
 | 
					            endcase
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    end else begin
 | 
					    end else if (`FPSIZES == 4) begin
 | 
				
			||||||
        always_comb begin
 | 
					        always_comb begin
 | 
				
			||||||
            case (FmtM)
 | 
					            case (FmtM)
 | 
				
			||||||
                2'h3: SumExpTmp = SumExpTmpTmp;
 | 
					                2'h3: SumExpTmp = SumExpTmpTmp;
 | 
				
			||||||
@ -664,7 +664,7 @@ module normalize(
 | 
				
			|||||||
            endcase
 | 
					            endcase
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    end else begin
 | 
					    end else if (`FPSIZES == 4) begin
 | 
				
			||||||
        logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL, Sum2LEZ, Sum2GEFL, Sum3LEZ, Sum3GEFL;
 | 
					        logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL, Sum2LEZ, Sum2GEFL, Sum3LEZ, Sum3GEFL;
 | 
				
			||||||
        assign Sum0LEZ  = SumExpTmpTmp[`NE+1] | ~|SumExpTmpTmp;
 | 
					        assign Sum0LEZ  = SumExpTmpTmp[`NE+1] | ~|SumExpTmpTmp;
 | 
				
			||||||
        assign Sum0GEFL = $signed(SumExpTmpTmp) >= $signed(-(`NE+2)'(`NF  )-(`NE+2)'(2));
 | 
					        assign Sum0GEFL = $signed(SumExpTmpTmp) >= $signed(-(`NE+2)'(`NF  )-(`NE+2)'(2));
 | 
				
			||||||
@ -719,7 +719,7 @@ module normalize(
 | 
				
			|||||||
        (|CorrSumShifted[3*`NF+2-`NF1:2*`NF+3]&((FmtM==`FMT1)|(FmtM==`FMT2))) | 
 | 
					        (|CorrSumShifted[3*`NF+2-`NF1:2*`NF+3]&((FmtM==`FMT1)|(FmtM==`FMT2))) | 
 | 
				
			||||||
        (|CorrSumShifted[3*`NF+2-`NF2:3*`NF+3-`NF1]&(FmtM==`FMT2));
 | 
					        (|CorrSumShifted[3*`NF+2-`NF2:3*`NF+3-`NF1]&(FmtM==`FMT2));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    end else begin        
 | 
					    end else if (`FPSIZES == 4) begin        
 | 
				
			||||||
        assign NormSumSticky = (|CorrSumShifted[2*`NF+2:0]) | 
 | 
					        assign NormSumSticky = (|CorrSumShifted[2*`NF+2:0]) | 
 | 
				
			||||||
        (|CorrSumShifted[3*`NF+2-`D_NF:2*`NF+3]&((FmtM==1)|(FmtM==0)|(FmtM==2))) | 
 | 
					        (|CorrSumShifted[3*`NF+2-`D_NF:2*`NF+3]&((FmtM==1)|(FmtM==0)|(FmtM==2))) | 
 | 
				
			||||||
        (|CorrSumShifted[3*`NF+2-`S_NF:3*`NF+3-`D_NF]&((FmtM==0)|(FmtM==2))) |
 | 
					        (|CorrSumShifted[3*`NF+2-`S_NF:3*`NF+3-`D_NF]&((FmtM==0)|(FmtM==2))) |
 | 
				
			||||||
@ -876,7 +876,7 @@ module fmaround(
 | 
				
			|||||||
            endcase
 | 
					            endcase
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    end else begin
 | 
					    end else if (`FPSIZES == 4) begin
 | 
				
			||||||
        always_comb begin
 | 
					        always_comb begin
 | 
				
			||||||
            case (FmtM)
 | 
					            case (FmtM)
 | 
				
			||||||
                2'h3: begin
 | 
					                2'h3: begin
 | 
				
			||||||
@ -995,7 +995,7 @@ module fmaround(
 | 
				
			|||||||
            endcase
 | 
					            endcase
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    end else begin        
 | 
					    end else if (`FPSIZES == 4) begin        
 | 
				
			||||||
        always_comb begin
 | 
					        always_comb begin
 | 
				
			||||||
            case (FmtM)
 | 
					            case (FmtM)
 | 
				
			||||||
                2'h3: RoundAdd = Minus1 ? {`FLEN+1{1'b1}} : {{{`FLEN{1'b0}}}, Plus1};
 | 
					                2'h3: RoundAdd = Minus1 ? {`FLEN+1{1'b1}} : {{{`FLEN{1'b0}}}, Plus1};
 | 
				
			||||||
@ -1063,7 +1063,7 @@ module fmaflags(
 | 
				
			|||||||
            endcase
 | 
					            endcase
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    end else begin        
 | 
					    end else if (`FPSIZES == 4) begin        
 | 
				
			||||||
        always_comb begin
 | 
					        always_comb begin
 | 
				
			||||||
            case (FmtM)
 | 
					            case (FmtM)
 | 
				
			||||||
                2'h3: GtMaxExp =  &FullResultExp[`NE-1:0] | FullResultExp[`NE];
 | 
					                2'h3: GtMaxExp =  &FullResultExp[`NE-1:0] | FullResultExp[`NE];
 | 
				
			||||||
@ -1223,7 +1223,7 @@ module resultselect(
 | 
				
			|||||||
            endcase
 | 
					            endcase
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    end else begin 
 | 
					    end else if (`FPSIZES == 4) begin 
 | 
				
			||||||
        always_comb begin
 | 
					        always_comb begin
 | 
				
			||||||
            case (FmtM)
 | 
					            case (FmtM)
 | 
				
			||||||
                2'h3: begin  
 | 
					                2'h3: begin  
 | 
				
			||||||
 | 
				
			|||||||
@ -261,7 +261,7 @@ module unpack (
 | 
				
			|||||||
            endcase
 | 
					            endcase
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    end else begin      // if all precsisons are supported - quad, double, single, and half
 | 
					    end else if (`FPSIZES == 4) begin      // if all precsisons are supported - quad, double, single, and half
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
        //    quad   |  double  |  single  |  half    
 | 
					        //    quad   |  double  |  single  |  half    
 | 
				
			||||||
        //-------------------------------------------------------------------
 | 
					        //-------------------------------------------------------------------
 | 
				
			||||||
 | 
				
			|||||||
@ -1450,30 +1450,30 @@ string imperas32f[] = '{
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 string wally64priv[] = '{
 | 
					 string wally64priv[] = '{
 | 
				
			||||||
    `WALLYTEST,
 | 
					    `WALLYTEST,
 | 
				
			||||||
    "rv64i_m/privilege/WALLY-CSR-permission-s-01", "0050a0",
 | 
					    "rv64i_m/privilege/WALLY-CSR-permission-s-01", "0060a0",
 | 
				
			||||||
    //"rv64i_m/privilege/WALLY-CSR-PERMISSIONS-M", "005070",
 | 
					    //"rv64i_m/privilege/WALLY-CSR-PERMISSIONS-M", "005090",
 | 
				
			||||||
    //"rv64i_m/privilege/WALLY-CSR-PERMISSIONS-S", "003070",
 | 
					    //"rv64i_m/privilege/WALLY-CSR-PERMISSIONS-S", "003090",
 | 
				
			||||||
    "rv64i_m/privilege/WALLY-CSR-permission-u-01", "0050a0",
 | 
					    "rv64i_m/privilege/WALLY-CSR-permission-u-01", "0060a0",
 | 
				
			||||||
   // "rv64i_m/privilege/WALLY-MARCHID", "003070",
 | 
					   // "rv64i_m/privilege/WALLY-MARCHID", "004090",
 | 
				
			||||||
/*    "rv64i_m/privilege/WALLY-MCAUSE", "003070",
 | 
					/*    "rv64i_m/privilege/WALLY-MCAUSE", "003090",
 | 
				
			||||||
    "rv64i_m/privilege/WALLY-MEDELEG", "003070",
 | 
					    "rv64i_m/privilege/WALLY-MEDELEG", "004090",
 | 
				
			||||||
    "rv64i_m/privilege/WALLY-MHARTID", "003070",
 | 
					    "rv64i_m/privilege/WALLY-MHARTID", "004090",
 | 
				
			||||||
    "rv64i_m/privilege/WALLY-MIMPID", "003070",*/
 | 
					    "rv64i_m/privilege/WALLY-MIMPID", "004090",*/
 | 
				
			||||||
    "rv64i_m/privilege/WALLY-minfo-01", "0040a0",
 | 
					    "rv64i_m/privilege/WALLY-minfo-01", "0050a0",
 | 
				
			||||||
    "rv64i_m/privilege/WALLY-misa-01", "0040a0",
 | 
					    "rv64i_m/privilege/WALLY-misa-01", "0050a0",
 | 
				
			||||||
    "rv64i_m/privilege/WALLY-MMU-SV39", "0040a0",
 | 
					    "rv64i_m/privilege/WALLY-MMU-SV39", "0050a0",
 | 
				
			||||||
    "rv64i_m/privilege/WALLY-MMU-SV48", "0040a0",
 | 
					    "rv64i_m/privilege/WALLY-MMU-SV48", "0050a0",
 | 
				
			||||||
/*    "rv64i_m/privilege/WALLY-MSTATUS", "002070",
 | 
					/*    "rv64i_m/privilege/WALLY-MSTATUS", "002090",
 | 
				
			||||||
    "rv64i_m/privilege/WALLY-MTVEC", "002070",
 | 
					    "rv64i_m/privilege/WALLY-MTVEC", "002090",
 | 
				
			||||||
    "rv64i_m/privilege/WALLY-MVENDORID", "003070", */
 | 
					    "rv64i_m/privilege/WALLY-MVENDORID", "004090", */
 | 
				
			||||||
    "rv64i_m/privilege/WALLY-PMA", "0040a0",
 | 
					    "rv64i_m/privilege/WALLY-PMA", "0050a0",
 | 
				
			||||||
    "rv64i_m/privilege/WALLY-PMP", "0040a0",
 | 
					    "rv64i_m/privilege/WALLY-PMP", "0050a0"
 | 
				
			||||||
//    "rv64i_m/privilege/WALLY-SCAUSE", "002070",
 | 
					//    "rv64i_m/privilege/WALLY-SCAUSE", "002090",
 | 
				
			||||||
    "rv64i_m/privilege/WALLY-scratch-01", "0040a0",
 | 
					//    "rv64i_m/privilege/WALLY-scratch-01", "0040a0",
 | 
				
			||||||
    "rv64i_m/privilege/WALLY-sscratch-s-01", "0040a0"
 | 
					//    "rv64i_m/privilege/WALLY-sscratch-s-01", "0040a0",
 | 
				
			||||||
//    "rv64i_m/privilege/WALLY-trap-01", "0040a0"
 | 
					//    "rv64i_m/privilege/WALLY-trap-01", "0050a0"
 | 
				
			||||||
//    "rv64i_m/privilege/WALLY-STVEC", "002070",
 | 
					//    "rv64i_m/privilege/WALLY-STVEC", "002090",
 | 
				
			||||||
//    "rv64i_m/privilege/WALLY-UCAUSE", "002070",
 | 
					//    "rv64i_m/privilege/WALLY-UCAUSE", "002090",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 };
 | 
					 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,19 +0,0 @@
 | 
				
			|||||||
# Makefile
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
CC     = gcc
 | 
					 | 
				
			||||||
CFLAGS = -O3
 | 
					 | 
				
			||||||
LIBS   = -lm
 | 
					 | 
				
			||||||
LFLAGS = -L. 
 | 
					 | 
				
			||||||
IFLAGS = -I../../../addins/SoftFloat-3e/source/include/
 | 
					 | 
				
			||||||
LIBS   = ../../../addins/SoftFloat-3e/build/Linux-x86_64-GCC/softfloat.a
 | 
					 | 
				
			||||||
SRCS   = $(wildcard *.c)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
PROGS = $(patsubst %.c,%,$(SRCS))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
all:	$(PROGS)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
%: %.c
 | 
					 | 
				
			||||||
	$(CC) $(CFLAGS) $(IFLAGS) $(LFLAGS) -o $@ $< $(LIBS)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
clean: 
 | 
					 | 
				
			||||||
	rm -f $(PROGS)
 | 
					 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							@ -1,52 +0,0 @@
 | 
				
			|||||||
#include <stdio.h>
 | 
					 | 
				
			||||||
#include <stdint.h>
 | 
					 | 
				
			||||||
#include "softfloat.h"
 | 
					 | 
				
			||||||
#include "softfloat_types.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int float_rounding_mode = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
union dp {
 | 
					 | 
				
			||||||
  unsigned short x[4];
 | 
					 | 
				
			||||||
  double y;
 | 
					 | 
				
			||||||
} X;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int main()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    uint8_t rounding_mode;
 | 
					 | 
				
			||||||
    uint8_t exceptions;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    uint64_t n, d, result;
 | 
					 | 
				
			||||||
    float64_t   d_n, d_d, d_result;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    n = 0x3feffffffefffff6;
 | 
					 | 
				
			||||||
    d = 0xffeffffffffffffe;
 | 
					 | 
				
			||||||
    //n = 0x00000000400001ff;
 | 
					 | 
				
			||||||
    //d = 0x3ffffdfffffffbfe;    
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    d_n.v = n;
 | 
					 | 
				
			||||||
    d_d.v = d;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    softfloat_roundingMode = rounding_mode;
 | 
					 | 
				
			||||||
    softfloat_exceptionFlags = 0;
 | 
					 | 
				
			||||||
    softfloat_detectTininess = softfloat_tininess_beforeRounding;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    d_result = f64_div(d_n, d_d);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //result = d_result.v;    
 | 
					 | 
				
			||||||
    //exceptions = softfloat_exceptionFlags & 0x1f;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    X.x[3] = (d_result.v & 0xffff000000000000) >> 48;
 | 
					 | 
				
			||||||
    X.x[2] = (d_result.v & 0x0000ffff00000000) >> 32;    
 | 
					 | 
				
			||||||
    X.x[1] = (d_result.v & 0x00000000ffff0000) >> 16;
 | 
					 | 
				
			||||||
    X.x[0] = (d_result.v & 0x000000000000ffff);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    printf("Number = %.4x\n", X.x[3]);
 | 
					 | 
				
			||||||
    printf("Number = %.4x\n", X.x[2]);
 | 
					 | 
				
			||||||
    printf("Number = %.4x\n", X.x[1]);
 | 
					 | 
				
			||||||
    printf("Number = %.4x\n", X.x[0]);
 | 
					 | 
				
			||||||
    printf("Number = %1.25lg\n", X.y);    
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							@ -1,47 +0,0 @@
 | 
				
			|||||||
#include <stdio.h>
 | 
					 | 
				
			||||||
#include <stdint.h>
 | 
					 | 
				
			||||||
#include "softfloat.h"
 | 
					 | 
				
			||||||
#include "softfloat_types.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int float_rounding_mode = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
union sp {
 | 
					 | 
				
			||||||
  unsigned short x[2];
 | 
					 | 
				
			||||||
  float y;
 | 
					 | 
				
			||||||
} X;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int main()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    uint8_t rounding_mode;
 | 
					 | 
				
			||||||
    uint8_t exceptions;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    uint32_t multiplier, multiplicand, addend, result;
 | 
					 | 
				
			||||||
    float32_t f_multiplier, f_multiplicand, f_addend, f_result;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    multiplier = 0xbf800000;
 | 
					 | 
				
			||||||
    multiplicand = 0xbf800000;
 | 
					 | 
				
			||||||
    addend = 0xffaaaaaa;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    f_multiplier.v = multiplier;
 | 
					 | 
				
			||||||
    f_multiplicand.v = multiplicand;
 | 
					 | 
				
			||||||
    f_addend.v = addend;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    softfloat_roundingMode = rounding_mode;
 | 
					 | 
				
			||||||
    softfloat_exceptionFlags = 0;
 | 
					 | 
				
			||||||
    softfloat_detectTininess = softfloat_tininess_beforeRounding;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    f_result = f32_mulAdd(f_multiplier, f_multiplicand, f_addend);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    result = f_result.v;    
 | 
					 | 
				
			||||||
    exceptions = softfloat_exceptionFlags & 0x1f;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    printf("%x\n", f_result.v);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Print out SP number
 | 
					 | 
				
			||||||
    X.x[1] = (f_result.v & 0xffff0000) >> 16;
 | 
					 | 
				
			||||||
    X.x[0] = (f_result.v & 0x0000ffff);
 | 
					 | 
				
			||||||
    printf("Number = %f\n", X.y);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,23 +1,11 @@
 | 
				
			|||||||
beef00b4 # Test 12.3.2.1: read 64 bits success in CLINT 
 | 
					beef00b4 # Test 12.3.2.1: read 64 bits success in CLINT 
 | 
				
			||||||
0000dead # all of these read successes are also confirming successful writes 
 | 
					0000dead # all of these read successes are also confirming successful writes 
 | 
				
			||||||
00000007 # write 32 bits with access fault in CLINT
 | 
					beef00b5 # read 32 bits success in CLINT (bottom 32 bits sign extended)
 | 
				
			||||||
00000000
 | 
					ffffffff
 | 
				
			||||||
00000005 # read 32 bits with access fault in CLINT
 | 
					000000b6 # read 16 bits success in CLINT (bottom 16 bits sign extended)
 | 
				
			||||||
00000000
 | 
					 | 
				
			||||||
00000bad
 | 
					 | 
				
			||||||
00000000
 | 
					 | 
				
			||||||
00000007 # write 16 bits with access fault in CLINT
 | 
					 | 
				
			||||||
00000000
 | 
					 | 
				
			||||||
00000005 # read 16 bits with access fault in CLINT
 | 
					 | 
				
			||||||
00000000
 | 
					 | 
				
			||||||
00000bad
 | 
					 | 
				
			||||||
00000000
 | 
					 | 
				
			||||||
00000007 # write 8 bits with access fault in CLINT
 | 
					 | 
				
			||||||
00000000
 | 
					 | 
				
			||||||
00000005 # read 8 bits with access fault in CLINT
 | 
					 | 
				
			||||||
00000000
 | 
					 | 
				
			||||||
00000bad
 | 
					 | 
				
			||||||
00000000
 | 
					00000000
 | 
				
			||||||
 | 
					ffffffb7 # read 8 bits success in CLINT (bottom 8 bits sign extended)
 | 
				
			||||||
 | 
					ffffffff
 | 
				
			||||||
00000001 # execute test with access fault in CLINT
 | 
					00000001 # execute test with access fault in CLINT
 | 
				
			||||||
00000000
 | 
					00000000
 | 
				
			||||||
00000bad
 | 
					00000bad
 | 
				
			||||||
 | 
				
			|||||||
@ -85,12 +85,12 @@ test_cases:
 | 
				
			|||||||
# Use timecmp register as readable and writable section of the CLINT
 | 
					# Use timecmp register as readable and writable section of the CLINT
 | 
				
			||||||
.8byte CLINT_BASE + 0x4000, 0x0000DEADBEEF00B4, write64_test  # 64-bit write:  success
 | 
					.8byte CLINT_BASE + 0x4000, 0x0000DEADBEEF00B4, write64_test  # 64-bit write:  success
 | 
				
			||||||
.8byte CLINT_BASE + 0x4000, 0x0000DEADBEEF00B4, read64_test # 64-bit read:   success
 | 
					.8byte CLINT_BASE + 0x4000, 0x0000DEADBEEF00B4, read64_test # 64-bit read:   success
 | 
				
			||||||
.8byte CLINT_BASE + 0x4000, 0x0000DEADBEEF00B5, write32_test # 32-bit write:  failure *** due to non-native length access
 | 
					.8byte CLINT_BASE + 0x4000, 0x0000DEADBEEF00B5, write32_test # 32-bit write: success
 | 
				
			||||||
.8byte CLINT_BASE + 0x4000, 0x0000DEADBEEF00B5, read32_test # 32-bit read:   failure
 | 
					.8byte CLINT_BASE + 0x4000, 0x0000DEADBEEF00B5, read32_test # 32-bit read:   success
 | 
				
			||||||
.8byte CLINT_BASE + 0x4000, 0x0000DEADBEEF00B6, write16_test # 16-bit write:  failure
 | 
					.8byte CLINT_BASE + 0x4000, 0x0000DEADBEEF00B6, write16_test # 16-bit write: success
 | 
				
			||||||
.8byte CLINT_BASE + 0x4000, 0x0000DEADBEEF00B6, read16_test # 16-bit read:   failure
 | 
					.8byte CLINT_BASE + 0x4000, 0x0000DEADBEEF00B6, read16_test # 16-bit read:   success
 | 
				
			||||||
.8byte CLINT_BASE + 0x4000, 0x0000DEADBEEF00B7, write08_test # 08-bit write:  failure
 | 
					.8byte CLINT_BASE + 0x4000, 0x0000DEADBEEF00B7, write08_test # 08-bit write: success
 | 
				
			||||||
.8byte CLINT_BASE + 0x4000, 0x0000DEADBEEF00B7, read08_test # 08-bit read:   failure
 | 
					.8byte CLINT_BASE + 0x4000, 0x0000DEADBEEF00B7, read08_test # 08-bit read:   success
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.8byte CLINT_BASE, 0xbad, executable_test# execute: instruction access fault
 | 
					.8byte CLINT_BASE, 0xbad, executable_test# execute: instruction access fault
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -41,7 +41,7 @@ RVTEST_CODE_BEGIN
 | 
				
			|||||||
    //   
 | 
					    //   
 | 
				
			||||||
    //   Initialize x6 as a virtual pointer to the test results
 | 
					    //   Initialize x6 as a virtual pointer to the test results
 | 
				
			||||||
    //   Initialize x16 as a physical pointer to the test results
 | 
					    //   Initialize x16 as a physical pointer to the test results
 | 
				
			||||||
    //   Set up stack pointer (sp = x2)
 | 
					    //   Set up stack pointer, mscratch, sscratch
 | 
				
			||||||
    //   
 | 
					    //   
 | 
				
			||||||
	// ---------------------------------------------------------------------------------------------
 | 
						// ---------------------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -50,8 +50,12 @@ RVTEST_CODE_BEGIN
 | 
				
			|||||||
    la x16, test_1_res // x16 reserved for the physical address equivalent of x6 to be used in trap handlers
 | 
					    la x16, test_1_res // x16 reserved for the physical address equivalent of x6 to be used in trap handlers
 | 
				
			||||||
                        // any time either is used, both must be updated.
 | 
					                        // any time either is used, both must be updated.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // address for stack
 | 
					    // address for normal user stack, mscratch stack, and sscratch stack
 | 
				
			||||||
    la sp, top_of_stack
 | 
					    la sp, mscratch_top
 | 
				
			||||||
 | 
					    csrw mscratch, sp
 | 
				
			||||||
 | 
					    la sp, sscratch_top
 | 
				
			||||||
 | 
					    csrw sscratch, sp
 | 
				
			||||||
 | 
					    la sp, stack_top
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.endm
 | 
					.endm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -72,7 +76,7 @@ cause_instr_addr_misaligned:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
cause_instr_access:
 | 
					cause_instr_access:
 | 
				
			||||||
    la x28, 0x0 // address zero is an address with no memory
 | 
					    la x28, 0x0 // address zero is an address with no memory
 | 
				
			||||||
    sd x1, -8(sp) // push the return adress ontot the stack
 | 
					    sd x1, -8(sp) // push the return adress onto the stack
 | 
				
			||||||
    addi sp, sp, -8
 | 
					    addi sp, sp, -8
 | 
				
			||||||
    jalr x28 // cause instruction access trap
 | 
					    jalr x28 // cause instruction access trap
 | 
				
			||||||
    ld x1, 0(sp) // pop return adress back from the stack
 | 
					    ld x1, 0(sp) // pop return adress back from the stack
 | 
				
			||||||
@ -83,7 +87,7 @@ cause_illegal_instr:
 | 
				
			|||||||
    .word 0x00000000 // a 32 bit zros is an illegal instruction
 | 
					    .word 0x00000000 // a 32 bit zros is an illegal instruction
 | 
				
			||||||
    ret
 | 
					    ret
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cause_breakpnt: // ****
 | 
					cause_breakpnt:
 | 
				
			||||||
    ebreak
 | 
					    ebreak
 | 
				
			||||||
    ret
 | 
					    ret
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -128,7 +132,9 @@ cause_time_interrupt:
 | 
				
			|||||||
    sw x31,4(x29)          // store into most significant word of MTIMECMP
 | 
					    sw x31,4(x29)          // store into most significant word of MTIMECMP
 | 
				
			||||||
nowrap:
 | 
					nowrap:
 | 
				
			||||||
    sw x28, 0(x29)         // store into least significant word of MTIMECMP
 | 
					    sw x28, 0(x29)         // store into least significant word of MTIMECMP
 | 
				
			||||||
    loop: j loop         // wait until interrupt occurs
 | 
					loop:
 | 
				
			||||||
 | 
					    wfi 
 | 
				
			||||||
 | 
					    j loop         // wait until interrupt occurs
 | 
				
			||||||
    ret
 | 
					    ret
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cause_soft_interrupt:
 | 
					cause_soft_interrupt:
 | 
				
			||||||
@ -150,7 +156,7 @@ end_trap_triggers:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
.macro TRAP_HANDLER MODE, VECTORED=1, DEBUG=0
 | 
					.macro TRAP_HANDLER MODE, VECTORED=1, DEBUG=0
 | 
				
			||||||
    // MODE decides which mode this trap handler will be taken in (M or S mode)
 | 
					    // MODE decides which mode this trap handler will be taken in (M or S mode)
 | 
				
			||||||
    // Vectored decides whether interrumpts are handled with the vector table at trap_handler_MODE (1)
 | 
					    // Vectored decides whether interrupts are handled with the vector table at trap_handler_MODE (1)
 | 
				
			||||||
    //      vs Using the non-vector approach the rest of the trap handler takes (0)
 | 
					    //      vs Using the non-vector approach the rest of the trap handler takes (0)
 | 
				
			||||||
    // DEBUG decides whether we will print mtval a string with status.mpie, status.mie, and status.mpp to the signature (1)
 | 
					    // DEBUG decides whether we will print mtval a string with status.mpie, status.mie, and status.mpp to the signature (1)
 | 
				
			||||||
    //      vs not saving that info to the signature (0)
 | 
					    //      vs not saving that info to the signature (0)
 | 
				
			||||||
@ -216,23 +222,28 @@ trap_handler_\MODE\():
 | 
				
			|||||||
    // *** ASSUMES that a cause value of 0 for an interrupt is unimplemented
 | 
					    // *** ASSUMES that a cause value of 0 for an interrupt is unimplemented
 | 
				
			||||||
    // otherwise, a vectored interrupt handler should jump to trap_handler_\MODE\() + 4 * Interrupt cause code
 | 
					    // otherwise, a vectored interrupt handler should jump to trap_handler_\MODE\() + 4 * Interrupt cause code
 | 
				
			||||||
    // No matter the value of VECTORED, exceptions (not interrupts) are handled in an unvecotred way
 | 
					    // No matter the value of VECTORED, exceptions (not interrupts) are handled in an unvecotred way
 | 
				
			||||||
    j soft_interrupt_\MODE\()    // 1: instruction access fault // the zero spot is taken up by the instruction to skip this table.
 | 
					    j s_soft_vector_\MODE\()    // 1: instruction access fault // the zero spot is taken up by the instruction to skip this table.
 | 
				
			||||||
    j segfault_\MODE\()            // 2: reserved
 | 
					    j segfault_\MODE\()            // 2: reserved
 | 
				
			||||||
    j soft_interrupt_\MODE\()    // 3: breakpoint
 | 
					    j m_soft_vector_\MODE\()    // 3: breakpoint
 | 
				
			||||||
    j segfault_\MODE\()            // 4: reserved
 | 
					    j segfault_\MODE\()            // 4: reserved
 | 
				
			||||||
    j time_interrupt_\MODE\()    // 5: load access fault
 | 
					    j s_time_vector_\MODE\()    // 5: load access fault
 | 
				
			||||||
    j segfault_\MODE\()            // 6: reserved
 | 
					    j segfault_\MODE\()            // 6: reserved
 | 
				
			||||||
    j time_interrupt_\MODE\()    // 7: store access fault
 | 
					    j m_time_vector_\MODE\()    // 7: store access fault
 | 
				
			||||||
    j segfault_\MODE\()            // 8: reserved
 | 
					    j segfault_\MODE\()            // 8: reserved
 | 
				
			||||||
    j ext_interrupt_\MODE\()     // 9: ecall from S-mode
 | 
					    j s_ext_vector_\MODE\()     // 9: ecall from S-mode
 | 
				
			||||||
    j segfault_\MODE\()            // 10: reserved
 | 
					    j segfault_\MODE\()            // 10: reserved
 | 
				
			||||||
    j ext_interrupt_\MODE\()     // 11: ecall from M-mode
 | 
					    j m_ext_vector_\MODE\()     // 11: ecall from M-mode
 | 
				
			||||||
    // 12 through >=16 are reserved or designated for platform use
 | 
					    // 12 through >=16 are reserved or designated for platform use
 | 
				
			||||||
 | 
					
 | 
				
			||||||
trap_unvectored_\MODE\():
 | 
					trap_unvectored_\MODE\():
 | 
				
			||||||
 | 
					    csrrw sp, \MODE\()scratch, sp // swap sp and scratch so we can use the scratch stack in the trap hanler without messing up sp's value or the stack itself.
 | 
				
			||||||
 | 
					    // *** NOTE: this means that nested traps will be screwed up but they shouldn't happen in any of these tests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					trap_stack_saved_\MODE\(): // jump here after handling vectored interupt since we already switch sp and scratch there
 | 
				
			||||||
    // save registers on stack before using
 | 
					    // save registers on stack before using
 | 
				
			||||||
    sd x1, -8(sp)       
 | 
					    sd x1, -8(sp)       
 | 
				
			||||||
    sd x5, -16(sp)
 | 
					    sd x5, -16(sp)
 | 
				
			||||||
 | 
					    sd x7, -24(sp) 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Record trap
 | 
					    // Record trap
 | 
				
			||||||
    csrr x1, \MODE\()cause     // record the mcause
 | 
					    csrr x1, \MODE\()cause     // record the mcause
 | 
				
			||||||
@ -262,49 +273,35 @@ trap_unvectored_\MODE\():
 | 
				
			|||||||
    // Respond to trap based on cause
 | 
					    // Respond to trap based on cause
 | 
				
			||||||
    // All interrupts should return after being logged
 | 
					    // All interrupts should return after being logged
 | 
				
			||||||
    csrr x1, \MODE\()cause
 | 
					    csrr x1, \MODE\()cause
 | 
				
			||||||
 | 
					    slli x1, x1, 3          // multiply cause by 8 to get offset in vector Table
 | 
				
			||||||
    li x5, 0x8000000000000000   // if msb is set, it is an interrupt
 | 
					    li x5, 0x8000000000000000   // if msb is set, it is an interrupt
 | 
				
			||||||
    and x5, x5, x1
 | 
					    and x5, x5, x1
 | 
				
			||||||
    bnez x5, trapreturn_\MODE\()   // return from interrupt
 | 
					    bnez x5, interrupt_handler_\MODE\()  // return from interrupt
 | 
				
			||||||
    // Other trap handling is specified in the vector Table
 | 
					    // Other trap handling is specified in the vector Table
 | 
				
			||||||
    slli x1, x1, 3      // multiply cause by 8 to get offset in vector Table
 | 
					 | 
				
			||||||
    la x5, exception_vector_table_\MODE\()
 | 
					    la x5, exception_vector_table_\MODE\()
 | 
				
			||||||
    add x5, x5, x1      // compute address of vector in Table
 | 
					    add x5, x5, x1      // compute address of vector in Table
 | 
				
			||||||
    ld x5, 0(x5)        // fectch address of handler from vector Table
 | 
					    ld x5, 0(x5)        // fectch address of handler from vector Table
 | 
				
			||||||
    jr x5               // and jump to the handler
 | 
					    jr x5               // and jump to the handler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interrupt_handler_\MODE\():
 | 
				
			||||||
 | 
					    la x5, interrupt_vector_table_\MODE\() // NOTE THIS IS NOT THE SAME AS VECTORED INTERRUPTS!!!
 | 
				
			||||||
 | 
					    add x5, x5, x1      // compute address of vector in Table
 | 
				
			||||||
 | 
					    ld x5, 0(x5)        // fectch address of handler from vector Table
 | 
				
			||||||
 | 
					    jr x5               // and jump to the handler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
segfault_\MODE\():
 | 
					segfault_\MODE\():
 | 
				
			||||||
    ld x5, -16(sp)      // restore registers from stack before faulting
 | 
					    sd x7, -24(sp)  // restore registers from stack before faulting 
 | 
				
			||||||
 | 
					    ld x5, -16(sp)
 | 
				
			||||||
    ld x1, -8(sp)       
 | 
					    ld x1, -8(sp)       
 | 
				
			||||||
    j terminate_test          // halt program.
 | 
					    j terminate_test          // halt program.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
trapreturn_\MODE\():
 | 
					trapreturn_\MODE\():
 | 
				
			||||||
    // look at the instruction to figure out whether to add 2 or 4 bytes to PC, or go to address specified in a1
 | 
					    csrr x1, \MODE\()epc
 | 
				
			||||||
    csrr x1, \MODE\()epc       // get the mepc
 | 
					    addi x1, x1, 4 // return to the address AFTER the trapping instruction
 | 
				
			||||||
    addi x1, x1, 4 // *** should be 2 for compressed instructions, see note.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ****** KMG: the following is no longer as easy to determine. mepc gets the virtual address of the trapped instruction, 
 | 
					 | 
				
			||||||
// ********     but in the handler, we work in M mode with physical addresses
 | 
					 | 
				
			||||||
//              This means the address in mepc is suddenly pointing somewhere else.
 | 
					 | 
				
			||||||
//              to get this to work, We could either retranslate the vaddr back into a paddr (probably on the scale of difficult to intractible)
 | 
					 | 
				
			||||||
//              or we could come up with some other ingenious way to stay in M mode and see if the instruction was compressed.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//     lw x5, 0(x1)        // read the faulting instruction
 | 
					 | 
				
			||||||
//     li x1, 3            // check bottom 2 bits of instruction to see if compressed
 | 
					 | 
				
			||||||
//     and x5, x5, x1      // mask the other bits
 | 
					 | 
				
			||||||
//     beq x5, x1, trapreturn_uncompressed_\MODE\()  // if 11, the instruction is return_uncompressed
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// trapreturn_compressed_\MODE\():
 | 
					 | 
				
			||||||
//     csrr x1, mepc       // get the mepc again
 | 
					 | 
				
			||||||
//     addi x1, x1, 2      // add 2 to find the next instruction
 | 
					 | 
				
			||||||
//     j trapreturn_specified_\MODE\() // and return
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// trapreturn_uncompressed_\MODE\():
 | 
					 | 
				
			||||||
//      csrr x1, mepc       // get the mepc again    
 | 
					 | 
				
			||||||
//      addi x1, x1, 4      // add 4 to find the next instruction
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
trapreturn_specified_\MODE\():
 | 
					trapreturn_specified_\MODE\():
 | 
				
			||||||
    // reset the necessary pointers and registers (x1, x5, x6, and the return address going to mepc)
 | 
					    // reset the necessary pointers and registers (x1, x5, x6, and the return address going to mepc)
 | 
				
			||||||
 | 
					    // note that we don't need to change x7 since it was a temporary register with no important address in it.
 | 
				
			||||||
    // so that when we return to a new virtual address, they're all in the right spot as well.
 | 
					    // so that when we return to a new virtual address, they're all in the right spot as well.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    beqz a1, trapreturn_finished_\MODE\() // either update values, of go to default return address.
 | 
					    beqz a1, trapreturn_finished_\MODE\() // either update values, of go to default return address.
 | 
				
			||||||
@ -318,13 +315,13 @@ trapreturn_specified_\MODE\():
 | 
				
			|||||||
    sll x5, x5, a2
 | 
					    sll x5, x5, a2
 | 
				
			||||||
    addi x5, x5, -1 // x5 = mask bits for offset into current pagetype
 | 
					    addi x5, x5, -1 // x5 = mask bits for offset into current pagetype
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // reset the top of the stack, x1
 | 
					    // reset the top of the stack, which will be put into ra
 | 
				
			||||||
    ld x7, -8(sp) 
 | 
					    ld x7, -8(sp) 
 | 
				
			||||||
    and x7, x5, x7 // x7 = offset for x1
 | 
					    and x7, x5, x7 // x7 = offset for x1
 | 
				
			||||||
    add x7, x7, a1 // x7 = new address for x1
 | 
					    add x7, x7, a1 // x7 = new address for x1
 | 
				
			||||||
    sd x7, -8(sp)
 | 
					    sd x7, -8(sp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // reset the second spot in the stack, x5
 | 
					    // reset the second spot in the stack, which will be put into x5
 | 
				
			||||||
    ld x7, -16(sp)
 | 
					    ld x7, -16(sp)
 | 
				
			||||||
    and x7, x5, x7 // x7 = offset for x5
 | 
					    and x7, x5, x7 // x7 = offset for x5
 | 
				
			||||||
    add x7, x7, a1 // x7 = new address for x5
 | 
					    add x7, x7, a1 // x7 = new address for x5
 | 
				
			||||||
@ -334,7 +331,7 @@ trapreturn_specified_\MODE\():
 | 
				
			|||||||
    and x7, x5, x6 // x7 = offset for x6
 | 
					    and x7, x5, x6 // x7 = offset for x6
 | 
				
			||||||
    add x6, x7, a1 // x6 = new address for the result pointer
 | 
					    add x6, x7, a1 // x6 = new address for the result pointer
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // set return address, stored temporarily in x1, to the next instruction, but in the new virtual page.
 | 
					    // reset x1, which temporarily holds the return address that will be written to mepc.
 | 
				
			||||||
    and x1, x5, x1 // x1 = offset for the return address
 | 
					    and x1, x5, x1 // x1 = offset for the return address
 | 
				
			||||||
    add x1, x1, a1 // x1 = new return address.
 | 
					    add x1, x1, a1 // x1 = new return address.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -343,9 +340,9 @@ trapreturn_specified_\MODE\():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
trapreturn_finished_\MODE\():
 | 
					trapreturn_finished_\MODE\():
 | 
				
			||||||
    csrw \MODE\()epc, x1            // update the epc with address of next instruction
 | 
					    csrw \MODE\()epc, x1            // update the epc with address of next instruction
 | 
				
			||||||
    ld x5, -16(sp)      // restore registers from stack before returning
 | 
					    ld x7, -24(sp)     // restore registers from stack before returning
 | 
				
			||||||
 | 
					    ld x5, -16(sp)
 | 
				
			||||||
    ld x1, -8(sp)
 | 
					    ld x1, -8(sp)
 | 
				
			||||||
    // *** this should be handled by indirectly clearing this bit csrw \MODE\()ip, 0x0 // clear interrupt pending register to indicate interrupt has been handled
 | 
					 | 
				
			||||||
    \MODE\()ret  // return from trap
 | 
					    \MODE\()ret  // return from trap
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ecallhandler_\MODE\():
 | 
					ecallhandler_\MODE\():
 | 
				
			||||||
@ -380,18 +377,17 @@ ecallhandler_changetousermode_\MODE\():
 | 
				
			|||||||
    j trapreturn_\MODE\()
 | 
					    j trapreturn_\MODE\()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
instrpagefault_\MODE\():
 | 
					instrpagefault_\MODE\():
 | 
				
			||||||
    ld x1, -8(sp) // load return address int x1 (the address AFTER the jal to the faulting address)
 | 
					    ld x1, -8(sp) // load return address from stack into ra (the address AFTER the jal to the faulting address)
 | 
				
			||||||
    j trapreturn_finished_\MODE\() // puts x1 into mepc, restores stack and returns to program (outside of faulting page)
 | 
					    j trapreturn_finished_\MODE\() // puts x1 into mepc, restores stack and returns to program (outside of faulting page)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
instrfault_\MODE\():
 | 
					instrfault_\MODE\():
 | 
				
			||||||
    ld x1, -8(sp) // load return address int x1 (the address AFTER the jal to the faulting address)
 | 
					    ld x1, -8(sp) // load return address from stack into ra (the address AFTER the jal to the faulting address)
 | 
				
			||||||
    j trapreturn_finished_\MODE\() // return to the code after recording the mcause
 | 
					    j trapreturn_finished_\MODE\() // return to the code at ra value from before trap
 | 
				
			||||||
 | 
					
 | 
				
			||||||
illegalinstr_\MODE\():
 | 
					illegalinstr_\MODE\():
 | 
				
			||||||
    j trapreturn_\MODE\() // return to the code after recording the mcause
 | 
					    j trapreturn_\MODE\() // return to the code after recording the mcause
 | 
				
			||||||
 | 
					
 | 
				
			||||||
accessfault_\MODE\():
 | 
					accessfault_\MODE\():
 | 
				
			||||||
    // *** What do I have to do here?
 | 
					 | 
				
			||||||
    j trapreturn_\MODE\()
 | 
					    j trapreturn_\MODE\()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
addr_misaligned_\MODE\():
 | 
					addr_misaligned_\MODE\():
 | 
				
			||||||
@ -400,36 +396,67 @@ addr_misaligned_\MODE\():
 | 
				
			|||||||
breakpt_\MODE\():
 | 
					breakpt_\MODE\():
 | 
				
			||||||
    j trapreturn_\MODE\()
 | 
					    j trapreturn_\MODE\()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
soft_interrupt_\MODE\():
 | 
					s_soft_vector_\MODE\():
 | 
				
			||||||
    li x5, 0x7EC // write 0x7EC (looks like VEC) to the output before the mcause and extras to indicate that this trap was handled with a vector table. 
 | 
					    csrrw sp, \MODE\()scratch, sp // swap sp and scratch so we can use the scratch stack in the trap hanler without messing up sp's value or the stack itself.
 | 
				
			||||||
    sd x5, 0(x16)
 | 
					    sd x5, -8(sp) // put x5 on the scratch stack before messing with it
 | 
				
			||||||
 | 
					    li x5, 0x7EC01 // write 0x7ec01 (for "VEC"tored and 01 for the interrupt code)
 | 
				
			||||||
 | 
					    j vectored_int_end_\MODE\()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					m_soft_vector_\MODE\():
 | 
				
			||||||
 | 
					    csrrw sp, \MODE\()scratch, sp // swap sp and scratch so we can use the scratch stack in the trap hanler without messing up sp's value or the stack itself.
 | 
				
			||||||
 | 
					    sd x5, -8(sp) // put x5 on the scratch stack before messing with it
 | 
				
			||||||
 | 
					    li x5, 0x7EC03 // write 0x7ec03 (for "VEC"tored and 03 for the interrupt code)
 | 
				
			||||||
 | 
					    j vectored_int_end_\MODE\()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					s_time_vector_\MODE\():
 | 
				
			||||||
 | 
					    csrrw sp, \MODE\()scratch, sp // swap sp and scratch so we can use the scratch stack in the trap hanler without messing up sp's value or the stack itself.
 | 
				
			||||||
 | 
					    sd x5, -8(sp) // put x5 on the scratch stack before messing with it
 | 
				
			||||||
 | 
					    li x5, 0x7EC05 // write 0x7ec05 (for "VEC"tored and 05 for the interrupt code)
 | 
				
			||||||
 | 
					    j vectored_int_end_\MODE\()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					m_time_vector_\MODE\():
 | 
				
			||||||
 | 
					    csrrw sp, \MODE\()scratch, sp // swap sp and scratch so we can use the scratch stack in the trap hanler without messing up sp's value or the stack itself.
 | 
				
			||||||
 | 
					    sd x5, -8(sp) // put x5 on the scratch stack before messing with it
 | 
				
			||||||
 | 
					    li x5, 0x7EC07 // write 0x7ec07 (for "VEC"tored and 07 for the interrupt code)
 | 
				
			||||||
 | 
					    j vectored_int_end_\MODE\()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					s_ext_vector_\MODE\():
 | 
				
			||||||
 | 
					    csrrw sp, \MODE\()scratch, sp // swap sp and scratch so we can use the scratch stack in the trap hanler without messing up sp's value or the stack itself.
 | 
				
			||||||
 | 
					    sd x5, -8(sp) // put x5 on the scratch stack before messing with it
 | 
				
			||||||
 | 
					    li x5, 0x7EC09 // write 0x7ec09 (for "VEC"tored and 08 for the interrupt code)
 | 
				
			||||||
 | 
					    j vectored_int_end_\MODE\()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					m_ext_vector_\MODE\():
 | 
				
			||||||
 | 
					    csrrw sp, \MODE\()scratch, sp // swap sp and scratch so we can use the scratch stack in the trap hanler without messing up sp's value or the stack itself.
 | 
				
			||||||
 | 
					    sd x5, -8(sp) // put x5 on the scratch stack before messing with it
 | 
				
			||||||
 | 
					    li x5, 0x7EC0B // write 0x7ec0B (for "VEC"tored and 0B for the interrupt code)
 | 
				
			||||||
 | 
					    j vectored_int_end_\MODE\()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vectored_int_end_\MODE\():
 | 
				
			||||||
 | 
					    sd x5, 0(x16) // store to signature to show vectored interrupts succeeded. 
 | 
				
			||||||
    addi x6, x6, 8
 | 
					    addi x6, x6, 8
 | 
				
			||||||
    addi x16, x16, 8
 | 
					    addi x16, x16, 8
 | 
				
			||||||
 | 
					    ld x5, -8(sp) // restore x5 before continuing to handle trap in case its needed.
 | 
				
			||||||
 | 
					    j trap_stack_saved_\MODE\()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					soft_interrupt_\MODE\():
 | 
				
			||||||
    la x28, 0x02000000 // Reset by clearing MSIP interrupt from CLINT
 | 
					    la x28, 0x02000000 // Reset by clearing MSIP interrupt from CLINT
 | 
				
			||||||
    sw x0, 0(x28)
 | 
					    sw x0, 0(x28)
 | 
				
			||||||
    j trap_unvectored_\MODE\()
 | 
					    j trapreturn_\MODE\()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
time_interrupt_\MODE\():
 | 
					time_interrupt_\MODE\():
 | 
				
			||||||
    li x5, 0x7EC
 | 
					 | 
				
			||||||
    sd x5, 0(x16)
 | 
					 | 
				
			||||||
    addi x6, x6, 8
 | 
					 | 
				
			||||||
    addi x16, x16, 8
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    la x29, 0x02004000    // MTIMECMP register in CLINT
 | 
					    la x29, 0x02004000    // MTIMECMP register in CLINT
 | 
				
			||||||
    li x30, 0xFFFFFFFF
 | 
					    li x30, 0xFFFFFFFF
 | 
				
			||||||
    sd x30, 0(x29) // reset interrupt by setting mtimecmp to 0xFFFFFFFF
 | 
					    sd x30, 0(x29) // reset interrupt by setting mtimecmp to 0xFFFFFFFF
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    j trap_unvectored_\MODE\()
 | 
					    ld x1, -8(sp) // load return address from stack into ra (the address AFTER the jal to the faulting address)
 | 
				
			||||||
 | 
					    j trapreturn_finished_\MODE\() // return to the code at ra value from before trap
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ext_interrupt_\MODE\():
 | 
					ext_interrupt_\MODE\():
 | 
				
			||||||
    li x5, 0x7EC
 | 
					 | 
				
			||||||
    sd x5, 0(x16)
 | 
					 | 
				
			||||||
    addi x6, x6, 8
 | 
					 | 
				
			||||||
    addi x16, x16, 8
 | 
					 | 
				
			||||||
    li x28, 0x10060000 // reset interrupt by clearing all the GPIO bits
 | 
					    li x28, 0x10060000 // reset interrupt by clearing all the GPIO bits
 | 
				
			||||||
    sw x0, 8(x28) // disable the first pin as an output
 | 
					    sw x0, 8(x28) // disable the first pin as an output
 | 
				
			||||||
    sw x0, 40(x28) // write a 0 to the first output pin (reset interrupt)
 | 
					    sw x0, 40(x28) // write a 0 to the first output pin (reset interrupt)
 | 
				
			||||||
    j trap_unvectored_\MODE\()
 | 
					    j trapreturn_\MODE\()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Table of trap behavior
 | 
					    // Table of trap behavior
 | 
				
			||||||
    // lists what to do on each exception (not interrupts)
 | 
					    // lists what to do on each exception (not interrupts)
 | 
				
			||||||
@ -455,6 +482,21 @@ exception_vector_table_\MODE\():
 | 
				
			|||||||
    .8byte segfault_\MODE\()      // 14: reserved
 | 
					    .8byte segfault_\MODE\()      // 14: reserved
 | 
				
			||||||
    .8byte trapreturn_\MODE\()    // 15: store page fault
 | 
					    .8byte trapreturn_\MODE\()    // 15: store page fault
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .align 3 // aligns this data table to an 8 byte boundary
 | 
				
			||||||
 | 
					interrupt_vector_table_\MODE\():
 | 
				
			||||||
 | 
					    .8byte segfault_\MODE\()            // 0: reserved
 | 
				
			||||||
 | 
					    .8byte s_soft_vector_\MODE\()    // 1: instruction access fault // the zero spot is taken up by the instruction to skip this table.
 | 
				
			||||||
 | 
					    .8byte segfault_\MODE\()            // 2: reserved
 | 
				
			||||||
 | 
					    .8byte m_soft_vector_\MODE\()    // 3: breakpoint
 | 
				
			||||||
 | 
					    .8byte segfault_\MODE\()            // 4: reserved
 | 
				
			||||||
 | 
					    .8byte s_time_vector_\MODE\()    // 5: load access fault
 | 
				
			||||||
 | 
					    .8byte segfault_\MODE\()            // 6: reserved
 | 
				
			||||||
 | 
					    .8byte m_time_vector_\MODE\()    // 7: store access fault
 | 
				
			||||||
 | 
					    .8byte segfault_\MODE\()            // 8: reserved
 | 
				
			||||||
 | 
					    .8byte s_ext_vector_\MODE\()     // 9: ecall from S-mode
 | 
				
			||||||
 | 
					    .8byte segfault_\MODE\()            // 10: reserved
 | 
				
			||||||
 | 
					    .8byte m_ext_vector_\MODE\()     // 11: ecall from M-mode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.align 3
 | 
					.align 3
 | 
				
			||||||
trap_return_pagetype_table_\MODE\():
 | 
					trap_return_pagetype_table_\MODE\():
 | 
				
			||||||
    .8byte 0xC  // 0: kilopage has 12 offset bits
 | 
					    .8byte 0xC  // 0: kilopage has 12 offset bits
 | 
				
			||||||
@ -1051,9 +1093,20 @@ rvtest_data:
 | 
				
			|||||||
RVTEST_DATA_END
 | 
					RVTEST_DATA_END
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.align 3 // align stack to 8 byte boundary
 | 
					.align 3 // align stack to 8 byte boundary
 | 
				
			||||||
bottom_of_stack:
 | 
					stack_bottom:
 | 
				
			||||||
    .fill 1024, 4, 0xdeadbeef 
 | 
					    .fill 1024, 4, 0xdeadbeef 
 | 
				
			||||||
top_of_stack:
 | 
					stack_top:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.align 3
 | 
				
			||||||
 | 
					mscratch_bottom:
 | 
				
			||||||
 | 
					    .fill 512, 4, 0xdeadbeef
 | 
				
			||||||
 | 
					mscratch_top:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.align 3
 | 
				
			||||||
 | 
					sscratch_bottom:
 | 
				
			||||||
 | 
					    .fill 512, 4, 0xdeadbeef
 | 
				
			||||||
 | 
					sscratch_top:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RVMODEL_DATA_BEGIN
 | 
					RVMODEL_DATA_BEGIN
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user