Skip to content

Commit

Permalink
Merge #19341 #19345
Browse files Browse the repository at this point in the history
19341: Picolibc updates r=benpicco a=keith-packard

### Contribution description

Minor updates to picolibc support for newer versions of picolibc, including 1.8.


### Testing procedure

Here's the current build result for a board I happen to have on my bench right now:

```
$ make -C examples/blinky BOARD=nucleo-f103rb FEATURES_REQUIRED=picolibc
...
/home/keithp/src/RIOT/sys/picolibc_syscalls_default/syscalls.c:319:1: error: unknown type name '_READ_WRITE_RETURN_TYPE'
  319 | _READ_WRITE_RETURN_TYPE read(int fd, void *dest, size_t count)
      | ^~~~~~~~~~~~~~~~~~~~~~~
/home/keithp/src/RIOT/sys/picolibc_syscalls_default/syscalls.c:351:1: error: unknown type name '_READ_WRITE_RETURN_TYPE'
  351 | _READ_WRITE_RETURN_TYPE write(int fd, const void *src, size_t count)
      | ^~~~~~~~~~~~~~~~~~~~~~~
...
```

### Description of changes

 1. Fix the read/write return values (Picolibc 1.8 uses POSIX standard types now)
 2. Add new symbols to linker scripts (Picolibc needs help dealing with TLS alignment)
 3. Align stack and thread local storage block during thread setup.


19345: cpu/riscv_common: convert to uword_t usage r=benpicco a=dylad

### Contribution description

This PR makes use of `uword_t` type in a few places in `cpu/riscv_common`.
This should not have any effect on produced binaries.

### Testing procedure

CI should be enough. 

### Issues/PRs references
Quickly adapt from #16994. It will help for 64 bits support one day ;)



Co-authored-by: Keith Packard <keithp@keithp.com>
Co-authored-by: Dylan Laduranty <dylan.laduranty@mesotic.com>
  • Loading branch information
3 people authored Mar 4, 2023
3 parents 8c6926d + 0ceb080 + 5f699ee commit a9310ed
Show file tree
Hide file tree
Showing 8 changed files with 44 additions and 14 deletions.
14 changes: 12 additions & 2 deletions core/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,9 +226,19 @@ kernel_pid_t thread_create(char *stack, int stacksize, uint8_t priority,
thread_t *thread = (thread_t *)(uintptr_t)(stack + stacksize);

#ifdef PICOLIBC_TLS
stacksize -= _tls_size();
#if __PICOLIBC_MAJOR__ > 1 || __PICOLIBC_MINOR__ >= 8
#define TLS_ALIGN (alignof(thread_t) > _tls_align() ? alignof(thread_t) : _tls_align())
#else
#define TLS_ALIGN alignof(thread_t)
#endif
char *tls = stack + stacksize - _tls_size();
/*
* Make sure the TLS area is aligned as required and that the
* resulting stack will also be aligned as required
*/
thread->tls = (void *) ((uintptr_t) tls & ~ (TLS_ALIGN - 1));
stacksize = (char *) thread->tls - stack;

thread->tls = stack + stacksize;
_init_tls(thread->tls);
#endif

Expand Down
4 changes: 4 additions & 0 deletions cpu/cortexm_common/ldscripts/cortexm_base.ld
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ SECTIONS
} > rom
__tls_size = __tbss_end - __tdata_start;
__tbss_size = __tls_size - __tdata_size;
PROVIDE( __tbss_offset = ADDR(.tbss) - ADDR(.tdata) );
PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) );
PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) );
PROVIDE( __arm64_tls_tcb_offset = MAX(16, __tls_align) );

/* .ARM.exidx is sorted, so has to go in its own output section. */
PROVIDE_HIDDEN (__exidx_start = .);
Expand Down
3 changes: 3 additions & 0 deletions cpu/lpc23xx/ldscripts/lpc23xx.ld
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ SECTIONS
} > rom
__tls_size = __tbss_end - __tdata_start;
__tbss_size = __tls_size - __tdata_size;
PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) );
PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) );
PROVIDE( __arm64_tls_tcb_offset = MAX(16, __tls_align) );

/* .ARM.exidx is sorted, so has to go in its own output section. */
PROVIDE_HIDDEN (__exidx_start = .);
Expand Down
11 changes: 6 additions & 5 deletions cpu/riscv_common/irq_arch.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "sched.h"
#include "plic.h"
#include "clic.h"
#include "architecture.h"

#include "vendor/riscv_csr.h"

