diff mbox series

[4/9] RISC-V: Add setjmp implementation

Message ID 20181106175837.9083-5-agraf@suse.de
State Superseded
Headers show
Series Add RISC-V support | expand

Commit Message

Alexander Graf Nov. 6, 2018, 5:58 p.m. UTC
This patch adds a 32/64 capable setjmp implementation for RISC-V.

Signed-off-by: Alexander Graf <agraf@suse.de>

---
 grub-core/lib/riscv/setjmp.S  | 82 +++++++++++++++++++++++++++++++++++++++++++
 include/grub/riscv32/setjmp.h | 27 ++++++++++++++
 include/grub/riscv64/setjmp.h | 27 ++++++++++++++
 3 files changed, 136 insertions(+)
 create mode 100644 grub-core/lib/riscv/setjmp.S
 create mode 100644 include/grub/riscv32/setjmp.h
 create mode 100644 include/grub/riscv64/setjmp.h

-- 
2.12.3


_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Comments

Alistair Francis Nov. 8, 2018, 11:07 p.m. UTC | #1
On Tue, 2018-11-06 at 18:58 +0100, Alexander Graf wrote:
> This patch adds a 32/64 capable setjmp implementation for RISC-V.

> 

> Signed-off-by: Alexander Graf <agraf@suse.de>


Reviewed-by: Alistair Francis <alistair.francis@wdc.com>


Alistair

> ---

>  grub-core/lib/riscv/setjmp.S  | 82

> +++++++++++++++++++++++++++++++++++++++++++

>  include/grub/riscv32/setjmp.h | 27 ++++++++++++++

>  include/grub/riscv64/setjmp.h | 27 ++++++++++++++

>  3 files changed, 136 insertions(+)

>  create mode 100644 grub-core/lib/riscv/setjmp.S

>  create mode 100644 include/grub/riscv32/setjmp.h

>  create mode 100644 include/grub/riscv64/setjmp.h

> 

> diff --git a/grub-core/lib/riscv/setjmp.S b/grub-

> core/lib/riscv/setjmp.S

> new file mode 100644

> index 000000000..053e2e6ba

> --- /dev/null

> +++ b/grub-core/lib/riscv/setjmp.S

> @@ -0,0 +1,82 @@

> +/*

> + *  GRUB  --  GRand Unified Bootloader

> + *  Copyright (C) 2013  Free Software Foundation, Inc.

> + *

> + *  GRUB is free software: you can redistribute it and/or modify

> + *  it under the terms of the GNU General Public License as

> published by

> + *  the Free Software Foundation, either version 3 of the License,

> or

> + *  (at your option) any later version.

> + *

> + *  GRUB is distributed in the hope that it will be useful,

> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of

> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

> + *  GNU General Public License for more details.

> + *

> + *  You should have received a copy of the GNU General Public

> License

> + *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>;.

> + */

> +

> +#include <grub/symbol.h>

> +#include <grub/dl.h>

> +

> +	.file	"setjmp.S"

> +GRUB_MOD_LICENSE "GPLv3+"

> +	.text

> +

> +#if __riscv_xlen == 64

> +#define STORE_IDX(reg, idx)     sd reg, (idx*8)(a0)

> +#define LOAD_IDX(reg, idx)      ld reg, (idx*8)(a0)

> +#else

> +#define STORE_IDX(reg, idx)     sw reg, (idx*4)(a0)

> +#define LOAD_IDX(reg, idx)      lw reg, (idx*4)(a0)

> +#endif

> +

> +/*

> + * int grub_setjmp (grub_jmp_buf env)

> + */

> +FUNCTION(grub_setjmp)

> +        /* Preserve all callee-saved registers and the SP */

> +        STORE_IDX(s0, 0)

> +        STORE_IDX(s1, 1)

> +        STORE_IDX(s2, 2)

> +        STORE_IDX(s3, 3)

> +        STORE_IDX(s4, 4)

> +        STORE_IDX(s5, 5)

> +        STORE_IDX(s6, 6)

> +        STORE_IDX(s7, 7)

