diff --git a/pipelined/src/fpu/fdivsqrt/fdivsqrt.sv b/pipelined/src/fpu/fdivsqrt/fdivsqrt.sv
index cde357bfa..604a0711f 100644
--- a/pipelined/src/fpu/fdivsqrt/fdivsqrt.sv
+++ b/pipelined/src/fpu/fdivsqrt/fdivsqrt.sv
@@ -79,5 +79,8 @@ module fdivsqrt(
     .X,.Dpreproc, .FirstWS(WS), .FirstWC(WC),
     .DivStartE, .Xe(XeE), .Ye(YeE), .XZeroE, .YZeroE,
     .DivBusy);
-  fdivsqrtpostproc fdivsqrtpostproc(.WS, .WC, .D, .FirstU, .FirstUM, .FirstC, .Firstun, .SqrtM, .SpecialCaseM, .QmM, .WZero, .DivSM);
+  fdivsqrtpostproc fdivsqrtpostproc(
+    .WS, .WC, .D, .FirstU, .FirstUM, .FirstC, .Firstun, 
+    .SqrtM, .SpecialCaseM, .RemOp(Funct3E[1]),
+    .QmM, .WZero, .DivSM);
 endmodule
\ No newline at end of file
diff --git a/pipelined/src/fpu/fdivsqrt/fdivsqrtpostproc.sv b/pipelined/src/fpu/fdivsqrt/fdivsqrtpostproc.sv
index e0acd0ed5..92bb1bd9b 100644
--- a/pipelined/src/fpu/fdivsqrt/fdivsqrtpostproc.sv
+++ b/pipelined/src/fpu/fdivsqrt/fdivsqrtpostproc.sv
@@ -31,13 +31,14 @@
 `include "wally-config.vh"
 
 module fdivsqrtpostproc(
-  input logic [`DIVb+3:0] WS, WC,
-  input logic [`DIVN-2:0]  D, // U0.N-1
-  input logic [`DIVb:0] FirstU, FirstUM, 
-  input logic [`DIVb+1:0] FirstC,
-  input logic  Firstun,
-  input logic SqrtM,
-  input logic SpecialCaseM,
+  input  logic [`DIVb+3:0] WS, WC,
+  input  logic [`DIVN-2:0]  D, // U0.N-1
+  input  logic [`DIVb:0] FirstU, FirstUM, 
+  input  logic [`DIVb+1:0] FirstC,
+  input  logic  Firstun,
+  input  logic SqrtM,
+  input  logic SpecialCaseM,
+  input  logic RemOp,
   output logic [`DIVb:0] QmM, 
   output logic WZero,
   output logic DivSM
