diff --git a/firmware.c b/firmware.c index 68fa8f9..704fc8f 100644 --- a/firmware.c +++ b/firmware.c @@ -1,7 +1,36 @@ -volatile int * const outreg = (int*)0x02000000; +/* + * PicoRV -- A Small and Extensible RISC-V Processor + * + * Copyright (C) 2019 Claire Wolf + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +void putc(int c) +{ + volatile char *p = (void*)0x02000000; + *p = c; +} + +void puts(char *s) +{ + while (*s) putc(*(s++)); +} int main() { - *outreg = 42; + puts("Hello World!\n"); + putc(0); return 0; } diff --git a/firmware.s b/firmware.s index dbf207c..8fdf925 100644 --- a/firmware.s +++ b/firmware.s @@ -52,7 +52,37 @@ addi x28, zero, 0 addi x29, zero, 0 addi x30, zero, 0 addi x31, zero, 0 -li sp, 0x00100000 + +# place SP at the end of RAM +li sp, 0x00010000 + +# copy data section +la a0, _sidata +la a1, _sdata +la a2, _edata +bge a1, a2, end_init_data +loop_init_data: +lw a3, 0(a0) +sw a3, 0(a1) +addi a0, a0, 4 +addi a1, a1, 4 +blt a1, a2, loop_init_data +end_init_data: + +# zero-init bss section +la a0, _sbss +la a1, _ebss +bge a0, a1, end_init_bss +loop_init_bss: +sw zero, 0(a0) +addi a0, a0, 4 +blt a0, a1, loop_init_bss +end_init_bss: + +# call main call main end: j end + + + diff --git a/sections.lds b/sections.lds index 23be526..fbc2c26 100644 --- a/sections.lds +++ b/sections.lds @@ -1,14 +1,64 @@ -MEMORY { +MEMORY +{ /* the memory in the testbench is 64k in size; * set LENGTH=48k and leave at least 16k for stack */ - mem : ORIGIN = 0x00000000, LENGTH = 0x0000c000 + RAM (xrw) : ORIGIN = 0x00000000, LENGTH = 0x00c000 } + SECTIONS { - .memory : { - . = 0x000000; - start*(.text); - *(.text); - *(*); - end = .; - } > mem + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + *(.srodata) /* .rodata sections (constants, strings, etc.) */ + *(.srodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + _etext = .; /* define a global symbol at end of code */ + _sidata = _etext; /* This is used by the startup in order to initialize the .data secion */ + } >RAM + + + /* This is the initialized data section + The program executes knowing that the data is in the RAM + but the loader puts the initial values in the FLASH (inidata). + It is one task of the startup to copy the initial values from FLASH to RAM. */ + .data : AT ( _sidata ) + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */ + _ram_start = .; /* create a global symbol at ram start for garbage collector */ + . = ALIGN(4); + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.sdata) /* .sdata sections */ + *(.sdata*) /* .sdata* sections */ + . = ALIGN(4); + _edata = .; /* define a global symbol at data end; used by startup code in order to initialise the .data section in RAM */ + } >RAM + + /* Uninitialized data section */ + .bss : + { + . = ALIGN(4); + _sbss = .; /* define a global symbol at bss start; used by startup code */ + *(.bss) + *(.bss*) + *(.sbss) + *(.sbss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end; used by startup code */ + } >RAM + + /* this is to define the start of the heap, and make sure we have a minimum size */ + .heap : + { + . = ALIGN(4); + _heap_start = .; /* define a global symbol at heap start */ + } >RAM } diff --git a/stupidrv_tb.sv b/stupidrv_tb.sv index 3147045..9f8e12b 100644 --- a/stupidrv_tb.sv +++ b/stupidrv_tb.sv @@ -2,7 +2,7 @@ module stupidrv_tb ( ); -localparam MEM_ADDR_WIDTH = 14; +localparam MEM_ADDR_WIDTH = 16; localparam TIMEOUT = (1<<10); reg clock;