> +        STORE_IDX(s8, 8)

> +        STORE_IDX(s9, 9)

> +        STORE_IDX(s10, 10)

> +        STORE_IDX(s11, 11)

> +        STORE_IDX(ra, 12)

> +        STORE_IDX(sp, 13)

> +        li  a0, 0

> +        ret

> +

> +/*

> + * int grub_longjmp (grub_jmp_buf env, int val)

> + */

> +FUNCTION(grub_longjmp)

> +        LOAD_IDX(s0, 0)

> +        LOAD_IDX(s1, 1)

> +        LOAD_IDX(s2, 2)

> +        LOAD_IDX(s3, 3)

> +        LOAD_IDX(s4, 4)

> +        LOAD_IDX(s5, 5)

> +        LOAD_IDX(s6, 6)

> +        LOAD_IDX(s7, 7)

> +        LOAD_IDX(s8, 8)

> +        LOAD_IDX(s9, 9)

> +        LOAD_IDX(s10, 10)

> +        LOAD_IDX(s11, 11)

> +        LOAD_IDX(ra, 12)

> +        LOAD_IDX(sp, 13)

> +

> +        /* Move the return value in place, but return 1 if passed 0.

> */

> +        beq a1, zero, longjmp_1

> +        mv a0, a1

> +        ret

> +

> +        longjmp_1:

> +        li a0, 1

> +        ret

> diff --git a/include/grub/riscv32/setjmp.h

> b/include/grub/riscv32/setjmp.h

> new file mode 100644

> index 000000000..7a0ed0548

> --- /dev/null

> +++ b/include/grub/riscv32/setjmp.h

> @@ -0,0 +1,27 @@

> +/*

> + *  GRUB  --  GRand Unified Bootloader

> + *  Copyright (C) 2013  Free Software Foundation, Inc.

> + *

> + *  GRUB is free software: you can redistribute it and/or modify

> + *  it under the terms of the GNU General Public License as

> published by

> + *  the Free Software Foundation, either version 3 of the License,

> or

> + *  (at your option) any later version.

> + *

> + *  GRUB is distributed in the hope that it will be useful,

> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of

> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

> + *  GNU General Public License for more details.

> + *

> + *  You should have received a copy of the GNU General Public

> License

> + *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>;.

> + */

> +

> +#ifndef GRUB_SETJMP_CPU_HEADER

> +#define GRUB_SETJMP_CPU_HEADER	1

> +

> +typedef unsigned long long grub_jmp_buf[14];

> +

> +int grub_setjmp (grub_jmp_buf env) RETURNS_TWICE;

> +void grub_longjmp (grub_jmp_buf env, int val) __attribute__

> ((noreturn));

> +

> +#endif /* ! GRUB_SETJMP_CPU_HEADER */

> diff --git a/include/grub/riscv64/setjmp.h

> b/include/grub/riscv64/setjmp.h

> new file mode 100644

> index 000000000..7a0ed0548

> --- /dev/null

> +++ b/include/grub/riscv64/setjmp.h

> @@ -0,0 +1,27 @@

> +/*

> + *  GRUB  --  GRand Unified Bootloader

> + *  Copyright (C) 2013  Free Software Foundation, Inc.

> + *

> + *  GRUB is free software: you can redistribute it and/or modify

> + *  it under the terms of the GNU General Public License as

> published by

> + *  the Free Software Foundation, either version 3 of the License,

> or

> + *  (at your option) any later version.

> + *

> + *  GRUB is distributed in the hope that it will be useful,

> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of

> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

> + *  GNU General Public License for more details.

> + *

> + *  You should have received a copy of the GNU General Public

> License

> + *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>;.

> + */

> +

> +#ifndef GRUB_SETJMP_CPU_HEADER

> +#define GRUB_SETJMP_CPU_HEADER	1

> +

> +typedef unsigned long long grub_jmp_buf[14];

> +

> +int grub_setjmp (grub_jmp_buf env) RETURNS_TWICE;

> +void grub_longjmp (grub_jmp_buf env, int val) __attribute__

