Fixed Issue #1321 about wally32periph failing on rv32imc; removed SEIP tests from WALLY-periph-01 and put them in WALY-periph-s

This commit is contained in:
David Harris 2025-04-12 20:32:51 -07:00
parent 556f965757
commit 3101d27d95
5 changed files with 1465 additions and 199 deletions

View file

@ -3584,6 +3584,7 @@ string wally32priv[] = '{
"rv32i_m/privilege/src/WALLY-endianness-01.S",
"rv32i_m/privilege/src/WALLY-satp-invalid-01.S",
// These peripherals are here instead of wally32periph because they don't work on rv32imc, which lacks a PMP register to configure
"rv32i_m/privilege/src/WALLY-periph-s-01.S",
"rv32i_m/privilege/src/WALLY-gpio-01.S",
"rv32i_m/privilege/src/WALLY-clint-01.S",
"rv32i_m/privilege/src/WALLY-uart-01.S",

View file

@ -1,20 +1,20 @@
01BEEF00
8000000B
00000000
0000000A
00000004
00000061
00000061
00000068
00000060
00000001
00000000
00000000
00000000
00000000
00000000
00000000
01BEEF01
01BEEF00 # Test 1 interrupt 0
8000000B # MEIP
00000000 # mcausehigh
0000000A # claim ID
00000004 # IIR
00000061 # LSR
00000061 # LSR after reading LSR
00000068 # RBR
00000060 # LSR after erading RBR too
00000001 # SCR
00000000 # null
00000000 # null
00000000 # null
00000000 # null
00000000 # null
00000000 #null
01BEEF01 # Test 1 interrupt 1
8000000B
00000000
00000003
@ -30,7 +30,7 @@ FFFFFFFF
FFF7FFFF
00000000
00000000
01BEEF02
01BEEF02 # Test 1 interrupt 2
8000000B
00000000
00000003
@ -46,7 +46,7 @@ FFFFFFFF
FFFFFFFE
00000000
00000000
01BEEF03
01BEEF03 # Test 1 interrupt 3
8000000B
00000000
0000000A
@ -62,7 +62,7 @@ FFFFFFFE
00000000
00000000
00000000
02BEEF04
02BEEF04 # Test 2 interrupt 4
8000000B
00000000
00000003
@ -78,7 +78,7 @@ FFFFFFFF
FFFF0F0F
00000000
00000000
02BEEF05
02BEEF05 # Test 2 interrupt 5
8000000B
00000000
00000003
@ -94,7 +94,7 @@ FFFFFFFF
CFCFFFFF
00000000
00000000
02BEEF06
02BEEF06 # Test 2 interrupt 6
8000000B
00000000
00000003
@ -110,7 +110,7 @@ CFFFFFFF
CFFFFFFF
00000000
00000000
02BEEF07
02BEEF07 # Test 2 interrupt 7
8000000B
00000000
00000003
@ -126,7 +126,7 @@ FFFFFFFF
F0FFFFFF
00000000
00000000
02BEEF08
02BEEF08 # Test 2 interrupt 8
8000000B
00000000
00000003
@ -142,7 +142,7 @@ FFFFFFFF
FF0000FF
00000000
00000000
02BEEF09
02BEEF09 # Test 2 interrupt 9
8000000B
00000000
00000003
@ -158,7 +158,7 @@ FF0000FF
CC0000CC
00000000
00000000
02BEEF0A
02BEEF0A # Test 2 interrupt 10
8000000B
00000000
00000003
@ -174,7 +174,7 @@ CCFFFFCC
CCFFFFCC
00000000
00000000
02BEEF0B
02BEEF0B Test 2 interrupt 11
8000000B
00000000
00000003
@ -190,7 +190,7 @@ FFFFFFFF
FF3333FF
00000000
00000000
02BEEF0C
02BEEF0C # Test 2 interrupt 12
8000000B
00000000
00000003
@ -206,7 +206,7 @@ FF3333FF
FF3333FF
00000000
00000000
02BEEF0D
02BEEF0D # Test 2 interrupt 13
8000000B
00000000
00000003
@ -222,7 +222,7 @@ FFFFFFFF
33FF3333
00000000
00000000
02BEEF0E
02BEEF0E # Test 2 interrupt 14
8000000B
00000000
00000003
@ -238,7 +238,7 @@ CCCCCCCC
33333333
00000000
00000000
02BEEF0F
02BEEF0F # Test 2 interrupt 15
8000000B
00000000
00000003
@ -254,7 +254,7 @@ FFFFEE00
FFFFEE00
00000000
00000000
02BEEF10 # Something here is failing
02BEEF10 # Test 2 interrupt 16
8000000B
00000000
00000003
@ -270,7 +270,7 @@ FFFFFFFF
FFFFFF00
00000000
00000000
02BEEF11 # this might be wrong
02BEEF11 # Test 2 interrupt 17
8000000B
00000000
00000003
@ -286,7 +286,7 @@ FFFFFFCC # low ip
FFFFFFCC # serviced low ip
00000000
00000000
03BEEF12
03BEEF12 # test 3 interrupt 18
8000000B
00000000
0000000A
@ -302,7 +302,7 @@ FFFFFFCC # serviced low ip
00000000
00000000
00000000
03BEEF13
03BEEF13 # Test 3 interrupt 19
8000000B
00000000
0000000A
@ -318,7 +318,7 @@ FFFFFFCC # serviced low ip
00000000
00000000
00000000
03BEEF14
03BEEF14 # Test 3 interrupt 20
8000000B
00000000
0000000A
@ -334,7 +334,7 @@ FFFFFFCC # serviced low ip
00000000
00000000
00000000
03BEEF15
03BEEF15 # Test 3 interrupt 21
8000000B
00000000
0000000A
@ -350,7 +350,7 @@ FFFFFFCC # serviced low ip
00000000
00000000
00000000
03BEEF16
03BEEF16 # Test 3 interrupt 22
8000000B
00000000
0000000A
@ -366,7 +366,7 @@ FFFFFFCC # serviced low ip
00000000
00000000
00000000
03BEEF17
03BEEF17 # Test 3 interrupt 23
8000000B
00000000
0000000A
@ -382,7 +382,7 @@ FFFFFFCC # serviced low ip
00000000
00000000
00000000
03BEEF18
03BEEF18 # Test 3 interrupt 24
8000000B
00000000
0000000A
@ -398,7 +398,7 @@ FFFFFFCC # serviced low ip
00000000
00000000
00000000
03BEEF19
03BEEF19 # Test 3 interrupt 25
8000000B
00000000
0000000A
@ -414,7 +414,7 @@ FFFFFFCC # serviced low ip
00000000
00000000
00000000
03BEEF1A
03BEEF1A # Test 3 interrupt 26
8000000B
00000000
0000000A
@ -430,67 +430,3 @@ FFFFFFCC # serviced low ip
00000000
00000000
00000000
04BEEF1B
80000009
00000000
0000000A
00000004
00000061
00000061
00000065
00000060
00000001
000000ff
00000000
00000000
00000000
00000000
00000000
04BEEF1C
80000009
00000000
00000003
00080000
00080000
00080000
00000000
00000000 # is it this one that's failing?
00000000
00080000 # failing
00080000
FFFFFFFF
FFF7FFFF
00000000
00000000
04BEEF1D
80000009
00000000
00000003
00000001
00000001
00000001
00000000
00080000
00000000
00080001
00000001
FFFFFFFF
FFFFFFFE
00000000
00000000
04BEEF1E # this might also be wrong
80000009
00000000
0000000A
00000004
00000061
00000061
0000006e
00000060
00000001
000000ff
00000000
00000000
00000000
00000000
00000000

