public inbox for newlib@sourceware.org
 help / color / mirror / Atom feed
* Problem with SBRK not returning from call on bare metal risk
@ 2023-03-06  7:36 Damien Towning
  2023-03-06 13:24 ` Dave Nadler
  0 siblings, 1 reply; 3+ messages in thread
From: Damien Towning @ 2023-03-06  7:36 UTC (permalink / raw)
  To: newlib

[-- Attachment #1: Type: text/plain, Size: 17423 bytes --]

So a bit of a background. I have the bonfire Risc-V 32 core running on a
T-35 FPGA board. The metal part of this is working great. The processor
runs. I've got it to turn around the segment display on the board. I've
also implemented my own _sbrk and got that to work I think consistently
with malloc. Now in my Risc-v 32 toolchain I have the newlib and I have
brought that in and with my own wrapped _sbrk I am able to use the system
defined malloc. But I am not entirely happy with this because I don't want
to be wrapping every function I encounter. So for example today I found
myself wrapping srand and rand. So I am pretty sure the reason my
nano_newlib isn't working is something to do with either not having the
correct variable names in my firmware.ld or something to do with disabling
the re-entrant behaviour of newlib. I've included in this email my
firmware.ld,platform.h,c code example. What happens is I call the _sbrk(0)
and ( in the simulator I am also running this in ) I never see a bad opcode
generated. It just seems like the processor goes away and never comes back.
Does anybody have any suggestions as to what might cause this sort of
problem ? I'd like to use the sbrk and other funcitons within the newlib
itself if possible without rolling my own.

------------- firmware.ld
MEMORY
{

   RAM (rwx)    : ORIGIN = 0x0C000000, LENGTH = 512K
}

ENTRY(_start)

SECTIONS
{
    _rombase = 0x0C000000;

  . = 0x0;

  .text : {
    *(.init)
    *(.text.*)

  } > RAM

  .data  ALIGN(4) : {
    *(.rodata.*)
    *(.rodata)
    *(.eh_frame)
    *(.sdata)
    *(.data)
    *(.sbss)
    *(.sbss.*)
    *(.gnu.linkonce.sb.*)
    *(.bss)
    *(.bss.*)
    *(.gnu.linkonce.b.*)
    *(COMMON)

    end = .; _end = .; __end = .;

 } > RAM

 _heap_end = _end;
 _heap_prev_end = _end;

}

PROVIDE(__heap_end = _end);
PROVIDE(__prev_heap_end = _end);
PROVIDE(__heap_start = _end+128K);

PROVIDE(__stack_top   = ORIGIN(RAM) + LENGTH(RAM));
PROVIDE(__stack_start = ORIGIN(RAM) + LENGTH(RAM));

PROVIDE(__heap_size = 128K );
PROVIDE(__stack_size = 128K );



/*
0x0C000000 +-------------------+
           |                   |
           |     ROM / Flash   |
0x0C080000 +-------------------+
           |                   |
           |      .data        |
           |-------------------|
           |     .bss / .sbss  |
           |-------------------|
           |        _end       |
           |-------------------|
           |        Heap       |
           |-------------------|
           |        Stack      |
0xXXXXXXXX +-------------------+
*/
--------------------------------------------------------------------------------------

---------platform.h
----------------------------------------------------------------
#ifndef BASIC_PLATFORM_H
#define BASIC_PLATFORM_H

// New Defintions for new bonfire-soc-io core
#define IO_BASE 0x04000000
#define SOC_IO_OFFSET 0x10000 // Offset from one I/O Device to the next
(64K range)

#define UART0_BASE IO_BASE
#define SPIFLASH_BASE (IO_BASE+SOC_IO_OFFSET)
#define GPIO_BASE (IO_BASE+3*SOC_IO_OFFSET)
#define UART1_BASE (IO_BASE+2*SOC_IO_OFFSET)

#define UART_BASE UART0_BASE // Backwards compatiblity

#define MTIME_BASE 0x0FFFF0000

#define DRAM_BASE 0x0
#define DRAM_SIZE 0
#define DRAM_TOP  (DRAM_BASE+DRAM_SIZE-1)
#define SRAM_BASE 0x0C000000
#define SRAM_SIZE 524288
#define SRAM_TOP  (SRAM_BASE+SRAM_SIZE-1)

//#define SYSCLK 12000000
//#define SYSCLK   33333333
//#define   SYSCLK   24997500
//#define   SYSCLK   88786000
#define     EXT_SYSCLK   89015000

#define SYSCLK       24997500

//#define EXT_SYSCLK   92370000  /* For reasons not clear to me when any
change is made to the interface   */
  /* configuration in Efinity and a new synthesis is done a clock time will
*/
  /* be calculated so you must build your efinity project. Take that new
 */
  /* time value. Update it here. Rebuild your hex file. Then rebuild your
*/
  /* efinity project AGAIN
 */


#define TIME_UNIT 1e+9;  // A billion

#ifndef SIMULATOR
#define SCALAR 1      // Relative Scalar division for efinity build
#define BAUD_SCALAR 1 // Relative Scalar division for efinity build
#else
#define SCALAR 10000    // Relative Scalar division for simulator. Use for
any of your own timing since
#define BAUD_SCALAR 20 // simulator runs slower than real hardware
#endif

#define CLK_PERIOD (TIME_UNIT / EXT_SYSCLK)  // in ns...

//#define DCACHE_SIZE 0 // (2048*4)  // DCache Size in Bytes

// Parameters for SPI Flash

#define FLASHSIZE (8192*1024)
#define MAX_FLASH_IMAGESIZE (2024*1024) // Max 2MB of flash used for boot
image
#define FLASH_IMAGEBASE (1024*3072)  // Boot Image starts at 3MB in Flash

#define PLATFORM_BAUDRATE (115200*BAUD_SCALAR)

#define NO_RECURSION
#define NO_SYSCALL
#define NO_FLASH
#define NO_XMODEM
#define NO_DRAMTEST

//#define GPIO_TEST

#endif
---------------------------------------------------------------------------------------------

---- sim_hello.c
------------------------------------------------------------------------
// ==============================================
// T35 S100 Module Test Code
// Damien Towning - 2022
// ==============================================
#include <stdioSo a bit of a background. I have the bonfire Risc-V 32 core
running on a T-35 FPGA board. The metal part of this is working great. The
processor runs. I've got it to turn around the segment display on the
board. I've also implemented my own _sbrk and got that to work I think
consistently with malloc. Now in my Risc-v 32 toolchain I have the newlib
and I have brought that in and with my own wrapped _sbrk I am able to use
the system defined malloc. But I am not entirely happy with this because I
don't want to be wrapping every function I encounter. So for example today
I found myself wrapping srand and rand. So I am pretty sure the reason my
nano_newlib isn't working is something to do with either not having the
correct variable names in my firmware.ld or something to do with disabling
the re-entrant behaviour of newlib. I've included in this email my
firmware.ld,platform.h,c code example. What happens is I call the _sbrk(0)
and ( in the simulator I am also running this in ) I never see a bad opcode
generated. It just seems like the processor goes away and never comes back.
Does anybody have any suggestions as to what might cause this sort of
problem ? I'd like to use the sbrk and other funcitons within the newlib
itself if possible without rolling my own.

------------- firmware.ld
MEMORY
{

   RAM (rwx)    : ORIGIN = 0x0C000000, LENGTH = 512K
}

ENTRY(_start)

SECTIONS
{
    _rombase = 0x0C000000;

  . = 0x0;

  .text : {
    *(.init)
    *(.text.*)

  } > RAM

  .data  ALIGN(4) : {
    *(.rodata.*)
    *(.rodata)
    *(.eh_frame)
    *(.sdata)
    *(.data)
    *(.sbss)
    *(.sbss.*)
    *(.gnu.linkonce.sb.*)
    *(.bss)
    *(.bss.*)
    *(.gnu.linkonce.b.*)
    *(COMMON)

    end = .; _end = .; __end = .;

 } > RAM

 _heap_end = _end;
 _heap_prev_end = _end;

}

PROVIDE(__heap_end = _end);
PROVIDE(__prev_heap_end = _end);
PROVIDE(__heap_start = _end+128K);

PROVIDE(__stack_top   = ORIGIN(RAM) + LENGTH(RAM));
PROVIDE(__stack_start = ORIGIN(RAM) + LENGTH(RAM));

PROVIDE(__heap_size = 128K );
PROVIDE(__stack_size = 128K );



/*
0x0C000000 +-------------------+
           |                   |
           |     ROM / Flash   |
0x0C080000 +-------------------+
           |                   |
           |      .data        |
           |-------------------|
           |     .bss / .sbss  |
           |-------------------|
           |        _end       |
           |-------------------|
           |        Heap       |
           |-------------------|
           |        Stack      |
0xXXXXXXXX +-------------------+
*/
--------------------------------------------------------------------------------------

---------platform.h
----------------------------------------------------------------
#ifndef BASIC_PLATFORM_H
#define BASIC_PLATFORM_H

// New Defintions for new bonfire-soc-io core
#define IO_BASE 0x04000000
#define SOC_IO_OFFSET 0x10000 // Offset from one I/O Device to the next
(64K range)

#define UART0_BASE IO_BASE
#define SPIFLASH_BASE (IO_BASE+SOC_IO_OFFSET)
#define GPIO_BASE (IO_BASE+3*SOC_IO_OFFSET)
#define UART1_BASE (IO_BASE+2*SOC_IO_OFFSET)

#define UART_BASE UART0_BASE // Backwards compatiblity

#define MTIME_BASE 0x0FFFF0000

#define DRAM_BASE 0x0
#define DRAM_SIZE 0
#define DRAM_TOP  (DRAM_BASE+DRAM_SIZE-1)
#define SRAM_BASE 0x0C000000
#define SRAM_SIZE 524288
#define SRAM_TOP  (SRAM_BASE+SRAM_SIZE-1)

//#define SYSCLK 12000000
//#define SYSCLK   33333333
//#define   SYSCLK   24997500
//#define   SYSCLK   88786000
#define     EXT_SYSCLK   89015000

#define SYSCLK       24997500

//#define EXT_SYSCLK   92370000  /* For reasons not clear to me when any
change is made to the interface   */
  /* configuration in Efinity and a new synthesis is done a clock time will
*/
  /* be calculated so you must build your efinity project. Take that new
 */
  /* time value. Update it here. Rebuild your hex file. Then rebuild your
*/
  /* efinity project AGAIN
 */


#define TIME_UNIT 1e+9;  // A billion

#ifndef SIMULATOR
#define SCALAR 1      // Relative Scalar division for efinity build
#define BAUD_SCALAR 1 // Relative Scalar division for efinity build
#else
#define SCALAR 10000    // Relative Scalar division for simulator. Use for
any of your own timing since
#define BAUD_SCALAR 20 // simulator runs slower than real hardware
#endif

#define CLK_PERIOD (TIME_UNIT / EXT_SYSCLK)  // in ns...

//#define DCACHE_SIZE 0 // (2048*4)  // DCache Size in Bytes

// Parameters for SPI Flash

#define FLASHSIZE (8192*1024)
#define MAX_FLASH_IMAGESIZE (2024*1024) // Max 2MB of flash used for boot
image
#define FLASH_IMAGEBASE (1024*3072)  // Boot Image starts at 3MB in Flash

#define PLATFORM_BAUDRATE (115200*BAUD_SCALAR)

#define NO_RECURSION
#define NO_SYSCALL
#define NO_FLASH
#define NO_XMODEM
#define NO_DRAMTEST

//#define GPIO_TEST

#endif
---------------------------------------------------------------------------------------------

---- sim_hello.c
------------------------------------------------------------------------
// ==============================================
// T35 S100 Module Test Code
// Damien Towning - 2022
// ==============================================
#include <stdio.h>
#include <stdlib.h>

//#include <newlib.h>
//#include <nano_malloc.h>
#include <errno.h>
#include <sys/types.h>
#include <string.h>
#include "bonfire.h"
#include "uart.h"
#include "bonfire_gpio.h"
#include "mem_rw.h"
#include "console.h"

extern void* sbrk(incr);


// ========================================
// Main function
// ========================================
int main() {

  setBaudRate(PLATFORM_BAUDRATE);

  caddr_t *ptr = sbrk(0);
  // code never returns from sbrk
  if (ptr == (void *)-1) {
    printk("Failed to allocate memory\r\n");
  }
  else {
    printk("Allocated memory at : %p\r\n", (void *) &ptr);
  }
  return 0;
}
------------------------------------------------------------------------------------
--- Makefile
--------------------------------------------------------------------

.PHONY: all clean

ARCH ?= rv32ia
ABI=ilp32
PLATFORM ?= S100_T35

#TARGET_PREFIX ?= riscv32-unknown-linux-gnu
TARGET_PREFIX ?= riscv32-unknown-elf
TARGET_CC := $(TARGET_PREFIX)-gcc
TARGET_LD := $(TARGET_PREFIX)-gcc
TARGET_SIZE := $(TARGET_PREFIX)-size
TARGET_OBJCOPY := $(TARGET_PREFIX)-objcopy
HEXDUMP ?= hexdump
DATA2MEM = /opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/data2mem

#PROJROOT = ../../..
#TOPLEVEL = ~/riscv/ise/bonfire/papilio_pro_dram_toplevel.bit
PLATFORMDIR=../platform

LINKDEF?=$(PLATFORMDIR)/$(PLATFORM)/firmware.ld

TARGET_CFLAGS +=  -march=$(ARCH) -mabi=$(ABI) -Wall -Os -g
 -fomit-frame-pointer \
-ffreestanding -fno-builtin  \
-Wall -Werror=implicit-function-declaration \
-D$(PLATFORM)

ifeq ($(SIMULATOR), 1)
  TARGET_CFLAGS+=-DSIMULATOR
endif

TARGET_CFLAGS+=-I$(PLATFORMDIR) -I$(PLATFORMDIR)/$(PLATFORM) -I../riscv

# If we wish to build with no newlib
#TARGET_LDFLAGS += -march=$(ARCH) -mabi=$(ABI) -nostartfiles   \
-Wl,-m,elf32lriscv,--wrap=malloc,--wrap=sbrk --specs=nosys.specs
-Wl,-T$(LINKDEF) \
-Wl,--gc-sections

TARGET_LDFLAGS += -march=$(ARCH) -mabi=$(ABI) -nostartfiles   \
-Wl,-m,elf32lriscv,--wrap=_srand,--wrap=_rand  --specs=nano.specs
-Wl,-Map=output.map,-T$(LINKDEF) \
-Wl,--gc-sections

all: sim_hello.hex memtest.hex nanotest.hex

%.o : %.S
$(TARGET_CC) $(TARGET_CFLAGS)  -c $<

%.o : %.c
$(TARGET_CC) $(TARGET_CFLAGS) -c $<

%.hex : %.elf
$(TARGET_OBJCOPY) -S -O binary  $< $(basename $@).bin
$(HEXDUMP) -v -e '1/4 "%08x\n"' $(basename $@).bin >$@
$(TARGET_PREFIX)-objdump -S -d $< >$(basename $@).lst
#$(TARGET_PREFIX)-objdump -D $< >$(basename $@).S
$(TARGET_PREFIX)-objdump -s $< >$(basename $@).dmp
$(TARGET_PREFIX)-size  $<

#sbrk.o: libwrap/sbrk.c
# $(TARGET_CC) $(TARGET_CFLAGS) -DSIM -c libwrap/sbrk.c

rand.o: libwrap/rand.c
$(TARGET_CC) $(TARGET_CFLAGS) -DSIM -c libwrap/rand.c

uart.o: uart.c
$(TARGET_CC) $(TARGET_CFLAGS) -DSIM -c uart.c

#sim_hello.o : sim_hello.c
# $(TARGET_CC) $(TARGET_CFLAGS) -DSIM  -c sim_hello.c

sim_hello.elf: start.o uart.o sim_hello.o snprintf.o console.o rand.o
$(TARGET_LD) -o $@ $(TARGET_LDFLAGS) start.o uart.o sim_hello.o snprintf.o
console.o rand.o

#memtest.elf: start.o uart.o memtest.o snprintf.o console.o mempattern.o
sbrk.o
# $(TARGET_LD) -o $@ $(TARGET_LDFLAGS) start.o uart.o memtest.o snprintf.o
console.o mempattern.o sbrk.o

#nanotest.elf: start.o uart.o nanotest.o snprintf.o console.o mempattern.o
sbrk.o
# $(TARGET_LD) -o $@ $(TARGET_LDFLAGS) start.o uart.o nanotest.o snprintf.o
console.o mempattern.o sbrk.o

#jump0.elf : jump0.S
# $(TARGET_LD) -o $@ -march=RV32IM -nostartfiles   -Wl,-T$(BOOTLINK) $<

clean:
rm -f *.o
---------------------------------------------------------------------------------------------.h>
#include <stdlib.h>

//#include <newlib.h>
//#include <nano_malloc.h>
#include <errno.h>
#include <sys/types.h>
#include <string.h>
#include "bonfire.h"
#include "uart.h"
#include "bonfire_gpio.h"
#include "mem_rw.h"
#include "console.h"

extern void* sbrk(incr);


// ========================================
// Main function
// ========================================
int main() {

  setBaudRate(PLATFORM_BAUDRATE);

  caddr_t *ptr = sbrk(0);
  // code never returns from sbrk
  if (ptr == (void *)-1) {
    printk("Failed to allocate memory\r\n");
  }
  else {
    printk("Allocated memory at : %p\r\n", (void *) &ptr);
  }
  return 0;
}
------------------------------------------------------------------------------------
--- Makefile
--------------------------------------------------------------------

.PHONY: all clean

ARCH ?= rv32ia
ABI=ilp32
PLATFORM ?= S100_T35

#TARGET_PREFIX ?= riscv32-unknown-linux-gnu
TARGET_PREFIX ?= riscv32-unknown-elf
TARGET_CC := $(TARGET_PREFIX)-gcc
TARGET_LD := $(TARGET_PREFIX)-gcc
TARGET_SIZE := $(TARGET_PREFIX)-size
TARGET_OBJCOPY := $(TARGET_PREFIX)-objcopy
HEXDUMP ?= hexdump
DATA2MEM = /opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/data2mem

#PROJROOT = ../../..
#TOPLEVEL = ~/riscv/ise/bonfire/papilio_pro_dram_toplevel.bit
PLATFORMDIR=../platform

LINKDEF?=$(PLATFORMDIR)/$(PLATFORM)/firmware.ld

TARGET_CFLAGS +=  -march=$(ARCH) -mabi=$(ABI) -Wall -Os -g
 -fomit-frame-pointer \
-ffreestanding -fno-builtin  \
-Wall -Werror=implicit-function-declaration \
-D$(PLATFORM)

ifeq ($(SIMULATOR), 1)
  TARGET_CFLAGS+=-DSIMULATOR
endif

TARGET_CFLAGS+=-I$(PLATFORMDIR) -I$(PLATFORMDIR)/$(PLATFORM) -I../riscv

# If we wish to build with no newlib
#TARGET_LDFLAGS += -march=$(ARCH) -mabi=$(ABI) -nostartfiles   \
-Wl,-m,elf32lriscv,--wrap=malloc,--wrap=sbrk --specs=nosys.specs
-Wl,-T$(LINKDEF) \
-Wl,--gc-sections

TARGET_LDFLAGS += -march=$(ARCH) -mabi=$(ABI) -nostartfiles   \
-Wl,-m,elf32lriscv,--wrap=_srand,--wrap=_rand  --specs=nano.specs
-Wl,-Map=output.map,-T$(LINKDEF) \
-Wl,--gc-sections

all: sim_hello.hex memtest.hex nanotest.hex

%.o : %.S
$(TARGET_CC) $(TARGET_CFLAGS)  -c $<

%.o : %.c
$(TARGET_CC) $(TARGET_CFLAGS) -c $<

%.hex : %.elf
$(TARGET_OBJCOPY) -S -O binary  $< $(basename $@).bin
$(HEXDUMP) -v -e '1/4 "%08x\n"' $(basename $@).bin >$@
$(TARGET_PREFIX)-objdump -S -d $< >$(basename $@).lst
#$(TARGET_PREFIX)-objdump -D $< >$(basename $@).S
$(TARGET_PREFIX)-objdump -s $< >$(basename $@).dmp
$(TARGET_PREFIX)-size  $<

#sbrk.o: libwrap/sbrk.c
# $(TARGET_CC) $(TARGET_CFLAGS) -DSIM -c libwrap/sbrk.c

rand.o: libwrap/rand.c
$(TARGET_CC) $(TARGET_CFLAGS) -DSIM -c libwrap/rand.c

uart.o: uart.c
$(TARGET_CC) $(TARGET_CFLAGS) -DSIM -c uart.c

#sim_hello.o : sim_hello.c
# $(TARGET_CC) $(TARGET_CFLAGS) -DSIM  -c sim_hello.c

sim_hello.elf: start.o uart.o sim_hello.o snprintf.o console.o rand.o
$(TARGET_LD) -o $@ $(TARGET_LDFLAGS) start.o uart.o sim_hello.o snprintf.o
console.o rand.o

#memtest.elf: start.o uart.o memtest.o snprintf.o console.o mempattern.o
sbrk.o
# $(TARGET_LD) -o $@ $(TARGET_LDFLAGS) start.o uart.o memtest.o snprintf.o
console.o mempattern.o sbrk.o

#nanotest.elf: start.o uart.o nanotest.o snprintf.o console.o mempattern.o
sbrk.o
# $(TARGET_LD) -o $@ $(TARGET_LDFLAGS) start.o uart.o nanotest.o snprintf.o
console.o mempattern.o sbrk.o

#jump0.elf : jump0.S
# $(TARGET_LD) -o $@ -march=RV32IM -nostartfiles   -Wl,-T$(BOOTLINK) $<

clean:
rm -f *.o
---------------------------------------------------------------------------------------------

-- 
Damien Towning

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Problem with SBRK not returning from call on bare metal risk
  2023-03-06  7:36 Problem with SBRK not returning from call on bare metal risk Damien Towning
@ 2023-03-06 13:24 ` Dave Nadler
  2023-03-08  1:23   ` Damien Towning
  0 siblings, 1 reply; 3+ messages in thread
From: Dave Nadler @ 2023-03-06 13:24 UTC (permalink / raw)
  To: Damien Towning, newlib

[-- Attachment #1: Type: text/plain, Size: 19225 bytes --]

Hi Damien - You need to verify the sbrk you're using actually provides 
the correct addresses.
In cases I'm familiar with, sbrk is provided by the chip-specific 
toolchain and not newlib.
Providing your own sbrk is not all bad...
Also, you need to be sure how newlib was built in the toolchain you are 
using;
you didn't show us the newlib configuration?
This might provide some help:
https://nadler.com/embedded/newlibAndFreeRTOS.html
Hope this helps!
Best Regards, Dave

On 3/6/2023 2:36 AM, Damien Towning wrote:
> So a bit of a background. I have the bonfire Risc-V 32 core running on a
> T-35 FPGA board. The metal part of this is working great. The processor
> runs. I've got it to turn around the segment display on the board. I've
> also implemented my own _sbrk and got that to work I think consistently
> with malloc. Now in my Risc-v 32 toolchain I have the newlib and I have
> brought that in and with my own wrapped _sbrk I am able to use the system
> defined malloc. But I am not entirely happy with this because I don't want
> to be wrapping every function I encounter. So for example today I found
> myself wrapping srand and rand. So I am pretty sure the reason my
> nano_newlib isn't working is something to do with either not having the
> correct variable names in my firmware.ld or something to do with disabling
> the re-entrant behaviour of newlib. I've included in this email my
> firmware.ld,platform.h,c code example. What happens is I call the _sbrk(0)
> and ( in the simulator I am also running this in ) I never see a bad opcode
> generated. It just seems like the processor goes away and never comes back.
> Does anybody have any suggestions as to what might cause this sort of
> problem ? I'd like to use the sbrk and other funcitons within the newlib
> itself if possible without rolling my own.
>
> ------------- firmware.ld
> MEMORY
> {
>
>     RAM (rwx)    : ORIGIN = 0x0C000000, LENGTH = 512K
> }
>
> ENTRY(_start)
>
> SECTIONS
> {
>      _rombase = 0x0C000000;
>
>    . = 0x0;
>
>    .text : {
>      *(.init)
>      *(.text.*)
>
>    } > RAM
>
>    .data  ALIGN(4) : {
>      *(.rodata.*)
>      *(.rodata)
>      *(.eh_frame)
>      *(.sdata)
>      *(.data)
>      *(.sbss)
>      *(.sbss.*)
>      *(.gnu.linkonce.sb.*)
>      *(.bss)
>      *(.bss.*)
>      *(.gnu.linkonce.b.*)
>      *(COMMON)
>
>      end = .; _end = .; __end = .;
>
>   } > RAM
>
>   _heap_end = _end;
>   _heap_prev_end = _end;
>
> }
>
> PROVIDE(__heap_end = _end);
> PROVIDE(__prev_heap_end = _end);
> PROVIDE(__heap_start = _end+128K);
>
> PROVIDE(__stack_top   = ORIGIN(RAM) + LENGTH(RAM));
> PROVIDE(__stack_start = ORIGIN(RAM) + LENGTH(RAM));
>
> PROVIDE(__heap_size = 128K );
> PROVIDE(__stack_size = 128K );
>
>
>
> /*
> 0x0C000000 +-------------------+
>             |                   |
>             |     ROM / Flash   |
> 0x0C080000 +-------------------+
>             |                   |
>             |      .data        |
>             |-------------------|
>             |     .bss / .sbss  |
>             |-------------------|
>             |        _end       |
>             |-------------------|
>             |        Heap       |
>             |-------------------|
>             |        Stack      |
> 0xXXXXXXXX +-------------------+
> */
> --------------------------------------------------------------------------------------
>
> ---------platform.h
> ----------------------------------------------------------------
> #ifndef BASIC_PLATFORM_H
> #define BASIC_PLATFORM_H
>
> // New Defintions for new bonfire-soc-io core
> #define IO_BASE 0x04000000
> #define SOC_IO_OFFSET 0x10000 // Offset from one I/O Device to the next
> (64K range)
>
> #define UART0_BASE IO_BASE
> #define SPIFLASH_BASE (IO_BASE+SOC_IO_OFFSET)
> #define GPIO_BASE (IO_BASE+3*SOC_IO_OFFSET)
> #define UART1_BASE (IO_BASE+2*SOC_IO_OFFSET)
>
> #define UART_BASE UART0_BASE // Backwards compatiblity
>
> #define MTIME_BASE 0x0FFFF0000
>
> #define DRAM_BASE 0x0
> #define DRAM_SIZE 0
> #define DRAM_TOP  (DRAM_BASE+DRAM_SIZE-1)
> #define SRAM_BASE 0x0C000000
> #define SRAM_SIZE 524288
> #define SRAM_TOP  (SRAM_BASE+SRAM_SIZE-1)
>
> //#define SYSCLK 12000000
> //#define SYSCLK   33333333
> //#define   SYSCLK   24997500
> //#define   SYSCLK   88786000
> #define     EXT_SYSCLK   89015000
>
> #define SYSCLK       24997500
>
> //#define EXT_SYSCLK   92370000  /* For reasons not clear to me when any
> change is made to the interface   */
>    /* configuration in Efinity and a new synthesis is done a clock time will
> */
>    /* be calculated so you must build your efinity project. Take that new
>   */
>    /* time value. Update it here. Rebuild your hex file. Then rebuild your
> */
>    /* efinity project AGAIN
>   */
>
>
> #define TIME_UNIT 1e+9;  // A billion
>
> #ifndef SIMULATOR
> #define SCALAR 1      // Relative Scalar division for efinity build
> #define BAUD_SCALAR 1 // Relative Scalar division for efinity build
> #else
> #define SCALAR 10000    // Relative Scalar division for simulator. Use for
> any of your own timing since
> #define BAUD_SCALAR 20 // simulator runs slower than real hardware
> #endif
>
> #define CLK_PERIOD (TIME_UNIT / EXT_SYSCLK)  // in ns...
>
> //#define DCACHE_SIZE 0 // (2048*4)  // DCache Size in Bytes
>
> // Parameters for SPI Flash
>
> #define FLASHSIZE (8192*1024)
> #define MAX_FLASH_IMAGESIZE (2024*1024) // Max 2MB of flash used for boot
> image
> #define FLASH_IMAGEBASE (1024*3072)  // Boot Image starts at 3MB in Flash
>
> #define PLATFORM_BAUDRATE (115200*BAUD_SCALAR)
>
> #define NO_RECURSION
> #define NO_SYSCALL
> #define NO_FLASH
> #define NO_XMODEM
> #define NO_DRAMTEST
>
> //#define GPIO_TEST
>
> #endif
> ---------------------------------------------------------------------------------------------
>
> ---- sim_hello.c
> ------------------------------------------------------------------------
> // ==============================================
> // T35 S100 Module Test Code
> // Damien Towning - 2022
> // ==============================================
> #include <stdioSo a bit of a background. I have the bonfire Risc-V 32 core
> running on a T-35 FPGA board. The metal part of this is working great. The
> processor runs. I've got it to turn around the segment display on the
> board. I've also implemented my own _sbrk and got that to work I think
> consistently with malloc. Now in my Risc-v 32 toolchain I have the newlib
> and I have brought that in and with my own wrapped _sbrk I am able to use
> the system defined malloc. But I am not entirely happy with this because I
> don't want to be wrapping every function I encounter. So for example today
> I found myself wrapping srand and rand. So I am pretty sure the reason my
> nano_newlib isn't working is something to do with either not having the
> correct variable names in my firmware.ld or something to do with disabling
> the re-entrant behaviour of newlib. I've included in this email my
> firmware.ld,platform.h,c code example. What happens is I call the _sbrk(0)
> and ( in the simulator I am also running this in ) I never see a bad opcode
> generated. It just seems like the processor goes away and never comes back.
> Does anybody have any suggestions as to what might cause this sort of
> problem ? I'd like to use the sbrk and other funcitons within the newlib
> itself if possible without rolling my own.
>
> ------------- firmware.ld
> MEMORY
> {
>
>     RAM (rwx)    : ORIGIN = 0x0C000000, LENGTH = 512K
> }
>
> ENTRY(_start)
>
> SECTIONS
> {
>      _rombase = 0x0C000000;
>
>    . = 0x0;
>
>    .text : {
>      *(.init)
>      *(.text.*)
>
>    } > RAM
>
>    .data  ALIGN(4) : {
>      *(.rodata.*)
>      *(.rodata)
>      *(.eh_frame)
>      *(.sdata)
>      *(.data)
>      *(.sbss)
>      *(.sbss.*)
>      *(.gnu.linkonce.sb.*)
>      *(.bss)
>      *(.bss.*)
>      *(.gnu.linkonce.b.*)
>      *(COMMON)
>
>      end = .; _end = .; __end = .;
>
>   } > RAM
>
>   _heap_end = _end;
>   _heap_prev_end = _end;
>
> }
>
> PROVIDE(__heap_end = _end);
> PROVIDE(__prev_heap_end = _end);
> PROVIDE(__heap_start = _end+128K);
>
> PROVIDE(__stack_top   = ORIGIN(RAM) + LENGTH(RAM));
> PROVIDE(__stack_start = ORIGIN(RAM) + LENGTH(RAM));
>
> PROVIDE(__heap_size = 128K );
> PROVIDE(__stack_size = 128K );
>
>
>
> /*
> 0x0C000000 +-------------------+
>             |                   |
>             |     ROM / Flash   |
> 0x0C080000 +-------------------+
>             |                   |
>             |      .data        |
>             |-------------------|
>             |     .bss / .sbss  |
>             |-------------------|
>             |        _end       |
>             |-------------------|
>             |        Heap       |
>             |-------------------|
>             |        Stack      |
> 0xXXXXXXXX +-------------------+
> */
> --------------------------------------------------------------------------------------
>
> ---------platform.h
> ----------------------------------------------------------------
> #ifndef BASIC_PLATFORM_H
> #define BASIC_PLATFORM_H
>
> // New Defintions for new bonfire-soc-io core
> #define IO_BASE 0x04000000
> #define SOC_IO_OFFSET 0x10000 // Offset from one I/O Device to the next
> (64K range)
>
> #define UART0_BASE IO_BASE
> #define SPIFLASH_BASE (IO_BASE+SOC_IO_OFFSET)
> #define GPIO_BASE (IO_BASE+3*SOC_IO_OFFSET)
> #define UART1_BASE (IO_BASE+2*SOC_IO_OFFSET)
>
> #define UART_BASE UART0_BASE // Backwards compatiblity
>
> #define MTIME_BASE 0x0FFFF0000
>
> #define DRAM_BASE 0x0
> #define DRAM_SIZE 0
> #define DRAM_TOP  (DRAM_BASE+DRAM_SIZE-1)
> #define SRAM_BASE 0x0C000000
> #define SRAM_SIZE 524288
> #define SRAM_TOP  (SRAM_BASE+SRAM_SIZE-1)
>
> //#define SYSCLK 12000000
> //#define SYSCLK   33333333
> //#define   SYSCLK   24997500
> //#define   SYSCLK   88786000
> #define     EXT_SYSCLK   89015000
>
> #define SYSCLK       24997500
>
> //#define EXT_SYSCLK   92370000  /* For reasons not clear to me when any
> change is made to the interface   */
>    /* configuration in Efinity and a new synthesis is done a clock time will
> */
>    /* be calculated so you must build your efinity project. Take that new
>   */
>    /* time value. Update it here. Rebuild your hex file. Then rebuild your
> */
>    /* efinity project AGAIN
>   */
>
>
> #define TIME_UNIT 1e+9;  // A billion
>
> #ifndef SIMULATOR
> #define SCALAR 1      // Relative Scalar division for efinity build
> #define BAUD_SCALAR 1 // Relative Scalar division for efinity build
> #else
> #define SCALAR 10000    // Relative Scalar division for simulator. Use for
> any of your own timing since
> #define BAUD_SCALAR 20 // simulator runs slower than real hardware
> #endif
>
> #define CLK_PERIOD (TIME_UNIT / EXT_SYSCLK)  // in ns...
>
> //#define DCACHE_SIZE 0 // (2048*4)  // DCache Size in Bytes
>
> // Parameters for SPI Flash
>
> #define FLASHSIZE (8192*1024)
> #define MAX_FLASH_IMAGESIZE (2024*1024) // Max 2MB of flash used for boot
> image
> #define FLASH_IMAGEBASE (1024*3072)  // Boot Image starts at 3MB in Flash
>
> #define PLATFORM_BAUDRATE (115200*BAUD_SCALAR)
>
> #define NO_RECURSION
> #define NO_SYSCALL
> #define NO_FLASH
> #define NO_XMODEM
> #define NO_DRAMTEST
>
> //#define GPIO_TEST
>
> #endif
> ---------------------------------------------------------------------------------------------
>
> ---- sim_hello.c
> ------------------------------------------------------------------------
> // ==============================================
> // T35 S100 Module Test Code
> // Damien Towning - 2022
> // ==============================================
> #include <stdio.h>
> #include <stdlib.h>
>
> //#include <newlib.h>
> //#include <nano_malloc.h>
> #include <errno.h>
> #include <sys/types.h>
> #include <string.h>
> #include "bonfire.h"
> #include "uart.h"
> #include "bonfire_gpio.h"
> #include "mem_rw.h"
> #include "console.h"
>
> extern void* sbrk(incr);
>
>
> // ========================================
> // Main function
> // ========================================
> int main() {
>
>    setBaudRate(PLATFORM_BAUDRATE);
>
>    caddr_t *ptr = sbrk(0);
>    // code never returns from sbrk
>    if (ptr == (void *)-1) {
>      printk("Failed to allocate memory\r\n");
>    }
>    else {
>      printk("Allocated memory at : %p\r\n", (void *) &ptr);
>    }
>    return 0;
> }
> ------------------------------------------------------------------------------------
> --- Makefile
> --------------------------------------------------------------------
>
> .PHONY: all clean
>
> ARCH ?= rv32ia
> ABI=ilp32
> PLATFORM ?= S100_T35
>
> #TARGET_PREFIX ?= riscv32-unknown-linux-gnu
> TARGET_PREFIX ?= riscv32-unknown-elf
> TARGET_CC := $(TARGET_PREFIX)-gcc
> TARGET_LD := $(TARGET_PREFIX)-gcc
> TARGET_SIZE := $(TARGET_PREFIX)-size
> TARGET_OBJCOPY := $(TARGET_PREFIX)-objcopy
> HEXDUMP ?= hexdump
> DATA2MEM = /opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/data2mem
>
> #PROJROOT = ../../..
> #TOPLEVEL = ~/riscv/ise/bonfire/papilio_pro_dram_toplevel.bit
> PLATFORMDIR=../platform
>
> LINKDEF?=$(PLATFORMDIR)/$(PLATFORM)/firmware.ld
>
> TARGET_CFLAGS +=  -march=$(ARCH) -mabi=$(ABI) -Wall -Os -g
>   -fomit-frame-pointer \
> -ffreestanding -fno-builtin  \
> -Wall -Werror=implicit-function-declaration \
> -D$(PLATFORM)
>
> ifeq ($(SIMULATOR), 1)
>    TARGET_CFLAGS+=-DSIMULATOR
> endif
>
> TARGET_CFLAGS+=-I$(PLATFORMDIR) -I$(PLATFORMDIR)/$(PLATFORM) -I../riscv
>
> # If we wish to build with no newlib
> #TARGET_LDFLAGS += -march=$(ARCH) -mabi=$(ABI) -nostartfiles   \
> -Wl,-m,elf32lriscv,--wrap=malloc,--wrap=sbrk --specs=nosys.specs
> -Wl,-T$(LINKDEF) \
> -Wl,--gc-sections
>
> TARGET_LDFLAGS += -march=$(ARCH) -mabi=$(ABI) -nostartfiles   \
> -Wl,-m,elf32lriscv,--wrap=_srand,--wrap=_rand  --specs=nano.specs
> -Wl,-Map=output.map,-T$(LINKDEF) \
> -Wl,--gc-sections
>
> all: sim_hello.hex memtest.hex nanotest.hex
>
> %.o : %.S
> $(TARGET_CC) $(TARGET_CFLAGS)  -c $<
>
> %.o : %.c
> $(TARGET_CC) $(TARGET_CFLAGS) -c $<
>
> %.hex : %.elf
> $(TARGET_OBJCOPY) -S -O binary  $< $(basename $@).bin
> $(HEXDUMP) -v -e '1/4 "%08x\n"' $(basename $@).bin >$@
> $(TARGET_PREFIX)-objdump -S -d $< >$(basename $@).lst
> #$(TARGET_PREFIX)-objdump -D $< >$(basename $@).S
> $(TARGET_PREFIX)-objdump -s $< >$(basename $@).dmp
> $(TARGET_PREFIX)-size  $<
>
> #sbrk.o: libwrap/sbrk.c
> # $(TARGET_CC) $(TARGET_CFLAGS) -DSIM -c libwrap/sbrk.c
>
> rand.o: libwrap/rand.c
> $(TARGET_CC) $(TARGET_CFLAGS) -DSIM -c libwrap/rand.c
>
> uart.o: uart.c
> $(TARGET_CC) $(TARGET_CFLAGS) -DSIM -c uart.c
>
> #sim_hello.o : sim_hello.c
> # $(TARGET_CC) $(TARGET_CFLAGS) -DSIM  -c sim_hello.c
>
> sim_hello.elf: start.o uart.o sim_hello.o snprintf.o console.o rand.o
> $(TARGET_LD) -o $@ $(TARGET_LDFLAGS) start.o uart.o sim_hello.o snprintf.o
> console.o rand.o
>
> #memtest.elf: start.o uart.o memtest.o snprintf.o console.o mempattern.o
> sbrk.o
> # $(TARGET_LD) -o $@ $(TARGET_LDFLAGS) start.o uart.o memtest.o snprintf.o
> console.o mempattern.o sbrk.o
>
> #nanotest.elf: start.o uart.o nanotest.o snprintf.o console.o mempattern.o
> sbrk.o
> # $(TARGET_LD) -o $@ $(TARGET_LDFLAGS) start.o uart.o nanotest.o snprintf.o
> console.o mempattern.o sbrk.o
>
> #jump0.elf : jump0.S
> # $(TARGET_LD) -o $@ -march=RV32IM -nostartfiles   -Wl,-T$(BOOTLINK) $<
>
> clean:
> rm -f *.o
> ---------------------------------------------------------------------------------------------.h>
> #include <stdlib.h>
>
> //#include <newlib.h>
> //#include <nano_malloc.h>
> #include <errno.h>
> #include <sys/types.h>
> #include <string.h>
> #include "bonfire.h"
> #include "uart.h"
> #include "bonfire_gpio.h"
> #include "mem_rw.h"
> #include "console.h"
>
> extern void* sbrk(incr);
>
>
> // ========================================
> // Main function
> // ========================================
> int main() {
>
>    setBaudRate(PLATFORM_BAUDRATE);
>
>    caddr_t *ptr = sbrk(0);
>    // code never returns from sbrk
>    if (ptr == (void *)-1) {
>      printk("Failed to allocate memory\r\n");
>    }
>    else {
>      printk("Allocated memory at : %p\r\n", (void *) &ptr);
>    }
>    return 0;
> }
> ------------------------------------------------------------------------------------
> --- Makefile
> --------------------------------------------------------------------
>
> .PHONY: all clean
>
> ARCH ?= rv32ia
> ABI=ilp32
> PLATFORM ?= S100_T35
>
> #TARGET_PREFIX ?= riscv32-unknown-linux-gnu
> TARGET_PREFIX ?= riscv32-unknown-elf
> TARGET_CC := $(TARGET_PREFIX)-gcc
> TARGET_LD := $(TARGET_PREFIX)-gcc
> TARGET_SIZE := $(TARGET_PREFIX)-size
> TARGET_OBJCOPY := $(TARGET_PREFIX)-objcopy
> HEXDUMP ?= hexdump
> DATA2MEM = /opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/data2mem
>
> #PROJROOT = ../../..
> #TOPLEVEL = ~/riscv/ise/bonfire/papilio_pro_dram_toplevel.bit
> PLATFORMDIR=../platform
>
> LINKDEF?=$(PLATFORMDIR)/$(PLATFORM)/firmware.ld
>
> TARGET_CFLAGS +=  -march=$(ARCH) -mabi=$(ABI) -Wall -Os -g
>   -fomit-frame-pointer \
> -ffreestanding -fno-builtin  \
> -Wall -Werror=implicit-function-declaration \
> -D$(PLATFORM)
>
> ifeq ($(SIMULATOR), 1)
>    TARGET_CFLAGS+=-DSIMULATOR
> endif
>
> TARGET_CFLAGS+=-I$(PLATFORMDIR) -I$(PLATFORMDIR)/$(PLATFORM) -I../riscv
>
> # If we wish to build with no newlib
> #TARGET_LDFLAGS += -march=$(ARCH) -mabi=$(ABI) -nostartfiles   \
> -Wl,-m,elf32lriscv,--wrap=malloc,--wrap=sbrk --specs=nosys.specs
> -Wl,-T$(LINKDEF) \
> -Wl,--gc-sections
>
> TARGET_LDFLAGS += -march=$(ARCH) -mabi=$(ABI) -nostartfiles   \
> -Wl,-m,elf32lriscv,--wrap=_srand,--wrap=_rand  --specs=nano.specs
> -Wl,-Map=output.map,-T$(LINKDEF) \
> -Wl,--gc-sections
>
> all: sim_hello.hex memtest.hex nanotest.hex
>
> %.o : %.S
> $(TARGET_CC) $(TARGET_CFLAGS)  -c $<
>
> %.o : %.c
> $(TARGET_CC) $(TARGET_CFLAGS) -c $<
>
> %.hex : %.elf
> $(TARGET_OBJCOPY) -S -O binary  $< $(basename $@).bin
> $(HEXDUMP) -v -e '1/4 "%08x\n"' $(basename $@).bin >$@
> $(TARGET_PREFIX)-objdump -S -d $< >$(basename $@).lst
> #$(TARGET_PREFIX)-objdump -D $< >$(basename $@).S
> $(TARGET_PREFIX)-objdump -s $< >$(basename $@).dmp
> $(TARGET_PREFIX)-size  $<
>
> #sbrk.o: libwrap/sbrk.c
> # $(TARGET_CC) $(TARGET_CFLAGS) -DSIM -c libwrap/sbrk.c
>
> rand.o: libwrap/rand.c
> $(TARGET_CC) $(TARGET_CFLAGS) -DSIM -c libwrap/rand.c
>
> uart.o: uart.c
> $(TARGET_CC) $(TARGET_CFLAGS) -DSIM -c uart.c
>
> #sim_hello.o : sim_hello.c
> # $(TARGET_CC) $(TARGET_CFLAGS) -DSIM  -c sim_hello.c
>
> sim_hello.elf: start.o uart.o sim_hello.o snprintf.o console.o rand.o
> $(TARGET_LD) -o $@ $(TARGET_LDFLAGS) start.o uart.o sim_hello.o snprintf.o
> console.o rand.o
>
> #memtest.elf: start.o uart.o memtest.o snprintf.o console.o mempattern.o
> sbrk.o
> # $(TARGET_LD) -o $@ $(TARGET_LDFLAGS) start.o uart.o memtest.o snprintf.o
> console.o mempattern.o sbrk.o
>
> #nanotest.elf: start.o uart.o nanotest.o snprintf.o console.o mempattern.o
> sbrk.o
> # $(TARGET_LD) -o $@ $(TARGET_LDFLAGS) start.o uart.o nanotest.o snprintf.o
> console.o mempattern.o sbrk.o
>
> #jump0.elf : jump0.S
> # $(TARGET_LD) -o $@ -march=RV32IM -nostartfiles   -Wl,-T$(BOOTLINK) $<
>
> clean:
> rm -f *.o
> ---------------------------------------------------------------------------------------------


-- 
Dave Nadler, USA East Coast voice (978) 263-0097,drn@nadler.com, Skype
  Dave.Nadler1

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Problem with SBRK not returning from call on bare metal risk
  2023-03-06 13:24 ` Dave Nadler
