diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/checksum.c | 47 | ||||
-rw-r--r-- | tests/debug.c | 27 | ||||
-rwxr-xr-x | tests/gdbserver.py | 225 | ||||
-rw-r--r-- | tests/mprv.S | 38 | ||||
-rw-r--r-- | tests/regs.s | 43 | ||||
-rw-r--r-- | tests/standalone.lds | 92 | ||||
-rw-r--r-- | tests/start.S | 12 |
7 files changed, 0 insertions, 484 deletions
diff --git a/tests/checksum.c b/tests/checksum.c deleted file mode 100644 index 36152fc..0000000 --- a/tests/checksum.c +++ /dev/null @@ -1,47 +0,0 @@ -#include <stdint.h> - -// CRC code from http://www.hackersdelight.org/hdcodetxt/crc.c.txt - -// Reverses (reflects) bits in a 32-bit word. -unsigned reverse(unsigned x) { - x = ((x & 0x55555555) << 1) | ((x >> 1) & 0x55555555); - x = ((x & 0x33333333) << 2) | ((x >> 2) & 0x33333333); - x = ((x & 0x0F0F0F0F) << 4) | ((x >> 4) & 0x0F0F0F0F); - x = (x << 24) | ((x & 0xFF00) << 8) | - ((x >> 8) & 0xFF00) | (x >> 24); - return x; -} - -// ----------------------------- crc32a -------------------------------- - -/* This is the basic CRC algorithm with no optimizations. It follows the -logic circuit as closely as possible. */ - -unsigned int crc32a(uint8_t *message, unsigned int size) { - int i, j; - unsigned int byte, crc; - - i = 0; - crc = 0xFFFFFFFF; - while (i < size) { - byte = message[i]; // Get next byte. - byte = reverse(byte); // 32-bit reversal. - for (j = 0; j <= 7; j++) { // Do eight times. - if ((int)(crc ^ byte) < 0) - crc = (crc << 1) ^ 0x04C11DB7; - else crc = crc << 1; - byte = byte << 1; // Ready next msg bit. - } - i = i + 1; - } - return reverse(~crc); -} - -extern uint8_t *data; -extern uint32_t length; - -uint32_t main() -{ - /* Compute a simple checksum. */ - return crc32a(data, length); -} diff --git a/tests/debug.c b/tests/debug.c deleted file mode 100644 index 2cad88f..0000000 --- a/tests/debug.c +++ /dev/null @@ -1,27 +0,0 @@ -#include <stdio.h> - -char c = 'x'; - -void print_row(int length) -{ - for (int x=0; x<length; x++) { - printf("%c", c); - } - printf("\n"); -} - -int main() -{ - volatile int i = 42; - const char *text = "constant\n"; - int threshold = 7; - - // Wait for the debugger to get us out of this loop. - while (i) - ; - - printf("%s", text); - for (int y=0; y < 10; y++) { - print_row(y); - } -} diff --git a/tests/gdbserver.py b/tests/gdbserver.py deleted file mode 100755 index f16a3cc..0000000 --- a/tests/gdbserver.py +++ /dev/null @@ -1,225 +0,0 @@ -#!/usr/bin/python - -import os -import testlib -import unittest -import tempfile -import time -import random -import binascii - -class DeleteSpike(unittest.TestCase): - def tearDown(self): - del self.spike - -class InstantHaltTest(DeleteSpike): - def setUp(self): - self.binary = testlib.compile("debug.c") - self.spike = testlib.Spike(self.binary, halted=True) - self.gdb = testlib.Gdb() - self.gdb.command("file %s" % self.binary) - self.gdb.command("target extended-remote localhost:%d" % self.spike.port) - - def test_instant_halt(self): - self.assertEqual(0x1000, self.gdb.p("$pc")) - # For some reason instret resets to 0. - self.assertLess(self.gdb.p("$instret"), 8) - self.gdb.command("stepi") - self.assertNotEqual(0x1000, self.gdb.p("$pc")) - - def test_change_pc(self): - """Change the PC right as we come out of reset.""" - # 0x13 is nop - self.gdb.command("p *((int*) 0x80000000)=0x13") - self.gdb.command("p *((int*) 0x80000004)=0x13") - self.gdb.command("p *((int*) 0x80000008)=0x13") - self.gdb.command("p $pc=0x80000000") - self.gdb.command("stepi") - self.assertEqual(0x80000004, self.gdb.p("$pc")) - self.gdb.command("stepi") - self.assertEqual(0x80000008, self.gdb.p("$pc")) - -class DebugTest(DeleteSpike): - def setUp(self): - self.binary = testlib.compile("debug.c") - self.spike = testlib.Spike(self.binary, halted=False) - self.gdb = testlib.Gdb() - self.gdb.command("file %s" % self.binary) - self.gdb.command("target extended-remote localhost:%d" % self.spike.port) - - def test_turbostep(self): - """Single step a bunch of times.""" - self.gdb.command("p i=0"); - last_pc = None - for _ in range(100): - self.gdb.command("stepi") - pc = self.gdb.command("p $pc") - self.assertNotEqual(last_pc, pc) - last_pc = pc - - def test_exit(self): - self.gdb.command("p i=0"); - output = self.gdb.command("c") - self.assertIn("Continuing", output) - self.assertIn("Remote connection closed", output) - - def test_breakpoint(self): - self.gdb.command("p i=0"); - self.gdb.command("b print_row") - # The breakpoint should be hit exactly 10 times. - for i in range(10): - output = self.gdb.command("c") - self.assertIn("Continuing", output) - self.assertIn("length=%d" % i, output) - self.assertIn("Breakpoint 1", output) - output = self.gdb.command("c") - self.assertIn("Continuing", output) - self.assertIn("Remote connection closed", output) - - def test_registers(self): - self.gdb.command("p i=0"); - # Try both forms to test gdb. - for cmd in ("info all-registers", "info registers all"): - output = self.gdb.command(cmd) - self.assertNotIn("Could not", output) - for reg in ('zero', 'ra', 'sp', 'gp', 'tp'): - self.assertIn(reg, output) - # mcpuid is one of the few registers that should have the high bit set - # (for rv64). - # Leave this commented out until gdb and spike agree on the encoding of - # mcpuid (which is going to be renamed to misa in any case). - #self.assertRegexpMatches(output, ".*mcpuid *0x80") - - # The instret register should always be changing. - last_instret = None - for _ in range(5): - instret = self.gdb.p("$instret") - self.assertNotEqual(instret, last_instret) - last_instret = instret - self.gdb.command("stepi") - - def test_interrupt(self): - """Sending gdb ^C while the program is running should cause it to halt.""" - self.gdb.c(wait=False) - time.sleep(0.1) - self.gdb.interrupt() - self.gdb.command("p i=123"); - self.gdb.c(wait=False) - time.sleep(0.1) - self.gdb.interrupt() - self.gdb.command("p i=0"); - output = self.gdb.c() - self.assertIn("Continuing", output) - self.assertIn("Remote connection closed", output) - -class RegsTest(DeleteSpike): - def setUp(self): - self.binary = testlib.compile("regs.s") - self.spike = testlib.Spike(self.binary, halted=False) - self.gdb = testlib.Gdb() - self.gdb.command("file %s" % self.binary) - self.gdb.command("target extended-remote localhost:%d" % self.spike.port) - - def test_write_gprs(self): - # Note a0 is missing from this list since it's used to hold the - # address. - regs = ("ra", "sp", "gp", "tp", "t0", "t1", "t2", "fp", "s1", - "a1", "a2", "a3", "a4", "a5", "a6", "a7", "s2", "s3", "s4", - "s5", "s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5", - "t6") - - self.gdb.command("p $pc=write_regs") - for i, r in enumerate(regs): - self.gdb.command("p $%s=%d" % (r, (0xdeadbeef<<i)+17)) - self.gdb.command("p $a0=data") - self.gdb.command("b all_done") - output = self.gdb.command("c") - self.assertIn("Breakpoint 1", output) - - # Just to get this data in the log. - self.gdb.command("x/30gx data") - self.gdb.command("info registers") - for n in range(len(regs)): - self.assertEqual(self.gdb.x("data+%d" % (8*n), 'g'), - (0xdeadbeef<<n)+17) - - def test_write_csrs(self): - # As much a test of gdb as of the simulator. - self.gdb.p("$mscratch=0") - self.gdb.stepi() - self.assertEqual(self.gdb.p("$mscratch"), 0) - self.gdb.p("$mscratch=123") - self.gdb.stepi() - self.assertEqual(self.gdb.p("$mscratch"), 123) - - self.gdb.command("p $fflags=9") - self.gdb.command("p $pc=write_regs") - self.gdb.command("p $a0=data") - self.gdb.command("b all_done") - self.gdb.command("c") - - self.assertEqual(9, self.gdb.p("$fflags")) - self.assertEqual(9, self.gdb.p("$x1")) - self.assertEqual(9, self.gdb.p("$csr1")) - -class DownloadTest(DeleteSpike): - def setUp(self): - length = 2**20 - fd = file("data.c", "w") - fd.write("#include <stdint.h>\n") - fd.write("uint32_t length = %d;\n" % length) - fd.write("uint8_t d[%d] = {\n" % length) - self.crc = 0 - for i in range(length / 16): - fd.write(" /* 0x%04x */ " % (i * 16)); - for _ in range(16): - value = random.randrange(1<<8) - fd.write("%d, " % value) - self.crc = binascii.crc32("%c" % value, self.crc) - fd.write("\n"); - fd.write("};\n"); - fd.write("uint8_t *data = &d[0];\n"); - fd.close() - - self.binary = testlib.compile("checksum.c", "data.c", "start.S", - "-mcmodel=medany", - "-T", "standalone.lds", - "-nostartfiles" - ) - self.spike = testlib.Spike(None, halted=True) - self.gdb = testlib.Gdb() - self.gdb.command("file %s" % self.binary) - self.gdb.command("target extended-remote localhost:%d" % self.spike.port) - - def test_download(self): - output = self.gdb.command("load") - self.assertNotIn("failed", output) - self.assertIn("Transfer rate", output) - self.gdb.command("b done") - self.gdb.c() - result = self.gdb.p("$a0") - self.assertEqual(self.crc, result) - -class MprvTest(DeleteSpike): - def setUp(self): - self.binary = testlib.compile("mprv.S", "-T", "standalone.lds", - "-nostartfiles") - self.spike = testlib.Spike(None, halted=True) - self.gdb = testlib.Gdb() - self.gdb.command("file %s" % self.binary) - self.gdb.command("target extended-remote localhost:%d" % self.spike.port) - self.gdb.command("load") - - def test_mprv(self): - """Test that the debugger can access memory when MPRV is set.""" - self.gdb.c(wait=False) - self.gdb.interrupt() - output = self.gdb.command("p/x *(int*)(((char*)&data)-0x80000000)") - self.assertIn("0xbead", output) - -if __name__ == '__main__': - # TROUBLESHOOTING TIPS - # If a particular test fails, run just that one test, eg.: - # ./tests/gdbserver.py MprvTest.test_mprv - # Then inspect gdb.log and spike.log to see what happened in more detail. - unittest.main() diff --git a/tests/mprv.S b/tests/mprv.S deleted file mode 100644 index 58eba0b..0000000 --- a/tests/mprv.S +++ /dev/null @@ -1,38 +0,0 @@ -#include "../riscv/encoding.h" -#define PGSHIFT 12 - - .global _start - - .section .text -_start: - # Set up a page table entry that maps 0x0... to 0x8... - la t0, page_table - srli t0, t0, PGSHIFT - csrw CSR_SPTBR, t0 - - # update mstatus - csrr t1, CSR_MSTATUS - li t0, (MSTATUS_MPRV | (VM_SV39 << 24)) - #li t0, ((VM_SV39 << 24)) - or t1, t0, t1 - csrw CSR_MSTATUS, t1 - - la t0, (loop - 0x80000000) - csrw CSR_MEPC, t0 - - # Exit supervisor mode, entering user mode at loop. - mret - -loop: - la t0, data - lw t1, 0(t0) - j loop - - .section .data -data: - .word 0xbead - - .balign 0x1000 -page_table: - .word ((0x80000000 >> 2) | PTE_V | PTE_U | PTE_R | PTE_W | PTE_X) - .word 0 diff --git a/tests/regs.s b/tests/regs.s deleted file mode 100644 index e6456e1..0000000 --- a/tests/regs.s +++ /dev/null @@ -1,43 +0,0 @@ - .global main -main: - j main - -write_regs: - sd x1, 0(a0) - sd x2, 8(a0) - sd x3, 16(a0) - sd x4, 24(a0) - sd x5, 32(a0) - sd x6, 40(a0) - sd x7, 48(a0) - sd x8, 56(a0) - sd x9, 64(a0) - sd x11, 72(a0) - sd x12, 80(a0) - sd x13, 88(a0) - sd x14, 96(a0) - sd x15, 104(a0) - sd x16, 112(a0) - sd x17, 120(a0) - sd x18, 128(a0) - sd x19, 136(a0) - sd x20, 144(a0) - sd x21, 152(a0) - sd x22, 160(a0) - sd x23, 168(a0) - sd x24, 176(a0) - sd x25, 184(a0) - sd x26, 192(a0) - sd x27, 200(a0) - sd x28, 208(a0) - sd x29, 216(a0) - sd x30, 224(a0) - sd x31, 232(a0) - - csrr x1, 1 # fflags - -all_done: - j all_done - -data: - .fill 64, 8, 0 diff --git a/tests/standalone.lds b/tests/standalone.lds deleted file mode 100644 index 330fa16..0000000 --- a/tests/standalone.lds +++ /dev/null @@ -1,92 +0,0 @@ -OUTPUT_ARCH( "riscv" ) - -ENTRY( _start ) - -SECTIONS -{ - - /*--------------------------------------------------------------------*/ - /* Code and read-only segment */ - /*--------------------------------------------------------------------*/ - - /* Begining of code and text segment */ - /* Leave some space for pk's data structures, which includes tohost/fromhost - * which are special addresses we ought to leave alone. */ - . = 0x80010000; - _ftext = .; - PROVIDE( eprol = . ); - - .text : - { - *(.text.init) - } - - /* text: Program code section */ - .text : - { - *(.text) - *(.text.*) - *(.gnu.linkonce.t.*) - } - - /* rodata: Read-only data */ - .rodata : - { - *(.rdata) - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - } - - /* End of code and read-only segment */ - PROVIDE( etext = . ); - _etext = .; - - /*--------------------------------------------------------------------*/ - /* Initialized data segment */ - /*--------------------------------------------------------------------*/ - - /* Start of initialized data segment */ - . = ALIGN(16); - _fdata = .; - - /* data: Writable data */ - .data : - { - *(.data) - *(.data.*) - *(.srodata*) - *(.gnu.linkonce.d.*) - *(.comment) - } - - /* End of initialized data segment */ - . = ALIGN(4); - PROVIDE( edata = . ); - _edata = .; - - /*--------------------------------------------------------------------*/ - /* Uninitialized data segment */ - /*--------------------------------------------------------------------*/ - - /* Start of uninitialized data segment */ - . = .; - _fbss = .; - - /* sbss: Uninitialized writeable small data section */ - . = .; - - /* bss: Uninitialized writeable data section */ - . = .; - _bss_start = .; - .bss : - { - *(.bss) - *(.bss.*) - *(.sbss*) - *(.gnu.linkonce.b.*) - *(COMMON) - } - - _end = .; -} diff --git a/tests/start.S b/tests/start.S deleted file mode 100644 index 76c37bb..0000000 --- a/tests/start.S +++ /dev/null @@ -1,12 +0,0 @@ - .global _start - -_start: - la sp, stack_end - jal main -done: - j done - - .data -stack: - .fill 4096, 1, 0 -stack_end: |