View file

@ -0,0 +1,496 @@
01BEEF00 # Test 1 interrupt 0
8000000B # MEIP
00000000 # mcausehigh
0000000A # claim ID
00000004 # IIR
00000061 # LSR
00000061 # LSR after reading LSR
00000068 # RBR
00000060 # LSR after erading RBR too
00000001 # SCR
00000000 # null
00000000 # null
00000000 # null
00000000 # null
00000000 # null
00000000 #null
01BEEF01 # Test 1 interrupt 1
8000000B
00000000
00000003
00080000
00080000
00080000
00000000
00000000
00000000
00080000
00080000
FFFFFFFF
FFF7FFFF
00000000
00000000
01BEEF02 # Test 1 interrupt 2
8000000B
00000000
00000003
00000001
00000001
00000001
00000000
00080000
00000000
00080001
00000001
FFFFFFFF
FFFFFFFE
00000000
00000000
01BEEF03 # Test 1 interrupt 3
8000000B
00000000
0000000A
00000004
00000061
00000061
00000065
00000060
00000001
00000000
00000000
00000000
00000000
00000000
00000000
02BEEF04 # Test 2 interrupt 4
8000000B
00000000
00000003
0000F0F0
3030F0F0
0000F0F0
00000000
00000001
00000000
0000F0F1
0000F0F0
FFFFFFFF
FFFF0F0F
00000000
00000000
02BEEF05 # Test 2 interrupt 5
8000000B
00000000
00000003
30300000
3030F0F0
30300000
00000000
0000F0F0
00000000
3030F0F0
30300000
FFFFFFFF
CFCFFFFF
00000000
00000000
02BEEF06 # Test 2 interrupt 6
8000000B
00000000
00000003
30000000
3030F0F0
00000000
00000000
00300000
00000000
30300000
30000000
CFFFFFFF
CFFFFFFF
00000000
00000000
02BEEF07 # Test 2 interrupt 7
8000000B
00000000
00000003
0F000000
0F0F0F0F
0F000000
00000000
30000000
00000000
3F000000
0F000000
FFFFFFFF
F0FFFFFF
00000000
00000000
02BEEF08 # Test 2 interrupt 8
8000000B
00000000
00000003
00FFFF00
00FFFF00
00FFFF00
00000000
00000000
00000000
00FFFF00
00FFFF00
FFFFFFFF
FF0000FF
00000000
00000000
02BEEF09 # Test 2 interrupt 9
8000000B
00000000
00000003
33FFFF33
33FFFF33
33000033
00000000
00000000
00000000
33FFFF33
33FFFF33
FF0000FF
CC0000CC
00000000
00000000
02BEEF0A # Test 2 interrupt 10
8000000B
00000000
00000003
33000033
33000033
00000000
00000000
00FFFF00
00000000
33FFFF33
33000033
CCFFFFCC
CCFFFFCC
00000000
00000000
02BEEF0B Test 2 interrupt 11
8000000B
00000000
00000003
00CCCC00
00CCCC00
00CCCC00
00000000
33000033
00000000
33CCCC33
00CCCC00
FFFFFFFF
FF3333FF
00000000
00000000
02BEEF0C # Test 2 interrupt 12
8000000B
00000000
00000003
00CCCC00
00CCCC00
00000000
00000000
00000000
00000000
00CCCC00
00CCCC00
FF3333FF
FF3333FF
00000000
00000000
02BEEF0D # Test 2 interrupt 13
8000000B
00000000
00000003
CC00CCCC
CCCCCCCC
CC00CCCC
00000000
00CCCC00
00000000
CC00CCCC
CC00CCCC
FFFFFFFF
33FF3333
00000000
00000000
02BEEF0E # Test 2 interrupt 14
8000000B
00000000
00000003
CCCCCCCC
CCCCCCCC
00CC0000
00000000
00000000
00000000
CCCCCCCC
CCCCCCCC
33FF3333
33333333
00000000
00000000
02BEEF0F # Test 2 interrupt 15
8000000B
00000000
00000003
000011FF
FF1111FF
33333333
00000000
FFFFEE00
00000000
FFFFFFFF
000011FF
FFFFEE00
FFFFEE00
00000000
00000000
02BEEF10 # Test 2 interrupt 16
8000000B
00000000
00000003
000000FF
00000000
000000FF
00000000
00000000
00000000
000000FF
000000FF
FFFFFFFF
FFFFFF00
00000000
00000000
02BEEF11 # Test 2 interrupt 17
8000000B
00000000
00000003
00000033 # input
00000000 # output
00000000 # rise ip
00000000 # serviced rise ip
000000CC # fall ip
00000000
000000FF # high ip
00000033 # why is this 0x33?
FFFFFFCC # low ip
FFFFFFCC # serviced low ip
00000000
00000000
03BEEF12 # test 3 interrupt 18
8000000B
00000000
0000000A
00000002
00000061
00000061
0000006C
00000060
00000001
00000000
00000000
00000000
00000000
00000000
00000000
03BEEF13 # Test 3 interrupt 19
8000000B
00000000
0000000A
00000002
00000021
00000021
0000006C
00000020
00000001
00000002
00000000
00000000
00000000
00000000
00000000
03BEEF14 # Test 3 interrupt 20
8000000B
00000000
0000000A
00000004
00000061
00000061
0000006F
00000060
00000001
00000000
00000000
00000000
00000000
00000000
00000000
03BEEF15 # Test 3 interrupt 21
8000000B
00000000
0000000A
00000004
00000061
00000061
00000020
00000060
00000001
00000003
00000000
00000000
00000000
00000000
00000000
03BEEF16 # Test 3 interrupt 22
8000000B
00000000
0000000A
00000004
00000061
00000061
00000074
00000060
00000001
00000020
00000000
00000000
00000000
00000000
00000000
03BEEF17 # Test 3 interrupt 23
8000000B
00000000
0000000A
00000002
00000020
00000020
00000074
00000020
00000001
00000003
00000000
00000000
00000000
00000000
00000000
03BEEF18 # Test 3 interrupt 24
8000000B
00000000
0000000A
00000002
00000020
00000020
00000074
00000020
00000001
00000003
00000000
00000000
00000000
00000000
00000000
03BEEF19 # Test 3 interrupt 25
8000000B
00000000
0000000A
00000004
00000061
00000061
00000065
00000060
00000001
00000003
00000000
00000000
00000000
00000000
00000000
03BEEF1A # Test 3 interrupt 26
8000000B
00000000
0000000A
00000006
00000063
00000061
00000047
00000060
00000001
000000FF
00000000
00000000
00000000
00000000
00000000
04BEEF1B # Test 4 interrupt 27
80000009
00000000
0000000A
00000004
00000061
00000061
00000065
00000060
00000001
000000ff
00000000
00000000
00000000
00000000
00000000
04BEEF1C # Test 4 interrupt 28
80000009
00000000
00000003
00080000
00080000
00080000
00000000
00000000
00000000
00080000
00080000
FFFFFFFF
FFF7FFFF
00000000
00000000
04BEEF1D # Test 4 interrupt 29
80000009
00000000
00000003
00000001
00000001
00000001
00000000
00080000
00000000
00080001
00000001
FFFFFFFF
FFFFFFFE
00000000
00000000
04BEEF1E # Test 4 interrupt 30
80000009
00000000
0000000A
00000004
00000061
00000061
0000006e
00000060
00000001
000000ff
00000000
00000000
00000000
00000000
00000000

