From 4078548ae31a47bd7f0c08168568c31193140230 Mon Sep 17 00:00:00 2001 From: Huang Qi Date: Thu, 3 Dec 2020 20:10:10 +0800 Subject: [PATCH] risc-v: Introduce basic setjmp support Signed-off-by: Huang Qi --- arch/risc-v/Kconfig | 3 + arch/risc-v/include/setjmp.h | 48 ++++++++++++++++ arch/risc-v/src/common/riscv_setjmp.S | 83 +++++++++++++++++++++++++++ arch/risc-v/src/fe310/Make.defs | 4 ++ arch/risc-v/src/gap8/Make.defs | 4 ++ arch/risc-v/src/k210/Make.defs | 4 ++ arch/risc-v/src/litex/Make.defs | 4 ++ arch/risc-v/src/nr5m100/Make.defs | 4 ++ 8 files changed, 154 insertions(+) create mode 100644 arch/risc-v/include/setjmp.h create mode 100644 arch/risc-v/src/common/riscv_setjmp.S diff --git a/arch/risc-v/Kconfig b/arch/risc-v/Kconfig index a9b9313ccb..4617062f72 100644 --- a/arch/risc-v/Kconfig +++ b/arch/risc-v/Kconfig @@ -55,15 +55,18 @@ endchoice config ARCH_RV32I bool default n + select ARCH_HAVE_SETJMP config ARCH_RV32IM bool default n + select ARCH_HAVE_SETJMP config ARCH_RV64GC bool default n select LIBC_ARCH_ELF_64BIT if LIBC_ARCH_ELF + select ARCH_HAVE_SETJMP config ARCH_FAMILY string diff --git a/arch/risc-v/include/setjmp.h b/arch/risc-v/include/setjmp.h new file mode 100644 index 0000000000..0eae01543e --- /dev/null +++ b/arch/risc-v/include/setjmp.h @@ -0,0 +1,48 @@ +/**************************************************************************** + * arch/risc-v/include/setjmp.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_INCLUDE_SETJUMP_H +#define __ARCH_RISCV_INCLUDE_SETJUMP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct setjmp_buf_s +{ + long regs[14]; +}; + +/* Traditional typedef for setjmp_buf */ + +typedef struct setjmp_buf_s jmp_buf[1]; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +int setjmp(jmp_buf env); +void longjmp(jmp_buf env, int val) noreturn_function; + +#endif diff --git a/arch/risc-v/src/common/riscv_setjmp.S b/arch/risc-v/src/common/riscv_setjmp.S new file mode 100644 index 0000000000..dca84d9e68 --- /dev/null +++ b/arch/risc-v/src/common/riscv_setjmp.S @@ -0,0 +1,83 @@ +############################################################################ +# arch/risc-v/src/common/riscv_setjmp.S +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +#if __riscv_xlen == 64 +# define SZREG 8 +# define REG_S sd +# define REG_L ld +#elif __riscv_xlen == 32 +# define SZREG 4 +# define REG_S sw +# define REG_L lw +#else +# error __riscv_xlen must equal 32 or 64 +#endif + +.section .text +.globl setjmp +.type setjmp, @function + +setjmp: + REG_S ra, 0*SZREG(a0) + REG_S s0, 1*SZREG(a0) + REG_S s1, 2*SZREG(a0) + + REG_S s2, 3*SZREG(a0) + REG_S s3, 4*SZREG(a0) + REG_S s4, 5*SZREG(a0) + REG_S s5, 6*SZREG(a0) + REG_S s6, 7*SZREG(a0) + REG_S s7, 8*SZREG(a0) + REG_S s8, 9*SZREG(a0) + REG_S s9, 10*SZREG(a0) + REG_S s10,11*SZREG(a0) + REG_S s11,12*SZREG(a0) + REG_S sp, 13*SZREG(a0) + + li a0, 0 + ret + .size setjmp, .-setjmp + +/* volatile void longjmp (jmp_buf, int); */ + +.section .text +.globl longjmp +.type longjmp, @function +longjmp: + REG_L ra, 0*SZREG(a0) + REG_L s0, 1*SZREG(a0) + REG_L s1, 2*SZREG(a0) + + REG_L s2, 3*SZREG(a0) + REG_L s3, 4*SZREG(a0) + REG_L s4, 5*SZREG(a0) + REG_L s5, 6*SZREG(a0) + REG_L s6, 7*SZREG(a0) + REG_L s7, 8*SZREG(a0) + REG_L s8, 9*SZREG(a0) + REG_L s9, 10*SZREG(a0) + REG_L s10,11*SZREG(a0) + REG_L s11,12*SZREG(a0) + REG_L sp, 13*SZREG(a0) + + seqz a0, a1 + add a0, a0, a1 # a0 = (a1 == 0) ? 1 : a1 + ret + .size longjmp, .-longjmp diff --git a/arch/risc-v/src/fe310/Make.defs b/arch/risc-v/src/fe310/Make.defs index edebdac5fb..15ff5c6729 100644 --- a/arch/risc-v/src/fe310/Make.defs +++ b/arch/risc-v/src/fe310/Make.defs @@ -37,6 +37,10 @@ HEAD_ASRC = fe310_vectors.S # Specify our general Assembly files CHIP_ASRCS = fe310_head.S riscv_syscall.S +ifeq ($(CONFIG_ARCH_SETJMP_H),y) +CMN_ASRCS += riscv_setjmp.S +endif + # Specify C code within the common directory to be included CMN_CSRCS += riscv_initialize.c riscv_swint.c CMN_CSRCS += riscv_allocateheap.c riscv_createstack.c riscv_exit.c diff --git a/arch/risc-v/src/gap8/Make.defs b/arch/risc-v/src/gap8/Make.defs index df49628f55..ceb7cf4e10 100644 --- a/arch/risc-v/src/gap8/Make.defs +++ b/arch/risc-v/src/gap8/Make.defs @@ -39,6 +39,10 @@ HEAD_ASRC = gap8_head.S CHIP_ASRCS = riscv_syscall.S +ifeq ($(CONFIG_ARCH_SETJMP_H),y) +CMN_ASRCS += riscv_setjmp.S +endif + # Override the arch to enable hardware MUL during assembly. # This is to support our hardware mul test. For that test, # we have to disable hardware mul for C code so the soft diff --git a/arch/risc-v/src/k210/Make.defs b/arch/risc-v/src/k210/Make.defs index 718a785f7b..3e42d59028 100644 --- a/arch/risc-v/src/k210/Make.defs +++ b/arch/risc-v/src/k210/Make.defs @@ -39,6 +39,10 @@ CHIP_ASRCS = k210_head.S CMN_ASRCS += riscv_testset.S +ifeq ($(CONFIG_ARCH_SETJMP_H),y) +CMN_ASRCS += riscv_setjmp.S +endif + # Specify C code within the common directory to be included CMN_CSRCS += riscv_initialize.c riscv_swint.c CMN_CSRCS += riscv_allocateheap.c riscv_createstack.c riscv_exit.c riscv_fault.c diff --git a/arch/risc-v/src/litex/Make.defs b/arch/risc-v/src/litex/Make.defs index e0faa24581..f157488e67 100644 --- a/arch/risc-v/src/litex/Make.defs +++ b/arch/risc-v/src/litex/Make.defs @@ -25,6 +25,10 @@ HEAD_ASRC = litex_vectors.S # Specify our general Assembly files CHIP_ASRCS = litex_head.S riscv_syscall.S +ifeq ($(CONFIG_ARCH_SETJMP_H),y) +CMN_ASRCS += riscv_setjmp.S +endif + # Specify C code within the common directory to be included CMN_CSRCS += riscv_initialize.c riscv_swint.c CMN_CSRCS += riscv_allocateheap.c riscv_createstack.c riscv_exit.c diff --git a/arch/risc-v/src/nr5m100/Make.defs b/arch/risc-v/src/nr5m100/Make.defs index 450bd6373b..4695348659 100644 --- a/arch/risc-v/src/nr5m100/Make.defs +++ b/arch/risc-v/src/nr5m100/Make.defs @@ -37,6 +37,10 @@ HEAD_ASRC = nr5_vectors.S # Specify our general Assembly files CHIP_ASRCS = nr5_head.S nr5_csr.S riscv_syscall.S +ifeq ($(CONFIG_ARCH_SETJMP_H),y) +CMN_ASRCS += riscv_setjmp.S +endif + # If we are compiling the NELIB library, then specify it # in AFLAGS so we can change up our startup behavior ifeq ($(CONFIG_LIB_NEWLIB),y)