> ((noreturn));

> +

> +#endif /* ! GRUB_SETJMP_CPU_HEADER */

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
diff mbox series

Patch

diff --git a/grub-core/lib/riscv/setjmp.S b/grub-core/lib/riscv/setjmp.S
new file mode 100644
index 000000000..053e2e6ba
--- /dev/null
+++ b/grub-core/lib/riscv/setjmp.S
@@ -0,0 +1,82 @@ 
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+#include <grub/dl.h>
+
+	.file	"setjmp.S"
+GRUB_MOD_LICENSE "GPLv3+"
+	.text
+
+#if __riscv_xlen == 64
+#define STORE_IDX(reg, idx)     sd reg, (idx*8)(a0)
+#define LOAD_IDX(reg, idx)      ld reg, (idx*8)(a0)
+#else
+#define STORE_IDX(reg, idx)     sw reg, (idx*4)(a0)
+#define LOAD_IDX(reg, idx)      lw reg, (idx*4)(a0)
+#endif
+
+/*
+ * int grub_setjmp (grub_jmp_buf env)
+ */
+FUNCTION(grub_setjmp)
+        /* Preserve all callee-saved registers and the SP */
+        STORE_IDX(s0, 0)
+        STORE_IDX(s1, 1)
+        STORE_IDX(s2, 2)
+        STORE_IDX(s3, 3)
+        STORE_IDX(s4, 4)
+        STORE_IDX(s5, 5)
+        STORE_IDX(s6, 6)
+        STORE_IDX(s7, 7)
+        STORE_IDX(s8, 8)
+        STORE_IDX(s9, 9)
+        STORE_IDX(s10, 10)
+        STORE_IDX(s11, 11)
+        STORE_IDX(ra, 12)
+        STORE_IDX(sp, 13)
+        li  a0, 0
+        ret
+
+/*
+ * int grub_longjmp (grub_jmp_buf env, int val)
+ */
+FUNCTION(grub_longjmp)
+        LOAD_IDX(s0, 0)
+        LOAD_IDX(s1, 1)
+        LOAD_IDX(s2, 2)
+        LOAD_IDX(s3, 3)
+        LOAD_IDX(s4, 4)
+        LOAD_IDX(s5, 5)
+        LOAD_IDX(s6, 6)
+        LOAD_IDX(s7, 7)
+        LOAD_IDX(s8, 8)
+        LOAD_IDX(s9, 9)
+        LOAD_IDX(s10, 10)
+        LOAD_IDX(s11, 11)
+        LOAD_IDX(ra, 12)
+        LOAD_IDX(sp, 13)
+
+        /* Move the return value in place, but return 1 if passed 0. */
+        beq a1, zero, longjmp_1
+        mv a0, a1
+        ret
+
+        longjmp_1:
+        li a0, 1
+        ret
diff --git a/include/grub/riscv32/setjmp.h b/include/grub/riscv32/setjmp.h
new file mode 100644
index 000000000..7a0ed0548
--- /dev/null
+++ b/include/grub/riscv32/setjmp.h
@@ -0,0 +1,27 @@ 
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_SETJMP_CPU_HEADER
+#define GRUB_SETJMP_CPU_HEADER	1
+
+typedef unsigned long long grub_jmp_buf[14];
+
+int grub_setjmp (grub_jmp_buf env) RETURNS_TWICE;
+void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn));
+
+#endif /* ! GRUB_SETJMP_CPU_HEADER */
diff --git a/include/grub/riscv64/setjmp.h b/include/grub/riscv64/setjmp.h
new file mode 100644
index 000000000..7a0ed0548
--- /dev/null
+++ b/include/grub/riscv64/setjmp.h
@@ -0,0 +1,27 @@ 
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_SETJMP_CPU_HEADER
+#define GRUB_SETJMP_CPU_HEADER	1
+
+typedef unsigned long long grub_jmp_buf[14];
+
+int grub_setjmp (grub_jmp_buf env) RETURNS_TWICE;
+void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn));
+
+#endif /* ! GRUB_SETJMP_CPU_HEADER */