View file

@ -1,6 +1,6 @@
///////////////////////////////////////////
// WALLY-PERIPH.S
// 64 bit version
// 32 bit version
//
// Ben Bracker (bbracker@hmc.edu)
//
@ -225,9 +225,6 @@ main_code: #####
# load address of trap handler
la t0, trap_handler
csrrw x0, mtvec, t0
# delegate all external interrupts to machine mode
li t0, 0xD00
csrrc x0, mideleg, t0
# set MIE
li t0, 0x8
csrrs x0, mstatus, t0
@ -803,96 +800,9 @@ Intr03BEEF1A:
1: bne t1,a0,1b
li a0, 0
####################################################
##### Test 4 - Signs of Life on PLIC Context 1 #####
####################################################
li a1, 0x04beef00 # group ID
# clear MEIE (good to turn off while configuring peripherals)
li t0, 0x800
csrrc x0, mie, t0
# ========== Configure PLIC ==========
# priority threshold = 0
li t0, 0xC200000
li t1, 0
sw t1, 0(t0)
# source 3 (GPIO) priority = 6
li t0, 0xC000000
li t1, 6
sw t1, 0x0C(t0)
# source 0xA (UART) priority = 7
li t1, 7
sw t1, 0x28(t0)
# disable sources 3,0xA on context 0
li t0, 0x0C002000
li t1, 0
sw t1, 0(t0)
# enable sources 3,0xA on context 1
li t0, 0x0C002080
li t1, 0b10000001000
sw t1, 0(t0)
# ========== Configure UART ==========
# MCR: Loop = 1
li t0, 0x10000000
li t1, 0b10000
sb t1, 4(t0)
# LCR: Use 8 data bits plus odd parity bit
li t1, 0b00001011
sb t1, 3(t0)
# IER: Enable Received Data Available Interrupt
li t1, 0x01
sb t1, 1(t0)
# ========== Configure GPIO ==========
# raise all input_en
li t0, 0x10060000
li t1, 0xFFFFFFFF
sw t1, 0x04(t0)
# raise all output_en
sw t1, 0x08(t0)
# raise all rise_en
sw t1, 0x18(t0)
# ========== Execute Test ==========
# set MEIE and SEIE
li t0, 0xA00
csrrs x0, mie, t0
Intr04BEEF1B:
# UART TX 'e'
li t0, 0x10000000
li t1, 'e'
sb t1, 0(t0)
# wait to finish
li t1, 0b00010000
1: bne t1,a0,1b
li a0, 0
Intr04BEEF1C:
# GPIO raise pin 19
li t0, 0x10060000
li t1, 0x00080000
sw t1, 0x0C(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
# Now let's go bonkers and trigger both!
Intr04BEEF1D:
# TX 'n'
li t0, 0x10000000
li t1, 'n'
sb t1, 0(t0)
Intr04BEEF1E:
# GPIO lower pin 19 raise pin 0
li t0, 0x10060000
li t1, 0x00000001
sw t1, 0x0C(t0)
# wait to finish
li t1, 0b00011000
1: bne t1,a0,1b
li a0, 0
# ---------------------------------------------------------------------------------------------
# PLIC Context 1 not in periph because it is unavailable without S mode in rv32imc
# See WALLY-periph-S for a version that does test PLIC context 1
//terminate_test:
// li a0, 2 // Trap handler behavior (go to machine mode)
// ecall // writes mcause to the output.
// csrw mtvec, x4 // restore original trap handler to halt program
RVTEST_CODE_END
RVMODEL_HALT

View file

@ -0,0 +1,923 @@
///////////////////////////////////////////
// WALLY-PERIPH.S
// 64 bit version
//
// Ben Bracker (bbracker@hmc.edu)
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
// Adapted from Imperas RISCV-TEST_SUITE
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
///////////////////////////////////////////
#include "model_test.h"
#include "arch_test.h"
RVTEST_ISA("RV32I_Zicsr")
// this test is blocked, it won't build or run. To unblock it remove the check ISA:=regex(BLOCKED);
RVTEST_CASE(0,"//check ISA:=regex(.*32.*);check ISA:=regex(.*I.*);def TEST_CASE_1=True;def NO_SAIL=True",periph)
.section .text.init
.globl rvtest_entry_point
rvtest_entry_point:
RVMODEL_BOOT
RVTEST_CODE_BEGIN
# ---------------------------------------------------------------------------------------------
j main_code
# 64 byte alignment for vectored traps to align with xtev
.align 6
###################
###################
trap_handler: #####
###################
###################
# save registers
addi sp, sp, 0x28
sw t0, 0x00(sp)
sw t1, 0x08(sp)
sw t2, 0x10(sp)
sw t3, 0x18(sp)
sw t4, 0x20(sp)
# ===================================
# ===== Signature Output Format =====
# ===================================
#
# Base address = <wally_signature>+0x40*<intr_num>
# Use sigout-translator.py for help with this!
#
# <offset>: <contents>
# 0x00: test ID = 0x<group_num>BEEF<intr_num>
# 0x04: mcause (low) = 0x8000000B (MEIP) or 0x80000009 (SEIP)
# 0x08: mcause (high) = 0x00000000
# ----- If GPIO -----
# 0x0C: claim ID = 3
# 0x10: input_val
# 0x14: output_val
# 0x18: incoming rise_ip
# 0x1C: serviced rise_ip = 0
# 0x20: incoming fall_ip
# 0x24: serviced fall_ip = 0
# 0x28: incoming high_ip
# 0x2C: serviced high_ip = 0
# 0x30: incoming low_ip
# 0x34: serviced low_ip = 0
# ----- If UART -----
# 0x0C: claim ID = 0xA
# 0x10: IIR
# 0x14: LSR
# 0x18: LSR (after reading LSR)
# 0x1C: RBR
# 0x20: LSR (after reading RBR too)
# 0x24: IIR (after reading everything else)
# 0x28: SCR
# 0x00: test ID = 0x<group_num>BEEF<intr_num>
la t0, wally_signature
sub t0, s0, t0 # sigout offset
srli t0, t0, 6 # intr_num
add t0, t0, a1
sw t0, 0x00(s0)
# 0x04: mcause (low) = 0x0000000B (MEIP) or 0x00000009 (SEIP)
# 0x08: mcause (high) = 0x80000000
csrrc t0, mcause, x0
andi t1, t0, 0x7FF
sw t0, 0x04(s0)
//srli t0,t0,32
sw x0, 0x08(s0)
# MEIP or SEIP?
# MEIP is on context 0
li t4, 0x0C200004
li t0, 0xB
beq t1, t0, meip
# SEIP is on context 1
li t4, 0x0C201004
meip:
# 0x0C: claim ID
# 3: GPIO
# A: UART
mv t0, t4
lw t1, 0(t0)
sw t1, 0x0C(s0)
li t2, 0xA
beq t1, t2, uart_handler
li t2, 3
bne t1, t2, trap_handler_end
gpio_handler:
# 0x10: input_val
li t0, 0x10060000
lw t1, 0x00(t0)
sw t1, 0x10(s0)
# 0x14: output_val
lw t1, 0x0C(t0)
sw t1, 0x14(s0)
# 0x18: incoming rise_ip
lw t1, 0x1C(t0)
sw t1, 0x18(s0)
# 0x1C: serviced rise_ip = 0
sw t1, 0x1C(t0)
lw t1, 0x1C(t0)
sw t1, 0x1C(s0)
# 0x20: incoming fall_ip
lw t1, 0x24(t0)
sw t1, 0x20(s0)
# 0x24: serviced fall_ip = 0
sw t1, 0x24(t0)
lw t1, 0x24(t0)
sw t1, 0x24(s0)
# 0x28: incoming high_ip
lw t1, 0x2C(t0)
sw t1, 0x28(s0)
# 0x2C: serviced high_ip = 0
sw t1, 0x2C(t0)
lw t1, 0x2C(t0)
sw t1, 0x2C(s0)
# 0x30: incoming low_ip
lw t1, 0x34(t0)
sw t1, 0x30(s0)
# 0x34: serviced low_ip = 0
sw t1, 0x34(t0)
lw t1, 0x34(t0)
sw t1, 0x34(s0)
# disable high_ie and low_ie so interrupt
# is not taken again immediately
li t1, 0
sw t1, 0x28(t0)
sw t1, 0x30(t0)
# signal to main code that gpio was serviced
ori a0, a0, 0b00001000
# signal to plic that gpio was serviced
mv t0, t4
li t1, 3
sw t1, 0(t0)
j trap_handler_end
uart_handler:
# 0x10: IIR
li t0, 0x10000000
lbu t1, 2(t0)
sw t1, 0x10(s0)
# 0x14: LSR
lbu t1, 5(t0)
sw t1, 0x14(s0)
# 0x18: LSR (after reading LSR)
lbu t1, 5(t0)
sw t1, 0x18(s0)
# 0x1C: RBR
lbu t1, 0(t0)
sw t1, 0x1C(s0)
# 0x20: LSR (after reading RBR)
lbu t1, 5(t0)
sw t1, 0x20(s0)
# 0x24: IIR (after reading everything else)
lbu t1, 2(t0)
sw t1, 0x24(s0)
# 0x28: SCR
lbu t1, 7(t0)
sw t1, 0x28(s0)
# signal to main code that uart was serviced
ori a0, a0, 0b00010000
# signal to plic that uart was serviced
mv t0, t4
li t1, 0xA
sw t1, 0(t0)
trap_handler_end:
# increment signature pointer
addi s0,s0,0x40
# restore vars
lw t0, 0x00(sp)
lw t1, 0x08(sp)
lw t2, 0x10(sp)
lw t3, 0x18(sp)
lw t4, 0x20(sp)
addi sp, sp, SEXT_IMM(-0x28)
mret
################
################
main_code: #####
################
################
##########################
##### Initialization #####
##########################
# ========== Global Vars ==========
la s0, wally_signature # signature output base adr
la sp, stack # stack pointer
li a0, 0 # interrupt complete flag
# ========== Configure Privileged Unit ==========
# load address of trap handler
la t0, trap_handler
csrrw x0, mtvec, t0
# delegate all external interrupts to machine mode
li t0, 0xD00
csrrc x0, mideleg, t0
# set MIE
li t0, 0x8
csrrs x0, mstatus, t0
##################################
##### Test 1 - Signs of Life #####
##################################
li a1, 0x01beef00 # group ID
# clear MEIE (good to turn off while configuring peripherals)
li t0, 0x800
csrrc x0, mie, t0
# ========== Configure PLIC ==========
# priority threshold = 0
li t0, 0xC200000
li t1, 0
sw t1, 0(t0)
# source 3 (GPIO) priority = 6
li t0, 0xC000000
li t1, 6
sw t1, 0x0C(t0)
# source 0xA (UART) priority = 7
li t1, 7
sw t1, 0x28(t0)
# enable sources 3,0xA
li t0, 0x0C002000
li t1, 0b10000001000
sw t1, 0(t0)
# ========== Configure UART ==========
# MCR: Loop = 1
li t0, 0x10000000
li t1, 0b10000
sb t1, 4(t0)
# LCR: Use 8 data bits plus odd parity bit
li t1, 0b00001011
sb t1, 3(t0)
# IER: Enable Received Data Available Interrupt
li t1, 0x01
sb t1, 1(t0)
# ========== Configure GPIO ==========
# raise all input_en
li t0, 0x10060000
li t1, 0xFFFFFFFF
sw t1, 0x04(t0)
# raise all output_en
sw t1, 0x08(t0)
# raise all rise_en
sw t1, 0x18(t0)
# ========== Execute Test ==========
# set MEIE
li t0, 0x800
csrrs x0, mie, t0
Intr01BEEF00:
# UART TX 'h'
li t0, 0x10000000
li t1, 'h'
sb t1, 0(t0)
# wait to finish
li t1, 0b00010000
1: bne t1,a0,1b
li a0, 0
Intr01BEEF01:
# GPIO raise pin 19
li t0, 0x10060000
li t1, 0x00080000
sw t1, 0x0C(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
# Now let's go bonkers and trigger both!
Intr01BEEF02:
# TX 'e'
li t0, 0x10000000
li t1, 'e'
sb t1, 0(t0)
Intr01BEEF03:
# GPIO lower pin 19 raise pin 0
li t0, 0x10060000
li t1, 0x00000001
sw t1, 0x0C(t0)
# wait to finish
li t1, 0b00011000
1: bne t1,a0,1b
li a0, 0
##################################
##### Test 2 - GPIO Testing #####
##################################
li a1, 0x02beef00 # group ID
# clear MEIE
li t0, 0x800
csrrc x0, mie, t0
# ========== Configure PLIC ==========
# priority threshold = 0
li t0, 0xC200000
li t1, 0
sw t1, 0(t0)
# source 3 (GPIO) priority = 1
li t0, 0xC000000
li t1, 1
sw t1, 0x0C(t0)
# enable source 3
li t0, 0x0C002000
li t1, 0b1000
sw t1, 0(t0)
# ========== Input Enables ==========
# Note that this inherits
# a bit of state from the previous test.
# Namely output_val = 0x00000001
#
# enable some inputs
li t0, 0x10060000
li t1, 0x0000FFFF
sw t1, 0x04(t0)
# enable all outputs
li t1, 0xFFFFFFFF
sw t1, 0x08(t0)
# enable all rising edge interrupts
sw t1, 0x18(t0)
# set MEIE
li t1, 0x800
csrrs x0, mie, t1
# raise some input-disabled pins
# interrupt should not happen
li t1, 0xF0F00001
sw t1, 0x0C(t0)
Intr02BEEF04:
# change some input-enabled pins
# interrupt should happen
li t1, 0x3030F0F0
sw t1, 0x0C(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
Intr02BEEF05:
# enable some different inputs
# this itself will cause some rise interrupts
li t1, 0xFFFF0000
sw t1, 0x04(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
# ========== Output Enables ==========
# enable all fall interrupts
li t1, 0xFFFFFFFF
sw t1, 0x20(t0)
Intr02BEEF06:
# disable some outputs
# should affect input value but not output val register itself
# this itself will cause some fall interrupts
li t1, 0xFF0000FF
sw t1, 0x08(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
# change pins whose inputs and/or outputs are disabled
# should not cause any rise or fall interrupts
li t1, 0x300F0F0F
sw t1, 0x0C(t0)
Intr02BEEF07:
# change pins whose inputs and outputs are enabled
li t1, 0x0F0F0F0F
sw t1, 0x0C(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
# ========== Clear GPIO State ==========
# (I've gotten a little annoyed with tests depending
# upon the results of previous tests).
# disable all interrupts
sw x0, 0x18(t0)
sw x0, 0x20(t0)
sw x0, 0x28(t0)
sw x0, 0x30(t0)
# enable all inputs
li t1, 0xFFFFFFFF
sw t1, 0x04(t0)
# enable all outputs
li t1, 0xFFFFFFFF
sw t1, 0x08(t0)
# set initial output state
sw x0, 0x0C(t0)
# clear all pending interrupts
li t1, 0xFFFFFFFF
sw t1, 0x1C(t0)
sw t1, 0x24(t0)
sw t1, 0x2C(t0)
sw t1, 0x34(t0)
# ========== Rise Interrupt Enables ==========
# enable some rising edge interrupts
li t1, 0x0000FFFF
sw t1, 0x18(t0)
Intr02BEEF08:
# raise some pins
li t1, 0x00FFFF00
sw t1, 0x0C(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
Intr02BEEF09:
# raise pins whose rise IEs are disabled
# should not cause an interrupt
li t1, 0x33FFFF00
sw t1, 0x0C(t0)
# raise pins whose rise IEs are enabled
li t1, 0x33FFFF33
sw t1, 0x0C(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
# =========== Fall Interrupts ===========
# (admittedly these are already used elsewhere)
# disable all rising edge interrupts
li t1, 0
sw t1, 0x18(t0)
# enable some falling edge interrupts
li t1, 0x0000FFFF
sw t1, 0x20(t0)
Intr02BEEF0A:
# lower some pins
li t1, 0x33000033
sw t1, 0x0C(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
# lower pins whose fall IEs are disabled
# and raise a bunch of other pins
# should not cause an interrupt
li t1, 0x00CCCC33
sw t1, 0x0C(t0)
Intr02BEEF0B:
# lower pins whose fall IEs are enabled
li t1, 0x00CCCC00
sw t1, 0x0C(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
# =========== High Interrupts ===========
# disable all falling edge interrupts
li t1, 0
sw t1, 0x20(t0)
# enable some high_ie's for low pins
# should not cause an interrupt
li t1, 0xFF0000FF
sw t1, 0x28(t0)
Intr02BEEF0C:
# enable some high_ie's for high pins
li t1, 0x0000FFFF
sw t1, 0x28(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
# lower all pins
li t1, 0
sw t1, 0x0C(t0)
# lower any existing high_ip's
li t1, 0xFFFFFFFF
sw t1, 0x2C(t0)
# re-enable some high_ie's
li t1, 0xFFFF0000
sw t1, 0x28(t0)
# raise some pins whose high_ie's are disabled
li t1, 0x0000CCCC
sw t1, 0x0C(t0)
# disable some inputs
li t1, 0xFF00FFFF
sw t1, 0x04(t0)
# raise some pins whose inputs are disabled
li t1, 0x00CCCCCC
sw t1, 0x0C(t0)
Intr02BEEF0D:
# raise some pins whose high_ie's and inputs are enabled
li t1, 0xCCCCCCCC
sw t1, 0x0C(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
# =========== Low Interrupts ===========
# disable all high interrupts
li t1, 0
sw t1, 0x28(t0)
# enable all inputs
li t1, 0xFFFFFFFF
sw t1, 0x04(t0)
# enable some low_ie's for high pins
# should not cause an interrupt
li t1, 0xCC0000CC
sw t1, 0x30(t0)
Intr02BEEF0E:
# enable some low_ie's for low pins
li t1, 0xCCCCFFFF
sw t1, 0x30(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
# raise all pins
li t1, 0xFFFFFFFF
sw t1, 0x0C(t0)
# lower any existing low_ip's
# actually takes a little time for vals
# to propagate through synchronizer
# so this extra load is a nop effectively
li t1, 0xFFFFFFFF
sw t1, 0x34(t0)
# re-enable some low_ie's
li t1, 0xFF0000FF
sw t1, 0x30(t0)
# lower some pins whose low_ie's are disabled
li t1, 0xFF1111FF
sw t1, 0x0C(t0)
Intr02BEEF0F:
# disable some inputs of pins whose low_ie's are enabled
li t1, 0x0000FFFF
sw t1, 0x04(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
# ========== Clear GPIO State ==========
# disable all interrupts
sw x0, 0x18(t0)
sw x0, 0x20(t0)
sw x0, 0x28(t0)
sw x0, 0x30(t0)
# enable all inputs
li t1, 0xFFFFFFFF
sw t1, 0x04(t0)
# enable all outputs
li t1, 0xFFFFFFFF
sw t1, 0x08(t0)
# set initial output state
sw x0, 0x0C(t0)
# clear all pending interrupts
li t1, 0xFFFFFFFF
sw t1, 0x1C(t0)
sw t1, 0x24(t0)
sw t1, 0x2C(t0)
sw t1, 0x34(t0)
# ========== Output XOR Test ==========
# enable some inputs
li t1, 0x0000FFFF
sw t1, 0x04(t0)
# enable some outputs
li t1, 0xFF0000FF
sw t1, 0x08(t0)
# enable all rising and falling edge interrupts
li t1, 0xFFFFFFFF
sw t1, 0x18(t0)
sw t1, 0x20(t0)
Intr02BEEF10:
# XOR all outputs
li t1, 0xFFFFFFFF
sw t1, 0x40(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
Intr02BEEF11:
# XOR some outputs
li t1, 0x33333333
sw t1, 0x40(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
# ========== Clear GPIO State ==========
# disable all interrupts
sw x0, 0x18(t0)
sw x0, 0x20(t0)
sw x0, 0x28(t0)
sw x0, 0x30(t0)
# enable all inputs
li t1, 0xFFFFFFFF
sw t1, 0x04(t0)
# enable all outputs
li t1, 0xFFFFFFFF
sw t1, 0x08(t0)
# set initial output state
sw x0, 0x0C(t0)
# clear XOR
li t1, 0x00000000
sw t1, 0x40(t0)
# clear all pending interrupts
li t1, 0xFFFFFFFF
sw t1, 0x1C(t0)
sw t1, 0x24(t0)
sw t1, 0x2C(t0)
sw t1, 0x34(t0)
##################################
##### Test 3 - UART Testing #####
##################################
li a1, 0x03beef00 # group ID
# clear MEIE
li t0, 0x800
csrrc x0, mie, t0
# ========== Configure PLIC ==========
# priority threshold = 0
li t0, 0xC200000
li t1, 0
sw t1, 0(t0)
# source 0xA (UART) priority = 1
li t0, 0xC000000
li t1, 1
sw t1, 0x28(t0)
# enable source 0xA
li t0, 0x0C002000
li t1, 0b10000000000
sw t1, 0(t0)
# ========== Transmitter Holding Register Empty Interrupt (THRE) ==========
# MCR: Loop = 1
li t0, 0x10000000
li t1, 0b00010000
sb t1, 4(t0)
# LCR: Use 8 data bits plus odd parity bit
li t1, 0b00001011
sb t1, 3(t0)
# IER: Disable all interrupts for now
li t1, 0x0
sb t1, 1(t0)
# set MEIE
li t1, 0x800
csrrs x0, mie, t1
# THR: TX 'l'
li t1, 'l'
sb t1, 0(t0)
# wait directly on UART for completion
li t1, 0b01100001
1: lb t2, 5(t0)
bne t1, t2, 1b
Intr03BEEF12:
# IER: enable THR empty intr (ETBEI)
li t1, 0b00000010
sb t1, 1(t0)
# wait to finish
li t1, 0b00010000
1: bne t1,a0,1b
li a0, 0
# IER: disable THR empty intr (ETBEI)
sb x0, 1(t0)
# THR: TX 'l'
li t1, 'l'
sb t1, 0(t0)
# THR: TX 'o'
li t1, 'o'
sb t1, 0(t0)
Intr03BEEF13:
# IER: enable THR empty intr (ETBEI)
li t1, 0b00000010
sb t1, 1(t0)
# This will take a few cycles before UART finishes TX'ing
# If we see SCR modifications in output, it means UART probably
# did wait until empty THR before triggering the interrupt.
sb t1, 7(t0)
# wait to finish
li t1, 0b00010000
1: bne t1,a0,1b
li a0, 0
# ========== Received Data Available Intrrupt (ERBFI) & Loop Mode ==========
# Clear SCR
sb x0, 7(t0)
Intr03BEEF14:
# IER: enable RBR ready intr ERBFI
li t1, 0x1
sb t1, 1(t0)
# wait to finish
li t1, 0b00010000
1: bne t1,a0,1b
li a0, 0
Intr03BEEF15:
# THR: TX ' '
li t1, 0x20
sb t1, 0(t0)
# This will take a few cycles before UART finishes RX'ing
# If we see SCR modifications in output, it means UART probably
# did wait until received data available before triggering the interrupt.
li t1, 3
sb t1, 7(t0)
# wait to finish
li t1, 0b00010000
1: bne t1,a0,1b
li a0, 0
Intr03BEEF16:
# THR: TX 't'
li t1, 't'
sb t1, 0(t0)
# Same shenanigans as before, only now we also confirm
# that you can read the RBR before new data is available
# without messing up the receive interrupt.
lb t1, 0(t0)
sb t1, 7(t0)
# wait to finish
li t1, 0b00010000
1: bne t1,a0,1b
li a0, 0
# MCR: Loop = 0
li t1, 0b00000000
sb t1, 4(t0)
# Clear SCR
sb x0, 7(t0)
# THR: TX 'h'
# should TX but not not trigger interrupt
li t1, 'h'
sb t1, 0(t0)
# wait directly on UART for completion
li t1, 0b01100000
1: lb t2, 5(t0)
bne t1, t2, 1b
# Can use THRE test from before to verify we are transmitting
# THR: TX 'e'
li t1, 'e'
sb t1, 0(t0)
# THR: TX 'r'
li t1, 'r'
sb t1, 0(t0)
Intr03BEEF17:
# IER: enable THR empty intr (ETBEI) and RBR ready intr (ERBFI)
li t1, 0b00000011
sb t1, 1(t0)
sb t1, 7(t0)
# wait to finish
li t1, 0b00010000
1: bne t1,a0,1b
li a0, 0
# manually wait until transmitter finishes before enabling loop mode
li t1, 0b01100000
1: lb t2, 5(t0)
bne t1, t2, 1b
# MCR: Loop = 1
li t1, 0b00010000
sb t1, 4(t0)
Intr03BEEF18:
Intr03BEEF19:
# THR: TX 'e'
li t1, 'e'
sb t1, 0(t0)
# wait to finish
li t1, 0b00010000
1: bne t1,a0,1b
li a0, 0
# wait to finish again
li t1, 0b00010000
1: bne t1,a0,1b
li a0, 0
# ========== Receiver Line Status Intr (ELSI) & Overrun Error (OE) ==========
# IER: Enable Receiver Line Status Intr (ELSI)
li t1, 0b00000100
sb t1, 1(t0)
li t1, 0xFF
sb t1, 7(t0)
# We can't cause all kinds of interesting errors, but at least we can
# cause an overrun error by transmitting twice without reading.
Intr03BEEF1A:
# THR: TX '\n'
li t1, 0xD
sb t1, 0(t0)
# THR: TX 'G'
li t1, 'G'
sb t1, 0(t0)
# wait to finish
li t1, 0b00010000
1: bne t1,a0,1b
li a0, 0
####################################################
##### Test 4 - Signs of Life on PLIC Context 1 #####
####################################################
li a1, 0x04beef00 # group ID
# clear MEIE (good to turn off while configuring peripherals)
li t0, 0x800
csrrc x0, mie, t0
# ========== Configure PLIC ==========
# priority threshold = 0
li t0, 0xC200000
li t1, 0
sw t1, 0(t0)
# source 3 (GPIO) priority = 6
li t0, 0xC000000
li t1, 6
sw t1, 0x0C(t0)
# source 0xA (UART) priority = 7
li t1, 7
sw t1, 0x28(t0)
# disable sources 3,0xA on context 0
li t0, 0x0C002000
li t1, 0
sw t1, 0(t0)
# enable sources 3,0xA on context 1
li t0, 0x0C002080
li t1, 0b10000001000
sw t1, 0(t0)
# ========== Configure UART ==========
# MCR: Loop = 1
li t0, 0x10000000
li t1, 0b10000
sb t1, 4(t0)
# LCR: Use 8 data bits plus odd parity bit
li t1, 0b00001011
sb t1, 3(t0)
# IER: Enable Received Data Available Interrupt
li t1, 0x01
sb t1, 1(t0)
# ========== Configure GPIO ==========
# raise all input_en
li t0, 0x10060000
li t1, 0xFFFFFFFF
sw t1, 0x04(t0)
# raise all output_en
sw t1, 0x08(t0)
# raise all rise_en
sw t1, 0x18(t0)
# ========== Execute Test ==========
# set MEIE and SEIE
li t0, 0xA00
csrrs x0, mie, t0
Intr04BEEF1B:
# UART TX 'e'
li t0, 0x10000000
li t1, 'e'
sb t1, 0(t0)
# wait to finish
li t1, 0b00010000
1: bne t1,a0,1b
li a0, 0
Intr04BEEF1C:
# GPIO raise pin 19
li t0, 0x10060000
li t1, 0x00080000
sw t1, 0x0C(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
# Now let's go bonkers and trigger both!
Intr04BEEF1D:
# TX 'n'
li t0, 0x10000000
li t1, 'n'
sb t1, 0(t0)
Intr04BEEF1E:
# GPIO lower pin 19 raise pin 0
li t0, 0x10060000
li t1, 0x00000001
sw t1, 0x0C(t0)
# wait to finish
li t1, 0b00011000
1: bne t1,a0,1b
li a0, 0
# ---------------------------------------------------------------------------------------------
//terminate_test:
// li a0, 2 // Trap handler behavior (go to machine mode)
// ecall // writes mcause to the output.
// csrw mtvec, x4 // restore original trap handler to halt program
RVTEST_CODE_END
RVMODEL_HALT
RVTEST_DATA_BEGIN
# stack memory (size 16 words)
.align 3
stack:
.fill 16, 8, 0xdeadbeef
#ifdef rvtest_mtrap_routine
mtrap_sigptr:
.fill 64*(XLEN/32),4,0xdeadbeef
#endif
#ifdef rvtest_gpr_save
gpr_save:
.fill 32*(XLEN/32),4,0xdeadbeef
#endif
RVTEST_DATA_END
RVMODEL_DATA_BEGIN
# signature output
wally_signature:
.fill 0x200, 8, 0x00000000
sig_end_canary:
.int 0x0
rvtest_sig_end:
RVMODEL_DATA_END