From 77ba5a18973bd02b461ab96047acfcc3fb62cf7b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 6 Jun 2015 14:01:37 +0200 Subject: Initial import --- firmware/makehex.py | 17 +++++++++++ firmware/sections.lds | 9 ++++++ firmware/sieve.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++ firmware/start.S | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++ firmware/stats.c | 43 +++++++++++++++++++++++++++ 5 files changed, 227 insertions(+) create mode 100644 firmware/makehex.py create mode 100644 firmware/sections.lds create mode 100644 firmware/sieve.c create mode 100644 firmware/start.S create mode 100644 firmware/stats.c (limited to 'firmware') diff --git a/firmware/makehex.py b/firmware/makehex.py new file mode 100644 index 0000000..a5ae740 --- /dev/null +++ b/firmware/makehex.py @@ -0,0 +1,17 @@ +#!/usr/bin/python3 + +from sys import argv + +with open(argv[1], "rb") as f: + bindata = f.read() + +assert len(bindata) < 60*1024 +assert len(bindata) % 4 == 0 + +for i in range(64*1024//4): + if i < len(bindata) // 4: + w = bindata[4*i : 4*i+4] + print("%02x%02x%02x%02x" % (w[3], w[2], w[1], w[0])) + else: + print("0") + diff --git a/firmware/sections.lds b/firmware/sections.lds new file mode 100644 index 0000000..5e6e40c --- /dev/null +++ b/firmware/sections.lds @@ -0,0 +1,9 @@ +SECTIONS { + .memory : { + . = 0x000000; + start*(.text); + *(.text); + *(*); + end = .; + } +} diff --git a/firmware/sieve.c b/firmware/sieve.c new file mode 100644 index 0000000..c3372f4 --- /dev/null +++ b/firmware/sieve.c @@ -0,0 +1,78 @@ +// A simple Sieve of Eratosthenes + +#include +#include + +#define BITMAP_SIZE 64 +#define OUTPORT 0x10000000 + +static uint32_t bitmap[BITMAP_SIZE/32]; + +static void bitmap_set(int idx) +{ + bitmap[idx/32] |= 1 << (idx % 32); +} + +static bool bitmap_get(int idx) +{ + return (bitmap[idx/32] & (1 << (idx % 32))) != 0; +} + +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++) = val % 10; + val = val / 10; + } + while (p != buffer) { + *((volatile uint32_t*)OUTPORT) = '0' + *(--p); + } +} + +static void print_prime(int idx, int val) +{ + if (idx < 10) + print_str(" "); + print_dec(idx); + if (idx / 10 == 1) + goto force_th; + switch (idx % 10) { + case 1: print_str("st"); break; + case 2: print_str("nd"); break; + case 3: print_str("rd"); break; + force_th: + default: print_str("th"); break; + } + print_str(" prime is "); + print_dec(val); + print_str(".\n"); +} + +void sieve() +{ + int i, j, k; + int idx = 1; + print_prime(idx++, 2); + for (i = 0; i < BITMAP_SIZE; i++) { + if (bitmap_get(i)) + continue; + print_prime(idx++, 3+2*i); + for (j = 2*(3+2*i);; j += 3+2*i) { + if (j%2 == 0) + continue; + k = (j-3)/2; + if (k >= BITMAP_SIZE) + break; + bitmap_set(k); + } + } +} + diff --git a/firmware/start.S b/firmware/start.S new file mode 100644 index 0000000..34e44d8 --- /dev/null +++ b/firmware/start.S @@ -0,0 +1,80 @@ + .section .text + .global start + .global sieve + .global stats + +#define TEST(n) \ + .global n; .global n ## _ret; \ + jal zero,n; n ## _ret: + +start: + TEST(lui) + TEST(auipc) + TEST(j) + TEST(jal) + TEST(jalr) + + TEST(beq) + TEST(bne) + TEST(blt) + TEST(bge) + TEST(bltu) + TEST(bgeu) + + TEST(lb) + TEST(lh) + TEST(lw) + TEST(lbu) + TEST(lhu) + + TEST(sb) + TEST(sh) + TEST(sw) + + TEST(addi) + TEST(slti) // also tests sltiu + TEST(xori) + TEST(ori) + TEST(andi) + TEST(slli) + TEST(srli) + TEST(srai) + + TEST(add) + TEST(sub) + TEST(sll) + TEST(slt) // what is with sltu ? + TEST(xor) + TEST(srl) + TEST(sra) + TEST(or) + TEST(and) + + TEST(fence_i) + TEST(simple) + + /* set stack pointer */ + lui sp,(64*1024)>>12 + + /* jump to sieve C code */ + jal ra,sieve + + /* jump to stats C code */ + jal ra,stats + + /* print "DONE\n" */ + lui a0,0x10000000>>12 + addi a1,zero,'D' + addi a2,zero,'O' + addi a3,zero,'N' + addi a4,zero,'E' + addi a5,zero,'\n' + sw a1,0(a0) + sw a2,0(a0) + sw a3,0(a0) + sw a4,0(a0) + sw a5,0(a0) + + /* break */ + sbreak + diff --git a/firmware/stats.c b/firmware/stats.c new file mode 100644 index 0000000..c7b1b8e --- /dev/null +++ b/firmware/stats.c @@ -0,0 +1,43 @@ +#include +#include +#define OUTPORT 0x10000000 + +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) +{ + char buffer[32]; + char *p = buffer; + while (val || digits > 0) { + if (val) + *(p++) = '0' + val % 10; + else + *(p++) = zero_pad ? '0' : ' '; + val = val / 10; + digits--; + } + while (p != buffer) { + if (p[-1] == ' ' && p[-2] == ' ') p[-1] = '.'; + *((volatile uint32_t*)OUTPORT) = *(--p); + } +} + +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); + print_str("\nInstruction counter .."); + print_dec(num_instr, 8, false); + print_str("\nCPI: "); + print_dec((num_cycles / num_instr), 0, false); + print_str("."); + print_dec(((100 * num_cycles) / num_instr) % 100, 2, true); + print_str("\n"); +} + -- cgit