From d4331491a87aa27fb77e5971c887e345886de2be Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 26 Jun 2015 22:02:22 +0200 Subject: [PATCH] Test firmware refactoring --- .gitignore | 2 +- Makefile | 10 ++- firmware/firmware.h | 22 ++++++ firmware/irq.c | 111 ++++++++++++++++++++++++++++++ firmware/print.c | 36 ++++++++++ firmware/sieve.c | 164 ++++++-------------------------------------- firmware/stats.c | 22 ++---- 7 files changed, 206 insertions(+), 161 deletions(-) create mode 100644 firmware/firmware.h create mode 100644 firmware/irq.c create mode 100644 firmware/print.c diff --git a/.gitignore b/.gitignore index 3dcece6..a8fbf72 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ /tests/*.o -/firmware/start.o +/firmware/*.o /firmware/firmware.bin /firmware/firmware.elf /firmware/firmware.hex diff --git a/Makefile b/Makefile index cf981e8..1d72601 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,6 @@ -TEST_OBJS=$(addsuffix .o,$(basename $(wildcard tests/*.S))) +TEST_OBJS = $(addsuffix .o,$(basename $(wildcard tests/*.S))) +FIRMWARE_OBJS = firmware/start.o firmware/irq.o firmware/print.o firmware/sieve.o firmware/stats.o test: testbench.exe firmware/firmware.hex vvp -N testbench.exe @@ -22,15 +23,18 @@ firmware/firmware.bin: firmware/firmware.elf riscv64-unknown-elf-objcopy -O binary $< $@ chmod -x $@ -firmware/firmware.elf: $(TEST_OBJS) firmware/sections.lds firmware/start.o firmware/sieve.c firmware/stats.c +firmware/firmware.elf: $(FIRMWARE_OBJS) $(TEST_OBJS) firmware/sections.lds riscv64-unknown-elf-gcc -Os -m32 -march=RV32I -ffreestanding -nostdlib -o $@ \ -Wl,-Bstatic,-T,firmware/sections.lds,-Map,firmware/firmware.map,--strip-debug \ - firmware/start.o firmware/sieve.c firmware/stats.c $(TEST_OBJS) -lgcc + $(FIRMWARE_OBJS) $(TEST_OBJS) -lgcc chmod -x $@ firmware/start.o: firmware/start.S riscv64-unknown-elf-gcc -c -m32 -o $@ $< +firmware/%.o: firmware/%.c + riscv64-unknown-elf-gcc -c -Os -m32 -march=RV32I -ffreestanding -nostdlib -o $@ $< + tests/%.o: tests/%.S tests/riscv_test.h tests/test_macros.h riscv64-unknown-elf-gcc -m32 -march=RV32I -c -o $@ -DTEST_FUNC_NAME=$(notdir $(basename $<)) \ -DTEST_FUNC_TXT='"$(notdir $(basename $<))"' -DTEST_FUNC_RET=$(notdir $(basename $<))_ret $< diff --git a/firmware/firmware.h b/firmware/firmware.h new file mode 100644 index 0000000..7744463 --- /dev/null +++ b/firmware/firmware.h @@ -0,0 +1,22 @@ +#ifndef FIRMWARE_H +#define FIRMWARE_H + +#include +#include + +// irq.c +uint32_t *irq(uint32_t *regs, uint32_t irqs); + +// print.c +void print_chr(char ch); +void print_str(const char *p); +void print_dec(int val); +void print_hex(unsigned int val); + +// sieve.c +void sieve(); + +// stats.c +void stats(); + +#endif diff --git a/firmware/irq.c b/firmware/irq.c new file mode 100644 index 0000000..e49ef47 --- /dev/null +++ b/firmware/irq.c @@ -0,0 +1,111 @@ + +#include "firmware.h" + +uint32_t *irq(uint32_t *regs, uint32_t irqs) +{ + static int ext_irq_4_count = 0; + static int ext_irq_5_count = 0; + static int timer_irq_count = 0; + + if ((irqs & (1<<4)) != 0) { + ext_irq_4_count++; + // print_str("[EXT-IRQ-4]"); + } + + if ((irqs & (1<<5)) != 0) { + ext_irq_5_count++; + // print_str("[EXT-IRQ-5]"); + } + + if ((irqs & 1) != 0) { + timer_irq_count++; + // print_str("[TIMER-IRQ]"); + } + + if ((irqs & 6) != 0) + { + int i, k; + uint32_t pc = regs[0] - 4; + uint32_t instr = *(uint32_t*)pc; + + print_str("\n"); + print_str("------------------------------------------------------------\n"); + + if ((irqs & 2) != 0) { + if (instr == 0x00100073) { + print_str("SBREAK instruction at 0x"); + print_hex(pc); + print_str("\n"); + } else { + print_str("Illegal Instruction at 0x"); + print_hex(pc); + print_str(": 0x"); + print_hex(instr); + print_str("\n"); + } + } + + if ((irqs & 4) != 0) { + print_str("Bus error in Instruction at 0x"); + print_hex(pc); + print_str(": 0x"); + print_hex(instr); + print_str("\n"); + } + + for (i = 0; i < 8; i++) + for (k = 0; k < 4; k++) + { + int r = i + k*8; + + if (r == 0) { + print_str("pc "); + } else + if (r < 10) { + print_chr('x'); + print_chr('0' + r); + print_chr(' '); + print_chr(' '); + } else + if (r < 20) { + print_chr('x'); + print_chr('1'); + print_chr('0' + r - 10); + print_chr(' '); + } else + if (r < 30) { + print_chr('x'); + print_chr('2'); + print_chr('0' + r - 20); + print_chr(' '); + } else { + print_chr('x'); + print_chr('3'); + print_chr('0' + r - 30); + print_chr(' '); + } + + print_hex(regs[r]); + print_str(k == 3 ? "\n" : " "); + } + + print_str("------------------------------------------------------------\n"); + + print_str("Number of fast external IRQs counted: "); + print_dec(ext_irq_4_count); + print_str("\n"); + + print_str("Number of slow external IRQs counted: "); + print_dec(ext_irq_5_count); + print_str("\n"); + + print_str("Number of timer IRQs counted: "); + print_dec(timer_irq_count); + print_str("\n"); + + __asm__("sbreak"); + } + + return regs; +} + diff --git a/firmware/print.c b/firmware/print.c new file mode 100644 index 0000000..03e9b09 --- /dev/null +++ b/firmware/print.c @@ -0,0 +1,36 @@ + +#include "firmware.h" + +#define OUTPORT 0x10000000 + +void print_chr(char ch) +{ + *((volatile uint32_t*)OUTPORT) = ch; +} + +void print_str(const char *p) +{ + while (*p != 0) + *((volatile uint32_t*)OUTPORT) = *(p++); +} + +void print_dec(int val) +{ + char buffer[10]; + char *p = buffer; + while (val || p == buffer) { + *(p++) = val % 10; + val = val / 10; + } + while (p != buffer) { + *((volatile uint32_t*)OUTPORT) = '0' + *(--p); + } +} + +void print_hex(unsigned int val) +{ + int i; + for (i = 32-4; i >= 0; i -= 4) + *((volatile uint32_t*)OUTPORT) = "0123456789ABCDEF"[(val >> i) % 16]; +} + diff --git a/firmware/sieve.c b/firmware/sieve.c index 6fb5b17..10fd1e0 100644 --- a/firmware/sieve.c +++ b/firmware/sieve.c @@ -1,12 +1,17 @@ // A simple Sieve of Eratosthenes -#include -#include +#include "firmware.h" #define BITMAP_SIZE 64 -#define OUTPORT 0x10000000 static uint32_t bitmap[BITMAP_SIZE/32]; +static uint32_t hash; + +static uint32_t mkhash(uint32_t a, uint32_t b) +{ + // The XOR version of DJB2 + return ((a << 5) + a) ^ b; +} static void bitmap_set(int idx) { @@ -18,37 +23,6 @@ static bool bitmap_get(int idx) return (bitmap[idx/32] & (1 << (idx % 32))) != 0; } -static void print_chr(char ch) -{ - *((volatile uint32_t*)OUTPORT) = ch; -} - -static void print_str(const char *p) -{ - while (*p != 0) - *((volatile uint32_t*)OUTPORT) = *(p++); -} - -static void print_dec(int val) -{ - char buffer[10]; - char *p = buffer; - while (val || p == buffer) { - *(p++) = val % 10; - val = val / 10; - } - while (p != buffer) { - *((volatile uint32_t*)OUTPORT) = '0' + *(--p); - } -} - -static void print_hex(unsigned int val) -{ - int i; - for (i = 32-4; i >= 0; i -= 4) - *((volatile uint32_t*)OUTPORT) = "0123456789ABCDEF"[(val >> i) % 16]; -} - static void print_prime(int idx, int val) { if (idx < 10) @@ -66,12 +40,16 @@ static void print_prime(int idx, int val) print_str(" prime is "); print_dec(val); print_str(".\n"); + + hash = mkhash(hash, idx); + hash = mkhash(hash, val); } void sieve() { int i, j, k; int idx = 1; + hash = 5381; print_prime(idx++, 2); for (i = 0; i < BITMAP_SIZE; i++) { if (bitmap_get(i)) @@ -86,113 +64,15 @@ void sieve() bitmap_set(k); } } -} - -uint32_t *irq(uint32_t *regs, uint32_t irqs) -{ - static int ext_irq_4_count = 0; - static int ext_irq_5_count = 0; - static int timer_irq_count = 0; - - if ((irqs & (1<<4)) != 0) { - ext_irq_4_count++; - // print_str("[EXT-IRQ-4]"); - } - - if ((irqs & (1<<5)) != 0) { - ext_irq_5_count++; - // print_str("[EXT-IRQ-5]"); - } - - if ((irqs & 1) != 0) { - timer_irq_count++; - // print_str("[TIMER-IRQ]"); - } - - if ((irqs & 6) != 0) - { - int i, k; - uint32_t pc = regs[0] - 4; - uint32_t instr = *(uint32_t*)pc; - - print_str("\n"); - print_str("------------------------------------------------------------\n"); - - if ((irqs & 2) != 0) { - if (instr == 0x00100073) { - print_str("SBREAK instruction at 0x"); - print_hex(pc); - print_str("\n"); - } else { - print_str("Illegal Instruction at 0x"); - print_hex(pc); - print_str(": 0x"); - print_hex(instr); - print_str("\n"); - } - } - - if ((irqs & 4) != 0) { - print_str("Bus error in Instruction at 0x"); - print_hex(pc); - print_str(": 0x"); - print_hex(instr); - print_str("\n"); - } - - for (i = 0; i < 8; i++) - for (k = 0; k < 4; k++) - { - int r = i + k*8; - - if (r == 0) { - print_str("pc "); - } else - if (r < 10) { - print_chr('x'); - print_chr('0' + r); - print_chr(' '); - print_chr(' '); - } else - if (r < 20) { - print_chr('x'); - print_chr('1'); - print_chr('0' + r - 10); - print_chr(' '); - } else - if (r < 30) { - print_chr('x'); - print_chr('2'); - print_chr('0' + r - 20); - print_chr(' '); - } else { - print_chr('x'); - print_chr('3'); - print_chr('0' + r - 30); - print_chr(' '); - } - - print_hex(regs[r]); - print_str(k == 3 ? "\n" : " "); - } - - print_str("------------------------------------------------------------\n"); - - print_str("Number of fast external IRQs counted: "); - print_dec(ext_irq_4_count); - print_str("\n"); - - print_str("Number of slow external IRQs counted: "); - print_dec(ext_irq_5_count); - print_str("\n"); - - print_str("Number of timer IRQs counted: "); - print_dec(timer_irq_count); - print_str("\n"); - - __asm__("sbreak"); - } - - return regs; + + print_str("checksum: "); + print_hex(hash); + + if (hash == 0x1772A48F) { + print_str(" OK\n"); + } else { + print_str(" ERROR\n"); + asm volatile ("sbreak"); + } } diff --git a/firmware/stats.c b/firmware/stats.c index c7b1b8e..21f97d5 100644 --- a/firmware/stats.c +++ b/firmware/stats.c @@ -1,14 +1,6 @@ -#include -#include -#define OUTPORT 0x10000000 +#include "firmware.h" -static void print_str(const char *p) -{ - while (*p != 0) - *((volatile uint32_t*)OUTPORT) = *(p++); -} - -static void print_dec(int val, int digits, bool zero_pad) +static void stats_print_dec(int val, int digits, bool zero_pad) { char buffer[32]; char *p = buffer; @@ -22,7 +14,7 @@ static void print_dec(int val, int digits, bool zero_pad) } while (p != buffer) { if (p[-1] == ' ' && p[-2] == ' ') p[-1] = '.'; - *((volatile uint32_t*)OUTPORT) = *(--p); + print_chr(*(--p)); } } @@ -31,13 +23,13 @@ void stats() int num_cycles, num_instr; asm("rdcycle %0; rdinstret %1;" : "=r"(num_cycles), "=r"(num_instr)); print_str("Cycle counter ........"); - print_dec(num_cycles, 8, false); + stats_print_dec(num_cycles, 8, false); print_str("\nInstruction counter .."); - print_dec(num_instr, 8, false); + stats_print_dec(num_instr, 8, false); print_str("\nCPI: "); - print_dec((num_cycles / num_instr), 0, false); + stats_print_dec((num_cycles / num_instr), 0, false); print_str("."); - print_dec(((100 * num_cycles) / num_instr) % 100, 2, true); + stats_print_dec(((100 * num_cycles) / num_instr) % 100, 2, true); print_str("\n"); }