0

So, I have recently finished my homemade RISC-V CPU using nothing else than logic ICs and memories. (If somebody is interested you can watch more here: https://www.youtube.com/watch?v=KzSaFFpBPDM)

This means that the hardware is set, and no significant changes can be done at this point in time. I'm using xPack for compiling: https://xpack.github.io/riscv-none-embed-gcc/, with the architecture set as RV32I. All is working except when I need to use a global variable, here is an example code:

#include <stdint.h>

int static_var_1 = 2;
int static_var_2 = 4;

int main(void)
{
    int var = static_var_1 + static_var_2;
}

Object dump (objdump) reveals this:

APP.elf:     file format elf32-littleriscv


Disassembly of section .text:

00000000 <_start>:
   0:   00080137            lui sp,0x80
   4:   ffc10113            addi    sp,sp,-4 # 7fffc <_estack>
   8:   00c000ef            jal ra,14 <main>
   c:   0040006f            j   10 <_exit>

00000010 <_exit>:
  10:   0000006f            j   10 <_exit>

00000014 <main>:
  14:   fe010113            addi    sp,sp,-32
  18:   00812e23            sw  s0,28(sp)
  1c:   02010413            addi    s0,sp,32
  20:   00002703            lw  a4,0(zero) # 0 <_start>
  24:   00402783            lw  a5,4(zero) # 4 <static_var_2>
  28:   00f707b3            add a5,a4,a5
  2c:   fef42623            sw  a5,-20(s0)
  30:   00000793            li  a5,0
  34:   00078513            mv  a0,a5
  38:   01c12403            lw  s0,28(sp)
  3c:   02010113            addi    sp,sp,32
  40:   00008067            ret

Disassembly of section .data:

00000000 <static_var_1>:
   0:   0002                    c.slli64    zero
    ...

00000004 <static_var_2>:
   4:   0004                    0x4
    ...

Disassembly of section ._user_heap_stack:

00000008 <._user_heap_stack>:
    ...

From my observation and this part of code

  20:   00002703            lw  a4,0(zero) # 0 <_start>
  24:   00402783            lw  a5,4(zero) # 4 <static_var_2>

it appears that the CPU wants to load the values directly from RAM, starting at address 0, but they were never put there in the first place. Does the CPU somehow assume that it will have a pre-loaded RAM at start/reset? How "normal" CPUs handle this situation and how I should solve mine? Is there some setting that would force the compiler to firstly fetch these variables into RAM?

This is a slightly similar problem to this one (RISC V Global variables access in assembly), but I don't really see how "compiler relaxation" could really help, but maybe I'm wrong...

Filip
  • 71
  • 6
  • Did you wrote your own linker script? – Eraklon Jul 12 '21 at 12:20
  • @Eraklon My friend helped me setup the linker script, unfortunately I don't really know how it exactly works – Filip Jul 12 '21 at 12:48
  • Did you ask `objdump` to show relocadtions? – Erik Eidt Jul 12 '21 at 14:09
  • @ErikEidt Once I learn what it is and does I will do that – Filip Jul 12 '21 at 14:10
  • @ErikEidt Maybe I'm doing it wrong, maybe I don't know what I'm looking for, but I didn't found out anything – Filip Jul 12 '21 at 14:45
  • ok, I don't know the specific answer but it might help others answer if you can provide (1) the toolchain, (2) command lines to build and dump the executable, and (3) linker scripts. Btw, it is *linker* relaxation.. (Of course, it can be turned off.) – Erik Eidt Jul 12 '21 at 21:22

1 Answers1

0

00000000 <_start>:

This binary is linked to be loaded at address 0. This is unusual (most people want to distinguish NULL pointer from valid addresses, and putting code into the zero page doesn't allow for such distinction).

Disassembly of section .data:
00000000 <static_var_1>:

This binary is linked to put .data section at address 0 as well. That can not work -- you must put .data somewhere else.

My friend helped me setup the linker script,

That linker script is definitely wrong. Find a better friend ;-)

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
  • But the CPU starts executing at address zero, so there must be something there. Even if the .data section was in the main program, it is still invalid instruction and the CPU will halt. What I think I need is for the .data section to be relocated and decoded as valid instructions; for example the 0x4 could be: `addi t0, zero, 4 sw t0, 0(zero)` I will post the linker script in a moment, but I'm not sure about that change of friends :))) – Filip Jul 13 '21 at 07:16
  • Okay, after internal discussion, it boiled down to "we need a new linker script". Oh well, where to start... – Filip Jul 13 '21 at 10:04