zephyr/arch/riscv/core/userspace.S
Nicolas Pitre a50c433012 riscv: exception code mega simplification and optimization
Complete revamp of the exception entry code, including syscall handling.
Proper syscall frame exception trigger. Many correctness fixes, hacks
removal, etc. etc.

I tried to make this into several commits, but this stuff is all
inter-related and a pain to split.

The diffstat summary:

 14 files changed, 250 insertions(+), 802 deletions(-)

Binary size (before):

   text	   data	    bss	    dec	    hex	filename
   1104	      0	      0	   1104	    450	isr.S.obj
     64	      0	      0	     64	     40	userspace.S.obj

Binary size (after):

   text	   data	    bss	    dec	    hex	filename
    600	      0	      0	    600	    258	isr.S.obj
     36	      0	      0	     36	     24	userspace.S.obj

Run of samples/userspace/syscall_perf (before):

*** Booting Zephyr OS build zephyr-v3.0.0-325-g3748accae018  ***
Main Thread started; qemu_riscv32
Supervisor thread started
User thread started
Supervisor thread(0x80010048):       384 cycles	     509 instructions
User thread(0x80010140):           77312 cycles	   77437 instructions

Run of samples/userspace/syscall_perf (after):

*** Booting Zephyr OS build zephyr-v3.0.0-326-g4c877a2753b3  ***
Main Thread started; qemu_riscv32
Supervisor thread started
User thread started
Supervisor thread(0x80010048):       384 cycles	     509 instructions
User thread(0x80010138):            7040 cycles     7165 instructions

Yes, that's more than a 10x speed-up!

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-03-21 07:28:05 -04:00

52 lines
1.1 KiB
ArmAsm

/*
* Userspace and service handler hooks
*
* Copyright (c) 2020 BayLibre, SAS
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <toolchain.h>
#include <linker/sections.h>
#include <offsets_short.h>
#include <arch/cpu.h>
#include <syscall.h>
#include <kernel_structs.h>
#include <arch/riscv/csr.h>
#include "asm_macros.inc"
/* exports */
GTEXT(arch_user_string_nlen)
GTEXT(z_riscv_user_string_nlen_fault_start)
GTEXT(z_riscv_user_string_nlen_fault_end)
GTEXT(z_riscv_user_string_nlen_fixup)
/*
* size_t arch_user_string_nlen(const char *s, size_t maxsize, int *err_arg)
*/
SECTION_FUNC(TEXT, arch_user_string_nlen)
li a5, 0 # Counter
sw a5, 0(a2) # Init error value to 0
loop:
add a4, a0, a5 # Determine character address
z_riscv_user_string_nlen_fault_start:
lbu a4, 0(a4) # Load string's character
z_riscv_user_string_nlen_fault_end:
beqz a4, exit # Test string's end of line
bne a5, a1, continue # Check if max length is reached
exit:
mv a0, a5 # Return counter value (length)
ret
continue:
addi a5, a5, 1 # Increment counter
j loop
z_riscv_user_string_nlen_fixup:
li a4, -1 # Put error to -1
sw a4, 0(a2)
j exit