@ 2023-03-08  1:23   ` Damien Towning
  0 siblings, 0 replies; 3+ messages in thread
From: Damien Towning @ 2023-03-08  1:23 UTC (permalink / raw)
  To: Dave Nadler; +Cc: newlib

[-- Attachment #1: Type: text/plain, Size: 20689 bytes --]

Thank you for the helpful response and the link. Having understood this
helped a lot. I went back to using my own _sbrk and the newlib malloc seems
to work okay with it. I think this is mostly about the variable names for
heap and stack matching what the newlib expects _and_ avoiding any of the
re-entrant stuff.  Am able to load up and free complex memory blocks out of
the heap.

Now what prompted my question to start with is that I am concerned about
implementing functions I do not ( or should not ) implement myself. So for
example I have had to implement the srand and rand functions myself because
those appear to be re-entrant in the newlib.  I've now moved on and got
another question to ask now about the math library which I think I will put
in a separate post :)



On Tue, Mar 7, 2023 at 12:24 AM Dave Nadler <drn@nadler.com> wrote:

> Hi Damien - You need to verify the sbrk you're using actually provides the
> correct addresses.
> In cases I'm familiar with, sbrk is provided by the chip-specific
> toolchain and not newlib.
> Providing your own sbrk is not all bad...
> Also, you need to be sure how newlib was built in the toolchain you are
> using;
> you didn't show us the newlib configuration?
> This might provide some help:
> https://nadler.com/embedded/newlibAndFreeRTOS.html
> Hope this helps!
> Best Regards, Dave
>
> On 3/6/2023 2:36 AM, Damien Towning wrote:
>
> So a bit of a background. I have the bonfire Risc-V 32 core running on a
> T-35 FPGA board. The metal part of this is working great. The processor
> runs. I've got it to turn around the segment display on the board. I've
> also implemented my own _sbrk and got that to work I think consistently
> with malloc. Now in my Risc-v 32 toolchain I have the newlib and I have
> brought that in and with my own wrapped _sbrk I am able to use the system
> defined malloc. But I am not entirely happy with this because I don't want
> to be wrapping every function I encounter. So for example today I found
> myself wrapping srand and rand. So I am pretty sure the reason my
> nano_newlib isn't working is something to do with either not having the
> correct variable names in my firmware.ld or something to do with disabling
> the re-entrant behaviour of newlib. I've included in this email my
> firmware.ld,platform.h,c code example. What happens is I call the _sbrk(0)
> and ( in the simulator I am also running this in ) I never see a bad opcode
> generated. It just seems like the processor goes away and never comes back.
> Does anybody have any suggestions as to what might cause this sort of
> problem ? I'd like to use the sbrk and other funcitons within the newlib
> itself if possible without rolling my own.
>
> ------------- firmware.ld
> MEMORY
> {
>
>    RAM (rwx)    : ORIGIN = 0x0C000000, LENGTH = 512K
> }
>
> ENTRY(_start)
>
> SECTIONS
> {
>     _rombase = 0x0C000000;
>
>   . = 0x0;
>
>   .text : {
>     *(.init)
>     *(.text.*)
>
>   } > RAM
>
>   .data  ALIGN(4) : {
>     *(.rodata.*)
>     *(.rodata)
>     *(.eh_frame)
>     *(.sdata)
>     *(.data)
>     *(.sbss)
>     *(.sbss.*)
>     *(.gnu.linkonce.sb.*)
>     *(.bss)
>     *(.bss.*)
>     *(.gnu.linkonce.b.*)
>     *(COMMON)
>
>     end = .; _end = .; __end = .;
>
>  } > RAM
>
>  _heap_end = _end;
>  _heap_prev_end = _end;
>
> }
>
> PROVIDE(__heap_end = _end);
> PROVIDE(__prev_heap_end = _end);
> PROVIDE(__heap_start = _end+128K);
>
> PROVIDE(__stack_top   = ORIGIN(RAM) + LENGTH(RAM));
> PROVIDE(__stack_start = ORIGIN(RAM) + LENGTH(RAM));
>
> PROVIDE(__heap_size = 128K );
> PROVIDE(__stack_size = 128K );
>
>
>
> /*
> 0x0C000000 +-------------------+
>            |                   |
>            |     ROM / Flash   |
> 0x0C080000 +-------------------+
>            |                   |
>            |      .data        |
>            |-------------------|
>            |     .bss / .sbss  |
>            |-------------------|
>            |        _end       |
>            |-------------------|
>            |        Heap       |
>            |-------------------|
>            |        Stack      |
> 0xXXXXXXXX +-------------------+
> */
> --------------------------------------------------------------------------------------
>
> ---------platform.h
> ----------------------------------------------------------------
> #ifndef BASIC_PLATFORM_H
> #define BASIC_PLATFORM_H
>
> // New Defintions for new bonfire-soc-io core
> #define IO_BASE 0x04000000
> #define SOC_IO_OFFSET 0x10000 // Offset from one I/O Device to the next
> (64K range)
>
> #define UART0_BASE IO_BASE
> #define SPIFLASH_BASE (IO_BASE+SOC_IO_OFFSET)
> #define GPIO_BASE (IO_BASE+3*SOC_IO_OFFSET)
> #define UART1_BASE (IO_BASE+2*SOC_IO_OFFSET)
>
> #define UART_BASE UART0_BASE // Backwards compatiblity
>
> #define MTIME_BASE 0x0FFFF0000
>
> #define DRAM_BASE 0x0
> #define DRAM_SIZE 0
> #define DRAM_TOP  (DRAM_BASE+DRAM_SIZE-1)
> #define SRAM_BASE 0x0C000000
> #define SRAM_SIZE 524288
> #define SRAM_TOP  (SRAM_BASE+SRAM_SIZE-1)
>
> //#define SYSCLK 12000000
> //#define SYSCLK   33333333
> //#define   SYSCLK   24997500
> //#define   SYSCLK   88786000
> #define     EXT_SYSCLK   89015000
>
> #define SYSCLK       24997500
>
> //#define EXT_SYSCLK   92370000  /* For reasons not clear to me when any
> change is made to the interface   */
>   /* configuration in Efinity and a new synthesis is done a clock time will
> */
>   /* be calculated so you must build your efinity project. Take that new
>  */
>   /* time value. Update it here. Rebuild your hex file. Then rebuild your
> */
>   /* efinity project AGAIN
>  */
>
>
> #define TIME_UNIT 1e+9;  // A billion
>
> #ifndef SIMULATOR
> #define SCALAR 1      // Relative Scalar division for efinity build
> #define BAUD_SCALAR 1 // Relative Scalar division for efinity build
> #else
> #define SCALAR 10000    // Relative Scalar division for simulator. Use for
> any of your own timing since
> #define BAUD_SCALAR 20 // simulator runs slower than real hardware
> #endif
>
> #define CLK_PERIOD (TIME_UNIT / EXT_SYSCLK)  // in ns...
>
> //#define DCACHE_SIZE 0 // (2048*4)  // DCache Size in Bytes
>
> // Parameters for SPI Flash
>
> #define FLASHSIZE (8192*1024)
> #define MAX_FLASH_IMAGESIZE (2024*1024) // Max 2MB of flash used for boot
> image
> #define FLASH_IMAGEBASE (1024*3072)  // Boot Image starts at 3MB in Flash
>
> #define PLATFORM_BAUDRATE (115200*BAUD_SCALAR)
>
> #define NO_RECURSION
> #define NO_SYSCALL
> #define NO_FLASH
> #define NO_XMODEM
> #define NO_DRAMTEST
>
> //#define GPIO_TEST
>
> #endif
> ---------------------------------------------------------------------------------------------
>
> ---- sim_hello.c
> ------------------------------------------------------------------------
> // ==============================================
> // T35 S100 Module Test Code
> // Damien Towning - 2022
> // ==============================================
> #include <stdioSo a bit of a background. I have the bonfire Risc-V 32 core
> running on a T-35 FPGA board. The metal part of this is working great. The
> processor runs. I've got it to turn around the segment display on the
> board. I've also implemented my own _sbrk and got that to work I think
> consistently with malloc. Now in my Risc-v 32 toolchain I have the newlib
> and I have brought that in and with my own wrapped _sbrk I am able to use
> the system defined malloc. But I am not entirely happy with this because I
> don't want to be wrapping every function I encounter. So for example today
> I found myself wrapping srand and rand. So I am pretty sure the reason my
> nano_newlib isn't working is something to do with either not having the
> correct variable names in my firmware.ld or something to do with disabling
> the re-entrant behaviour of newlib. I've included in this email my
> firmware.ld,platform.h,c code example. What happens is I call the _sbrk(0)
> and ( in the simulator I am also running this in ) I never see a bad opcode
> generated. It just seems like the processor goes away and never comes back.
> Does anybody have any suggestions as to what might cause this sort of
> problem ? I'd like to use the sbrk and other funcitons within the newlib
> itself if possible without rolling my own.
>
> ------------- firmware.ld
> MEMORY
> {
>
>    RAM (rwx)    : ORIGIN = 0x0C000000, LENGTH = 512K
> }
>
> ENTRY(_start)
>
> SECTIONS
> {
>     _rombase = 0x0C000000;
>
>   . = 0x0;
>
>   .text : {
>     *(.init)
>     *(.text.*)
>
>   } > RAM
>
>   .data  ALIGN(4) : {
>     *(.rodata.*)
>     *(.rodata)
>     *(.eh_frame)
>     *(.sdata)
>     *(.data)
>     *(.sbss)
>     *(.sbss.*)
>     *(.gnu.linkonce.sb.*)
>     *(.bss)
>     *(.bss.*)
>     *(.gnu.linkonce.b.*)
>     *(COMMON)
>
>     end = .; _end = .; __end = .;
>
>  } > RAM
>
>  _heap_end = _end;
>  _heap_prev_end = _end;
>
> }
>
> PROVIDE(__heap_end = _end);
> PROVIDE(__prev_heap_end = _end);
> PROVIDE(__heap_start = _end+128K);
>
> PROVIDE(__stack_top   = ORIGIN(RAM) + LENGTH(RAM));
> PROVIDE(__stack_start = ORIGIN(RAM) + LENGTH(RAM));
>
> PROVIDE(__heap_size = 128K );
> PROVIDE(__stack_size = 128K );
>
>
>
> /*
> 0x0C000000 +-------------------+
>            |                   |
>            |     ROM / Flash   |
> 0x0C080000 +-------------------+
>            |                   |
>            |      .data        |
>            |-------------------|
>            |     .bss / .sbss  |
>            |-------------------|
>            |        _end       |
>            |-------------------|
>            |        Heap       |
>            |-------------------|
>            |        Stack      |
> 0xXXXXXXXX +-------------------+
> */
> --------------------------------------------------------------------------------------
>
> ---------platform.h
> ----------------------------------------------------------------
> #ifndef BASIC_PLATFORM_H
> #define BASIC_PLATFORM_H
>
> // New Defintions for new bonfire-soc-io core
> #define IO_BASE 0x04000000
> #define SOC_IO_OFFSET 0x10000 // Offset from one I/O Device to the next
> (64K range)
>
> #define UART0_BASE IO_BASE
> #define SPIFLASH_BASE (IO_BASE+SOC_IO_OFFSET)
> #define GPIO_BASE (IO_BASE+3*SOC_IO_OFFSET)
> #define UART1_BASE (IO_BASE+2*SOC_IO_OFFSET)
>
> #define UART_BASE UART0_BASE // Backwards compatiblity
>
> #define MTIME_BASE 0x0FFFF0000
>
> #define DRAM_BASE 0x0
> #define DRAM_SIZE 0
> #define DRAM_TOP  (DRAM_BASE+DRAM_SIZE-1)
> #define SRAM_BASE 0x0C000000
> #define SRAM_SIZE 524288
> #define SRAM_TOP  (SRAM_BASE+SRAM_SIZE-1)
>
> //#define SYSCLK 12000000
> //#define SYSCLK   33333333
> //#define   SYSCLK   24997500
> //#define   SYSCLK   88786000
> #define     EXT_SYSCLK   89015000
>
> #define SYSCLK       24997500
>
> //#define EXT_SYSCLK   92370000  /* For reasons not clear to me when any
> change is made to the interface   */
>   /* configuration in Efinity and a new synthesis is done a clock time will
> */
>   /* be calculated so you must build your efinity project. Take that new
>  */
>   /* time value. Update it here. Rebuild your hex file. Then rebuild your
> */
>   /* efinity project AGAIN
>  */
>
>
> #define TIME_UNIT 1e+9;  // A billion
>
> #ifndef SIMULATOR
> #define SCALAR 1      // Relative Scalar division for efinity build
> #define BAUD_SCALAR 1 // Relative Scalar division for efinity build
> #else
> #define SCALAR 10000    // Relative Scalar division for simulator. Use for
> any of your own timing since
> #define BAUD_SCALAR 20 // simulator runs slower than real hardware
> #endif
>
> #define CLK_PERIOD (TIME_UNIT / EXT_SYSCLK)  // in ns...
>
> //#define DCACHE_SIZE 0 // (2048*4)  // DCache Size in Bytes
>
> // Parameters for SPI Flash
>
> #define FLASHSIZE (8192*1024)
> #define MAX_FLASH_IMAGESIZE (2024*1024) // Max 2MB of flash used for boot
> image
> #define FLASH_IMAGEBASE (1024*3072)  // Boot Image starts at 3MB in Flash
>
> #define PLATFORM_BAUDRATE (115200*BAUD_SCALAR)
>
> #define NO_RECURSION
> #define NO_SYSCALL
> #define NO_FLASH
> #define NO_XMODEM
> #define NO_DRAMTEST
>
> //#define GPIO_TEST
>
> #endif
> ---------------------------------------------------------------------------------------------
>
> ---- sim_hello.c
> ------------------------------------------------------------------------
> // ==============================================
> // T35 S100 Module Test Code
> // Damien Towning - 2022
> // ==============================================
> #include <stdio.h>
> #include <stdlib.h>
>
> //#include <newlib.h>
> //#include <nano_malloc.h>
> #include <errno.h>
> #include <sys/types.h>
> #include <string.h>
> #include "bonfire.h"
> #include "uart.h"
> #include "bonfire_gpio.h"
> #include "mem_rw.h"
> #include "console.h"
>
> extern void* sbrk(incr);
>
>
> // ========================================
> // Main function
> // ========================================
> int main() {
>
>   setBaudRate(PLATFORM_BAUDRATE);
>
>   caddr_t *ptr = sbrk(0);
>   // code never returns from sbrk
>   if (ptr == (void *)-1) {
>     printk("Failed to allocate memory\r\n");
>   }
>   else {
>     printk("Allocated memory at : %p\r\n", (void *) &ptr);
>   }
>   return 0;
> }
> ------------------------------------------------------------------------------------
> --- Makefile
> --------------------------------------------------------------------
>
> .PHONY: all clean
>
> ARCH ?= rv32ia
> ABI=ilp32
> PLATFORM ?= S100_T35
>
> #TARGET_PREFIX ?= riscv32-unknown-linux-gnu
> TARGET_PREFIX ?= riscv32-unknown-elf
> TARGET_CC := $(TARGET_PREFIX)-gcc
> TARGET_LD := $(TARGET_PREFIX)-gcc
> TARGET_SIZE := $(TARGET_PREFIX)-size
> TARGET_OBJCOPY := $(TARGET_PREFIX)-objcopy
> HEXDUMP ?= hexdump
> DATA2MEM = /opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/data2mem
>
> #PROJROOT = ../../..
> #TOPLEVEL = ~/riscv/ise/bonfire/papilio_pro_dram_toplevel.bit
> PLATFORMDIR=../platform
>
> LINKDEF?=$(PLATFORMDIR)/$(PLATFORM)/firmware.ld
>
> TARGET_CFLAGS +=  -march=$(ARCH) -mabi=$(ABI) -Wall -Os -g
>  -fomit-frame-pointer \
> -ffreestanding -fno-builtin  \
> -Wall -Werror=implicit-function-declaration \
> -D$(PLATFORM)
>
> ifeq ($(SIMULATOR), 1)
>   TARGET_CFLAGS+=-DSIMULATOR
> endif
>
> TARGET_CFLAGS+=-I$(PLATFORMDIR) -I$(PLATFORMDIR)/$(PLATFORM) -I../riscv
>
> # If we wish to build with no newlib
> #TARGET_LDFLAGS += -march=$(ARCH) -mabi=$(ABI) -nostartfiles   \
> -Wl,-m,elf32lriscv,--wrap=malloc,--wrap=sbrk --specs=nosys.specs
> -Wl,-T$(LINKDEF) \
> -Wl,--gc-sections
>
> TARGET_LDFLAGS += -march=$(ARCH) -mabi=$(ABI) -nostartfiles   \
> -Wl,-m,elf32lriscv,--wrap=_srand,--wrap=_rand  --specs=nano.specs
> -Wl,-Map=output.map,-T$(LINKDEF) \
> -Wl,--gc-sections
>
> all: sim_hello.hex memtest.hex nanotest.hex
>
> %.o : %.S
> $(TARGET_CC) $(TARGET_CFLAGS)  -c $<
>
> %.o : %.c
> $(TARGET_CC) $(TARGET_CFLAGS) -c $<
>
> %.hex : %.elf
> $(TARGET_OBJCOPY) -S -O binary  $< $(basename $@).bin
> $(HEXDUMP) -v -e '1/4 "%08x\n"' $(basename $@).bin >$@
> $(TARGET_PREFIX)-objdump -S -d $< >$(basename $@).lst
> #$(TARGET_PREFIX)-objdump -D $< >$(basename $@).S
> $(TARGET_PREFIX)-objdump -s $< >$(basename $@).dmp
> $(TARGET_PREFIX)-size  $<
>
> #sbrk.o: libwrap/sbrk.c
> # $(TARGET_CC) $(TARGET_CFLAGS) -DSIM -c libwrap/sbrk.c
>
> rand.o: libwrap/rand.c
> $(TARGET_CC) $(TARGET_CFLAGS) -DSIM -c libwrap/rand.c
>
> uart.o: uart.c
> $(TARGET_CC) $(TARGET_CFLAGS) -DSIM -c uart.c
>
> #sim_hello.o : sim_hello.c
> # $(TARGET_CC) $(TARGET_CFLAGS) -DSIM  -c sim_hello.c
>
> sim_hello.elf: start.o uart.o sim_hello.o snprintf.o console.o rand.o
> $(TARGET_LD) -o $@ $(TARGET_LDFLAGS) start.o uart.o sim_hello.o snprintf.o
> console.o rand.o
>
> #memtest.elf: start.o uart.o memtest.o snprintf.o console.o mempattern.o
> sbrk.o
> # $(TARGET_LD) -o $@ $(TARGET_LDFLAGS) start.o uart.o memtest.o snprintf.o
> console.o mempattern.o sbrk.o
>
> #nanotest.elf: start.o uart.o nanotest.o snprintf.o console.o mempattern.o
> sbrk.o
> # $(TARGET_LD) -o $@ $(TARGET_LDFLAGS) start.o uart.o nanotest.o snprintf.o
> console.o mempattern.o sbrk.o
>
> #jump0.elf : jump0.S
> # $(TARGET_LD) -o $@ -march=RV32IM -nostartfiles   -Wl,-T$(BOOTLINK) $<
>
> clean:
> rm -f *.o
> ---------------------------------------------------------------------------------------------.h>
> #include <stdlib.h>
>
> //#include <newlib.h>
> //#include <nano_malloc.h>
> #include <errno.h>
> #include <sys/types.h>
> #include <string.h>
> #include "bonfire.h"
> #include "uart.h"
> #include "bonfire_gpio.h"
> #include "mem_rw.h"
> #include "console.h"
>
> extern void* sbrk(incr);
>
>
> // ========================================
> // Main function
> // ========================================
> int main() {
>
>   setBaudRate(PLATFORM_BAUDRATE);
>
>   caddr_t *ptr = sbrk(0);
>   // code never returns from sbrk
>   if (ptr == (void *)-1) {
>     printk("Failed to allocate memory\r\n");
>   }
>   else {
>     printk("Allocated memory at : %p\r\n", (void *) &ptr);
>   }
>   return 0;
> }
> ------------------------------------------------------------------------------------
> --- Makefile
> --------------------------------------------------------------------
>
> .PHONY: all clean
>
> ARCH ?= rv32ia
> ABI=ilp32
> PLATFORM ?= S100_T35
>
> #TARGET_PREFIX ?= riscv32-unknown-linux-gnu
> TARGET_PREFIX ?= riscv32-unknown-elf
> TARGET_CC := $(TARGET_PREFIX)-gcc
> TARGET_LD := $(TARGET_PREFIX)-gcc
> TARGET_SIZE := $(TARGET_PREFIX)-size
> TARGET_OBJCOPY := $(TARGET_PREFIX)-objcopy
> HEXDUMP ?= hexdump
> DATA2MEM = /opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/data2mem
>
> #PROJROOT = ../../..
> #TOPLEVEL = ~/riscv/ise/bonfire/papilio_pro_dram_toplevel.bit
> PLATFORMDIR=../platform
>
> LINKDEF?=$(PLATFORMDIR)/$(PLATFORM)/firmware.ld
>
> TARGET_CFLAGS +=  -march=$(ARCH) -mabi=$(ABI) -Wall -Os -g
>  -fomit-frame-pointer \
> -ffreestanding -fno-builtin  \
> -Wall -Werror=implicit-function-declaration \
> -D$(PLATFORM)
>
> ifeq ($(SIMULATOR), 1)
>   TARGET_CFLAGS+=-DSIMULATOR
> endif
>
> TARGET_CFLAGS+=-I$(PLATFORMDIR) -I$(PLATFORMDIR)/$(PLATFORM) -I../riscv
>
> # If we wish to build with no newlib
> #TARGET_LDFLAGS += -march=$(ARCH) -mabi=$(ABI) -nostartfiles   \
> -Wl,-m,elf32lriscv,--wrap=malloc,--wrap=sbrk --specs=nosys.specs
> -Wl,-T$(LINKDEF) \
> -Wl,--gc-sections
>
> TARGET_LDFLAGS += -march=$(ARCH) -mabi=$(ABI) -nostartfiles   \
> -Wl,-m,elf32lriscv,--wrap=_srand,--wrap=_rand  --specs=nano.specs
> -Wl,-Map=output.map,-T$(LINKDEF) \
> -Wl,--gc-sections
>
> all: sim_hello.hex memtest.hex nanotest.hex
>
> %.o : %.S
> $(TARGET_CC) $(TARGET_CFLAGS)  -c $<
>
> %.o : %.c
> $(TARGET_CC) $(TARGET_CFLAGS) -c $<
>
> %.hex : %.elf
> $(TARGET_OBJCOPY) -S -O binary  $< $(basename $@).bin
> $(HEXDUMP) -v -e '1/4 "%08x\n"' $(basename $@).bin >$@
> $(TARGET_PREFIX)-objdump -S -d $< >$(basename $@).lst
> #$(TARGET_PREFIX)-objdump -D $< >$(basename $@).S
> $(TARGET_PREFIX)-objdump -s $< >$(basename $@).dmp
> $(TARGET_PREFIX)-size  $<
>
> #sbrk.o: libwrap/sbrk.c
> # $(TARGET_CC) $(TARGET_CFLAGS) -DSIM -c libwrap/sbrk.c
>
> rand.o: libwrap/rand.c
> $(TARGET_CC) $(TARGET_CFLAGS) -DSIM -c libwrap/rand.c
>
> uart.o: uart.c
> $(TARGET_CC) $(TARGET_CFLAGS) -DSIM -c uart.c
>
> #sim_hello.o : sim_hello.c
> # $(TARGET_CC) $(TARGET_CFLAGS) -DSIM  -c sim_hello.c
>
> sim_hello.elf: start.o uart.o sim_hello.o snprintf.o console.o rand.o
> $(TARGET_LD) -o $@ $(TARGET_LDFLAGS) start.o uart.o sim_hello.o snprintf.o
> console.o rand.o
>
> #memtest.elf: start.o uart.o memtest.o snprintf.o console.o mempattern.o
> sbrk.o
> # $(TARGET_LD) -o $@ $(TARGET_LDFLAGS) start.o uart.o memtest.o snprintf.o
> console.o mempattern.o sbrk.o
>
> #nanotest.elf: start.o uart.o nanotest.o snprintf.o console.o mempattern.o
> sbrk.o
> # $(TARGET_LD) -o $@ $(TARGET_LDFLAGS) start.o uart.o nanotest.o snprintf.o
> console.o mempattern.o sbrk.o
>
> #jump0.elf : jump0.S
> # $(TARGET_LD) -o $@ -march=RV32IM -nostartfiles   -Wl,-T$(BOOTLINK) $<
>
> clean:
> rm -f *.o
> ---------------------------------------------------------------------------------------------
>
>
> --
> Dave Nadler, USA East Coast voice (978) 263-0097, drn@nadler.com, Skype
>  Dave.Nadler1
>
>

-- 
Damien Towning

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2023-03-08  1:23 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-06  7:36 Problem with SBRK not returning from call on bare metal risk Damien Towning
2023-03-06 13:24 ` Dave Nadler
2023-03-08  1:23   ` Damien Towning

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).