Expand Down Expand Up @@ -83,13 +84,13 @@ void riscv_irq_init(void)
* @brief Global trap and interrupt handler
*/
__attribute((used))
static void handle_trap(uint32_t mcause)
static void handle_trap(uword_t mcause)
{
/* Tell RIOT to set sched_context_switch_request instead of
* calling thread_yield(). */
riscv_in_isr = 1;

uint32_t trap = mcause & CPU_CSR_MCAUSE_CAUSE_MSK;
uword_t trap = mcause & CPU_CSR_MCAUSE_CAUSE_MSK;

/* Check for INT or TRAP */
if ((mcause & MCAUSE_INT) == MCAUSE_INT) {
Expand Down Expand Up @@ -129,16 +130,16 @@ static void handle_trap(uint32_t mcause)
sched_context_switch_request = 1;
/* Increment the return program counter past the ecall
* instruction */
uint32_t return_pc = read_csr(mepc);
uword_t return_pc = read_csr(mepc);
write_csr(mepc, return_pc + 4);
break;
}
default:
#ifdef DEVELHELP
printf("Unhandled trap:\n");
printf(" mcause: 0x%" PRIx32 "\n", trap);
printf(" mepc: 0x%lx\n", read_csr(mepc));
printf(" mtval: 0x%lx\n", read_csr(mtval));
printf(" mepc: 0x%" PRIx32 "\n", read_csr(mepc));
printf(" mtval: 0x%" PRIx32 "\n", read_csr(mtval));
#endif
/* Unknown trap */
core_panic(PANIC_GENERAL_ERROR, "Unhandled trap");
Expand Down
2 changes: 2 additions & 0 deletions cpu/riscv_common/ldscripts/riscv_base.ld
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ SECTIONS
} >flash : tls
__tls_size = __tbss_end - __tdata_start;
__tbss_size = __tls_size - __tdata_size;
PROVIDE( __tbss_offset = ADDR(.tbss) - ADDR(.tdata) );
PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) );

.lalign :
{
Expand Down
7 changes: 4 additions & 3 deletions cpu/riscv_common/periph/plic.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "assert.h"
#include "cpu.h"
#include "plic.h"
#include "architecture.h"

/* Local macros to calculate register offsets */
#ifndef _REG32
Expand All @@ -42,7 +43,7 @@ static plic_isr_cb_t _ext_isrs[PLIC_NUM_INTERRUPTS];

static inline volatile uint32_t *_get_claim_complete_addr(void)
{
uint32_t hart_id = read_csr(mhartid);
uword_t hart_id = read_csr(mhartid);

/* Construct the claim address */
return &PLIC_REG(PLIC_CLAIM_OFFSET +
Expand All @@ -51,7 +52,7 @@ static inline volatile uint32_t *_get_claim_complete_addr(void)

static inline volatile uint32_t *_get_threshold_addr(void)
{
uint32_t hart_id = read_csr(mhartid);
uword_t hart_id = read_csr(mhartid);

/* Construct the claim address */
return &PLIC_REG(PLIC_THRESHOLD_OFFSET +
Expand All @@ -60,7 +61,7 @@ static inline volatile uint32_t *_get_threshold_addr(void)

static inline volatile uint32_t *_get_irq_reg(unsigned irq)
{
uint32_t hart_id = read_csr(mhartid);
uword_t hart_id = read_csr(mhartid);

return &PLIC_REG(PLIC_ENABLE_OFFSET +
(hart_id << PLIC_ENABLE_SHIFT_PER_TARGET)) +
Expand Down
7 changes: 4 additions & 3 deletions cpu/riscv_common/thread_arch.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "thread.h"
#include "sched.h"
#include "context_frame.h"
#include "architecture.h"

/**
* @brief Noticeable marker marking the beginning of a stack segment
Expand Down Expand Up @@ -101,11 +102,11 @@ char *thread_stack_init(thread_task_func_t task_func,
memset(sf, 0, sizeof(*sf));

/* set initial reg values */
sf->pc = (uint32_t)task_func;
sf->a0 = (uint32_t)arg;
sf->pc = (uword_t)task_func;
sf->a0 = (uword_t)arg;

/* if the thread exits go to sched_task_exit() */
sf->ra = (uint32_t)sched_task_exit;
sf->ra = (uword_t)sched_task_exit;

return (char *)stk_top;
}
Expand Down
10 changes: 9 additions & 1 deletion sys/picolibc_syscalls_default/syscalls.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ _exit(int n)
{
LOG_INFO("#! exit %i: powering off\n", n);
pm_off();
while(1);
for (;;) {
}
}

/**
Expand Down Expand Up @@ -304,6 +305,13 @@ int open(const char *name, int flags, int mode)
#endif
}

/*
* Picolibc newer than 1.8 uses standard posix types for read/write
* return values
*/
#if __PICOLIBC_MAJOR__ > 1 || __PICOLIBC_MINOR__ >= 8
#define _READ_WRITE_RETURN_TYPE ssize_t
#endif
/**
* @brief Read bytes from an open file
*
Expand Down

0 comments on commit a9310ed

Please sign in to comment.