diff --git a/tests/testsBP/zsbl/Makefile b/tests/testsBP/zsbl/Makefile
new file mode 100644
index 000000000..6dec9c797
--- /dev/null
+++ b/tests/testsBP/zsbl/Makefile
@@ -0,0 +1,112 @@
+CEXT		:= c
+CPPEXT		:= cpp
+AEXT		:= s
+SEXT		:= S
+SRCEXT 		:= \([$(CEXT)$(AEXT)$(SEXT)]\|$(CPPEXT)\)
+OBJEXT		:= o
+DEPEXT		:= d
+SRCDIR		:= .
+BUILDDIR	:= OBJ
+
+SOURCES		?= $(shell find $(SRCDIR) -type f -regex ".*\.$(SRCEXT)" | sort)
+OBJECTS		:= $(SOURCES:.$(CEXT)=.$(OBJEXT))
+OBJECTS		:= $(OBJECTS:.$(AEXT)=.$(OBJEXT))
+OBJECTS		:= $(OBJECTS:.$(SEXT)=.$(OBJEXT))
+OBJECTS		:= $(OBJECTS:.$(CPPEXT)=.$(OBJEXT))
+OBJECTS		:= $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(OBJECTS))
+
+TARGETDIR	:= bin
+TARGET		:= $(TARGETDIR)/fpga-test-sdc
+ROOT		:= ..
+LIBRARY_DIRS	:= 
+LIBRARY_FILES	:=
+
+MARCH           :=-march=rv64imfdc
+MABI            :=-mabi=lp64d
+LINK_FLAGS      :=$(MARCH) $(MABI) -nostartfiles
+LINKER		:=linker.x
+
+
+AFLAGS =$(MARCH) $(MABI) -W
+CFLAGS =$(MARCH) $(MABI) -mcmodel=medany  -O2
+AS=riscv64-unknown-elf-as
+CC=riscv64-unknown-elf-gcc
+AR=riscv64-unknown-elf-ar
+
+
+#Default Make
+all: directories  $(TARGET).memfile
+
+#Remake
+remake: clean all
+
+#Make the Directories
+directories:
+	@mkdir -p $(TARGETDIR)
+	@mkdir -p $(BUILDDIR)
+
+clean:
+	rm -rf $(BUILDDIR) $(TARGETDIR) *.memfile *.objdump 
+
+
+#Needed for building additional library projects
+ifdef LIBRARY_DIRS
+LIBS+=${LIBRARY_DIRS:%=-L%}  ${LIBRARY_FILES:%=-l%}
+INC+=${LIBRARY_DIRS:%=-I%}
+
+${LIBRARY_DIRS}: 
+	make -C $@ -j 1
+
+.PHONY: $(LIBRARY_DIRS) $(TARGET)
+endif
+
+
+#Pull in dependency info for *existing* .o files
+-include $(OBJECTS:.$(OBJEXT)=.$(DEPEXT))
+
+#Link
+$(TARGET): $(OBJECTS) $(LIBRARY_DIRS)
+	$(CC) $(LINK_FLAGS) -g -o $(TARGET) $(OBJECTS) ${LIBS} -T ${LINKER}
+
+
+#Compile
+$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(CEXT)
+	@mkdir -p $(dir $@)
+	$(CC) $(CFLAGS) $(INC) -c -o $@ $< > $(BUILDDIR)/$*.list
+	@$(CC) $(CFLAGS) $(INC) -MM $(SRCDIR)/$*.$(CEXT) > $(BUILDDIR)/$*.$(DEPEXT)
+	@cp -f $(BUILDDIR)/$*.$(DEPEXT) $(BUILDDIR)/$*.$(DEPEXT).tmp
+	@sed -e 's|.*:|$(BUILDDIR)/$*.$(OBJEXT):|' < $(BUILDDIR)/$*.$(DEPEXT).tmp > $(BUILDDIR)/$*.$(DEPEXT)
+	@sed -e 's/.*://' -e 's/\\$$//' < $(BUILDDIR)/$*.$(DEPEXT).tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $(BUILDDIR)/$*.$(DEPEXT)
+	@rm -f $(BUILDDIR)/$*.$(DEPEXT).tmp
+
+# gcc won't output dependencies for assembly files for some reason
+# most asm files don't have dependencies so the echo will work for now.
+$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(AEXT)
+	@mkdir -p $(dir $@)
+	$(CC) $(CFLAGS) -c -o $@ $< > $(BUILDDIR)/$*.list
+	@echo $@: $< > $(BUILDDIR)/$*.$(DEPEXT)
+
+$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(SEXT)
+	@mkdir -p $(dir $@)
+	$(CC) $(CFLAGS) $(INC) -c -o $@ $< > $(BUILDDIR)/$*.list
+	@echo $@: $< > $(BUILDDIR)/$*.$(DEPEXT)
+
+# C++
+$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(CPPEXT)
+	@mkdir -p $(dir $@)
+	$(CC) $(CFLAGS) $(INC) -c -o $@ $< > $(BUILDDIR)/$*.list
+	@$(CC) $(CFLAGS) $(INC) -MM $(SRCDIR)/$*.$(CPPEXT) > $(BUILDDIR)/$*.$(DEPEXT)
+	@cp -f $(BUILDDIR)/$*.$(DEPEXT) $(BUILDDIR)/$*.$(DEPEXT).tmp
+	@sed -e 's|.*:|$(BUILDDIR)/$*.$(OBJEXT):|' < $(BUILDDIR)/$*.$(DEPEXT).tmp > $(BUILDDIR)/$*.$(DEPEXT)
+	@sed -e 's/.*://' -e 's/\\$$//' < $(BUILDDIR)/$*.$(DEPEXT).tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $(BUILDDIR)/$*.$(DEPEXT)
+	@rm -f $(BUILDDIR)/$*.$(DEPEXT).tmp
+
+# convert to hex
+$(TARGET).memfile: $(TARGET)
+	@echo 'Making object dump file.'
+	@riscv64-unknown-elf-objdump -D $< > $<.objdump
+	@echo 'Making memory file'
+	riscv64-unknown-elf-elf2hex --bit-width 64 --input $^ --output $@
+	extractFunctionRadix.sh $<.objdump
+	mkdir -p ../../imperas-riscv-tests/work/rv64BP/
+	cp -f $(TARGETDIR)/* ../../imperas-riscv-tests/work/rv64BP/
diff --git a/tests/testsBP/zsbl/bios.s b/tests/testsBP/zsbl/bios.s
new file mode 100644
index 000000000..ebeadcf59
--- /dev/null
+++ b/tests/testsBP/zsbl/bios.s
@@ -0,0 +1,98 @@
+PERIOD = 11000000
+#PERIOD = 20
+
+.section .init
+.global _start
+.type _start, @function
+
+		
+_start:
+	  # Initialize global pointer
+	.option push
+	.option norelax
+	1:auipc gp, %pcrel_hi(__global_pointer$)
+	addi  gp, gp, %pcrel_lo(1b)
+	.option pop
+	
+	li x1, 0
+	li x2, 0
+	li x4, 0
+	li x5, 0
+	li x6, 0
+	li x7, 0
+	li x8, 0
+	li x9, 0
+	li x10, 0
+	li x11, 0
+	li x12, 0
+	li x13, 0
+	li x14, 0
+	li x15, 0
+	li x16, 0
+	li x17, 0
+	li x18, 0
+	li x19, 0
+	li x20, 0
+	li x21, 0
+	li x22, 0
+	li x23, 0
+	li x24, 0
+	li x25, 0
+	li x26, 0
+	li x27, 0
+	li x28, 0
+	li x29, 0
+	li x30, 0
+	li x31, 0
+
+
+	# set the stack pointer to the top of memory - 8 bytes (pointer size)
+	li sp, 0x87FFFFF8
+
+	jal ra, main
+	
+	fence.i
+	# now toggle led so we know the copy completed.
+
+	# write to gpio
+	li	t2, 0xFF
+	la	t3, 0x1006000C
+	li	t4, 5
+
+loop:
+
+	# delay
+	li	t0, PERIOD/2
+delay1:	
+	addi	t0, t0, -1
+	bge	t0, x0, delay1
+	sw	t2, 0x0(t3)
+
+	li	t0, PERIOD/2
+delay2:	
+	addi	t0, t0, -1
+	bge	t0, x0, delay2
+	sw	x0, 0x0(t3)
+
+	addi	t4, t4, -1
+	bgt	t4, x0, loop
+
+
+	# now that the card is copied and the led toggled we
+	# jump to the copied contents of the sd card.
+
+jumpToLinux:
+	csrr a0, mhartid
+        li s0, 0x80000000
+        la a1, _dtb
+        jr s0
+end_of_bios:	
+
+
+
+.section .rodata
+.globl _dtb
+.align 4, 0
+_dtb:
+.incbin "wally-vcu118.dtb"
+
diff --git a/tests/testsBP/zsbl/copyFlash.c b/tests/testsBP/zsbl/copyFlash.c
new file mode 100644
index 000000000..4165fe21c
--- /dev/null
+++ b/tests/testsBP/zsbl/copyFlash.c
@@ -0,0 +1,40 @@
+///////////////////////////////////////////
+// copyFlash.sv
+//
+// Written: Ross Thompson September 25, 2021
+// Modified: 
+//
+// Purpose: copies flash card into memory
+// 
+// A component of the Wally configurable RISC-V project.
+// 
+// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
+//
+// 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 "sdcDriver.h"
+
+void copyFlash(long int blockAddr, long int * Dst, int numBlocks) {
+
+  setSDCCLK(4); // must be even, 1 gives no division.
+  waitInitSDC();
+
+  int index;
+
+  for(index = 0; index < numBlocks; index++) {
+    copySDC512(blockAddr+(index*512), Dst+(index*512/8));
+  }
+  
+    
+}
diff --git a/tests/testsBP/zsbl/gpt.c b/tests/testsBP/zsbl/gpt.c
new file mode 100644
index 000000000..0c645d70e
--- /dev/null
+++ b/tests/testsBP/zsbl/gpt.c
@@ -0,0 +1,119 @@
+#include "gpt.h"
+
+#include "sdcDriver.h"
+
+#include "uart.h"
+#include <stddef.h>
+
+int gpt_find_boot_partition(long int* dest, uint32_t size)
+{
+  //int ret = init_sd();
+  int ret;
+  setSDCCLK(4); // must be even, 1 gives no division.
+  waitInitSDC();
+  ret = 0;
+    if (ret != 0) {
+        print_uart("could not initialize sd... exiting\r\n");
+        return -1;
+    }
+
+    print_uart("sd initialized!\r\n");
+
+    // load LBA1
+    size_t block_size = 512/8;
+    long int lba1_buf[block_size];
+
+    //int res = sd_copy(lba1_buf, 1, 1);
+    int res;
+    copySDC512(1, lba1_buf);
+    res = 0;
+
+    if (res != 0)
+    {
+        print_uart("SD card failed!\r\n");
+        print_uart("sd copy return value: ");
+        print_uart_addr(res);
+        print_uart("\r\n");
+        return -2;
+    }
+
+    gpt_pth_t *lba1 = (gpt_pth_t *)lba1_buf;
+
+    print_uart("gpt partition table header:");
+    print_uart("\r\n\tsignature:\t");
+    print_uart_addr(lba1->signature);
+    print_uart("\r\n\trevision:\t");
+    print_uart_int(lba1->revision);
+    print_uart("\r\n\tsize:\t\t");
+    print_uart_int(lba1->header_size);
+    print_uart("\r\n\tcrc_header:\t");
+    print_uart_int(lba1->crc_header);
+    print_uart("\r\n\treserved:\t");
+    print_uart_int(lba1->reserved);
+    print_uart("\r\n\tcurrent lba:\t");
+    print_uart_addr(lba1->current_lba);
+    print_uart("\r\n\tbackup lda:\t");
+    print_uart_addr(lba1->backup_lba);
+    print_uart("\r\n\tpartition entries lba:   \t");
+    print_uart_addr(lba1->partition_entries_lba);
+    print_uart("\r\n\tnumber partition entries:\t");
+    print_uart_int(lba1->nr_partition_entries);
+    print_uart("\r\n\tsize partition entries:  \t");
+    print_uart_int(lba1->size_partition_entry);
+    print_uart("\r\n");
+
+    long int lba2_buf[block_size];
+
+    //res = sd_copy(lba2_buf, lba1->partition_entries_lba, 1);
+    copySDC512(lba1->partition_entries_lba, lba2_buf);
+    res = 0;
+
+    if (res != 0)
+    {
+        print_uart("SD card failed!\r\n");
+        print_uart("sd copy return value: ");
+        print_uart_addr(res);
+        print_uart("\r\n");
+        return -2;
+    }
+
+    for (int i = 0; i < 4; i++)
+    {
+        partition_entries_t *part_entry = (partition_entries_t *)(lba2_buf + (i * 128));
+        print_uart("gpt partition entry ");
+        print_uart_byte(i);
+        print_uart("\r\n\tpartition type guid:\t");
+        for (int j = 0; j < 16; j++)
+            print_uart_byte(part_entry->partition_type_guid[j]);
+        print_uart("\r\n\tpartition guid:     \t");
+        for (int j = 0; j < 16; j++)
+            print_uart_byte(part_entry->partition_guid[j]);
+        print_uart("\r\n\tfirst lba:\t");
+        print_uart_addr(part_entry->first_lba);
+        print_uart("\r\n\tlast lba:\t");
+        print_uart_addr(part_entry->last_lba);
+        print_uart("\r\n\tattributes:\t");
+        print_uart_addr(part_entry->attributes);
+        print_uart("\r\n\tname:\t");
+        for (int j = 0; j < 72; j++)
+            print_uart_byte(part_entry->name[j]);
+        print_uart("\r\n");
+    }
+
+    partition_entries_t *boot = (partition_entries_t *)(lba2_buf);
+    print_uart("copying boot image ");
+    //res = sd_copy(dest, boot->first_lba, boot->last_lba - boot->first_lba + 1);
+    copyFlash(boot->first_lba, dest, boot->last_lba - boot->first_lba + 1);
+
+    if (res != 0)
+    {
+        print_uart("SD card failed!\r\n");
+        print_uart("sd copy return value: ");
+        print_uart_addr(res);
+        print_uart("\r\n");
+        return -2;
+    }
+
+    print_uart(" done!\r\n");
+    return 0;
+}
diff --git a/tests/testsBP/zsbl/gpt.h b/tests/testsBP/zsbl/gpt.h
new file mode 100644
index 000000000..dcc27ae8a
--- /dev/null
+++ b/tests/testsBP/zsbl/gpt.h
@@ -0,0 +1,39 @@
+#pragma once
+
+#include <stdint.h>
+
+// LBA 0: Protective MBR
+// ignored here
+
+// Partition Table Header (LBA 1)
+typedef struct gpt_pth
+{
+    uint64_t signature;
+    uint32_t revision;
+    uint32_t header_size; //! little endian, usually 0x5c = 92
+    uint32_t crc_header;
+    uint32_t reserved; //! must be 0
+    uint64_t current_lba;
+    uint64_t backup_lba;
+    uint64_t first_usable_lba;
+    uint64_t last_usable_lba;
+    uint8_t disk_guid[16];
+    uint64_t partition_entries_lba;
+    uint32_t nr_partition_entries;
+    uint32_t size_partition_entry; //! usually 0x80 = 128
+    uint32_t crc_partition_entry;
+} gpt_pth_t;
+
+// Partition Entries (LBA 2-33)
+typedef struct partition_entries
+{
+    uint8_t partition_type_guid[16];
+    uint8_t partition_guid[16];
+    uint64_t first_lba;
+    uint64_t last_lba; //! inclusive
+    uint64_t attributes;
+    uint8_t name[72]; //! utf16 encoded
+} partition_entries_t;
+
+// Find boot partition and load it to the destination
+int gpt_find_boot_partition(long int* dest, uint32_t size);
diff --git a/tests/testsBP/zsbl/main.c b/tests/testsBP/zsbl/main.c
new file mode 100644
index 000000000..898025c30
--- /dev/null
+++ b/tests/testsBP/zsbl/main.c
@@ -0,0 +1,26 @@
+#include "uart.h"
+#include "sdcDriver.h"
+#include "gpt.h"
+
+int main()
+{
+    init_uart(30000000, 115200);
+    print_uart("Hello World!\r\n");
+
+    int res = gpt_find_boot_partition((long int *)0x80000000UL, 2 * 16384);
+
+    if (res == 0)
+    {
+      return 0;
+    }
+
+    while (1)
+    {
+        // do nothing
+    }
+}
+
+void handle_trap(void)
+{
+    // print_uart("trap\r\n");
+}
diff --git a/tests/testsBP/zsbl/sdcDriver.c b/tests/testsBP/zsbl/sdcDriver.c
new file mode 100644
index 000000000..edbe0677d
--- /dev/null
+++ b/tests/testsBP/zsbl/sdcDriver.c
@@ -0,0 +1,69 @@
+///////////////////////////////////////////
+// SDC.sv
+//
+// Written: Ross Thompson September 25, 2021
+// Modified: 
+//
+// Purpose: driver for sdc reader.
+// 
+// A component of the Wally configurable RISC-V project.
+// 
+// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
+//
+// 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 "sdcDriver.h"
+
+#define SDC_MAIL_BOX 0x12100
+
+void copySDC512(long int blockAddr, long int * Dst) {
+
+  waitInitSDC();
+
+  volatile long int * mailBoxAddr;
+  volatile int * mailBoxCmd;
+  volatile int * mailBoxStatus;
+  volatile long int * mailBoxReadData;
+  mailBoxStatus = (int *) (SDC_MAIL_BOX + 0x4);  
+  mailBoxCmd = (int *) (SDC_MAIL_BOX + 0x8);
+  mailBoxAddr = (long int *) (SDC_MAIL_BOX + 0x10);
+  mailBoxReadData = (long int *) (SDC_MAIL_BOX + 0x18);  
+  
+  // write the SDC address register with the blockAddr
+  *mailBoxAddr = blockAddr;
+  *mailBoxCmd = 0x4;
+
+  // wait until the mailbox has valid data
+  // this occurs when status[1] = 0
+  while((*mailBoxStatus & 0x2) == 0x2);
+
+  int index;
+  for(index = 0; index < 512/8; index++) {
+    Dst[index] = *mailBoxReadData;
+  }
+}
+
+volatile void waitInitSDC(){
+  volatile int * mailBoxStatus;
+  mailBoxStatus = (int *) (SDC_MAIL_BOX + 0x4);
+  while((*mailBoxStatus & 0x1) != 0x1);
+}
+
+void setSDCCLK(int divider){
+  divider = (1 - (divider >> 1));
+  volatile int * mailBoxCLK;
+  mailBoxCLK = (int *) (SDC_MAIL_BOX + 0x0);
+  *mailBoxCLK = divider;
+}
diff --git a/tests/testsBP/zsbl/sdcDriver.h b/tests/testsBP/zsbl/sdcDriver.h
new file mode 100644
index 000000000..3e7381837
--- /dev/null
+++ b/tests/testsBP/zsbl/sdcDriver.h
@@ -0,0 +1,10 @@
+#ifndef __SDCDRIVER_H
+#define __SDCDRIVER_H
+
+
+void copySDC512(long int, long int *);
+volatile void waitInitSDC();
+void setSDCCLK(int);
+void copyFlash(long int, long int *, int);
+
+#endif
diff --git a/tests/testsBP/zsbl/smp.h b/tests/testsBP/zsbl/smp.h
new file mode 100644
index 000000000..bb037755d
--- /dev/null
+++ b/tests/testsBP/zsbl/smp.h
@@ -0,0 +1,52 @@
+#pragma once
+
+// The hart that non-SMP tests should run on
+#ifndef NONSMP_HART
+#define NONSMP_HART 0
+#endif
+
+// The maximum number of HARTs this code supports
+#define CLINT_CTRL_ADDR 0x2000000
+#ifndef MAX_HARTS
+#define MAX_HARTS 256
+#endif
+#define CLINT_END_HART_IPI CLINT_CTRL_ADDR + (MAX_HARTS * 4)
+
+/* If your test needs to temporarily block multiple-threads, do this:
+ *    smp_pause(reg1, reg2)
+ *    ... single-threaded work ...
+ *    smp_resume(reg1, reg2)
+ *    ... multi-threaded work ...
+ */
+
+#define smp_pause(reg1, reg2) \
+    li reg2, 0x8;             \
+    csrw mie, reg2;           \
+    li reg1, NONSMP_HART;     \
+    csrr reg2, mhartid;       \
+    bne reg1, reg2, 42f
+
+#define smp_resume(reg1, reg2)   \
+    li reg1, CLINT_CTRL_ADDR;    \
+    41:;                         \
+    li reg2, 1;                  \
+    sw reg2, 0(reg1);            \
+    addi reg1, reg1, 4;          \
+    li reg2, CLINT_END_HART_IPI; \
+    blt reg1, reg2, 41b;         \
+    42:;                         \
+    wfi;                         \
+    csrr reg2, mip;              \
+    andi reg2, reg2, 0x8;        \
+    beqz reg2, 42b;              \
+    li reg1, CLINT_CTRL_ADDR;    \
+    csrr reg2, mhartid;          \
+    slli reg2, reg2, 2;          \
+    add reg2, reg2, reg1;        \
+    sw zero, 0(reg2);            \
+    41:;                         \
+    lw reg2, 0(reg1);            \
+    bnez reg2, 41b;              \
+    addi reg1, reg1, 4;          \
+    li reg2, CLINT_END_HART_IPI; \
+    blt reg1, reg2, 41b
diff --git a/tests/testsBP/zsbl/uart.c b/tests/testsBP/zsbl/uart.c
new file mode 100644
index 000000000..a8084ee5e
--- /dev/null
+++ b/tests/testsBP/zsbl/uart.c
@@ -0,0 +1,91 @@
+#include "uart.h"
+
+void write_reg_u8(uintptr_t addr, uint8_t value)
+{
+    volatile uint8_t *loc_addr = (volatile uint8_t *)addr;
+    *loc_addr = value;
+}
+
+uint8_t read_reg_u8(uintptr_t addr)
+{
+    return *(volatile uint8_t *)addr;
+}
+
+int is_transmit_empty()
+{
+    return read_reg_u8(UART_LINE_STATUS) & 0x20;
+}
+
+void write_serial(char a)
+{
+    while (is_transmit_empty() == 0) {};
+
+    write_reg_u8(UART_THR, a);
+}
+
+void init_uart(uint32_t freq, uint32_t baud)
+{
+    uint32_t divisor = freq / (baud << 4);
+
+    write_reg_u8(UART_INTERRUPT_ENABLE, 0x00); // Disable all interrupts
+    write_reg_u8(UART_LINE_CONTROL, 0x80);     // Enable DLAB (set baud rate divisor)
+    write_reg_u8(UART_DLAB_LSB, divisor);         // divisor (lo byte)
+    write_reg_u8(UART_DLAB_MSB, (divisor >> 8) & 0xFF);  // divisor (hi byte)
+    write_reg_u8(UART_LINE_CONTROL, 0x03);     // 8 bits, no parity, one stop bit
+    write_reg_u8(UART_FIFO_CONTROL, 0xC7);     // Enable FIFO, clear them, with 14-byte threshold
+    write_reg_u8(UART_MODEM_CONTROL, 0x20);    // Autoflow mode
+}
+
+void print_uart(const char *str)
+{
+    const char *cur = &str[0];
+    while (*cur != '\0')
+    {
+        write_serial((uint8_t)*cur);
+        ++cur;
+    }
+}
+
+uint8_t bin_to_hex_table[16] = {
+    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
+
+void bin_to_hex(uint8_t inp, uint8_t res[2])
+{
+    res[1] = bin_to_hex_table[inp & 0xf];
+    res[0] = bin_to_hex_table[(inp >> 4) & 0xf];
+    return;
+}
+
+void print_uart_int(uint32_t addr)
+{
+    int i;
+    for (i = 3; i > -1; i--)
+    {
+        uint8_t cur = (addr >> (i * 8)) & 0xff;
+        uint8_t hex[2];
+        bin_to_hex(cur, hex);
+        write_serial(hex[0]);
+        write_serial(hex[1]);
+    }
+}
+
+void print_uart_addr(uint64_t addr)
+{
+    int i;
+    for (i = 7; i > -1; i--)
+    {
+        uint8_t cur = (addr >> (i * 8)) & 0xff;
+        uint8_t hex[2];
+        bin_to_hex(cur, hex);
+        write_serial(hex[0]);
+        write_serial(hex[1]);
+    }
+}
+
+void print_uart_byte(uint8_t byte)
+{
+    uint8_t hex[2];
+    bin_to_hex(byte, hex);
+    write_serial(hex[0]);
+    write_serial(hex[1]);
+}
diff --git a/tests/testsBP/zsbl/uart.h b/tests/testsBP/zsbl/uart.h
new file mode 100644
index 000000000..df3aef9c8
--- /dev/null
+++ b/tests/testsBP/zsbl/uart.h
@@ -0,0 +1,27 @@
+#pragma once
+
+#include <stdint.h>
+
+#define UART_BASE 0x10000000
+
+#define UART_RBR UART_BASE + 0
+#define UART_THR UART_BASE + 0
+#define UART_INTERRUPT_ENABLE UART_BASE + 4
+#define UART_INTERRUPT_IDENT UART_BASE + 8
+#define UART_FIFO_CONTROL UART_BASE + 8
+#define UART_LINE_CONTROL UART_BASE + 12
+#define UART_MODEM_CONTROL UART_BASE + 16
+#define UART_LINE_STATUS UART_BASE + 20
+#define UART_MODEM_STATUS UART_BASE + 24
+#define UART_DLAB_LSB UART_BASE + 0
+#define UART_DLAB_MSB UART_BASE + 4
+
+void init_uart();
+
+void print_uart(const char* str);
+
+void print_uart_int(uint32_t addr);
+
+void print_uart_addr(uint64_t addr);
+
+void print_uart_byte(uint8_t byte);
diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-TEST-LIB-32.h b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-TEST-LIB-32.h
index 1293d23ad..454d05be5 100644
--- a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-TEST-LIB-32.h
+++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-TEST-LIB-32.h
@@ -1073,15 +1073,19 @@ uart_data_wait:
     li a4, 0x61
 uart_read_LSR_IIR:
     lb t4, 0(t3) // save IIR before reading LSR mgith clear it
-//  check if t4 is the rxfifotime out interrupt if it is then read the fifo then go back and repeat this.
-    li t7, 6
-    beq t4, t7, uart_rxfifo_timout
+    //  check if IIR is the rxfifotimeout interrupt. if it is, then read the fifo then go back and repeat this.
+    li t5, 6
+    beq t4, t5, uart_rxfifo_timout
     lb t5, 0(t2) // read LSR
     andi t6, t5, 0x61  // wait until all transmissions are done and data is ready
     bne a4, t6, uart_read_LSR_IIR
+    j uart_data_ready
 uart_rxfifo_timout:
-//read the fifo until empty
-   j uart_read_LSR_IIR
+    li t4, 0x10000000 // read from the fifo
+    lb t5, 0(t4)
+    lb t5, 0(t4)
+    //read the fifo until empty
+    j uart_read_LSR_IIR
 
 
 uart_data_ready:
diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-uart-timeout-01.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-uart-timeout-01.S
index 1523b3699..9e19ff202 100644
--- a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-uart-timeout-01.S
+++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-uart-timeout-01.S
@@ -92,16 +92,16 @@ TEST_STACK_AND_DATA
         // claim and completed have the same address.
         // then you'll return by mret.
 
-trap_handler:   
-        // this will only get uart interrupts
-        li s0, plicBaseAddr
-        addi s0, s0, 0x200004 // claim offset 
-        lw s1, 0(s0)
+# trap_handler:   
+#         // this will only get uart interrupts
+#         //li s0, plicBaseAddr
+#         addi s0, s0, 0x200004 // claim offset 
+#         lw s1, 0(s0)
 
-        // check that s1 is 10 and not something else
-        // read uart rx fifo
+#         // check that s1 is 10 and not something else
+#         // read uart rx fifo
         
 
-        // completed
-        sw s1, 0(s0) // tells the plic the isr is done.
-        mret
+#         // completed
+#         sw s1, 0(s0) // tells the plic the isr is done.
+#         mret