All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 00/10] Add RISC-V support
@ 2018-11-14 17:27 Alexander Graf
  2018-11-14 17:27 ` [PATCH v3 01/10] efi: Rename armxx to arch Alexander Graf
                   ` (9 more replies)
  0 siblings, 10 replies; 41+ messages in thread
From: Alexander Graf @ 2018-11-14 17:27 UTC (permalink / raw)
  To: grub-devel
  Cc: leif.lindholm, Peter Jones, Paul Walmsley, David Abdurachmanov,
	atish.patra, schwab, Michael Chang, Alistair Francis, Lukas Auer,
	greentime @ andestech . com, rickchen36 @ gmail . com, Bin Meng

As part of the plan for total world domination, we would like to make sure
that booting on RISC-V is in a sane state before anyone goes and does quick
hacks "just because".

For that reason, U-Boot supports UEFI booting on RISC-V for a while now.
This patch set is the second part of the puzzle, with grub learning how to
deal with a UEFI enabled RISC-V target.

The third bit (still missing) is to actually make a working Linux UEFI port.
But that will come, I'm sure :).

Looking forward to review feedback and testing,

v1 -> v2:

  - adapt to new grub_open_file() API
  - adapt to new grub_create_loader_cmdline() API

v2 -> v3:

  - fix riscv32 target

Alex

Alexander Graf (10):
  efi: Rename armxx to arch
  PE: Add RISC-V definitions
  elf.h: Add RISC-V definitions
  RISC-V: Add setjmp implementation
  RISC-V: Add early startup code
  RISC-V: Add Linux load logic
  RISC-V: Add awareness for RISC-V reloations
  RISC-V: Add auxiliary files
  RISC-V: Add to build system
  fdt: Add device tree file type

 configure.ac                       |  28 ++-
 gentpl.py                          |  11 +-
 grub-core/Makefile.am              |  12 ++
 grub-core/Makefile.core.def        |  29 +++
 grub-core/commands/efi/shim_lock.c |   1 +
 grub-core/commands/file.c          |  14 +-
 grub-core/kern/compiler-rt.c       |   6 +-
 grub-core/kern/dl.c                |   6 +-
 grub-core/kern/efi/mm.c            |   2 +-
 grub-core/kern/emu/cache.c         |   6 +
 grub-core/kern/emu/cache_s.S       |   1 +
 grub-core/kern/emu/lite.c          |   2 +
 grub-core/kern/riscv/cache.c       |  64 +++++++
 grub-core/kern/riscv/cache_flush.S |  40 +++++
 grub-core/kern/riscv/dl.c          | 335 +++++++++++++++++++++++++++++++++++
 grub-core/kern/riscv/efi/init.c    |  82 +++++++++
 grub-core/kern/riscv/efi/startup.S |  49 ++++++
 grub-core/lib/efi/halt.c           |   3 +-
 grub-core/lib/riscv/setjmp.S       |  82 +++++++++
 grub-core/lib/setjmp.S             |   2 +
 grub-core/loader/arm64/linux.c     |  10 +-
 grub-core/loader/arm64/xen_boot.c  |   6 +-
 grub-core/loader/efi/fdt.c         |   2 +-
 grub-core/loader/riscv/linux.c     | 352 +++++++++++++++++++++++++++++++++++++
 include/grub/arm/linux.h           |   2 +-
 include/grub/arm64/linux.h         |   2 +-
 include/grub/compiler-rt.h         |  12 +-
 include/grub/dl.h                  |   6 +-
 include/grub/efi/api.h             |   3 +-
 include/grub/efi/efi.h             |   6 +-
 include/grub/efi/pe32.h            |   5 +
 include/grub/elf.h                 |  59 +++++++
 include/grub/file.h                |   2 +
 include/grub/misc.h                |   3 +-
 include/grub/riscv32/efi/memory.h  |   6 +
 include/grub/riscv32/linux.h       |  41 +++++
 include/grub/riscv32/setjmp.h      |  27 +++
 include/grub/riscv32/time.h        |  28 +++
 include/grub/riscv32/types.h       |  34 ++++
 include/grub/riscv64/efi/memory.h  |   6 +
 include/grub/riscv64/linux.h       |  43 +++++
 include/grub/riscv64/setjmp.h      |  27 +++
 include/grub/riscv64/time.h        |  28 +++
 include/grub/riscv64/types.h       |  34 ++++
 include/grub/util/install.h        |   2 +
 util/grub-install-common.c         |   2 +
 util/grub-install.c                |  28 +++
 util/grub-mkimagexx.c              | 268 ++++++++++++++++++++++++++++
 util/grub-mknetdir.c               |   4 +-
 util/grub-mkrescue.c               |  16 +-
 util/grub-module-verifier.c        |  56 ++++++
 util/mkimage.c                     |  32 ++++
 52 files changed, 1889 insertions(+), 38 deletions(-)
 create mode 100644 grub-core/kern/riscv/cache.c
 create mode 100644 grub-core/kern/riscv/cache_flush.S
 create mode 100644 grub-core/kern/riscv/dl.c
 create mode 100644 grub-core/kern/riscv/efi/init.c
 create mode 100644 grub-core/kern/riscv/efi/startup.S
 create mode 100644 grub-core/lib/riscv/setjmp.S
 create mode 100644 grub-core/loader/riscv/linux.c
 create mode 100644 include/grub/riscv32/efi/memory.h
 create mode 100644 include/grub/riscv32/linux.h
 create mode 100644 include/grub/riscv32/setjmp.h
 create mode 100644 include/grub/riscv32/time.h
 create mode 100644 include/grub/riscv32/types.h
 create mode 100644 include/grub/riscv64/efi/memory.h
 create mode 100644 include/grub/riscv64/linux.h
 create mode 100644 include/grub/riscv64/setjmp.h
 create mode 100644 include/grub/riscv64/time.h
 create mode 100644 include/grub/riscv64/types.h

-- 
2.12.3



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

* [PATCH v3 01/10] efi: Rename armxx to arch
  2018-11-14 17:27 [PATCH v3 00/10] Add RISC-V support Alexander Graf
@ 2018-11-14 17:27 ` Alexander Graf
  2018-11-18 11:41   ` Bin Meng
  2018-11-14 17:27 ` [PATCH v3 02/10] PE: Add RISC-V definitions Alexander Graf
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 41+ messages in thread
From: Alexander Graf @ 2018-11-14 17:27 UTC (permalink / raw)
  To: grub-devel
  Cc: leif.lindholm, Peter Jones, Paul Walmsley, David Abdurachmanov,
	atish.patra, schwab, Michael Chang, Alistair Francis, Lukas Auer,
	greentime @ andestech . com, rickchen36 @ gmail . com, Bin Meng

Some architectures want to boot Linux as plain UEFI binary. Today that
really only encompasses ARM and AArch64, but going forward more
architectures may adopt that model.

So rename our internal API accordingly.

Signed-off-by: Alexander Graf <agraf@suse.de>
Acked-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 grub-core/loader/arm64/linux.c    | 10 +++++-----
 grub-core/loader/arm64/xen_boot.c |  6 +++---
 include/grub/arm/linux.h          |  2 +-
 include/grub/arm64/linux.h        |  2 +-
 include/grub/efi/efi.h            |  4 ++--
 5 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
index b8315b53f..d8c12dc8a 100644
--- a/grub-core/loader/arm64/linux.c
+++ b/grub-core/loader/arm64/linux.c
@@ -49,7 +49,7 @@ static grub_addr_t initrd_start;
 static grub_addr_t initrd_end;
 
 grub_err_t
-grub_armxx_efi_linux_check_image (struct linux_armxx_kernel_header * lh)
+grub_arch_efi_linux_check_image (struct linux_arch_kernel_header * lh)
 {
   if (lh->magic != GRUB_LINUX_ARMXX_MAGIC_SIGNATURE)
     return grub_error(GRUB_ERR_BAD_OS, "invalid magic number");
@@ -110,7 +110,7 @@ failure:
 }
 
 grub_err_t
-grub_armxx_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args)
+grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args)
 {
   grub_efi_memory_mapped_device_path_t *mempath;
   grub_efi_handle_t image_handle;
@@ -173,7 +173,7 @@ grub_linux_boot (void)
   if (finalize_params_linux () != GRUB_ERR_NONE)
     return grub_errno;
 
-  return (grub_armxx_efi_linux_boot_image((grub_addr_t)kernel_addr,
+  return (grub_arch_efi_linux_boot_image((grub_addr_t)kernel_addr,
                                           kernel_size, linux_args));
 }
 
@@ -287,7 +287,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
 		int argc, char *argv[])
 {
   grub_file_t file = 0;
-  struct linux_armxx_kernel_header lh;
+  struct linux_arch_kernel_header lh;
 
   grub_dl_ref (my_mod);
 
@@ -306,7 +306,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
   if (grub_file_read (file, &lh, sizeof (lh)) < (long) sizeof (lh))
     return grub_errno;
 
-  if (grub_armxx_efi_linux_check_image (&lh) != GRUB_ERR_NONE)
+  if (grub_arch_efi_linux_check_image (&lh) != GRUB_ERR_NONE)
     goto fail;
 
   grub_loader_unset();
diff --git a/grub-core/loader/arm64/xen_boot.c b/grub-core/loader/arm64/xen_boot.c
index 1003a0b99..fdf0a346a 100644
--- a/grub-core/loader/arm64/xen_boot.c
+++ b/grub-core/loader/arm64/xen_boot.c
@@ -265,7 +265,7 @@ xen_boot (void)
   if (err)
     return err;
 
-  return grub_armxx_efi_linux_boot_image (xen_hypervisor->start,
+  return grub_arch_efi_linux_boot_image (xen_hypervisor->start,
 					  xen_hypervisor->size,
 					  xen_hypervisor->cmdline);
 }
@@ -468,8 +468,8 @@ grub_cmd_xen_hypervisor (grub_command_t cmd __attribute__ ((unused)),
 
   if (grub_file_read (file, &sh, sizeof (sh)) != (long) sizeof (sh))
     goto fail;
-  if (grub_armxx_efi_linux_check_image
-      ((struct linux_armxx_kernel_header *) &sh) != GRUB_ERR_NONE)
+  if (grub_arch_efi_linux_check_image
+      ((struct linux_arch_kernel_header *) &sh) != GRUB_ERR_NONE)
     goto fail;
   grub_file_seek (file, 0);
 
diff --git a/include/grub/arm/linux.h b/include/grub/arm/linux.h
index 712ba17b9..995800126 100644
--- a/include/grub/arm/linux.h
+++ b/include/grub/arm/linux.h
@@ -36,7 +36,7 @@ struct linux_arm_kernel_header {
 
 #if defined(__arm__)
 # define GRUB_LINUX_ARMXX_MAGIC_SIGNATURE GRUB_LINUX_ARM_MAGIC_SIGNATURE
-# define linux_armxx_kernel_header linux_arm_kernel_header
+# define linux_arch_kernel_header linux_arm_kernel_header
 #endif
 
 #if defined GRUB_MACHINE_UBOOT
diff --git a/include/grub/arm64/linux.h b/include/grub/arm64/linux.h
index 8655067e0..4269adc6d 100644
--- a/include/grub/arm64/linux.h
+++ b/include/grub/arm64/linux.h
@@ -38,7 +38,7 @@ struct linux_arm64_kernel_header
 
 #if defined(__aarch64__)
 # define GRUB_LINUX_ARMXX_MAGIC_SIGNATURE GRUB_LINUX_ARM64_MAGIC_SIGNATURE
-# define linux_armxx_kernel_header linux_arm64_kernel_header
+# define linux_arch_kernel_header linux_arm64_kernel_header
 #endif
 
 #endif /* ! GRUB_ARM64_LINUX_HEADER */
diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
index 2c6648d46..ec44aef7e 100644
--- a/include/grub/efi/efi.h
+++ b/include/grub/efi/efi.h
@@ -94,8 +94,8 @@ extern void (*EXPORT_VAR(grub_efi_net_config)) (grub_efi_handle_t hnd,
 void *EXPORT_FUNC(grub_efi_get_firmware_fdt)(void);
 grub_err_t EXPORT_FUNC(grub_efi_get_ram_base)(grub_addr_t *);
 #include <grub/cpu/linux.h>
-grub_err_t grub_armxx_efi_linux_check_image(struct linux_armxx_kernel_header *lh);
-grub_err_t grub_armxx_efi_linux_boot_image(grub_addr_t addr, grub_size_t size,
+grub_err_t grub_arch_efi_linux_check_image(struct linux_arch_kernel_header *lh);
+grub_err_t grub_arch_efi_linux_boot_image(grub_addr_t addr, grub_size_t size,
                                            char *args);
 #endif
 
-- 
2.12.3



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

* [PATCH v3 02/10] PE: Add RISC-V definitions
  2018-11-14 17:27 [PATCH v3 00/10] Add RISC-V support Alexander Graf
  2018-11-14 17:27 ` [PATCH v3 01/10] efi: Rename armxx to arch Alexander Graf
@ 2018-11-14 17:27 ` Alexander Graf
  2018-11-18 11:41   ` Bin Meng
  2018-11-14 17:27 ` [PATCH v3 03/10] elf.h: " Alexander Graf
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 41+ messages in thread
From: Alexander Graf @ 2018-11-14 17:27 UTC (permalink / raw)
  To: grub-devel
  Cc: leif.lindholm, Peter Jones, Paul Walmsley, David Abdurachmanov,
	atish.patra, schwab, Michael Chang, Alistair Francis, Lukas Auer,
	greentime @ andestech . com, rickchen36 @ gmail . com, Bin Meng

The PE format defines magic numbers as well as relocation identifiers for
RISC-V. Add them to our include file, so we can make use of them.

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 include/grub/efi/pe32.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h
index 7d44732d2..d1359eb66 100644
--- a/include/grub/efi/pe32.h
+++ b/include/grub/efi/pe32.h
@@ -70,6 +70,8 @@ struct grub_pe32_coff_header
 #define GRUB_PE32_MACHINE_X86_64		0x8664
 #define GRUB_PE32_MACHINE_ARMTHUMB_MIXED	0x01c2
 #define GRUB_PE32_MACHINE_ARM64			0xAA64
+#define GRUB_PE32_MACHINE_RISCV32		0x5032
+#define GRUB_PE32_MACHINE_RISCV64		0x5064
 
 #define GRUB_PE32_RELOCS_STRIPPED		0x0001
 #define GRUB_PE32_EXECUTABLE_IMAGE		0x0002
@@ -281,9 +283,12 @@ struct grub_pe32_fixup_block
 #define GRUB_PE32_REL_BASED_HIGHADJ	4
 #define GRUB_PE32_REL_BASED_MIPS_JMPADDR 5
 #define GRUB_PE32_REL_BASED_ARM_MOV32A  5
+#define GRUB_PE32_REL_BASED_RISCV_HI20	5
 #define GRUB_PE32_REL_BASED_SECTION	6
 #define GRUB_PE32_REL_BASED_REL		7
 #define GRUB_PE32_REL_BASED_ARM_MOV32T  7
+#define GRUB_PE32_REL_BASED_RISCV_LOW12I 7
+#define GRUB_PE32_REL_BASED_RISCV_LOW12S 8
 #define GRUB_PE32_REL_BASED_IA64_IMM64	9
 #define GRUB_PE32_REL_BASED_DIR64	10
 #define GRUB_PE32_REL_BASED_HIGH3ADJ	11
-- 
2.12.3



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

* [PATCH v3 03/10] elf.h: Add RISC-V definitions
  2018-11-14 17:27 [PATCH v3 00/10] Add RISC-V support Alexander Graf
  2018-11-14 17:27 ` [PATCH v3 01/10] efi: Rename armxx to arch Alexander Graf
  2018-11-14 17:27 ` [PATCH v3 02/10] PE: Add RISC-V definitions Alexander Graf
@ 2018-11-14 17:27 ` Alexander Graf
  2018-11-18 11:41   ` Bin Meng
  2018-11-14 17:27 ` [PATCH v3 04/10] RISC-V: Add setjmp implementation Alexander Graf
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 41+ messages in thread
From: Alexander Graf @ 2018-11-14 17:27 UTC (permalink / raw)
  To: grub-devel
  Cc: leif.lindholm, Peter Jones, Paul Walmsley, David Abdurachmanov,
	atish.patra, schwab, Michael Chang, Alistair Francis, Lukas Auer,
	greentime @ andestech . com, rickchen36 @ gmail . com, Bin Meng

The RISC-V ABI document outlines ELF header structure and relocation
information. Pull the respective magic numbers into our elf header
so we can make use of them.

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 include/grub/elf.h | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/include/grub/elf.h b/include/grub/elf.h
index c8492f9dc..76c6a5a02 100644
--- a/include/grub/elf.h
+++ b/include/grub/elf.h
@@ -247,6 +247,7 @@ typedef struct
 #define EM_XTENSA	94		/* Tensilica Xtensa Architecture */
 #define EM_NUM		95
 #define EM_AARCH64	183		/* ARM 64-bit architecture */
+#define EM_RISCV	243		/* RISC-V */
 
 /* If it is necessary to assign new unofficial EM_* values, please
    pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
@@ -2473,6 +2474,64 @@ typedef Elf32_Addr Elf32_Conflict;
 
 #define R_X86_64_NUM		24
 
+/* RISC-V relocations */
+#define R_RISCV_NONE            0
+#define R_RISCV_32              1
+#define R_RISCV_64              2
+#define R_RISCV_RELATIVE        3
+#define R_RISCV_COPY            4
+#define R_RISCV_JUMP_SLOT       5
+#define R_RISCV_TLS_DTPMOD32    6
+#define R_RISCV_TLS_DTPMOD64    7
+#define R_RISCV_TLS_DTPREL32    8
+#define R_RISCV_TLS_DTPREL64    9
+#define R_RISCV_TLS_TPREL32     10
+#define R_RISCV_TLS_TPREL64     11
+
+#define R_RISCV_BRANCH          16
+#define R_RISCV_JAL             17
+#define R_RISCV_CALL            18
+#define R_RISCV_CALL_PLT        19
+#define R_RISCV_GOT_HI20        20
+#define R_RISCV_TLS_GOT_HI20    21
+#define R_RISCV_TLS_GD_HI20     22
+#define R_RISCV_PCREL_HI20      23
+#define R_RISCV_PCREL_LO12_I    24
+#define R_RISCV_PCREL_LO12_S    25
+#define R_RISCV_HI20            26
+#define R_RISCV_LO12_I          27
+#define R_RISCV_LO12_S          28
+#define R_RISCV_TPREL_HI20      29
+#define R_RISCV_TPREL_LO12_I    30
+#define R_RISCV_TPREL_LO12_S    31
+#define R_RISCV_TPREL_ADD       32
+#define R_RISCV_ADD8            33
+#define R_RISCV_ADD16           34
+#define R_RISCV_ADD32           35
+#define R_RISCV_ADD64           36
+#define R_RISCV_SUB8            37
+#define R_RISCV_SUB16           38
+#define R_RISCV_SUB32           39
+#define R_RISCV_SUB64           40
+#define R_RISCV_GNU_VTINHERIT   41
+#define R_RISCV_GNU_VTENTRY     42
+#define R_RISCV_ALIGN           43
+#define R_RISCV_RVC_BRANCH      44
+#define R_RISCV_RVC_JUMP        45
+#define R_RISCV_LUI             46
+#define R_RISCV_GPREL_I         47
+#define R_RISCV_GPREL_S         48
+#define R_RISCV_TPREL_I         49
+#define R_RISCV_TPREL_S         50
+#define R_RISCV_RELAX           51
+#define R_RISCV_SUB6            52
+#define R_RISCV_SET6            53
+#define R_RISCV_SET8            54
+#define R_RISCV_SET16           55
+#define R_RISCV_SET32           56
+#define R_RISCV_32_PCREL        57
+
+
 #ifdef GRUB_TARGET_WORDSIZE
 #if GRUB_TARGET_WORDSIZE == 32
 
-- 
2.12.3



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

* [PATCH v3 04/10] RISC-V: Add setjmp implementation
  2018-11-14 17:27 [PATCH v3 00/10] Add RISC-V support Alexander Graf
                   ` (2 preceding siblings ...)
  2018-11-14 17:27 ` [PATCH v3 03/10] elf.h: " Alexander Graf
@ 2018-11-14 17:27 ` Alexander Graf
  2018-11-18 11:41   ` Bin Meng
  2018-11-21 15:31   ` Daniel Kiper
  2018-11-14 17:27 ` [PATCH v3 05/10] RISC-V: Add early startup code Alexander Graf
                   ` (5 subsequent siblings)
  9 siblings, 2 replies; 41+ messages in thread
From: Alexander Graf @ 2018-11-14 17:27 UTC (permalink / raw)
  To: grub-devel
  Cc: leif.lindholm, Peter Jones, Paul Walmsley, David Abdurachmanov,
	atish.patra, schwab, Michael Chang, Alistair Francis, Lukas Auer,
	greentime @ andestech . com, rickchen36 @ gmail . com, Bin Meng

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>
---
 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 */
-- 
2.12.3



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

* [PATCH v3 05/10] RISC-V: Add early startup code
  2018-11-14 17:27 [PATCH v3 00/10] Add RISC-V support Alexander Graf
                   ` (3 preceding siblings ...)
  2018-11-14 17:27 ` [PATCH v3 04/10] RISC-V: Add setjmp implementation Alexander Graf
@ 2018-11-14 17:27 ` Alexander Graf
  2018-11-18 11:41   ` Bin Meng
  2018-11-14 17:27 ` [PATCH v3 06/10] RISC-V: Add Linux load logic Alexander Graf
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 41+ messages in thread
From: Alexander Graf @ 2018-11-14 17:27 UTC (permalink / raw)
  To: grub-devel
  Cc: leif.lindholm, Peter Jones, Paul Walmsley, David Abdurachmanov,
	atish.patra, schwab, Michael Chang, Alistair Francis, Lukas Auer,
	greentime @ andestech . com, rickchen36 @ gmail . com, Bin Meng

On entry, we need to save the system table pointer as well as our image
handle. Add an early startup file that saves them and then brings us
into our main function.

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 grub-core/kern/riscv/efi/startup.S | 49 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)
 create mode 100644 grub-core/kern/riscv/efi/startup.S

diff --git a/grub-core/kern/riscv/efi/startup.S b/grub-core/kern/riscv/efi/startup.S
new file mode 100644
index 000000000..026f99bab
--- /dev/null
+++ b/grub-core/kern/riscv/efi/startup.S
@@ -0,0 +1,49 @@
+/*
+ *  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>
+
+#if __riscv_xlen == 64
+#define sl		sd
+#define ll		ld
+#else
+#define sl		sw
+#define ll		lw
+#endif
+
+
+	.file 	"startup.S"
+	.text
+FUNCTION(_start)
+	/*
+	 *  EFI_SYSTEM_TABLE and EFI_HANDLE are passed in a1/a0.
+	 */
+
+	ll	a2, efi_image_handle_val
+	sl	a0, 0(a2)
+	ll	a2, efi_system_table_val
+	sl	a1, 0(a2)
+	ll	a2, grub_main_val
+	jr	a2
+grub_main_val:
+	.quad	EXT_C(grub_main)
+efi_system_table_val:
+	.quad	EXT_C(grub_efi_system_table)
+efi_image_handle_val:
+	.quad	EXT_C(grub_efi_image_handle)
+
-- 
2.12.3



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

* [PATCH v3 06/10] RISC-V: Add Linux load logic
  2018-11-14 17:27 [PATCH v3 00/10] Add RISC-V support Alexander Graf
                   ` (4 preceding siblings ...)
  2018-11-14 17:27 ` [PATCH v3 05/10] RISC-V: Add early startup code Alexander Graf
@ 2018-11-14 17:27 ` Alexander Graf
  2018-11-16 22:18   ` Alistair Francis
  2018-11-21 15:43   ` Daniel Kiper
  2018-11-14 17:27 ` [PATCH v3 07/10] RISC-V: Add awareness for RISC-V reloations Alexander Graf
                   ` (3 subsequent siblings)
  9 siblings, 2 replies; 41+ messages in thread
From: Alexander Graf @ 2018-11-14 17:27 UTC (permalink / raw)
  To: grub-devel
  Cc: leif.lindholm, Peter Jones, Paul Walmsley, David Abdurachmanov,
	atish.patra, schwab, Michael Chang, Alistair Francis, Lukas Auer,
	greentime @ andestech . com, rickchen36 @ gmail . com, Bin Meng

We currently only support to run grub on RISC-V as UEFI payload. Ideally,
we also only want to support running Linux underneath as UEFI payload.

Prepare that with a Linux boot case that is not enabled in Linux yet. At
least it will give people something to test against when they enable the
Linux UEFI port.

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

---

v1 -> v2:

  - adapt to new grub_open_file() API
  - adapt to new grub_create_loader_cmdline() API
---
 grub-core/loader/riscv/linux.c | 352 +++++++++++++++++++++++++++++++++++++++++
 include/grub/riscv32/linux.h   |  41 +++++
 include/grub/riscv64/linux.h   |  43 +++++
 3 files changed, 436 insertions(+)
 create mode 100644 grub-core/loader/riscv/linux.c
 create mode 100644 include/grub/riscv32/linux.h
 create mode 100644 include/grub/riscv64/linux.h

diff --git a/grub-core/loader/riscv/linux.c b/grub-core/loader/riscv/linux.c
new file mode 100644
index 000000000..2527bb7fc
--- /dev/null
+++ b/grub-core/loader/riscv/linux.c
@@ -0,0 +1,352 @@
+/*
+ *  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/charset.h>
+#include <grub/command.h>
+#include <grub/err.h>
+#include <grub/file.h>
+#include <grub/fdt.h>
+#include <grub/linux.h>
+#include <grub/loader.h>
+#include <grub/mm.h>
+#include <grub/types.h>
+#include <grub/cpu/linux.h>
+#include <grub/efi/efi.h>
+#include <grub/efi/fdtload.h>
+#include <grub/efi/memory.h>
+#include <grub/efi/pe32.h>
+#include <grub/i18n.h>
+#include <grub/lib/cmdline.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+static grub_dl_t my_mod;
+static int loaded;
+
+static void *kernel_addr;
+static grub_uint64_t kernel_size;
+
+static char *linux_args;
+static grub_uint32_t cmdline_size;
+
+static grub_addr_t initrd_start;
+static grub_addr_t initrd_end;
+
+grub_err_t
+grub_arch_efi_linux_check_image (struct linux_riscv_kernel_header * lh)
+{
+  if (lh->magic != GRUB_LINUX_RISCV_MAGIC_SIGNATURE)
+    return grub_error(GRUB_ERR_BAD_OS, "invalid magic number");
+
+  if ((lh->code0 & 0xffff) != GRUB_PE32_MAGIC)
+    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+		       N_("plain image kernel not supported - rebuild with CONFIG_(U)EFI_STUB enabled"));
+
+  grub_dprintf ("linux", "UEFI stub kernel:\n");
+  grub_dprintf ("linux", "PE/COFF header @ %08x\n", lh->hdr_offset);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+finalize_params_linux (void)
+{
+  int node, retval;
+
+  void *fdt;
+
+  fdt = grub_fdt_load (0x400);
+
+  if (!fdt)
+    goto failure;
+
+  node = grub_fdt_find_subnode (fdt, 0, "chosen");
+  if (node < 0)
+    node = grub_fdt_add_subnode (fdt, 0, "chosen");
+
+  if (node < 1)
+    goto failure;
+
+  /* Set initrd info */
+  if (initrd_start && initrd_end > initrd_start)
+    {
+      grub_dprintf ("linux", "Initrd @ %p-%p\n",
+		    (void *) initrd_start, (void *) initrd_end);
+
+      retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-start",
+				    initrd_start);
+      if (retval)
+	goto failure;
+      retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-end",
+				    initrd_end);
+      if (retval)
+	goto failure;
+    }
+
+  if (grub_fdt_install() != GRUB_ERR_NONE)
+    goto failure;
+
+  return GRUB_ERR_NONE;
+
+failure:
+  grub_fdt_unload();
+  return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT");
+}
+
+grub_err_t
+grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args)
+{
+  grub_efi_memory_mapped_device_path_t *mempath;
+  grub_efi_handle_t image_handle;
+  grub_efi_boot_services_t *b;
+  grub_efi_status_t status;
+  grub_efi_loaded_image_t *loaded_image;
+  int len;
+
+  mempath = grub_malloc (2 * sizeof (grub_efi_memory_mapped_device_path_t));
+  if (!mempath)
+    return grub_errno;
+
+  mempath[0].header.type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE;
+  mempath[0].header.subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE;
+  mempath[0].header.length = grub_cpu_to_le16_compile_time (sizeof (*mempath));
+  mempath[0].memory_type = GRUB_EFI_LOADER_DATA;
+  mempath[0].start_address = addr;
+  mempath[0].end_address = addr + size;
+
+  mempath[1].header.type = GRUB_EFI_END_DEVICE_PATH_TYPE;
+  mempath[1].header.subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
+  mempath[1].header.length = sizeof (grub_efi_device_path_t);
+
+  b = grub_efi_system_table->boot_services;
+  status = b->load_image (0, grub_efi_image_handle,
+			  (grub_efi_device_path_t *) mempath,
+			  (void *) addr, size, &image_handle);
+  if (status != GRUB_EFI_SUCCESS)
+    return grub_error (GRUB_ERR_BAD_OS, "cannot load image");
+
+  grub_dprintf ("linux", "linux command line: '%s'\n", args);
+
+  /* Convert command line to UCS-2 */
+  loaded_image = grub_efi_get_loaded_image (image_handle);
+  loaded_image->load_options_size = len =
+    (grub_strlen (args) + 1) * sizeof (grub_efi_char16_t);
+  loaded_image->load_options =
+    grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size));
+  if (!loaded_image->load_options)
+    return grub_errno;
+
+  loaded_image->load_options_size =
+    2 * grub_utf8_to_utf16 (loaded_image->load_options, len,
+			    (grub_uint8_t *) args, len, NULL);
+
+  grub_dprintf ("linux", "starting image %p\n", image_handle);
+  status = b->start_image (image_handle, 0, NULL);
+
+  /* When successful, not reached */
+  b->unload_image (image_handle);
+  grub_efi_free_pages ((grub_addr_t) loaded_image->load_options,
+		       GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size));
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_linux_boot (void)
+{
+  if (finalize_params_linux () != GRUB_ERR_NONE)
+    return grub_errno;
+
+  return (grub_arch_efi_linux_boot_image((grub_addr_t)kernel_addr,
+                                         kernel_size, linux_args));
+}
+
+static grub_err_t
+grub_linux_unload (void)
+{
+  grub_dl_unref (my_mod);
+  loaded = 0;
+  if (initrd_start)
+    grub_efi_free_pages ((grub_efi_physical_address_t) initrd_start,
+			 GRUB_EFI_BYTES_TO_PAGES (initrd_end - initrd_start));
+  initrd_start = initrd_end = 0;
+  grub_free (linux_args);
+  if (kernel_addr)
+    grub_efi_free_pages ((grub_addr_t) kernel_addr,
+			 GRUB_EFI_BYTES_TO_PAGES (kernel_size));
+  grub_fdt_unload ();
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+		 int argc, char *argv[])
+{
+  struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 };
+  int initrd_size, initrd_pages;
+  void *initrd_mem = NULL;
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
+      goto fail;
+    }
+
+  if (!loaded)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT,
+		  N_("you need to load the kernel first"));
+      goto fail;
+    }
+
+  if (grub_initrd_init (argc, argv, &initrd_ctx))
+    goto fail;
+
+  initrd_size = grub_get_initrd_size (&initrd_ctx);
+  grub_dprintf ("linux", "Loading initrd\n");
+
+  initrd_pages = (GRUB_EFI_BYTES_TO_PAGES (initrd_size));
+  initrd_mem = grub_efi_allocate_any_pages (initrd_pages);
+  if (!initrd_mem)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
+      goto fail;
+    }
+
+  if (grub_initrd_load (&initrd_ctx, argv, initrd_mem))
+    goto fail;
+
+  initrd_start = (grub_addr_t) initrd_mem;
+  initrd_end = initrd_start + initrd_size;
+  grub_dprintf ("linux", "[addr=%p, size=0x%x]\n",
+		(void *) initrd_start, initrd_size);
+
+ fail:
+  grub_initrd_close (&initrd_ctx);
+  if (initrd_mem && !initrd_start)
+    grub_efi_free_pages ((grub_addr_t) initrd_mem, initrd_pages);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+		int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  struct linux_riscv_kernel_header lh;
+
+  grub_dl_ref (my_mod);
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
+      goto fail;
+    }
+
+  file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL);
+  if (!file)
+    goto fail;
+
+  kernel_size = grub_file_size (file);
+
+  if (grub_file_read (file, &lh, sizeof (lh)) < (long) sizeof (lh))
+    return grub_errno;
+
+  if (grub_arch_efi_linux_check_image (&lh) != GRUB_ERR_NONE)
+    goto fail;
+
+  grub_loader_unset();
+
+  grub_dprintf ("linux", "kernel file size: %lld\n", (long long) kernel_size);
+  kernel_addr = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (kernel_size));
+  grub_dprintf ("linux", "kernel numpages: %lld\n",
+		(long long) GRUB_EFI_BYTES_TO_PAGES (kernel_size));
+  if (!kernel_addr)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
+      goto fail;
+    }
+
+  grub_file_seek (file, 0);
+  if (grub_file_read (file, kernel_addr, kernel_size)
+      < (grub_int64_t) kernel_size)
+    {
+      if (!grub_errno)
+	grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), argv[0]);
+      goto fail;
+    }
+
+  grub_dprintf ("linux", "kernel @ %p\n", kernel_addr);
+
+  cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE);
+  linux_args = grub_malloc (cmdline_size);
+  if (!linux_args)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
+      goto fail;
+    }
+  grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE));
+  grub_create_loader_cmdline (argc, argv,
+			      linux_args + sizeof (LINUX_IMAGE) - 1,
+			      cmdline_size,
+			      GRUB_VERIFY_KERNEL_CMDLINE);
+
+  if (grub_errno == GRUB_ERR_NONE)
+    {
+      grub_loader_set (grub_linux_boot, grub_linux_unload, 0);
+      loaded = 1;
+    }
+
+fail:
+  if (file)
+    grub_file_close (file);
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_dl_unref (my_mod);
+      loaded = 0;
+    }
+
+  if (linux_args && !loaded)
+    grub_free (linux_args);
+
+  if (kernel_addr && !loaded)
+    grub_efi_free_pages ((grub_addr_t) kernel_addr,
+			 GRUB_EFI_BYTES_TO_PAGES (kernel_size));
+
+  return grub_errno;
+}
+
+
+static grub_command_t cmd_linux, cmd_initrd;
+
+GRUB_MOD_INIT (linux)
+{
+  cmd_linux = grub_register_command ("linux", grub_cmd_linux, 0,
+				     N_("Load Linux."));
+  cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, 0,
+				      N_("Load initrd."));
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI (linux)
+{
+  grub_unregister_command (cmd_linux);
+  grub_unregister_command (cmd_initrd);
+}
diff --git a/include/grub/riscv32/linux.h b/include/grub/riscv32/linux.h
new file mode 100644
index 000000000..5c70d00b4
--- /dev/null
+++ b/include/grub/riscv32/linux.h
@@ -0,0 +1,41 @@
+/*
+ *  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_RISCV32_LINUX_HEADER
+#define GRUB_RISCV32_LINUX_HEADER 1
+
+#define GRUB_LINUX_RISCV_MAGIC_SIGNATURE 0x52534356 /* 'RSCV' */
+
+/* From linux/Documentation/riscv/booting.txt */
+struct linux_riscv_kernel_header
+{
+  grub_uint32_t code0;		/* Executable code */
+  grub_uint32_t code1;		/* Executable code */
+  grub_uint64_t text_offset;    /* Image load offset */
+  grub_uint64_t res0;		/* reserved */
+  grub_uint64_t res1;		/* reserved */
+  grub_uint64_t res2;		/* reserved */
+  grub_uint64_t res3;		/* reserved */
+  grub_uint64_t res4;		/* reserved */
+  grub_uint32_t magic;		/* Magic number, little endian, "RSCV" */
+  grub_uint32_t hdr_offset;	/* Offset of PE/COFF header */
+};
+
+# define linux_arch_kernel_header linux_riscv_kernel_header
+
+#endif /* ! GRUB_RISCV32_LINUX_HEADER */
diff --git a/include/grub/riscv64/linux.h b/include/grub/riscv64/linux.h
new file mode 100644
index 000000000..aa6b8687e
--- /dev/null
+++ b/include/grub/riscv64/linux.h
@@ -0,0 +1,43 @@
+/*
+ *  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_RISCV64_LINUX_HEADER
+#define GRUB_RISCV64_LINUX_HEADER 1
+
+#define GRUB_LINUX_RISCV_MAGIC_SIGNATURE 0x52534356 /* 'RSCV' */
+
+#define GRUB_EFI_PE_MAGIC	0x5A4D
+
+/* From linux/Documentation/riscv/booting.txt */
+struct linux_riscv_kernel_header
+{
+  grub_uint32_t code0;		/* Executable code */
+  grub_uint32_t code1;		/* Executable code */
+  grub_uint64_t text_offset;    /* Image load offset */
+  grub_uint64_t res0;		/* reserved */
+  grub_uint64_t res1;		/* reserved */
+  grub_uint64_t res2;		/* reserved */
+  grub_uint64_t res3;		/* reserved */
+  grub_uint64_t res4;		/* reserved */
+  grub_uint32_t magic;		/* Magic number, little endian, "RSCV" */
+  grub_uint32_t hdr_offset;	/* Offset of PE/COFF header */
+};
+
+# define linux_arch_kernel_header linux_riscv_kernel_header
+
+#endif /* ! GRUB_RISCV64_LINUX_HEADER */
-- 
2.12.3



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

* [PATCH v3 07/10] RISC-V: Add awareness for RISC-V reloations
  2018-11-14 17:27 [PATCH v3 00/10] Add RISC-V support Alexander Graf
                   ` (5 preceding siblings ...)
  2018-11-14 17:27 ` [PATCH v3 06/10] RISC-V: Add Linux load logic Alexander Graf
@ 2018-11-14 17:27 ` Alexander Graf
  2018-11-21 15:51   ` Daniel Kiper
  2018-11-14 17:27 ` [PATCH v3 08/10] RISC-V: Add auxiliary files Alexander Graf
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 41+ messages in thread
From: Alexander Graf @ 2018-11-14 17:27 UTC (permalink / raw)
  To: grub-devel
  Cc: leif.lindholm, Peter Jones, Paul Walmsley, David Abdurachmanov,
	atish.patra, schwab, Michael Chang, Alistair Francis, Lukas Auer,
	greentime @ andestech . com, rickchen36 @ gmail . com, Bin Meng

This patch adds awareness of RISC-V relocations throughout the grub tools
as well as dynamic linkage and elf->PE relocation conversion support.

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

---

v2 -> v3:

  - Fix riscv32 target
---
 grub-core/kern/dl.c         |   6 +-
 grub-core/kern/riscv/dl.c   | 335 ++++++++++++++++++++++++++++++++++++++++++++
 include/grub/dl.h           |   6 +-
 util/grub-mkimagexx.c       | 268 +++++++++++++++++++++++++++++++++++
 util/grub-module-verifier.c |  56 ++++++++
 5 files changed, 666 insertions(+), 5 deletions(-)
 create mode 100644 grub-core/kern/riscv/dl.c

diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
index f8d58f029..48eb5e7b6 100644
--- a/grub-core/kern/dl.c
+++ b/grub-core/kern/dl.c
@@ -225,7 +225,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
   unsigned i;
   const Elf_Shdr *s;
   grub_size_t tsize = 0, talign = 1;
-#if !defined (__i386__) && !defined (__x86_64__)
+#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv)
   grub_size_t tramp;
   grub_size_t got;
   grub_err_t err;
@@ -241,7 +241,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
 	talign = s->sh_addralign;
     }
 
-#if !defined (__i386__) && !defined (__x86_64__)
+#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv)
   err = grub_arch_dl_get_tramp_got_size (e, &tramp, &got);
   if (err)
     return err;
@@ -304,7 +304,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
 	  mod->segment = seg;
 	}
     }
-#if !defined (__i386__) && !defined (__x86_64__)
+#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv)
   ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_TRAMP_ALIGN);
   mod->tramp = ptr;
   mod->trampptr = ptr;
diff --git a/grub-core/kern/riscv/dl.c b/grub-core/kern/riscv/dl.c
new file mode 100644
index 000000000..503b67df1
--- /dev/null
+++ b/grub-core/kern/riscv/dl.c
@@ -0,0 +1,335 @@
+/* dl.c - arch-dependent part of loadable module support */
+/*
+ *  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/dl.h>
+#include <grub/elf.h>
+#include <grub/misc.h>
+#include <grub/err.h>
+#include <grub/mm.h>
+#include <grub/i18n.h>
+
+#define LDR 0x58000050
+#define BR 0xd61f0200
+
+
+/*
+ * Check if EHDR is a valid ELF header.
+ */
+grub_err_t
+grub_arch_dl_check_header (void *ehdr)
+{
+  Elf_Ehdr *e = ehdr;
+
+  /* Check the magic numbers.  */
+  if (e->e_ident[EI_DATA] != ELFDATA2LSB || e->e_machine != EM_RISCV)
+    return grub_error (GRUB_ERR_BAD_OS,
+		       N_("invalid arch-dependent ELF magic"));
+
+  return GRUB_ERR_NONE;
+}
+
+#pragma GCC diagnostic ignored "-Wcast-align"
+
+/* Relocate symbols. */
+grub_err_t
+grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
+			       Elf_Shdr *s, grub_dl_segment_t seg)
+{
+  Elf_Rel *rel, *max;
+
+  for (rel = (Elf_Rel *) ((char *) ehdr + s->sh_offset),
+	 max = (Elf_Rel *) ((char *) rel + s->sh_size);
+       rel < max;
+       rel = (Elf_Rel *) ((char *) rel + s->sh_entsize))
+    {
+      Elf_Sym *sym;
+      void *place;
+      grub_size_t sym_addr;
+
+      if (rel->r_offset >= seg->size)
+	return grub_error (GRUB_ERR_BAD_MODULE,
+			   "reloc offset is out of the segment");
+
+      sym = (Elf_Sym *) ((char *) mod->symtab
+			 + mod->symsize * ELF_R_SYM (rel->r_info));
+
+      sym_addr = sym->st_value;
+      if (s->sh_type == SHT_RELA)
+	sym_addr += ((Elf_Rela *) rel)->r_addend;
+
+      place = (void *) ((grub_addr_t) seg->addr + rel->r_offset);
+
+      switch (ELF_R_TYPE (rel->r_info))
+	{
+	case R_RISCV_32:
+	  {
+	    grub_uint32_t *abs_place = place;
+
+	    grub_dprintf ("dl", "  reloc_abs32 %p => 0x%016llx\n",
+			  place, (unsigned long long) sym_addr);
+
+	    *abs_place = (grub_uint32_t) sym_addr;
+	  }
+	  break;
+	case R_RISCV_64:
+	  {
+	    grub_size_t *abs_place = place;
+
+	    grub_dprintf ("dl", "  reloc_abs64 %p => 0x%016llx\n",
+			  place, (unsigned long long) sym_addr);
+
+	    *abs_place = (grub_size_t) sym_addr;
+	  }
+	  break;
+
+	case R_RISCV_ADD8:
+	  {
+	    grub_uint8_t *abs_place = place;
+
+	    *abs_place += (grub_uint8_t) sym_addr;
+	  }
+	  break;
+	case R_RISCV_ADD16:
+	  {
+	    grub_uint16_t *abs_place = place;
+
+	    *abs_place += (grub_uint16_t) sym_addr;
+	  }
+	  break;
+	case R_RISCV_ADD32:
+	  {
+	    grub_uint32_t *abs_place = place;
+
+	    *abs_place += (grub_uint32_t) sym_addr;
+	  }
+	  break;
+	case R_RISCV_ADD64:
+	  {
+	    grub_size_t *abs_place = place;
+
+	    *abs_place += (grub_size_t) sym_addr;
+	  }
+	  break;
+
+	case R_RISCV_SUB8:
+	  {
+	    grub_uint8_t *abs_place = place;
+
+	    *abs_place -= (grub_uint8_t) sym_addr;
+	  }
+	  break;
+	case R_RISCV_SUB16:
+	  {
+	    grub_uint16_t *abs_place = place;
+
+	    *abs_place -= (grub_uint16_t) sym_addr;
+	  }
+	  break;
+	case R_RISCV_SUB32:
+	  {
+	    grub_uint32_t *abs_place = place;
+
+	    *abs_place -= (grub_uint32_t) sym_addr;
+	  }
+	  break;
+	case R_RISCV_SUB64:
+	  {
+	    grub_size_t *abs_place = place;
+
+	    *abs_place -= (grub_size_t) sym_addr;
+	  }
+	  break;
+
+	case R_RISCV_BRANCH:
+	  {
+	    grub_uint32_t *abs_place = place;
+	    grub_ssize_t off = sym_addr - (grub_addr_t) place;
+	    grub_uint32_t imm12 = (off & 0x1000) << (31 - 12);
+	    grub_uint32_t imm11 = (off & 0x800) >> (11 - 7);
+	    grub_uint32_t imm10_5 = (off & 0x7e0) << (30 - 10);
+	    grub_uint32_t imm4_1 = (off & 0x1e) << (11 - 4);
+	    *abs_place = (*abs_place & 0x1fff07f)
+			 | imm12 | imm11 | imm10_5 | imm4_1;
+	  }
+	  break;
+
+	case R_RISCV_JAL:
+	  {
+	    grub_uint32_t *abs_place = place;
+	    grub_ssize_t off = sym_addr - (grub_addr_t) place;
+	    grub_uint32_t imm20 = (off & 0x100000) << (31 - 20);
+	    grub_uint32_t imm19_12 = (off & 0xff000);
+	    grub_uint32_t imm11 = (off & 0x800) << (20 - 11);
+	    grub_uint32_t imm10_1 = (off & 0x7fe) << (30 - 10);
+	    *abs_place = (*abs_place & 0xfff)
+			 | imm20 | imm19_12 | imm11 | imm10_1;
+	  }
+	  break;
+
+	case R_RISCV_CALL:
+	  {
+	    grub_uint32_t *abs_place = place;
+	    grub_ssize_t off = sym_addr - (grub_addr_t) place;
+	    grub_uint32_t hi20, lo12;
+
+	    if (off != (grub_int32_t) off)
+	      return grub_error (GRUB_ERR_BAD_MODULE, "relocation overflow");
+
+	    hi20 = (off + 0x800) & 0xfffff000;
+	    lo12 = (off - hi20) & 0xfff;
+	    abs_place[0] = (abs_place[0] & 0xfff) | hi20;
+	    abs_place[1] = (abs_place[1] & 0xfffff) | (lo12 << 20);
+	  }
+	  break;
+
+	case R_RISCV_RVC_BRANCH:
+	  {
+	    grub_uint16_t *abs_place = place;
+	    grub_ssize_t off = sym_addr - (grub_addr_t) place;
+	    grub_uint16_t imm8 = (off & 0x100) << (12 - 8);
+	    grub_uint16_t imm7_6 = (off & 0xc0) >> (6 - 5);
+	    grub_uint16_t imm5 = (off & 0x20) >> (5 - 2);
+	    grub_uint16_t imm4_3 = (off & 0x18) << (12 - 5);
+	    grub_uint16_t imm2_1 = (off & 0x6) << (12 - 10);
+	    *abs_place = (*abs_place & 0xe383)
+			 | imm8 | imm7_6 | imm5 | imm4_3 | imm2_1;
+	  }
+	  break;
+
+	case R_RISCV_RVC_JUMP:
+	  {
+	    grub_uint16_t *abs_place = place;
+	    grub_ssize_t off = sym_addr - (grub_addr_t) place;
+	    grub_uint16_t imm11 = (off & 0x800) << (12 - 11);
+	    grub_uint16_t imm10 = (off & 0x400) >> (10 - 8);
+	    grub_uint16_t imm9_8 = (off & 0x300) << (12 - 11);
+	    grub_uint16_t imm7 = (off & 0x80) >> (7 - 6);
+	    grub_uint16_t imm6 = (off & 0x40) << (12 - 11);
+	    grub_uint16_t imm5 = (off & 0x20) >> (5 - 2);
+	    grub_uint16_t imm4 = (off & 0x10) << (12 - 5);
+	    grub_uint16_t imm3_1 = (off & 0xe) << (12 - 10);
+	    *abs_place = ((*abs_place & 0xe003)
+			  | imm11 | imm10 | imm9_8 | imm7 | imm6
+			  | imm5 | imm4 | imm3_1);
+	  }
+	  break;
+
+	case R_RISCV_PCREL_HI20:
+	  {
+	    grub_uint32_t *abs_place = place;
+	    grub_ssize_t off = sym_addr - (grub_addr_t) place;
+	    grub_int32_t hi20;
+
+	    if (off != (grub_int32_t)off)
+	      return grub_error (GRUB_ERR_BAD_MODULE, "relocation overflow");
+
+	    hi20 = (off + 0x800) & 0xfffff000;
+	    *abs_place = (*abs_place & 0xfff) | hi20;
+	  }
+	break;
+
+	case R_RISCV_PCREL_LO12_I:
+	case R_RISCV_PCREL_LO12_S:
+	  {
+	    grub_uint32_t *t32 = place;
+	    Elf_Rela *rel2;
+	    /* Search backwards for matching HI20 reloc.  */
+	    for (rel2 = (Elf_Rela *) ((char *) rel - s->sh_entsize);
+		    (unsigned long)rel2 >= ((unsigned long)ehdr + s->sh_offset);
+		    rel2 = (Elf_Rela *) ((char *) rel2 - s->sh_entsize))
+	      {
+		Elf_Addr rel2_info;
+		Elf_Addr rel2_offset;
+		Elf_Addr rel2_sym_addr;
+		Elf_Addr rel2_loc;
+		grub_ssize_t rel2_off;
+		grub_ssize_t off;
+		Elf_Sym *sym2;
+
+		rel2_offset = rel2->r_offset;
+		rel2_info = rel2->r_info;
+		rel2_loc = (grub_addr_t) seg->addr + rel2_offset;
+
+		if (ELF_R_TYPE (rel2_info) == R_RISCV_PCREL_HI20
+		    && rel2_loc == sym_addr)
+		  {
+		    sym2 = (Elf_Sym *) ((char *) mod->symtab
+				+ mod->symsize * ELF_R_SYM (rel2->r_info));
+		    rel2_sym_addr = sym2->st_value;
+		    if (s->sh_type == SHT_RELA)
+		      rel2_sym_addr += ((Elf_Rela *) rel2)->r_addend;
+
+		    rel2_off = rel2_sym_addr - rel2_loc;
+		    off = rel2_off - ((rel2_off + 0x800) & 0xfffff000);
+
+		    if (ELF_R_TYPE (rel->r_info) == R_RISCV_PCREL_LO12_I)
+		      *t32 = (*t32 & 0xfffff) | (off & 0xfff) << 20;
+		    else
+		      {
+			grub_uint32_t imm11_5 = (off & 0xfe0) << (31 - 11);
+			grub_uint32_t imm4_0 = (off & 0x1f) << (11 - 4);
+			*t32 = (*t32 & 0x1fff07f) | imm11_5 | imm4_0;
+		      }
+		    break;
+		  }
+	      }
+	    if ((unsigned long)rel2 < ((unsigned long)ehdr + s->sh_offset))
+	      return grub_error (GRUB_ERR_BAD_MODULE, "cannot find matching HI20 relocation");
+	  }
+	  break;
+
+	case R_RISCV_HI20:
+	  {
+	    grub_uint32_t *abs_place = place;
+	    *abs_place = (*abs_place & 0xfff) |
+			 (((grub_int32_t) sym_addr + 0x800) & 0xfffff000);
+	  }
+	  break;
+
+	case R_RISCV_LO12_I:
+	  {
+	    grub_uint32_t *abs_place = place;
+	    grub_int32_t lo12 = (grub_int32_t) sym_addr -
+				(((grub_int32_t) sym_addr + 0x800) & 0xfffff000);
+	    *abs_place = (*abs_place & 0xfffff) | ((lo12 & 0xfff) << 20);
+	  }
+	  break;
+
+	case R_RISCV_LO12_S:
+	  {
+	    grub_uint32_t *abs_place = place;
+	    grub_int32_t lo12 = (grub_int32_t) sym_addr -
+				(((grub_int32_t) sym_addr + 0x800) & 0xfffff000);
+	    grub_uint32_t imm11_5 = (lo12 & 0xfe0) << (31 - 11);
+	    grub_uint32_t imm4_0 = (lo12 & 0x1f) << (11 - 4);
+	    *abs_place = (*abs_place & 0x1fff07f) | imm11_5 | imm4_0;
+	  }
+	  break;
+
+	case R_RISCV_RELAX:
+	  break;
+	default:
+	  return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+			     N_("relocation 0x%x is not implemented yet"),
+			     ELF_R_TYPE (rel->r_info));
+	}
+    }
+
+  return GRUB_ERR_NONE;
+}
diff --git a/include/grub/dl.h b/include/grub/dl.h
index fee27a14c..f03c03561 100644
--- a/include/grub/dl.h
+++ b/include/grub/dl.h
@@ -292,12 +292,14 @@ grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
 				 grub_size_t *got);
 #endif
 
-#if defined (__powerpc__) || defined (__mips__) || defined (__arm__)
+#if defined (__powerpc__) || defined (__mips__) || defined (__arm__) || \
+    (defined(__riscv) && (__riscv_xlen == 32))
 #define GRUB_ARCH_DL_TRAMP_ALIGN 4
 #define GRUB_ARCH_DL_GOT_ALIGN 4
 #endif
 
-#if defined (__aarch64__) || defined (__sparc__)
+#if defined (__aarch64__) || defined (__sparc__) || \
+    (defined(__riscv) && (__riscv_xlen == 64))
 #define GRUB_ARCH_DL_TRAMP_ALIGN 8
 #define GRUB_ARCH_DL_GOT_ALIGN 8
 #endif
diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c
index a483c674c..a94d03540 100644
--- a/util/grub-mkimagexx.c
+++ b/util/grub-mkimagexx.c
@@ -1188,6 +1188,205 @@ SUFFIX (relocate_addrs) (Elf_Ehdr *e, struct section_metadata *smd,
 		 break;
 	       }
 #endif /* MKIMAGE_ELF32 */
+	     case EM_RISCV:
+	       {
+		 grub_uint64_t *t64 = (grub_uint64_t *) target;
+		 grub_uint32_t *t32 = (grub_uint32_t *) target;
+		 grub_uint16_t *t16 = (grub_uint16_t *) target;
+		 grub_uint8_t *t8 = (grub_uint8_t *) target;
+		 grub_int64_t off = (long)sym_addr - target_section_addr - offset
+				    - image_target->vaddr_offset;
+
+		 sym_addr += addend;
+
+		 switch (ELF_R_TYPE (info))
+		   {
+		   case R_RISCV_ADD8:
+		     {
+		       *t8 = *t8 + sym_addr;
+		     }
+		     break;
+		   case R_RISCV_ADD16:
+		     {
+		       *t16 = grub_host_to_target16 (grub_target_to_host16 (*t16) + sym_addr);
+		     }
+		     break;
+		   case R_RISCV_32:
+		   case R_RISCV_ADD32:
+		     {
+		       *t32 = grub_host_to_target32 (grub_target_to_host32 (*t32) + sym_addr);
+		     }
+		     break;
+		   case R_RISCV_64:
+		   case R_RISCV_ADD64:
+		     {
+		       *t64 = grub_host_to_target64 (grub_target_to_host64 (*t64) + sym_addr);
+		     }
+		     break;
+
+		   case R_RISCV_SUB8:
+		     {
+		       *t8 = sym_addr - *t8;
+		     }
+		     break;
+		   case R_RISCV_SUB16:
+		     {
+		       *t16 = grub_host_to_target16 (grub_target_to_host16 (*t16) - sym_addr);
+		     }
+		     break;
+		   case R_RISCV_SUB32:
+		     {
+		       *t32 = grub_host_to_target32 (grub_target_to_host32 (*t32) - sym_addr);
+		     }
+		     break;
+		   case R_RISCV_SUB64:
+		     {
+		       *t64 = grub_host_to_target64 (grub_target_to_host64 (*t64) - sym_addr);
+		     }
+		     break;
+		   case R_RISCV_BRANCH:
+		     {
+		       grub_uint32_t imm12 = (off & 0x1000) << (31 - 12);
+		       grub_uint32_t imm11 = (off & 0x800) >> (11 - 7);
+		       grub_uint32_t imm10_5 = (off & 0x7e0) << (30 - 10);
+		       grub_uint32_t imm4_1 = (off & 0x1e) << (11 - 4);
+		       *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0x1fff07f)
+						     | imm12 | imm11 | imm10_5 | imm4_1);
+		     }
+		     break;
+		   case R_RISCV_JAL:
+		     {
+		       grub_uint32_t imm20 = (off & 0x100000) << (31 - 20);
+		       grub_uint32_t imm19_12 = (off & 0xff000);
+		       grub_uint32_t imm11 = (off & 0x800) << (20 - 11);
+		       grub_uint32_t imm10_1 = (off & 0x7fe) << (30 - 10);
+		       *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0xfff)
+						     | imm20 | imm19_12 | imm11 | imm10_1);
+		     }
+		     break;
+		   case R_RISCV_CALL:
+		     {
+		       grub_uint32_t hi20, lo12;
+
+		       if (off != (grub_int32_t)off)
+			 grub_util_error ("target %lx not reachable from pc=%lx", (long)sym_addr, (long)target);
+
+		       hi20 = (off + 0x800) & 0xfffff000;
+		       lo12 = (off - hi20) & 0xfff;
+		       t32[0] = grub_host_to_target32 ((grub_target_to_host32 (t32[0]) & 0xfff) | hi20);
+		       t32[1] = grub_host_to_target32 ((grub_target_to_host32 (t32[1]) & 0xfffff) | (lo12 << 20));
+		     }
+		     break;
+		   case R_RISCV_RVC_BRANCH:
+		     {
+		       grub_uint16_t imm8 = (off & 0x100) << (12 - 8);
+		       grub_uint16_t imm7_6 = (off & 0xc0) >> (6 - 5);
+		       grub_uint16_t imm5 = (off & 0x20) >> (5 - 2);
+		       grub_uint16_t imm4_3 = (off & 0x18) << (12 - 5);
+		       grub_uint16_t imm2_1 = (off & 0x6) << (12 - 10);
+		       *t16 = grub_host_to_target16 ((grub_target_to_host16 (*t16) & 0xe383)
+						     | imm8 | imm7_6 | imm5 | imm4_3 | imm2_1);
+		     }
+		     break;
+		   case R_RISCV_RVC_JUMP:
+		     {
+		       grub_uint16_t imm11 = (off & 0x800) << (12 - 11);
+		       grub_uint16_t imm10 = (off & 0x400) >> (10 - 8);
+		       grub_uint16_t imm9_8 = (off & 0x300) << (12 - 11);
+		       grub_uint16_t imm7 = (off & 0x80) >> (7 - 6);
+		       grub_uint16_t imm6 = (off & 0x40) << (12 - 11);
+		       grub_uint16_t imm5 = (off & 0x20) >> (5 - 2);
+		       grub_uint16_t imm4 = (off & 0x10) << (12 - 5);
+		       grub_uint16_t imm3_1 = (off & 0xe) << (12 - 10);
+		       *t16 = grub_host_to_target16 ((grub_target_to_host16 (*t16) & 0xe003)
+						     | imm11 | imm10 | imm9_8 | imm7 | imm6
+						     | imm5 | imm4 | imm3_1);
+		     }
+		     break;
+		   case R_RISCV_PCREL_HI20:
+		     {
+		       grub_int32_t hi20;
+
+		       if (off != (grub_int32_t)off)
+			 grub_util_error ("target %lx not reachable from pc=%lx", (long)sym_addr, (long)target);
+
+		       hi20 = (off + 0x800) & 0xfffff000;
+		       *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0xfff) | hi20);
+		     }
+		     break;
+		   case R_RISCV_PCREL_LO12_I:
+		   case R_RISCV_PCREL_LO12_S:
+		     {
+		       Elf_Rela *rel2;
+		       Elf_Word k;
+		       /* Search backwards for matching HI20 reloc.  */
+		       for (k = j, rel2 = (Elf_Rela *) ((char *) r - r_size);
+			    k > 0;
+			    k--, rel2 = (Elf_Rela *) ((char *) rel2 - r_size))
+			 {
+			   Elf_Addr rel2_info;
+			   Elf_Addr rel2_offset;
+			   Elf_Addr rel2_sym_addr;
+			   Elf_Addr rel2_addend;
+			   Elf_Addr rel2_loc;
+			   grub_int64_t rel2_off;
+
+			   rel2_offset = grub_target_to_host (rel2->r_offset);
+			   rel2_info = grub_target_to_host (rel2->r_info);
+			   rel2_loc = target_section_addr + rel2_offset + image_target->vaddr_offset;
+
+			   if (ELF_R_TYPE (rel2_info) == R_RISCV_PCREL_HI20
+			       && rel2_loc == sym_addr)
+			     {
+			       rel2_sym_addr = SUFFIX (get_symbol_address)
+				 (e, smd->symtab, ELF_R_SYM (rel2_info),
+				  image_target);
+			       rel2_addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ?
+				 grub_target_to_host (rel2->r_addend) : 0;
+			       rel2_off = rel2_sym_addr + rel2_addend - rel2_loc;
+			       off = rel2_off - ((rel2_off + 0x800) & 0xfffff000);
+
+			       if (ELF_R_TYPE (info) == R_RISCV_PCREL_LO12_I)
+				 *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0xfffff) | (off & 0xfff) << 20);
+			       else
+				 {
+				   grub_uint32_t imm11_5 = (off & 0xfe0) << (31 - 11);
+				   grub_uint32_t imm4_0 = (off & 0x1f) << (11 - 4);
+				   *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0x1fff07f) | imm11_5 | imm4_0);
+				 }
+			       break;
+			     }
+			 }
+		       if (k == 0)
+			 grub_util_error ("cannot find matching HI20 relocation");
+		     }
+		     break;
+		   case R_RISCV_HI20:
+		     *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0xfff) | (((grub_int32_t) sym_addr + 0x800) & 0xfffff000));
+		     break;
+		   case R_RISCV_LO12_I:
+		     {
+		       grub_int32_t lo12 = (grub_int32_t) sym_addr - (((grub_int32_t) sym_addr + 0x800) & 0xfffff000);
+		       *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0xfffff) | ((lo12 & 0xfff) << 20));
+		     }
+		     break;
+		   case R_RISCV_LO12_S:
+		     {
+		       grub_int32_t lo12 = (grub_int32_t) sym_addr - (((grub_int32_t) sym_addr + 0x800) & 0xfffff000);
+		       grub_uint32_t imm11_5 = (lo12 & 0xfe0) << (31 - 11);
+		       grub_uint32_t imm4_0 = (lo12 & 0x1f) << (11 - 4);
+		       *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0x1fff07f) | imm11_5 | imm4_0);
+		     }
+		     break;
+		   case R_RISCV_RELAX:
+		     break;
+		   default:
+		     grub_util_error (_("relocation 0x%x is not implemented yet"),
+				      (unsigned int) ELF_R_TYPE (info));
+		     break;
+		   }
+	       break;
+	       }
 	     default:
 	       grub_util_error ("unknown architecture type %d",
 				image_target->elf_target);
@@ -1472,6 +1671,75 @@ translate_relocation_pe (struct translate_context *ctx,
 	}
       break;
 #endif /* defined(MKIMAGE_ELF32) */
+    case EM_RISCV:
+      switch (ELF_R_TYPE (info))
+	{
+	case R_RISCV_32:
+	  {
+	    ctx->current_address
+	      = add_fixup_entry (&ctx->lst,
+				 GRUB_PE32_REL_BASED_HIGHLOW,
+				 addr, 0, ctx->current_address,
+				 image_target);
+	  }
+	  break;
+	case R_RISCV_64:
+	  {
+	    ctx->current_address
+	      = add_fixup_entry (&ctx->lst,
+				 GRUB_PE32_REL_BASED_DIR64,
+				 addr, 0, ctx->current_address,
+				 image_target);
+	  }
+	  break;
+	  /* Relative relocations do not require fixup entries. */
+	case R_RISCV_BRANCH:
+	case R_RISCV_JAL:
+	case R_RISCV_CALL:
+	case R_RISCV_PCREL_HI20:
+	case R_RISCV_PCREL_LO12_I:
+	case R_RISCV_PCREL_LO12_S:
+	case R_RISCV_RVC_BRANCH:
+	case R_RISCV_RVC_JUMP:
+	case R_RISCV_ADD32:
+	case R_RISCV_SUB32:
+	  grub_util_info ("  %s:  not adding fixup: 0x%08x : 0x%08x", __FUNCTION__, (unsigned int) addr, (unsigned int) ctx->current_address);
+	  break;
+	case R_RISCV_HI20:
+	  {
+	    ctx->current_address
+	      = add_fixup_entry (&ctx->lst,
+				 GRUB_PE32_REL_BASED_RISCV_HI20,
+				 addr, 0, ctx->current_address,
+				 image_target);
+	  }
+	  break;
+	case R_RISCV_LO12_I:
+	  {
+	    ctx->current_address
+	      = add_fixup_entry (&ctx->lst,
+				 GRUB_PE32_REL_BASED_RISCV_LOW12I,
+				 addr, 0, ctx->current_address,
+				 image_target);
+	  }
+	  break;
+	case R_RISCV_LO12_S:
+	  {
+	    ctx->current_address
+	      = add_fixup_entry (&ctx->lst,
+				 GRUB_PE32_REL_BASED_RISCV_LOW12S,
+				 addr, 0, ctx->current_address,
+				 image_target);
+	  }
+	  break;
+	case R_RISCV_RELAX:
+	  break;
+	default:
+	  grub_util_error (_("relocation 0x%x is not implemented yet"),
+			   (unsigned int) ELF_R_TYPE (info));
+	  break;
+	}
+      break;
     default:
       grub_util_error ("unknown machine type 0x%x", image_target->elf_target);
     }
diff --git a/util/grub-module-verifier.c b/util/grub-module-verifier.c
index 03ba1ab43..7a32b010c 100644
--- a/util/grub-module-verifier.c
+++ b/util/grub-module-verifier.c
@@ -117,6 +117,62 @@ struct grub_module_verifier_arch archs[] = {
       R_AARCH64_LDST64_ABS_LO12_NC,
       R_AARCH64_PREL32,
       -1
+    } },
+  { "riscv32", 4, 0, EM_RISCV, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
+      R_RISCV_32,
+      R_RISCV_64,
+      R_RISCV_ADD8,
+      R_RISCV_ADD16,
+      R_RISCV_ADD32,
+      R_RISCV_ADD64,
+      R_RISCV_SUB8,
+      R_RISCV_SUB16,
+      R_RISCV_SUB32,
+      R_RISCV_SUB64,
+      R_RISCV_ALIGN,
+      R_RISCV_BRANCH,
+      R_RISCV_CALL,
+      R_RISCV_CALL_PLT,
+      R_RISCV_GOT_HI20,
+      R_RISCV_HI20,
+      R_RISCV_JAL,
+      R_RISCV_LO12_I,
+      R_RISCV_LO12_S,
+      R_RISCV_PCREL_HI20,
+      R_RISCV_PCREL_LO12_I,
+      R_RISCV_PCREL_LO12_S,
+      R_RISCV_RELAX,
+      R_RISCV_RVC_BRANCH,
+      R_RISCV_RVC_JUMP,
+      -1
+    } },
+  { "riscv64", 8, 0, EM_RISCV, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
+      R_RISCV_32,
+      R_RISCV_64,
+      R_RISCV_ADD8,
+      R_RISCV_ADD16,
+      R_RISCV_ADD32,
+      R_RISCV_ADD64,
+      R_RISCV_SUB8,
+      R_RISCV_SUB16,
+      R_RISCV_SUB32,
+      R_RISCV_SUB64,
+      R_RISCV_ALIGN,
+      R_RISCV_BRANCH,
+      R_RISCV_CALL,
+      R_RISCV_CALL_PLT,
+      R_RISCV_GOT_HI20,
+      R_RISCV_HI20,
+      R_RISCV_JAL,
+      R_RISCV_LO12_I,
+      R_RISCV_LO12_S,
+      R_RISCV_PCREL_HI20,
+      R_RISCV_PCREL_LO12_I,
+      R_RISCV_PCREL_LO12_S,
+      R_RISCV_RELAX,
+      R_RISCV_RVC_BRANCH,
+      R_RISCV_RVC_JUMP,
+      -1
     }
   },
 };
-- 
2.12.3



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

* [PATCH v3 08/10] RISC-V: Add auxiliary files
  2018-11-14 17:27 [PATCH v3 00/10] Add RISC-V support Alexander Graf
                   ` (6 preceding siblings ...)
  2018-11-14 17:27 ` [PATCH v3 07/10] RISC-V: Add awareness for RISC-V reloations Alexander Graf
@ 2018-11-14 17:27 ` Alexander Graf
  2018-11-17 22:51   ` Auer, Lukas
  2018-11-21 16:02   ` Daniel Kiper
  2018-11-14 17:27 ` [PATCH v3 09/10] RISC-V: Add to build system Alexander Graf
  2018-11-14 17:27 ` [PATCH v3 10/10] fdt: Add device tree file type Alexander Graf
  9 siblings, 2 replies; 41+ messages in thread
From: Alexander Graf @ 2018-11-14 17:27 UTC (permalink / raw)
  To: grub-devel
  Cc: leif.lindholm, Peter Jones, Paul Walmsley, David Abdurachmanov,
	atish.patra, schwab, Michael Chang, Alistair Francis, Lukas Auer,
	greentime @ andestech . com, rickchen36 @ gmail . com, Bin Meng

To support a new architecture we need to provide a few helper functions
for memory, cache, timer, etc support.

This patch adds the remainders of those. Some bits are still disabled,
as I couldn't guarantee that we're always running on models / in modes
where the respective hardware is available.

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

---

v2 -> v3:

  - Fix riscv32 target
---
 grub-core/kern/riscv/cache.c       | 64 +++++++++++++++++++++++++++++
 grub-core/kern/riscv/cache_flush.S | 40 +++++++++++++++++++
 grub-core/kern/riscv/efi/init.c    | 82 ++++++++++++++++++++++++++++++++++++++
 include/grub/riscv32/efi/memory.h  |  6 +++
 include/grub/riscv32/time.h        | 28 +++++++++++++
 include/grub/riscv32/types.h       | 34 ++++++++++++++++
 include/grub/riscv64/efi/memory.h  |  6 +++
 include/grub/riscv64/time.h        | 28 +++++++++++++
 include/grub/riscv64/types.h       | 34 ++++++++++++++++
 9 files changed, 322 insertions(+)
 create mode 100644 grub-core/kern/riscv/cache.c
 create mode 100644 grub-core/kern/riscv/cache_flush.S
 create mode 100644 grub-core/kern/riscv/efi/init.c
 create mode 100644 include/grub/riscv32/efi/memory.h
 create mode 100644 include/grub/riscv32/time.h
 create mode 100644 include/grub/riscv32/types.h
 create mode 100644 include/grub/riscv64/efi/memory.h
 create mode 100644 include/grub/riscv64/time.h
 create mode 100644 include/grub/riscv64/types.h

diff --git a/grub-core/kern/riscv/cache.c b/grub-core/kern/riscv/cache.c
new file mode 100644
index 000000000..15dbe6927
--- /dev/null
+++ b/grub-core/kern/riscv/cache.c
@@ -0,0 +1,64 @@
+/*
+ *  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/cache.h>
+#include <grub/misc.h>
+
+static grub_int64_t dlinesz;
+static grub_int64_t ilinesz;
+
+/* Prototypes for asm functions. */
+void grub_arch_clean_dcache_range (grub_addr_t beg, grub_addr_t end,
+				   grub_size_t line_size);
+void grub_arch_invalidate_icache_range (grub_addr_t beg, grub_addr_t end,
+					grub_size_t line_size);
+
+static void
+probe_caches (void)
+{
+  /* TODO */
+  dlinesz = 32;
+  ilinesz = 32;
+}
+
+void
+grub_arch_sync_caches (void *address, grub_size_t len)
+{
+  grub_size_t start, end, max_align;
+
+  if (dlinesz == 0)
+    probe_caches();
+  if (dlinesz == 0)
+    grub_fatal ("Unknown cache line size!");
+
+  max_align = dlinesz > ilinesz ? dlinesz : ilinesz;
+
+  start = ALIGN_DOWN ((grub_size_t) address, max_align);
+  end = ALIGN_UP ((grub_size_t) address + len, max_align);
+
+  grub_arch_clean_dcache_range (start, end, dlinesz);
+  grub_arch_invalidate_icache_range (start, end, ilinesz);
+}
+
+void
+grub_arch_sync_dma_caches (volatile void *address, grub_size_t len)
+{
+  /* DMA incoherent devices not supported yet */
+  if (address || len || 1)
+    return;
+}
diff --git a/grub-core/kern/riscv/cache_flush.S b/grub-core/kern/riscv/cache_flush.S
new file mode 100644
index 000000000..033a8aac3
--- /dev/null
+++ b/grub-core/kern/riscv/cache_flush.S
@@ -0,0 +1,40 @@
+/*
+ *  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>
+
+	.file	"cache_flush.S"
+	.text
+
+/*
+ * Simple cache maintenance functions
+ */
+
+// a0 - *beg (inclusive)
+// a1 - *end (exclusive)
+// a2 - line size
+FUNCTION(grub_arch_clean_dcache_range)
+	// TODO
+	ret
+
+// a0 - *beg (inclusive)
+// a1 - *end (exclusive)
+// a2 - line size
+FUNCTION(grub_arch_invalidate_icache_range)
+	// TODO
+	ret
diff --git a/grub-core/kern/riscv/efi/init.c b/grub-core/kern/riscv/efi/init.c
new file mode 100644
index 000000000..199de08a7
--- /dev/null
+++ b/grub-core/kern/riscv/efi/init.c
@@ -0,0 +1,82 @@
+/* init.c - initialize a riscv-based EFI system */
+/*
+ *  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/env.h>
+#include <grub/kernel.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/time.h>
+#include <grub/efi/efi.h>
+#include <grub/loader.h>
+
+static grub_uint64_t timer_frequency_in_khz;
+
+static grub_uint64_t
+grub_efi_get_time_ms (void)
+{
+  grub_uint64_t tmr;
+
+#if 0
+#if __riscv_xlen == 64
+  asm volatile ("rdtime %0" : "=r" (tmr));
+#else
+  grub_uint32_t lo, hi, tmp;
+  asm volatile (
+    "1:\n"
+    "rdtimeh %0\n"
+    "rdtime %1\n"
+    "rdtimeh %2\n"
+    "bne %0, %2, 1b"
+    : "=&r" (hi), "=&r" (lo), "=&r" (tmp));
+  tmr = ((u64)hi << 32) | lo;
+#endif
+#else
+  static grub_uint64_t val;
+  tmr = val++;
+#endif
+
+  return tmr / timer_frequency_in_khz;
+}
+
+
+void
+grub_machine_init (void)
+{
+  grub_uint64_t time_before, time_after;
+
+  grub_efi_init ();
+
+  /* Calculate timer frequency */
+  timer_frequency_in_khz = 1;
+  time_before = grub_efi_get_time_ms();
+  grub_efi_stall(1000);
+  time_after = grub_efi_get_time_ms();
+  timer_frequency_in_khz = time_after - time_before;
+
+  grub_install_get_time_ms (grub_efi_get_time_ms);
+}
+
+void
+grub_machine_fini (int flags)
+{
+  if (!(flags & GRUB_LOADER_FLAG_NORETURN))
+    return;
+
+  grub_efi_fini ();
+}
diff --git a/include/grub/riscv32/efi/memory.h b/include/grub/riscv32/efi/memory.h
new file mode 100644
index 000000000..e61c474ff
--- /dev/null
+++ b/include/grub/riscv32/efi/memory.h
@@ -0,0 +1,6 @@
+#ifndef GRUB_MEMORY_CPU_HEADER
+#include <grub/efi/memory.h>
+
+#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffffUL
+
+#endif /* ! GRUB_MEMORY_CPU_HEADER */
diff --git a/include/grub/riscv32/time.h b/include/grub/riscv32/time.h
new file mode 100644
index 000000000..f9546ec0e
--- /dev/null
+++ b/include/grub/riscv32/time.h
@@ -0,0 +1,28 @@
+/*
+ *  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 KERNEL_CPU_TIME_HEADER
+#define KERNEL_CPU_TIME_HEADER	1
+
+static __inline void
+grub_cpu_idle (void)
+{
+  /* TODO */
+}
+
+#endif /* ! KERNEL_CPU_TIME_HEADER */
diff --git a/include/grub/riscv32/types.h b/include/grub/riscv32/types.h
new file mode 100644
index 000000000..8c90ce2ec
--- /dev/null
+++ b/include/grub/riscv32/types.h
@@ -0,0 +1,34 @@
+/*
+ *  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_TYPES_CPU_HEADER
+#define GRUB_TYPES_CPU_HEADER	1
+
+/* The size of void *.  */
+#define GRUB_TARGET_SIZEOF_VOID_P	4
+
+/* The size of long.  */
+#define GRUB_TARGET_SIZEOF_LONG		4
+
+/* currently only support little-endian.  */
+#undef GRUB_TARGET_WORDS_BIGENDIAN
+
+/* Unaligned accesses can be very slow, so avoid them */
+#undef GRUB_HAVE_UNALIGNED_ACCESS
+
+#endif /* ! GRUB_TYPES_CPU_HEADER */
diff --git a/include/grub/riscv64/efi/memory.h b/include/grub/riscv64/efi/memory.h
new file mode 100644
index 000000000..c6cb32417
--- /dev/null
+++ b/include/grub/riscv64/efi/memory.h
@@ -0,0 +1,6 @@
+#ifndef GRUB_MEMORY_CPU_HEADER
+#include <grub/efi/memory.h>
+
+#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffffffffULL
+
+#endif /* ! GRUB_MEMORY_CPU_HEADER */
diff --git a/include/grub/riscv64/time.h b/include/grub/riscv64/time.h
new file mode 100644
index 000000000..f9546ec0e
--- /dev/null
+++ b/include/grub/riscv64/time.h
@@ -0,0 +1,28 @@
+/*
+ *  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 KERNEL_CPU_TIME_HEADER
+#define KERNEL_CPU_TIME_HEADER	1
+
+static __inline void
+grub_cpu_idle (void)
+{
+  /* TODO */
+}
+
+#endif /* ! KERNEL_CPU_TIME_HEADER */
diff --git a/include/grub/riscv64/types.h b/include/grub/riscv64/types.h
new file mode 100644
index 000000000..8823bc7d8
--- /dev/null
+++ b/include/grub/riscv64/types.h
@@ -0,0 +1,34 @@
+/*
+ *  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_TYPES_CPU_HEADER
+#define GRUB_TYPES_CPU_HEADER	1
+
+/* The size of void *.  */
+#define GRUB_TARGET_SIZEOF_VOID_P	8
+
+/* The size of long.  */
+#define GRUB_TARGET_SIZEOF_LONG		8
+
+/* currently only support little-endian.  */
+#undef GRUB_TARGET_WORDS_BIGENDIAN
+
+/* Unaligned accesses can be very slow, so avoid them */
+#undef GRUB_HAVE_UNALIGNED_ACCESS
+
+#endif /* ! GRUB_TYPES_CPU_HEADER */
-- 
2.12.3



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

* [PATCH v3 09/10] RISC-V: Add to build system
  2018-11-14 17:27 [PATCH v3 00/10] Add RISC-V support Alexander Graf
                   ` (7 preceding siblings ...)
  2018-11-14 17:27 ` [PATCH v3 08/10] RISC-V: Add auxiliary files Alexander Graf
@ 2018-11-14 17:27 ` Alexander Graf
  2018-11-18 11:41   ` Bin Meng
  2018-11-21 16:09   ` Daniel Kiper
  2018-11-14 17:27 ` [PATCH v3 10/10] fdt: Add device tree file type Alexander Graf
  9 siblings, 2 replies; 41+ messages in thread
From: Alexander Graf @ 2018-11-14 17:27 UTC (permalink / raw)
  To: grub-devel
  Cc: leif.lindholm, Peter Jones, Paul Walmsley, David Abdurachmanov,
	atish.patra, schwab, Michael Chang, Alistair Francis, Lukas Auer,
	greentime @ andestech . com, rickchen36 @ gmail . com, Bin Meng

This patch adds support for RISC-V to the grub build system. With this
patch, I can successfully build grub on RISC-V as a UEFI application.

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

---

v2 -> v3:

  - Fix riscv32 target
---
 configure.ac                 | 28 ++++++++++++++++++++++++++--
 gentpl.py                    | 11 +++++++----
 grub-core/Makefile.am        | 12 ++++++++++++
 grub-core/Makefile.core.def  | 29 +++++++++++++++++++++++++++++
 grub-core/commands/file.c    | 14 +++++++++++++-
 grub-core/kern/compiler-rt.c |  6 ++++--
 grub-core/kern/efi/mm.c      |  2 +-
 grub-core/kern/emu/cache.c   |  6 ++++++
 grub-core/kern/emu/cache_s.S |  1 +
 grub-core/kern/emu/lite.c    |  2 ++
 grub-core/lib/efi/halt.c     |  3 ++-
 grub-core/lib/setjmp.S       |  2 ++
 include/grub/compiler-rt.h   | 12 ++++++++----
 include/grub/efi/api.h       |  3 ++-
 include/grub/efi/efi.h       |  2 +-
 include/grub/misc.h          |  3 ++-
 include/grub/util/install.h  |  2 ++
 util/grub-install-common.c   |  2 ++
 util/grub-install.c          | 28 ++++++++++++++++++++++++++++
 util/grub-mknetdir.c         |  4 +++-
 util/grub-mkrescue.c         | 16 +++++++++++++++-
 util/mkimage.c               | 32 ++++++++++++++++++++++++++++++++
 22 files changed, 200 insertions(+), 20 deletions(-)

diff --git a/configure.ac b/configure.ac
index 5e63c4af3..2cc2ffb2c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -104,6 +104,12 @@ case "$target_cpu" in
   aarch64*)
 		target_cpu=arm64
 		;;
+  riscv32*)
+		target_cpu=riscv32
+		;;
+  riscv64*)
+		target_cpu=riscv64
+		;;
 esac
 
 # Specify the platform (such as firmware).
@@ -127,6 +133,8 @@ if test "x$with_platform" = x; then
     ia64-*) platform=efi ;;
     arm-*) platform=uboot ;;
     arm64-*) platform=efi ;;
+    riscv32-*) platform=efi ;;
+    riscv64-*) platform=efi ;;
     *)
       AC_MSG_WARN([unsupported CPU: "$target_cpu" - only building utilities])
       platform=none
@@ -174,6 +182,8 @@ case "$target_cpu"-"$platform" in
   arm-coreboot) ;;
   arm-efi) ;;
   arm64-efi) ;;
+  riscv32-efi) ;;
+  riscv64-efi) ;;
   *-emu) ;;
   *-none) ;;
   *) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;;
@@ -826,6 +836,16 @@ if test x"$platform" != xemu ; then
        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
 		         [grub_cv_target_cc_soft_float="-mgeneral-regs-only"], [])
     fi
+    if test "x$target_cpu" = xriscv32; then
+       CFLAGS="$TARGET_CFLAGS -march=rv32imac -mabi=ilp32 -Werror"
+       AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+		         [grub_cv_target_cc_soft_float="-march=rv32imac -mabi=ilp32"], [])
+    fi
+    if test "x$target_cpu" = xriscv64; then
+       CFLAGS="$TARGET_CFLAGS -march=rv64imac -mabi=lp64 -Werror"
+       AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+		         [grub_cv_target_cc_soft_float="-march=rv64imac -mabi=lp64"], [])
+    fi
     if test "x$target_cpu" = xia64; then
        CFLAGS="$TARGET_CFLAGS -mno-inline-float-divide -mno-inline-sqrt -Werror"
        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
@@ -1141,7 +1161,7 @@ AC_SUBST(TARGET_LDFLAGS_OLDMAGIC)
 
 LDFLAGS="$TARGET_LDFLAGS"
 
-if test "$target_cpu" = x86_64 || test "$target_cpu" = sparc64 ; then
+if test "$target_cpu" = x86_64 || test "$target_cpu" = sparc64 || test "$target_cpu" = riscv64 ; then
   # Use large model to support 4G memory
   AC_CACHE_CHECK([whether option -mcmodel=large works], grub_cv_cc_mcmodel, [
     CFLAGS="$TARGET_CFLAGS -mcmodel=large"
@@ -1151,7 +1171,7 @@ if test "$target_cpu" = x86_64 || test "$target_cpu" = sparc64 ; then
   ])
   if test "x$grub_cv_cc_mcmodel" = xyes; then
     TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=large"
-  elif test "$target_cpu" = sparc64; then
+  elif test "$target_cpu" = sparc64 || test "$target_cpu" = riscv64; then
     TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=medany"
   fi
 fi
@@ -1913,6 +1933,10 @@ AM_CONDITIONAL([COND_arm_coreboot], [test x$target_cpu = xarm -a x$platform = xc
 AM_CONDITIONAL([COND_arm_efi], [test x$target_cpu = xarm -a x$platform = xefi])
 AM_CONDITIONAL([COND_arm64], [test x$target_cpu = xarm64 ])
 AM_CONDITIONAL([COND_arm64_efi], [test x$target_cpu = xarm64 -a x$platform = xefi])
+AM_CONDITIONAL([COND_riscv32], [test x$target_cpu = xriscv32 ])
+AM_CONDITIONAL([COND_riscv64], [test x$target_cpu = xriscv64 ])
+AM_CONDITIONAL([COND_riscv32_efi], [test x$target_cpu = xriscv32 -a x$platform = xefi])
+AM_CONDITIONAL([COND_riscv64_efi], [test x$target_cpu = xriscv64 -a x$platform = xefi])
 
 AM_CONDITIONAL([COND_HOST_HURD], [test x$host_kernel = xhurd])
 AM_CONDITIONAL([COND_HOST_LINUX], [test x$host_kernel = xlinux])
diff --git a/gentpl.py b/gentpl.py
index da67965a4..996fda9d5 100644
--- a/gentpl.py
+++ b/gentpl.py
@@ -32,7 +32,7 @@ GRUB_PLATFORMS = [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot",
                    "mips_loongson", "sparc64_ieee1275",
                    "powerpc_ieee1275", "mips_arc", "ia64_efi",
                    "mips_qemu_mips", "arm_uboot", "arm_efi", "arm64_efi",
-                   "arm_coreboot"]
+                   "arm_coreboot", "riscv32_efi", "riscv64_efi" ]
 
 GROUPS = {}
 
@@ -47,9 +47,12 @@ GROUPS["sparc64"]  = [ "sparc64_ieee1275" ]
 GROUPS["powerpc"]  = [ "powerpc_ieee1275" ]
 GROUPS["arm"]      = [ "arm_uboot", "arm_efi", "arm_coreboot" ]
 GROUPS["arm64"]    = [ "arm64_efi" ]
+GROUPS["riscv32"]  = [ "riscv32_efi" ]
+GROUPS["riscv64"]  = [ "riscv64_efi" ]
 
 # Groups based on firmware
-GROUPS["efi"]  = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi", "arm64_efi" ]
+GROUPS["efi"]  = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi", "arm64_efi",
+		   "riscv32_efi", "riscv64_efi" ]
 GROUPS["ieee1275"]   = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" ]
 GROUPS["uboot"] = [ "arm_uboot" ]
 GROUPS["xen"]  = [ "i386_xen", "x86_64_xen" ]
@@ -76,11 +79,11 @@ GROUPS["terminfomodule"]   = GRUB_PLATFORMS[:];
 for i in GROUPS["terminfoinkernel"]: GROUPS["terminfomodule"].remove(i)
 
 # Flattened Device Trees (FDT)
-GROUPS["fdt"] = [ "arm64_efi", "arm_uboot", "arm_efi" ]
+GROUPS["fdt"] = [ "arm64_efi", "arm_uboot", "arm_efi", "riscv32_efi", "riscv64_efi" ]
 
 # Needs software helpers for division
 # Must match GRUB_DIVISION_IN_SOFTWARE in misc.h
-GROUPS["softdiv"] = GROUPS["arm"] + ["ia64_efi"]
+GROUPS["softdiv"] = GROUPS["arm"] + ["ia64_efi"] + GROUPS["riscv32"]
 GROUPS["no_softdiv"]   = GRUB_PLATFORMS[:]
 for i in GROUPS["softdiv"]: GROUPS["no_softdiv"].remove(i)
 
diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am
index f4ff62b76..30e849c5e 100644
--- a/grub-core/Makefile.am
+++ b/grub-core/Makefile.am
@@ -266,6 +266,18 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
 endif
 
+if COND_riscv32_efi
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
+endif
+
+if COND_riscv64_efi
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
+endif
+
 if COND_emu
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/datetime.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/misc.h
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 6e2cc8444..11b1d56a9 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -65,6 +65,12 @@ kernel = {
   arm64_efi_ldflags          = '-Wl,-r,-d';
   arm64_efi_stripflags       = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version -R .eh_frame';
 
+  riscv32_efi_ldflags      = '-Wl,-r,-d';
+  riscv32_efi_stripflags   = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version -R .eh_frame';
+
+  riscv64_efi_ldflags      = '-Wl,-r,-d';
+  riscv64_efi_stripflags   = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version -R .eh_frame';
+
   i386_pc_ldflags          = '$(TARGET_IMG_LDFLAGS)';
   i386_pc_ldflags          = '$(TARGET_IMG_BASE_LDOPT),0x9000';
   i386_qemu_ldflags        = '$(TARGET_IMG_LDFLAGS)';
@@ -111,6 +117,8 @@ kernel = {
   arm_coreboot_startup = kern/arm/startup.S;
   arm_efi_startup = kern/arm/efi/startup.S;
   arm64_efi_startup = kern/arm64/efi/startup.S;
+  riscv32_efi_startup = kern/riscv/efi/startup.S;
+  riscv64_efi_startup = kern/riscv/efi/startup.S;
 
   common = kern/command.c;
   common = kern/corecmd.c;
@@ -234,6 +242,12 @@ kernel = {
   arm64_efi = kern/arm64/efi/init.c;
   arm64_efi = kern/efi/fdt.c;
 
+  riscv32_efi = kern/riscv/efi/init.c;
+  riscv32_efi = kern/efi/fdt.c;
+
+  riscv64_efi = kern/riscv/efi/init.c;
+  riscv64_efi = kern/efi/fdt.c;
+
   i386_pc = kern/i386/pc/init.c;
   i386_pc = kern/i386/pc/mmap.c;
   i386_pc = term/i386/pc/console.c;
@@ -305,6 +319,14 @@ kernel = {
   arm64 = kern/arm64/dl.c;
   arm64 = kern/arm64/dl_helper.c;
 
+  riscv32 = kern/riscv/cache.c;
+  riscv32 = kern/riscv/cache_flush.S;
+  riscv32 = kern/riscv/dl.c;
+
+  riscv64 = kern/riscv/cache.c;
+  riscv64 = kern/riscv/cache_flush.S;
+  riscv64 = kern/riscv/dl.c;
+
   emu = disk/host.c;
   emu = kern/emu/cache_s.S;
   emu = kern/emu/hostdisk.c;
@@ -780,6 +802,8 @@ module = {
   enable = arm64_efi;
   enable = arm_uboot;
   enable = arm_coreboot;
+  enable = riscv32_efi;
+  enable = riscv64_efi;
 };
 
 module = {
@@ -1611,6 +1635,7 @@ module = {
   extra_dist = lib/ia64/longjmp.S;
   extra_dist = lib/arm/setjmp.S;
   extra_dist = lib/arm64/setjmp.S;
+  extra_dist = lib/riscv/setjmp.S;
 };
 
 module = {
@@ -1707,6 +1732,8 @@ module = {
   arm_efi = loader/arm64/linux.c;
   arm_uboot = loader/arm/linux.c;
   arm64 = loader/arm64/linux.c;
+  riscv32 = loader/riscv/linux.c;
+  riscv64 = loader/riscv/linux.c;
   common = loader/linux.c;
   common = lib/cmdline.c;
   enable = noemu;
@@ -1798,6 +1825,8 @@ module = {
   enable = ia64_efi;
   enable = arm_efi;
   enable = arm64_efi;
+  enable = riscv32_efi;
+  enable = riscv64_efi;
   enable = mips;
 };
 
diff --git a/grub-core/commands/file.c b/grub-core/commands/file.c
index 4f81aa1f9..2574e6685 100644
--- a/grub-core/commands/file.c
+++ b/grub-core/commands/file.c
@@ -90,6 +90,10 @@ static const struct grub_arg_option options[] = {
    N_("Check if FILE is ARM64 EFI file"), 0, 0},
   {"is-arm-efi", 0, 0,
    N_("Check if FILE is ARM EFI file"), 0, 0},
+  {"is-riscv32-efi", 0, 0,
+   N_("Check if FILE is RISC-V 32bit EFI file"), 0, 0},
+  {"is-riscv64-efi", 0, 0,
+   N_("Check if FILE is RISC-V 64bit EFI file"), 0, 0},
   {"is-hibernated-hiberfil", 0, 0,
    N_("Check if FILE is hiberfil.sys in hibernated state"), 0, 0},
   {"is-x86_64-xnu", 0, 0,
@@ -130,6 +134,7 @@ enum
   IS_IA_EFI,
   IS_ARM64_EFI,
   IS_ARM_EFI,
+  IS_RISCV_EFI,
   IS_HIBERNATED,
   IS_XNU64,
   IS_XNU32,
@@ -571,6 +576,7 @@ grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args)
     case IS_IA_EFI:
     case IS_ARM64_EFI:
     case IS_ARM_EFI:
+    case IS_RISCV_EFI:
       {
 	char signature[4];
 	grub_uint32_t pe_offset;
@@ -616,7 +622,13 @@ grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args)
 	    && coff_head.machine !=
 	    grub_cpu_to_le16_compile_time (GRUB_PE32_MACHINE_ARMTHUMB_MIXED))
 	  break;
-	if (type == IS_IA_EFI || type == IS_64_EFI || type == IS_ARM64_EFI)
+	if (type == IS_RISCV_EFI
+	    && coff_head.machine !=
+	    grub_cpu_to_le16_compile_time (GRUB_PE32_MACHINE_RISCV64))
+          /* TODO: Determine bitness dynamically */
+	  break;
+	if (type == IS_IA_EFI || type == IS_64_EFI || type == IS_ARM64_EFI ||
+	    type == IS_RISCV_EFI)
 	  {
 	    struct grub_pe64_optional_header o64;
 	    if (grub_file_read (file, &o64, sizeof (o64)) != sizeof (o64))
diff --git a/grub-core/kern/compiler-rt.c b/grub-core/kern/compiler-rt.c
index 5cfcb3907..6ae1c6844 100644
--- a/grub-core/kern/compiler-rt.c
+++ b/grub-core/kern/compiler-rt.c
@@ -237,7 +237,8 @@ union component64
   };
 };
 
-#if defined (__powerpc__) || defined (__arm__) || defined(__mips__)
+#if defined (__powerpc__) || defined (__arm__) || defined(__mips__) || \
+    (defined(__riscv) && (__riscv_xlen == 32))
 
 /* Based on libgcc2.c from gcc suite.  */
 grub_uint64_t
@@ -343,7 +344,8 @@ __ucmpdi2 (grub_uint64_t a, grub_uint64_t b)
 
 #endif
 
-#if defined (__powerpc__) || defined(__mips__) || defined(__sparc__) || defined(__arm__)
+#if defined (__powerpc__) || defined(__mips__) || defined(__sparc__) || \
+    defined(__arm__) || defined(__riscv)
 
 /* Based on libgcc2.c from gcc suite.  */
 grub_uint32_t
diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
index 42ad7c570..a29af9fa5 100644
--- a/grub-core/kern/efi/mm.c
+++ b/grub-core/kern/efi/mm.c
@@ -634,7 +634,7 @@ grub_efi_mm_init (void)
 		       2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
 }
 
-#if defined (__aarch64__) || defined (__arm__)
+#if defined (__aarch64__) || defined (__arm__) || defined (__riscv)
 grub_err_t
 grub_efi_get_ram_base(grub_addr_t *base_addr)
 {
diff --git a/grub-core/kern/emu/cache.c b/grub-core/kern/emu/cache.c
index 6f89e871a..113682cc4 100644
--- a/grub-core/kern/emu/cache.c
+++ b/grub-core/kern/emu/cache.c
@@ -25,5 +25,11 @@ grub_arch_sync_caches (void *address, grub_size_t len)
   return _flush_cache (address, len, 0);
 }
 
+#elif defined(__riscv)
+void
+grub_arch_sync_caches (void *address, grub_size_t len)
+{
+}
+
 #endif
 
diff --git a/grub-core/kern/emu/cache_s.S b/grub-core/kern/emu/cache_s.S
index 76cf7560d..e27b865f9 100644
--- a/grub-core/kern/emu/cache_s.S
+++ b/grub-core/kern/emu/cache_s.S
@@ -9,6 +9,7 @@
 #elif defined(__powerpc__)
 #include "../powerpc/cache.S"
 #elif defined(__ia64__) || defined(__arm__) || defined(__aarch64__) || defined(__mips__)
+#elif defined(__riscv)
 #else
 #error "No target cpu type is defined"
 #endif
diff --git a/grub-core/kern/emu/lite.c b/grub-core/kern/emu/lite.c
index b2fc93d7f..b327d4e41 100644
--- a/grub-core/kern/emu/lite.c
+++ b/grub-core/kern/emu/lite.c
@@ -24,6 +24,8 @@
 #elif defined(__aarch64__)
 #include "../arm64/dl_helper.c"
 #include "../arm64/dl.c"
+#elif defined(__riscv)
+#include "../riscv/dl.c"
 #else
 #error "No target cpu type is defined"
 #endif
diff --git a/grub-core/lib/efi/halt.c b/grub-core/lib/efi/halt.c
index e9441c844..5859f0498 100644
--- a/grub-core/lib/efi/halt.c
+++ b/grub-core/lib/efi/halt.c
@@ -29,7 +29,8 @@ void
 grub_halt (void)
 {
   grub_machine_fini (GRUB_LOADER_FLAG_NORETURN);
-#if !defined(__ia64__) && !defined(__arm__) && !defined(__aarch64__)
+#if !defined(__ia64__) && !defined(__arm__) && !defined(__aarch64__) && \
+    !defined(__riscv)
   grub_acpi_halt ();
 #endif
   efi_call_4 (grub_efi_system_table->runtime_services->reset_system,
diff --git a/grub-core/lib/setjmp.S b/grub-core/lib/setjmp.S
index f6e4905e2..aa297ab0a 100644
--- a/grub-core/lib/setjmp.S
+++ b/grub-core/lib/setjmp.S
@@ -15,6 +15,8 @@
 #include "./arm/setjmp.S"
 #elif defined(__aarch64__)
 #include "./arm64/setjmp.S"
+#elif defined(__riscv)
+#include "./riscv/setjmp.S"
 #else
 #error "Unknown target cpu type"
 #endif
diff --git a/include/grub/compiler-rt.h b/include/grub/compiler-rt.h
index dc73649a5..6bc6fc827 100644
--- a/include/grub/compiler-rt.h
+++ b/include/grub/compiler-rt.h
@@ -53,13 +53,15 @@ EXPORT_FUNC (__umoddi3) (grub_uint64_t a, grub_uint64_t b);
 
 #endif
 
-#if defined (__sparc__) || defined (__powerpc__) || defined (__mips__) || defined (__arm__)
+#if defined (__sparc__) || defined (__powerpc__) || defined (__mips__) || \
+    defined (__arm__) || defined(__riscv)
 unsigned
 EXPORT_FUNC (__ctzdi2) (grub_uint64_t x);
 #define NEED_CTZDI2 1
 #endif
 
-#if defined (__mips__) || defined (__arm__)
+#if defined (__mips__) || defined (__arm__) || \
+    (defined(__riscv) && (__riscv_xlen == 32))
 unsigned
 EXPORT_FUNC (__ctzsi2) (grub_uint32_t x);
 #define NEED_CTZSI2 1
@@ -150,7 +152,8 @@ void EXPORT_FUNC (_savegpr_31) (void);
 
 #endif
 
-#if defined (__powerpc__) || defined(__mips__) || defined (__arm__)
+#if defined (__powerpc__) || defined(__mips__) || defined (__arm__) || \
+    (defined(__riscv) && (__riscv_xlen == 32))
 
 int
 EXPORT_FUNC(__ucmpdi2) (grub_uint64_t a, grub_uint64_t b);
@@ -165,7 +168,8 @@ grub_uint64_t
 EXPORT_FUNC (__lshrdi3) (grub_uint64_t u, int b);
 #endif
 
-#if defined (__powerpc__) || defined(__mips__) || defined(__sparc__) || defined (__arm__)
+#if defined (__powerpc__) || defined(__mips__) || defined(__sparc__) || \
+    defined (__arm__) || defined(__riscv)
 grub_uint32_t
 EXPORT_FUNC(__bswapsi2) (grub_uint32_t u);
 
diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
index c7c9f0e1d..addcbfa8f 100644
--- a/include/grub/efi/api.h
+++ b/include/grub/efi/api.h
@@ -1686,7 +1686,8 @@ struct grub_efi_block_io
 typedef struct grub_efi_block_io grub_efi_block_io_t;
 
 #if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \
-  || defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__)
+  || defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__) \
+  || defined(__riscv)
 
 #define efi_call_0(func)		func()
 #define efi_call_1(func, a)		func(a)
diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
index ec44aef7e..e90e00dc4 100644
--- a/include/grub/efi/efi.h
+++ b/include/grub/efi/efi.h
@@ -90,7 +90,7 @@ extern void (*EXPORT_VAR(grub_efi_net_config)) (grub_efi_handle_t hnd,
 						char **device,
 						char **path);
 
-#if defined(__arm__) || defined(__aarch64__)
+#if defined(__arm__) || defined(__aarch64__) || defined(__riscv)
 void *EXPORT_FUNC(grub_efi_get_firmware_fdt)(void);
 grub_err_t EXPORT_FUNC(grub_efi_get_ram_base)(grub_addr_t *);
 #include <grub/cpu/linux.h>
diff --git a/include/grub/misc.h b/include/grub/misc.h
index 372f009e8..ee48eb7a7 100644
--- a/include/grub/misc.h
+++ b/include/grub/misc.h
@@ -340,7 +340,8 @@ grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n,
 					  grub_uint64_t *r);
 
 /* Must match softdiv group in gentpl.py.  */
-#if !defined(GRUB_MACHINE_EMU) && (defined(__arm__) || defined(__ia64__))
+#if !defined(GRUB_MACHINE_EMU) && (defined(__arm__) || defined(__ia64__) || \
+    (defined(__riscv) && (__riscv_xlen == 32)))
 #define GRUB_DIVISION_IN_SOFTWARE 1
 #else
 #define GRUB_DIVISION_IN_SOFTWARE 0
diff --git a/include/grub/util/install.h b/include/grub/util/install.h
index 0dba8b67f..15186e8ea 100644
--- a/include/grub/util/install.h
+++ b/include/grub/util/install.h
@@ -102,6 +102,8 @@ enum grub_install_plat
     GRUB_INSTALL_PLATFORM_X86_64_XEN,
     GRUB_INSTALL_PLATFORM_ARM64_EFI,
     GRUB_INSTALL_PLATFORM_ARM_COREBOOT,
+    GRUB_INSTALL_PLATFORM_RISCV32_EFI,
+    GRUB_INSTALL_PLATFORM_RISCV64_EFI,
     GRUB_INSTALL_PLATFORM_MAX
   };
 
diff --git a/util/grub-install-common.c b/util/grub-install-common.c
index 0a2e24a79..d0cc93725 100644
--- a/util/grub-install-common.c
+++ b/util/grub-install-common.c
@@ -728,6 +728,8 @@ static struct
     [GRUB_INSTALL_PLATFORM_ARM64_EFI] =        { "arm64",   "efi"       },
     [GRUB_INSTALL_PLATFORM_ARM_UBOOT] =        { "arm",     "uboot"     },
     [GRUB_INSTALL_PLATFORM_ARM_COREBOOT] =     { "arm",     "coreboot"  },
+    [GRUB_INSTALL_PLATFORM_RISCV32_EFI] =      { "riscv32", "efi"       },
+    [GRUB_INSTALL_PLATFORM_RISCV64_EFI] =      { "riscv64", "efi"       },
   }; 
 
 char *
diff --git a/util/grub-install.c b/util/grub-install.c
index 78d0138cb..6649b2c14 100644
--- a/util/grub-install.c
+++ b/util/grub-install.c
@@ -477,6 +477,8 @@ have_bootdev (enum grub_install_plat pl)
     case GRUB_INSTALL_PLATFORM_IA64_EFI:
     case GRUB_INSTALL_PLATFORM_ARM_EFI:
     case GRUB_INSTALL_PLATFORM_ARM64_EFI:
+    case GRUB_INSTALL_PLATFORM_RISCV32_EFI:
+    case GRUB_INSTALL_PLATFORM_RISCV64_EFI:
     case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
     case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
     case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
@@ -899,6 +901,8 @@ main (int argc, char *argv[])
     case GRUB_INSTALL_PLATFORM_X86_64_EFI:
     case GRUB_INSTALL_PLATFORM_ARM_EFI:
     case GRUB_INSTALL_PLATFORM_ARM64_EFI:
+    case GRUB_INSTALL_PLATFORM_RISCV32_EFI:
+    case GRUB_INSTALL_PLATFORM_RISCV64_EFI:
     case GRUB_INSTALL_PLATFORM_IA64_EFI:
     case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
     case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
@@ -943,6 +947,8 @@ main (int argc, char *argv[])
     case GRUB_INSTALL_PLATFORM_X86_64_EFI:
     case GRUB_INSTALL_PLATFORM_ARM_EFI:
     case GRUB_INSTALL_PLATFORM_ARM64_EFI:
+    case GRUB_INSTALL_PLATFORM_RISCV32_EFI:
+    case GRUB_INSTALL_PLATFORM_RISCV64_EFI:
     case GRUB_INSTALL_PLATFORM_IA64_EFI:
     case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
     case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
@@ -995,6 +1001,8 @@ main (int argc, char *argv[])
     case GRUB_INSTALL_PLATFORM_X86_64_EFI:
     case GRUB_INSTALL_PLATFORM_ARM_EFI:
     case GRUB_INSTALL_PLATFORM_ARM64_EFI:
+    case GRUB_INSTALL_PLATFORM_RISCV32_EFI:
+    case GRUB_INSTALL_PLATFORM_RISCV64_EFI:
     case GRUB_INSTALL_PLATFORM_IA64_EFI:
       is_efi = 1;
       break;
@@ -1108,6 +1116,12 @@ main (int argc, char *argv[])
 	    case GRUB_INSTALL_PLATFORM_ARM64_EFI:
 	      efi_file = "BOOTAA64.EFI";
 	      break;
+	    case GRUB_INSTALL_PLATFORM_RISCV32_EFI:
+	      efi_file = "BOOTRISCV32.EFI";
+	      break;
+	    case GRUB_INSTALL_PLATFORM_RISCV64_EFI:
+	      efi_file = "BOOTRISCV64.EFI";
+	      break;
 	    default:
 	      grub_util_error ("%s", _("You've found a bug"));
 	      break;
@@ -1135,6 +1149,12 @@ main (int argc, char *argv[])
 	    case GRUB_INSTALL_PLATFORM_ARM64_EFI:
 	      efi_file = "grubaa64.efi";
 	      break;
+	    case GRUB_INSTALL_PLATFORM_RISCV32_EFI:
+	      efi_file = "grubriscv32.efi";
+	      break;
+	    case GRUB_INSTALL_PLATFORM_RISCV64_EFI:
+	      efi_file = "grubriscv64.efi";
+	      break;
 	    default:
 	      efi_file = "grub.efi";
 	      break;
@@ -1437,6 +1457,8 @@ main (int argc, char *argv[])
 		  case GRUB_INSTALL_PLATFORM_X86_64_EFI:
 		  case GRUB_INSTALL_PLATFORM_ARM_EFI:
 		  case GRUB_INSTALL_PLATFORM_ARM64_EFI:
+		  case GRUB_INSTALL_PLATFORM_RISCV32_EFI:
+		  case GRUB_INSTALL_PLATFORM_RISCV64_EFI:
 		  case GRUB_INSTALL_PLATFORM_IA64_EFI:
 		    g = grub_util_guess_efi_drive (*curdev);
 		    break;
@@ -1529,6 +1551,8 @@ main (int argc, char *argv[])
     case GRUB_INSTALL_PLATFORM_X86_64_EFI:
     case GRUB_INSTALL_PLATFORM_ARM_EFI:
     case GRUB_INSTALL_PLATFORM_ARM64_EFI:
+    case GRUB_INSTALL_PLATFORM_RISCV32_EFI:
+    case GRUB_INSTALL_PLATFORM_RISCV64_EFI:
     case GRUB_INSTALL_PLATFORM_IA64_EFI:
       core_name = "core.efi";
       snprintf (mkimage_target, sizeof (mkimage_target),
@@ -1631,6 +1655,8 @@ main (int argc, char *argv[])
       break;
     case GRUB_INSTALL_PLATFORM_ARM_EFI:
     case GRUB_INSTALL_PLATFORM_ARM64_EFI:
+    case GRUB_INSTALL_PLATFORM_RISCV32_EFI:
+    case GRUB_INSTALL_PLATFORM_RISCV64_EFI:
     case GRUB_INSTALL_PLATFORM_IA64_EFI:
     case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS:
     case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS:
@@ -1865,6 +1891,8 @@ main (int argc, char *argv[])
       /* FALLTHROUGH */
     case GRUB_INSTALL_PLATFORM_ARM_EFI:
     case GRUB_INSTALL_PLATFORM_ARM64_EFI:
+    case GRUB_INSTALL_PLATFORM_RISCV32_EFI:
+    case GRUB_INSTALL_PLATFORM_RISCV64_EFI:
     case GRUB_INSTALL_PLATFORM_IA64_EFI:
       {
 	char *dst = grub_util_path_concat (2, efidir, efi_file);
diff --git a/util/grub-mknetdir.c b/util/grub-mknetdir.c
index 82073d5cc..602574d52 100644
--- a/util/grub-mknetdir.c
+++ b/util/grub-mknetdir.c
@@ -107,7 +107,9 @@ static const struct
     [GRUB_INSTALL_PLATFORM_X86_64_EFI] = { "x86_64-efi", "efinet", ".efi" },
     [GRUB_INSTALL_PLATFORM_IA64_EFI] = { "ia64-efi", "efinet", ".efi" },
     [GRUB_INSTALL_PLATFORM_ARM_EFI] = { "arm-efi", "efinet", ".efi" },
-    [GRUB_INSTALL_PLATFORM_ARM64_EFI] = { "arm64-efi", "efinet", ".efi" }
+    [GRUB_INSTALL_PLATFORM_ARM64_EFI] = { "arm64-efi", "efinet", ".efi" },
+    [GRUB_INSTALL_PLATFORM_RISCV32_EFI] = { "riscv32-efi", "efinet", ".efi" },
+    [GRUB_INSTALL_PLATFORM_RISCV64_EFI] = { "riscv64-efi", "efinet", ".efi" },
   };
 
 static void
diff --git a/util/grub-mkrescue.c b/util/grub-mkrescue.c
index 9545945d8..21e5ce4e4 100644
--- a/util/grub-mkrescue.c
+++ b/util/grub-mkrescue.c
@@ -538,6 +538,8 @@ main (int argc, char *argv[])
 	  || source_dirs[GRUB_INSTALL_PLATFORM_IA64_EFI]
 	  || source_dirs[GRUB_INSTALL_PLATFORM_ARM_EFI]
 	  || source_dirs[GRUB_INSTALL_PLATFORM_ARM64_EFI]
+	  || source_dirs[GRUB_INSTALL_PLATFORM_RISCV32_EFI]
+	  || source_dirs[GRUB_INSTALL_PLATFORM_RISCV64_EFI]
 	  || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI])
 	system_area = SYS_AREA_COMMON;
       else if (source_dirs[GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275])
@@ -735,7 +737,9 @@ main (int argc, char *argv[])
       || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI]
       || source_dirs[GRUB_INSTALL_PLATFORM_IA64_EFI]
       || source_dirs[GRUB_INSTALL_PLATFORM_ARM_EFI]
-      || source_dirs[GRUB_INSTALL_PLATFORM_ARM64_EFI])
+      || source_dirs[GRUB_INSTALL_PLATFORM_ARM64_EFI]
+      || source_dirs[GRUB_INSTALL_PLATFORM_RISCV32_EFI]
+      || source_dirs[GRUB_INSTALL_PLATFORM_RISCV64_EFI])
     {
       char *efidir = grub_util_make_temporary_dir ();
       char *efidir_efi = grub_util_path_concat (2, efidir, "efi");
@@ -770,6 +774,16 @@ main (int argc, char *argv[])
 			     imgname);
       free (imgname);
 
+      imgname = grub_util_path_concat (2, efidir_efi_boot, "bootriscv32.efi");
+      make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_RISCV32_EFI, "riscv32-efi",
+			     imgname);
+      free (imgname);
+
+      imgname = grub_util_path_concat (2, efidir_efi_boot, "bootriscv64.efi");
+      make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_RISCV64_EFI, "riscv64-efi",
+			     imgname);
+      free (imgname);
+
       if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI])
 	{
 	  imgname = grub_util_path_concat (2, efidir_efi_boot, "boot.efi");
diff --git a/util/mkimage.c b/util/mkimage.c
index e22d82afa..b5368ffd2 100644
--- a/util/mkimage.c
+++ b/util/mkimage.c
@@ -609,6 +609,38 @@ static const struct grub_install_image_target_desc image_targets[] =
       .pe_target = GRUB_PE32_MACHINE_ARM64,
       .elf_target = EM_AARCH64,
     },
+    {
+      .dirname = "riscv32-efi",
+      .names = { "riscv32-efi", NULL },
+      .voidp_sizeof = 4,
+      .bigendian = 0,
+      .id = IMAGE_EFI,
+      .flags = PLATFORM_FLAGS_NONE,
+      .total_module_size = TARGET_NO_FIELD,
+      .decompressor_compressed_size = TARGET_NO_FIELD,
+      .decompressor_uncompressed_size = TARGET_NO_FIELD,
+      .decompressor_uncompressed_addr = TARGET_NO_FIELD,
+      .section_align = GRUB_PE32_SECTION_ALIGNMENT,
+      .vaddr_offset = EFI32_HEADER_SIZE,
+      .pe_target = GRUB_PE32_MACHINE_RISCV32,
+      .elf_target = EM_RISCV,
+    },
+    {
+      .dirname = "riscv64-efi",
+      .names = { "riscv64-efi", NULL },
+      .voidp_sizeof = 8,
+      .bigendian = 0,
+      .id = IMAGE_EFI,
+      .flags = PLATFORM_FLAGS_NONE,
+      .total_module_size = TARGET_NO_FIELD,
+      .decompressor_compressed_size = TARGET_NO_FIELD,
+      .decompressor_uncompressed_size = TARGET_NO_FIELD,
+      .decompressor_uncompressed_addr = TARGET_NO_FIELD,
+      .section_align = GRUB_PE32_SECTION_ALIGNMENT,
+      .vaddr_offset = EFI64_HEADER_SIZE,
+      .pe_target = GRUB_PE32_MACHINE_RISCV64,
+      .elf_target = EM_RISCV,
+    },
   };
 
 #include <grub/lib/LzmaEnc.h>
-- 
2.12.3



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

* [PATCH v3 10/10] fdt: Add device tree file type
  2018-11-14 17:27 [PATCH v3 00/10] Add RISC-V support Alexander Graf
                   ` (8 preceding siblings ...)
  2018-11-14 17:27 ` [PATCH v3 09/10] RISC-V: Add to build system Alexander Graf
@ 2018-11-14 17:27 ` Alexander Graf
  2018-11-16 22:07   ` Alistair Francis
                     ` (2 more replies)
  9 siblings, 3 replies; 41+ messages in thread
From: Alexander Graf @ 2018-11-14 17:27 UTC (permalink / raw)
  To: grub-devel
  Cc: leif.lindholm, Peter Jones, Paul Walmsley, David Abdurachmanov,
	atish.patra, schwab, Michael Chang, Alistair Francis, Lukas Auer,
	greentime @ andestech . com, rickchen36 @ gmail . com, Bin Meng

We now have signature check logic in grub which allows us to treat
files differently depending on their file type.

Mark a loaded device tree as such and treat it like an overlayed ACPI
table. Both describe hardware, so I suppose their threat level is the
same.

Signed-off-by: Alexander Graf <agraf@suse.de>
---
 grub-core/commands/efi/shim_lock.c | 1 +
 grub-core/loader/efi/fdt.c         | 2 +-
 include/grub/file.h                | 2 ++
 3 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/grub-core/commands/efi/shim_lock.c b/grub-core/commands/efi/shim_lock.c
index 01246b0fc..90dccb0c7 100644
--- a/grub-core/commands/efi/shim_lock.c
+++ b/grub-core/commands/efi/shim_lock.c
@@ -81,6 +81,7 @@ shim_lock_init (grub_file_t io, enum grub_file_type type,
       /* Fall through. */
 
     case GRUB_FILE_TYPE_ACPI_TABLE:
+    case GRUB_FILE_TYPE_DEVICE_TREE:
       *flags = GRUB_VERIFY_FLAGS_DEFER_AUTH;
 
       return GRUB_ERR_NONE;
diff --git a/grub-core/loader/efi/fdt.c b/grub-core/loader/efi/fdt.c
index a4c6e8036..d8ebe648e 100644
--- a/grub-core/loader/efi/fdt.c
+++ b/grub-core/loader/efi/fdt.c
@@ -123,7 +123,7 @@ grub_cmd_devicetree (grub_command_t cmd __attribute__ ((unused)),
       return GRUB_ERR_NONE;
     }
 
-  dtb = grub_file_open (argv[0]);
+  dtb = grub_file_open (argv[0], GRUB_FILE_TYPE_DEVICE_TREE);
   if (!dtb)
     goto out;
 
diff --git a/include/grub/file.h b/include/grub/file.h
index 19dda67f6..b8fb13017 100644
--- a/include/grub/file.h
+++ b/include/grub/file.h
@@ -93,6 +93,8 @@ enum grub_file_type
     GRUB_FILE_TYPE_FILE_ID,
     /* File holding ACPI table.  */
     GRUB_FILE_TYPE_ACPI_TABLE,
+    /* File holding Device Tree.  */
+    GRUB_FILE_TYPE_DEVICE_TREE,
     /* File we intend show to user.  */
     GRUB_FILE_TYPE_CAT,
     GRUB_FILE_TYPE_HEXCAT,
-- 
2.12.3



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

* Re: [PATCH v3 10/10] fdt: Add device tree file type
  2018-11-14 17:27 ` [PATCH v3 10/10] fdt: Add device tree file type Alexander Graf
@ 2018-11-16 22:07   ` Alistair Francis
  2018-11-19 10:11   ` Andreas Schwab
  2018-11-21 16:27   ` Daniel Kiper
  2 siblings, 0 replies; 41+ messages in thread
From: Alistair Francis @ 2018-11-16 22:07 UTC (permalink / raw)
  To: grub-devel, agraf
  Cc: pjones, paul.walmsley, bmeng.cn, greentime, schwab, mchang,
	leif.lindholm, lukas.auer, david.abdurachmanov, Atish Patra,
	rickchen36

On Wed, 2018-11-14 at 18:27 +0100, Alexander Graf wrote:
> We now have signature check logic in grub which allows us to treat
> files differently depending on their file type.
> 
> Mark a loaded device tree as such and treat it like an overlayed ACPI
> table. Both describe hardware, so I suppose their threat level is the
> same.
> 
> Signed-off-by: Alexander Graf <agraf@suse.de>

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

Alistair

> ---
>  grub-core/commands/efi/shim_lock.c | 1 +
>  grub-core/loader/efi/fdt.c         | 2 +-
>  include/grub/file.h                | 2 ++
>  3 files changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/grub-core/commands/efi/shim_lock.c b/grub-
> core/commands/efi/shim_lock.c
> index 01246b0fc..90dccb0c7 100644
> --- a/grub-core/commands/efi/shim_lock.c
> +++ b/grub-core/commands/efi/shim_lock.c
> @@ -81,6 +81,7 @@ shim_lock_init (grub_file_t io, enum grub_file_type
> type,
>        /* Fall through. */
>  
>      case GRUB_FILE_TYPE_ACPI_TABLE:
> +    case GRUB_FILE_TYPE_DEVICE_TREE:
>        *flags = GRUB_VERIFY_FLAGS_DEFER_AUTH;
>  
>        return GRUB_ERR_NONE;
> diff --git a/grub-core/loader/efi/fdt.c b/grub-core/loader/efi/fdt.c
> index a4c6e8036..d8ebe648e 100644
> --- a/grub-core/loader/efi/fdt.c
> +++ b/grub-core/loader/efi/fdt.c
> @@ -123,7 +123,7 @@ grub_cmd_devicetree (grub_command_t cmd
> __attribute__ ((unused)),
>        return GRUB_ERR_NONE;
>      }
>  
> -  dtb = grub_file_open (argv[0]);
> +  dtb = grub_file_open (argv[0], GRUB_FILE_TYPE_DEVICE_TREE);
>    if (!dtb)
>      goto out;
>  
> diff --git a/include/grub/file.h b/include/grub/file.h
> index 19dda67f6..b8fb13017 100644
> --- a/include/grub/file.h
> +++ b/include/grub/file.h
> @@ -93,6 +93,8 @@ enum grub_file_type
>      GRUB_FILE_TYPE_FILE_ID,
>      /* File holding ACPI table.  */
>      GRUB_FILE_TYPE_ACPI_TABLE,
> +    /* File holding Device Tree.  */
> +    GRUB_FILE_TYPE_DEVICE_TREE,
>      /* File we intend show to user.  */
>      GRUB_FILE_TYPE_CAT,
>      GRUB_FILE_TYPE_HEXCAT,

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

* Re: [PATCH v3 06/10] RISC-V: Add Linux load logic
  2018-11-14 17:27 ` [PATCH v3 06/10] RISC-V: Add Linux load logic Alexander Graf
@ 2018-11-16 22:18   ` Alistair Francis
  2018-11-21 15:43   ` Daniel Kiper
  1 sibling, 0 replies; 41+ messages in thread
From: Alistair Francis @ 2018-11-16 22:18 UTC (permalink / raw)
  To: grub-devel, agraf
  Cc: pjones, paul.walmsley, bmeng.cn, greentime, schwab, mchang,
	leif.lindholm, lukas.auer, david.abdurachmanov, Atish Patra,
	rickchen36

On Wed, 2018-11-14 at 18:27 +0100, Alexander Graf wrote:
> We currently only support to run grub on RISC-V as UEFI payload.
> Ideally,
> we also only want to support running Linux underneath as UEFI
> payload.
> 
> Prepare that with a Linux boot case that is not enabled in Linux yet.
> At
> least it will give people something to test against when they enable
> the
> Linux UEFI port.
> 
> Signed-off-by: Alexander Graf <agraf@suse.de>

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

Alistair

> 
> ---
> 
> v1 -> v2:
> 
>   - adapt to new grub_open_file() API
>   - adapt to new grub_create_loader_cmdline() API
> ---
>  grub-core/loader/riscv/linux.c | 352
> +++++++++++++++++++++++++++++++++++++++++
>  include/grub/riscv32/linux.h   |  41 +++++
>  include/grub/riscv64/linux.h   |  43 +++++
>  3 files changed, 436 insertions(+)
>  create mode 100644 grub-core/loader/riscv/linux.c
>  create mode 100644 include/grub/riscv32/linux.h
>  create mode 100644 include/grub/riscv64/linux.h
> 
> diff --git a/grub-core/loader/riscv/linux.c b/grub-
> core/loader/riscv/linux.c
> new file mode 100644
> index 000000000..2527bb7fc
> --- /dev/null
> +++ b/grub-core/loader/riscv/linux.c
> @@ -0,0 +1,352 @@
> +/*
> + *  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/charset.h>
> +#include <grub/command.h>
> +#include <grub/err.h>
> +#include <grub/file.h>
> +#include <grub/fdt.h>
> +#include <grub/linux.h>
> +#include <grub/loader.h>
> +#include <grub/mm.h>
> +#include <grub/types.h>
> +#include <grub/cpu/linux.h>
> +#include <grub/efi/efi.h>
> +#include <grub/efi/fdtload.h>
> +#include <grub/efi/memory.h>
> +#include <grub/efi/pe32.h>
> +#include <grub/i18n.h>
> +#include <grub/lib/cmdline.h>
> +
> +GRUB_MOD_LICENSE ("GPLv3+");
> +
> +static grub_dl_t my_mod;
> +static int loaded;
> +
> +static void *kernel_addr;
> +static grub_uint64_t kernel_size;
> +
> +static char *linux_args;
> +static grub_uint32_t cmdline_size;
> +
> +static grub_addr_t initrd_start;
> +static grub_addr_t initrd_end;
> +
> +grub_err_t
> +grub_arch_efi_linux_check_image (struct linux_riscv_kernel_header *
> lh)
> +{
> +  if (lh->magic != GRUB_LINUX_RISCV_MAGIC_SIGNATURE)
> +    return grub_error(GRUB_ERR_BAD_OS, "invalid magic number");
> +
> +  if ((lh->code0 & 0xffff) != GRUB_PE32_MAGIC)
> +    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
> +		       N_("plain image kernel not supported - rebuild
> with CONFIG_(U)EFI_STUB enabled"));
> +
> +  grub_dprintf ("linux", "UEFI stub kernel:\n");
> +  grub_dprintf ("linux", "PE/COFF header @ %08x\n", lh->hdr_offset);
> +
> +  return GRUB_ERR_NONE;
> +}
> +
> +static grub_err_t
> +finalize_params_linux (void)
> +{
> +  int node, retval;
> +
> +  void *fdt;
> +
> +  fdt = grub_fdt_load (0x400);
> +
> +  if (!fdt)
> +    goto failure;
> +
> +  node = grub_fdt_find_subnode (fdt, 0, "chosen");
> +  if (node < 0)
> +    node = grub_fdt_add_subnode (fdt, 0, "chosen");
> +
> +  if (node < 1)
> +    goto failure;
> +
> +  /* Set initrd info */
> +  if (initrd_start && initrd_end > initrd_start)
> +    {
> +      grub_dprintf ("linux", "Initrd @ %p-%p\n",
> +		    (void *) initrd_start, (void *) initrd_end);
> +
> +      retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-start",
> +				    initrd_start);
> +      if (retval)
> +	goto failure;
> +      retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-end",
> +				    initrd_end);
> +      if (retval)
> +	goto failure;
> +    }
> +
> +  if (grub_fdt_install() != GRUB_ERR_NONE)
> +    goto failure;
> +
> +  return GRUB_ERR_NONE;
> +
> +failure:
> +  grub_fdt_unload();
> +  return grub_error(GRUB_ERR_BAD_OS, "failed to install/update
> FDT");
> +}
> +
> +grub_err_t
> +grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size,
> char *args)
> +{
> +  grub_efi_memory_mapped_device_path_t *mempath;
> +  grub_efi_handle_t image_handle;
> +  grub_efi_boot_services_t *b;
> +  grub_efi_status_t status;
> +  grub_efi_loaded_image_t *loaded_image;
> +  int len;
> +
> +  mempath = grub_malloc (2 * sizeof
> (grub_efi_memory_mapped_device_path_t));
> +  if (!mempath)
> +    return grub_errno;
> +
> +  mempath[0].header.type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE;
> +  mempath[0].header.subtype =
> GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE;
> +  mempath[0].header.length = grub_cpu_to_le16_compile_time (sizeof
> (*mempath));
> +  mempath[0].memory_type = GRUB_EFI_LOADER_DATA;
> +  mempath[0].start_address = addr;
> +  mempath[0].end_address = addr + size;
> +
> +  mempath[1].header.type = GRUB_EFI_END_DEVICE_PATH_TYPE;
> +  mempath[1].header.subtype =
> GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
> +  mempath[1].header.length = sizeof (grub_efi_device_path_t);
> +
> +  b = grub_efi_system_table->boot_services;
> +  status = b->load_image (0, grub_efi_image_handle,
> +			  (grub_efi_device_path_t *) mempath,
> +			  (void *) addr, size, &image_handle);
> +  if (status != GRUB_EFI_SUCCESS)
> +    return grub_error (GRUB_ERR_BAD_OS, "cannot load image");
> +
> +  grub_dprintf ("linux", "linux command line: '%s'\n", args);
> +
> +  /* Convert command line to UCS-2 */
> +  loaded_image = grub_efi_get_loaded_image (image_handle);
> +  loaded_image->load_options_size = len =
> +    (grub_strlen (args) + 1) * sizeof (grub_efi_char16_t);
> +  loaded_image->load_options =
> +    grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES
> (loaded_image->load_options_size));
> +  if (!loaded_image->load_options)
> +    return grub_errno;
> +
> +  loaded_image->load_options_size =
> +    2 * grub_utf8_to_utf16 (loaded_image->load_options, len,
> +			    (grub_uint8_t *) args, len, NULL);
> +
> +  grub_dprintf ("linux", "starting image %p\n", image_handle);
> +  status = b->start_image (image_handle, 0, NULL);
> +
> +  /* When successful, not reached */
> +  b->unload_image (image_handle);
> +  grub_efi_free_pages ((grub_addr_t) loaded_image->load_options,
> +		       GRUB_EFI_BYTES_TO_PAGES (loaded_image-
> >load_options_size));
> +
> +  return grub_errno;
> +}
> +
> +static grub_err_t
> +grub_linux_boot (void)
> +{
> +  if (finalize_params_linux () != GRUB_ERR_NONE)
> +    return grub_errno;
> +
> +  return (grub_arch_efi_linux_boot_image((grub_addr_t)kernel_addr,
> +                                         kernel_size, linux_args));
> +}
> +
> +static grub_err_t
> +grub_linux_unload (void)
> +{
> +  grub_dl_unref (my_mod);
> +  loaded = 0;
> +  if (initrd_start)
> +    grub_efi_free_pages ((grub_efi_physical_address_t) initrd_start,
> +			 GRUB_EFI_BYTES_TO_PAGES (initrd_end -
> initrd_start));
> +  initrd_start = initrd_end = 0;
> +  grub_free (linux_args);
> +  if (kernel_addr)
> +    grub_efi_free_pages ((grub_addr_t) kernel_addr,
> +			 GRUB_EFI_BYTES_TO_PAGES (kernel_size));
> +  grub_fdt_unload ();
> +  return GRUB_ERR_NONE;
> +}
> +
> +static grub_err_t
> +grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
> +		 int argc, char *argv[])
> +{
> +  struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 };
> +  int initrd_size, initrd_pages;
> +  void *initrd_mem = NULL;
> +
> +  if (argc == 0)
> +    {
> +      grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
> +      goto fail;
> +    }
> +
> +  if (!loaded)
> +    {
> +      grub_error (GRUB_ERR_BAD_ARGUMENT,
> +		  N_("you need to load the kernel first"));
> +      goto fail;
> +    }
> +
> +  if (grub_initrd_init (argc, argv, &initrd_ctx))
> +    goto fail;
> +
> +  initrd_size = grub_get_initrd_size (&initrd_ctx);
> +  grub_dprintf ("linux", "Loading initrd\n");
> +
> +  initrd_pages = (GRUB_EFI_BYTES_TO_PAGES (initrd_size));
> +  initrd_mem = grub_efi_allocate_any_pages (initrd_pages);
> +  if (!initrd_mem)
> +    {
> +      grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
> +      goto fail;
> +    }
> +
> +  if (grub_initrd_load (&initrd_ctx, argv, initrd_mem))
> +    goto fail;
> +
> +  initrd_start = (grub_addr_t) initrd_mem;
> +  initrd_end = initrd_start + initrd_size;
> +  grub_dprintf ("linux", "[addr=%p, size=0x%x]\n",
> +		(void *) initrd_start, initrd_size);
> +
> + fail:
> +  grub_initrd_close (&initrd_ctx);
> +  if (initrd_mem && !initrd_start)
> +    grub_efi_free_pages ((grub_addr_t) initrd_mem, initrd_pages);
> +
> +  return grub_errno;
> +}
> +
> +static grub_err_t
> +grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
> +		int argc, char *argv[])
> +{
> +  grub_file_t file = 0;
> +  struct linux_riscv_kernel_header lh;
> +
> +  grub_dl_ref (my_mod);
> +
> +  if (argc == 0)
> +    {
> +      grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
> +      goto fail;
> +    }
> +
> +  file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL);
> +  if (!file)
> +    goto fail;
> +
> +  kernel_size = grub_file_size (file);
> +
> +  if (grub_file_read (file, &lh, sizeof (lh)) < (long) sizeof (lh))
> +    return grub_errno;
> +
> +  if (grub_arch_efi_linux_check_image (&lh) != GRUB_ERR_NONE)
> +    goto fail;
> +
> +  grub_loader_unset();
> +
> +  grub_dprintf ("linux", "kernel file size: %lld\n", (long long)
> kernel_size);
> +  kernel_addr = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES
> (kernel_size));
> +  grub_dprintf ("linux", "kernel numpages: %lld\n",
> +		(long long) GRUB_EFI_BYTES_TO_PAGES (kernel_size));
> +  if (!kernel_addr)
> +    {
> +      grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
> +      goto fail;
> +    }
> +
> +  grub_file_seek (file, 0);
> +  if (grub_file_read (file, kernel_addr, kernel_size)
> +      < (grub_int64_t) kernel_size)
> +    {
> +      if (!grub_errno)
> +	grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
> argv[0]);
> +      goto fail;
> +    }
> +
> +  grub_dprintf ("linux", "kernel @ %p\n", kernel_addr);
> +
> +  cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof
> (LINUX_IMAGE);
> +  linux_args = grub_malloc (cmdline_size);
> +  if (!linux_args)
> +    {
> +      grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
> +      goto fail;
> +    }
> +  grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE));
> +  grub_create_loader_cmdline (argc, argv,
> +			      linux_args + sizeof (LINUX_IMAGE) - 1,
> +			      cmdline_size,
> +			      GRUB_VERIFY_KERNEL_CMDLINE);
> +
> +  if (grub_errno == GRUB_ERR_NONE)
> +    {
> +      grub_loader_set (grub_linux_boot, grub_linux_unload, 0);
> +      loaded = 1;
> +    }
> +
> +fail:
> +  if (file)
> +    grub_file_close (file);
> +
> +  if (grub_errno != GRUB_ERR_NONE)
> +    {
> +      grub_dl_unref (my_mod);
> +      loaded = 0;
> +    }
> +
> +  if (linux_args && !loaded)
> +    grub_free (linux_args);
> +
> +  if (kernel_addr && !loaded)
> +    grub_efi_free_pages ((grub_addr_t) kernel_addr,
> +			 GRUB_EFI_BYTES_TO_PAGES (kernel_size));
> +
> +  return grub_errno;
> +}
> +
> +
> +static grub_command_t cmd_linux, cmd_initrd;
> +
> +GRUB_MOD_INIT (linux)
> +{
> +  cmd_linux = grub_register_command ("linux", grub_cmd_linux, 0,
> +				     N_("Load Linux."));
> +  cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, 0,
> +				      N_("Load initrd."));
> +  my_mod = mod;
> +}
> +
> +GRUB_MOD_FINI (linux)
> +{
> +  grub_unregister_command (cmd_linux);
> +  grub_unregister_command (cmd_initrd);
> +}
> diff --git a/include/grub/riscv32/linux.h
> b/include/grub/riscv32/linux.h
> new file mode 100644
> index 000000000..5c70d00b4
> --- /dev/null
> +++ b/include/grub/riscv32/linux.h
> @@ -0,0 +1,41 @@
> +/*
> + *  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_RISCV32_LINUX_HEADER
> +#define GRUB_RISCV32_LINUX_HEADER 1
> +
> +#define GRUB_LINUX_RISCV_MAGIC_SIGNATURE 0x52534356 /* 'RSCV' */
> +
> +/* From linux/Documentation/riscv/booting.txt */
> +struct linux_riscv_kernel_header
> +{
> +  grub_uint32_t code0;		/* Executable code */
> +  grub_uint32_t code1;		/* Executable code */
> +  grub_uint64_t text_offset;    /* Image load offset */
> +  grub_uint64_t res0;		/* reserved */
> +  grub_uint64_t res1;		/* reserved */
> +  grub_uint64_t res2;		/* reserved */
> +  grub_uint64_t res3;		/* reserved */
> +  grub_uint64_t res4;		/* reserved */
> +  grub_uint32_t magic;		/* Magic number, little endian,
> "RSCV" */
> +  grub_uint32_t hdr_offset;	/* Offset of PE/COFF header */
> +};
> +
> +# define linux_arch_kernel_header linux_riscv_kernel_header
> +
> +#endif /* ! GRUB_RISCV32_LINUX_HEADER */
> diff --git a/include/grub/riscv64/linux.h
> b/include/grub/riscv64/linux.h
> new file mode 100644
> index 000000000..aa6b8687e
> --- /dev/null
> +++ b/include/grub/riscv64/linux.h
> @@ -0,0 +1,43 @@
> +/*
> + *  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_RISCV64_LINUX_HEADER
> +#define GRUB_RISCV64_LINUX_HEADER 1
> +
> +#define GRUB_LINUX_RISCV_MAGIC_SIGNATURE 0x52534356 /* 'RSCV' */
> +
> +#define GRUB_EFI_PE_MAGIC	0x5A4D
> +
> +/* From linux/Documentation/riscv/booting.txt */
> +struct linux_riscv_kernel_header
> +{
> +  grub_uint32_t code0;		/* Executable code */
> +  grub_uint32_t code1;		/* Executable code */
> +  grub_uint64_t text_offset;    /* Image load offset */
> +  grub_uint64_t res0;		/* reserved */
> +  grub_uint64_t res1;		/* reserved */
> +  grub_uint64_t res2;		/* reserved */
> +  grub_uint64_t res3;		/* reserved */
> +  grub_uint64_t res4;		/* reserved */
> +  grub_uint32_t magic;		/* Magic number, little endian,
> "RSCV" */
> +  grub_uint32_t hdr_offset;	/* Offset of PE/COFF header */
> +};
> +
> +# define linux_arch_kernel_header linux_riscv_kernel_header
> +
> +#endif /* ! GRUB_RISCV64_LINUX_HEADER */

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

* Re: [PATCH v3 08/10] RISC-V: Add auxiliary files
  2018-11-14 17:27 ` [PATCH v3 08/10] RISC-V: Add auxiliary files Alexander Graf
@ 2018-11-17 22:51   ` Auer, Lukas
  2018-11-25 23:01     ` Alexander Graf
  2018-11-21 16:02   ` Daniel Kiper
  1 sibling, 1 reply; 41+ messages in thread
From: Auer, Lukas @ 2018-11-17 22:51 UTC (permalink / raw)
  To: grub-devel, agraf
  Cc: pjones, paul.walmsley, Alistair.Francis, bmeng.cn, greentime,
	schwab, mchang, leif.lindholm, david.abdurachmanov, atish.patra,
	rickchen36

On Wed, 2018-11-14 at 18:27 +0100, Alexander Graf wrote:
> To support a new architecture we need to provide a few helper
> functions
> for memory, cache, timer, etc support.
> 
> This patch adds the remainders of those. Some bits are still
> disabled,
> as I couldn't guarantee that we're always running on models / in
> modes
> where the respective hardware is available.
> 
> Signed-off-by: Alexander Graf <agraf@suse.de>
> 
> ---
> 
> v2 -> v3:
> 
>   - Fix riscv32 target
> ---
>  grub-core/kern/riscv/cache.c       | 64
> +++++++++++++++++++++++++++++
>  grub-core/kern/riscv/cache_flush.S | 40 +++++++++++++++++++
>  grub-core/kern/riscv/efi/init.c    | 82
> ++++++++++++++++++++++++++++++++++++++
>  include/grub/riscv32/efi/memory.h  |  6 +++
>  include/grub/riscv32/time.h        | 28 +++++++++++++
>  include/grub/riscv32/types.h       | 34 ++++++++++++++++
>  include/grub/riscv64/efi/memory.h  |  6 +++
>  include/grub/riscv64/time.h        | 28 +++++++++++++
>  include/grub/riscv64/types.h       | 34 ++++++++++++++++
>  9 files changed, 322 insertions(+)
>  create mode 100644 grub-core/kern/riscv/cache.c
>  create mode 100644 grub-core/kern/riscv/cache_flush.S
>  create mode 100644 grub-core/kern/riscv/efi/init.c
>  create mode 100644 include/grub/riscv32/efi/memory.h
>  create mode 100644 include/grub/riscv32/time.h
>  create mode 100644 include/grub/riscv32/types.h
>  create mode 100644 include/grub/riscv64/efi/memory.h
>  create mode 100644 include/grub/riscv64/time.h
>  create mode 100644 include/grub/riscv64/types.h
> 
> diff --git a/grub-core/kern/riscv/cache.c b/grub-
> core/kern/riscv/cache.c
> new file mode 100644
> index 000000000..15dbe6927
> --- /dev/null
> +++ b/grub-core/kern/riscv/cache.c
> @@ -0,0 +1,64 @@
> +/*
> + *  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/cache.h>
> +#include <grub/misc.h>
> +
> +static grub_int64_t dlinesz;
> +static grub_int64_t ilinesz;
> +
> +/* Prototypes for asm functions. */
> +void grub_arch_clean_dcache_range (grub_addr_t beg, grub_addr_t end,
> +				   grub_size_t line_size);
> +void grub_arch_invalidate_icache_range (grub_addr_t beg, grub_addr_t
> end,
> +					grub_size_t line_size);
> +
> +static void
> +probe_caches (void)
> +{
> +  /* TODO */
> +  dlinesz = 32;
> +  ilinesz = 32;
> +}
> +
> +void
> +grub_arch_sync_caches (void *address, grub_size_t len)
> +{
> +  grub_size_t start, end, max_align;
> +
> +  if (dlinesz == 0)
> +    probe_caches();
> +  if (dlinesz == 0)
> +    grub_fatal ("Unknown cache line size!");
> +
> +  max_align = dlinesz > ilinesz ? dlinesz : ilinesz;
> +
> +  start = ALIGN_DOWN ((grub_size_t) address, max_align);
> +  end = ALIGN_UP ((grub_size_t) address + len, max_align);
> +
> +  grub_arch_clean_dcache_range (start, end, dlinesz);
> +  grub_arch_invalidate_icache_range (start, end, ilinesz);
> +}
> +
> +void
> +grub_arch_sync_dma_caches (volatile void *address, grub_size_t len)
> +{
> +  /* DMA incoherent devices not supported yet */
> +  if (address || len || 1)
> +    return;
> +}
> diff --git a/grub-core/kern/riscv/cache_flush.S b/grub-
> core/kern/riscv/cache_flush.S
> new file mode 100644
> index 000000000..033a8aac3
> --- /dev/null
> +++ b/grub-core/kern/riscv/cache_flush.S
> @@ -0,0 +1,40 @@
> +/*
> + *  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>
> +
> +	.file	"cache_flush.S"
> +	.text
> +
> +/*
> + * Simple cache maintenance functions
> + */
> +
> +// a0 - *beg (inclusive)
> +// a1 - *end (exclusive)
> +// a2 - line size
> +FUNCTION(grub_arch_clean_dcache_range)
> +	// TODO
> +	ret
> +
> +// a0 - *beg (inclusive)
> +// a1 - *end (exclusive)
> +// a2 - line size
> +FUNCTION(grub_arch_invalidate_icache_range)
> +	// TODO
> +	ret

You can use fence.i here to synchronize writes to instruction memory
with instruction fetches. Essentially a instruction cache flush, but
different processors may choose different implementations for it.

Lukas

> diff --git a/grub-core/kern/riscv/efi/init.c b/grub-
> core/kern/riscv/efi/init.c
> new file mode 100644
> index 000000000..199de08a7
> --- /dev/null
> +++ b/grub-core/kern/riscv/efi/init.c
> @@ -0,0 +1,82 @@
> +/* init.c - initialize a riscv-based EFI system */
> +/*
> + *  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/env.h>
> +#include <grub/kernel.h>
> +#include <grub/misc.h>
> +#include <grub/mm.h>
> +#include <grub/time.h>
> +#include <grub/efi/efi.h>
> +#include <grub/loader.h>
> +
> +static grub_uint64_t timer_frequency_in_khz;
> +
> +static grub_uint64_t
> +grub_efi_get_time_ms (void)
> +{
> +  grub_uint64_t tmr;
> +
> +#if 0
> +#if __riscv_xlen == 64
> +  asm volatile ("rdtime %0" : "=r" (tmr));
> +#else
> +  grub_uint32_t lo, hi, tmp;
> +  asm volatile (
> +    "1:\n"
> +    "rdtimeh %0\n"
> +    "rdtime %1\n"
> +    "rdtimeh %2\n"
> +    "bne %0, %2, 1b"
> +    : "=&r" (hi), "=&r" (lo), "=&r" (tmp));
> +  tmr = ((u64)hi << 32) | lo;
> +#endif
> +#else
> +  static grub_uint64_t val;
> +  tmr = val++;
> +#endif
> +
> +  return tmr / timer_frequency_in_khz;
> +}
> +
> +
> +void
> +grub_machine_init (void)
> +{
> +  grub_uint64_t time_before, time_after;
> +
> +  grub_efi_init ();
> +
> +  /* Calculate timer frequency */
> +  timer_frequency_in_khz = 1;
> +  time_before = grub_efi_get_time_ms();
> +  grub_efi_stall(1000);
> +  time_after = grub_efi_get_time_ms();
> +  timer_frequency_in_khz = time_after - time_before;
> +
> +  grub_install_get_time_ms (grub_efi_get_time_ms);
> +}
> +
> +void
> +grub_machine_fini (int flags)
> +{
> +  if (!(flags & GRUB_LOADER_FLAG_NORETURN))
> +    return;
> +
> +  grub_efi_fini ();
> +}
> diff --git a/include/grub/riscv32/efi/memory.h
> b/include/grub/riscv32/efi/memory.h
> new file mode 100644
> index 000000000..e61c474ff
> --- /dev/null
> +++ b/include/grub/riscv32/efi/memory.h
> @@ -0,0 +1,6 @@
> +#ifndef GRUB_MEMORY_CPU_HEADER
> +#include <grub/efi/memory.h>
> +
> +#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffffUL
> +
> +#endif /* ! GRUB_MEMORY_CPU_HEADER */
> diff --git a/include/grub/riscv32/time.h
> b/include/grub/riscv32/time.h
> new file mode 100644
> index 000000000..f9546ec0e
> --- /dev/null
> +++ b/include/grub/riscv32/time.h
> @@ -0,0 +1,28 @@
> +/*
> + *  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 KERNEL_CPU_TIME_HEADER
> +#define KERNEL_CPU_TIME_HEADER	1
> +
> +static __inline void
> +grub_cpu_idle (void)
> +{
> +  /* TODO */
> +}
> +
> +#endif /* ! KERNEL_CPU_TIME_HEADER */
> diff --git a/include/grub/riscv32/types.h
> b/include/grub/riscv32/types.h
> new file mode 100644
> index 000000000..8c90ce2ec
> --- /dev/null
> +++ b/include/grub/riscv32/types.h
> @@ -0,0 +1,34 @@
> +/*
> + *  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_TYPES_CPU_HEADER
> +#define GRUB_TYPES_CPU_HEADER	1
> +
> +/* The size of void *.  */
> +#define GRUB_TARGET_SIZEOF_VOID_P	4
> +
> +/* The size of long.  */
> +#define GRUB_TARGET_SIZEOF_LONG		4
> +
> +/* currently only support little-endian.  */
> +#undef GRUB_TARGET_WORDS_BIGENDIAN
> +
> +/* Unaligned accesses can be very slow, so avoid them */
> +#undef GRUB_HAVE_UNALIGNED_ACCESS
> +
> +#endif /* ! GRUB_TYPES_CPU_HEADER */
> diff --git a/include/grub/riscv64/efi/memory.h
> b/include/grub/riscv64/efi/memory.h
> new file mode 100644
> index 000000000..c6cb32417
> --- /dev/null
> +++ b/include/grub/riscv64/efi/memory.h
> @@ -0,0 +1,6 @@
> +#ifndef GRUB_MEMORY_CPU_HEADER
> +#include <grub/efi/memory.h>
> +
> +#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffffffffULL
> +
> +#endif /* ! GRUB_MEMORY_CPU_HEADER */
> diff --git a/include/grub/riscv64/time.h
> b/include/grub/riscv64/time.h
> new file mode 100644
> index 000000000..f9546ec0e
> --- /dev/null
> +++ b/include/grub/riscv64/time.h
> @@ -0,0 +1,28 @@
> +/*
> + *  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 KERNEL_CPU_TIME_HEADER
> +#define KERNEL_CPU_TIME_HEADER	1
> +
> +static __inline void
> +grub_cpu_idle (void)
> +{
> +  /* TODO */
> +}
> +
> +#endif /* ! KERNEL_CPU_TIME_HEADER */
> diff --git a/include/grub/riscv64/types.h
> b/include/grub/riscv64/types.h
> new file mode 100644
> index 000000000..8823bc7d8
> --- /dev/null
> +++ b/include/grub/riscv64/types.h
> @@ -0,0 +1,34 @@
> +/*
> + *  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_TYPES_CPU_HEADER
> +#define GRUB_TYPES_CPU_HEADER	1
> +
> +/* The size of void *.  */
> +#define GRUB_TARGET_SIZEOF_VOID_P	8
> +
> +/* The size of long.  */
> +#define GRUB_TARGET_SIZEOF_LONG		8
> +
> +/* currently only support little-endian.  */
> +#undef GRUB_TARGET_WORDS_BIGENDIAN
> +
> +/* Unaligned accesses can be very slow, so avoid them */
> +#undef GRUB_HAVE_UNALIGNED_ACCESS
> +
> +#endif /* ! GRUB_TYPES_CPU_HEADER */

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

* Re: [PATCH v3 01/10] efi: Rename armxx to arch
  2018-11-14 17:27 ` [PATCH v3 01/10] efi: Rename armxx to arch Alexander Graf
@ 2018-11-18 11:41   ` Bin Meng
  0 siblings, 0 replies; 41+ messages in thread
From: Bin Meng @ 2018-11-18 11:41 UTC (permalink / raw)
  To: Alexander Graf
  Cc: grub-devel, Leif Lindholm, pjones, paul.walmsley,
	David Abdurachmanov, atish.patra, schwab, mchang,
	Alistair.Francis, Lukas Auer, greentime, rickchen36

On Thu, Nov 15, 2018 at 1:27 AM Alexander Graf <agraf@suse.de> wrote:
>
> Some architectures want to boot Linux as plain UEFI binary. Today that
> really only encompasses ARM and AArch64, but going forward more
> architectures may adopt that model.
>
> So rename our internal API accordingly.
>
> Signed-off-by: Alexander Graf <agraf@suse.de>
> Acked-by: Leif Lindholm <leif.lindholm@linaro.org>
> Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
> ---
>  grub-core/loader/arm64/linux.c    | 10 +++++-----
>  grub-core/loader/arm64/xen_boot.c |  6 +++---
>  include/grub/arm/linux.h          |  2 +-
>  include/grub/arm64/linux.h        |  2 +-
>  include/grub/efi/efi.h            |  4 ++--
>  5 files changed, 12 insertions(+), 12 deletions(-)
>

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>


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

* Re: [PATCH v3 02/10] PE: Add RISC-V definitions
  2018-11-14 17:27 ` [PATCH v3 02/10] PE: Add RISC-V definitions Alexander Graf
@ 2018-11-18 11:41   ` Bin Meng
  0 siblings, 0 replies; 41+ messages in thread
From: Bin Meng @ 2018-11-18 11:41 UTC (permalink / raw)
  To: Alexander Graf
  Cc: grub-devel, Leif Lindholm, pjones, paul.walmsley,
	David Abdurachmanov, atish.patra, schwab, mchang,
	Alistair.Francis, Lukas Auer, greentime, rickchen36

On Thu, Nov 15, 2018 at 1:27 AM Alexander Graf <agraf@suse.de> wrote:
>
> The PE format defines magic numbers as well as relocation identifiers for
> RISC-V. Add them to our include file, so we can make use of them.
>
> Signed-off-by: Alexander Graf <agraf@suse.de>
> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
> Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
> ---
>  include/grub/efi/pe32.h | 5 +++++
>  1 file changed, 5 insertions(+)
>

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>


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

* Re: [PATCH v3 03/10] elf.h: Add RISC-V definitions
  2018-11-14 17:27 ` [PATCH v3 03/10] elf.h: " Alexander Graf
@ 2018-11-18 11:41   ` Bin Meng
  0 siblings, 0 replies; 41+ messages in thread
From: Bin Meng @ 2018-11-18 11:41 UTC (permalink / raw)
  To: Alexander Graf
  Cc: grub-devel, Leif Lindholm, pjones, paul.walmsley,
	David Abdurachmanov, atish.patra, schwab, mchang,
	Alistair.Francis, Lukas Auer, greentime, rickchen36

On Thu, Nov 15, 2018 at 1:27 AM Alexander Graf <agraf@suse.de> wrote:
>
> The RISC-V ABI document outlines ELF header structure and relocation
> information. Pull the respective magic numbers into our elf header
> so we can make use of them.
>
> Signed-off-by: Alexander Graf <agraf@suse.de>
> Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
> ---
>  include/grub/elf.h | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 59 insertions(+)
>

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>


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

* Re: [PATCH v3 04/10] RISC-V: Add setjmp implementation
  2018-11-14 17:27 ` [PATCH v3 04/10] RISC-V: Add setjmp implementation Alexander Graf
@ 2018-11-18 11:41   ` Bin Meng
  2018-11-21 15:31   ` Daniel Kiper
  1 sibling, 0 replies; 41+ messages in thread
From: Bin Meng @ 2018-11-18 11:41 UTC (permalink / raw)
  To: Alexander Graf
  Cc: grub-devel, Leif Lindholm, pjones, paul.walmsley,
	David Abdurachmanov, atish.patra, schwab, mchang,
	Alistair.Francis, Lukas Auer, greentime, rickchen36

On Thu, Nov 15, 2018 at 1:27 AM Alexander Graf <agraf@suse.de> 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>
> ---
>  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
>

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>


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

* Re: [PATCH v3 05/10] RISC-V: Add early startup code
  2018-11-14 17:27 ` [PATCH v3 05/10] RISC-V: Add early startup code Alexander Graf
@ 2018-11-18 11:41   ` Bin Meng
  0 siblings, 0 replies; 41+ messages in thread
From: Bin Meng @ 2018-11-18 11:41 UTC (permalink / raw)
  To: Alexander Graf
  Cc: grub-devel, Leif Lindholm, pjones, paul.walmsley,
	David Abdurachmanov, atish.patra, schwab, mchang,
	Alistair.Francis, Lukas Auer, greentime, rickchen36

On Thu, Nov 15, 2018 at 1:27 AM Alexander Graf <agraf@suse.de> wrote:
>
> On entry, we need to save the system table pointer as well as our image
> handle. Add an early startup file that saves them and then brings us
> into our main function.
>
> Signed-off-by: Alexander Graf <agraf@suse.de>
> Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
> ---
>  grub-core/kern/riscv/efi/startup.S | 49 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 49 insertions(+)
>  create mode 100644 grub-core/kern/riscv/efi/startup.S
>

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>


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

* Re: [PATCH v3 09/10] RISC-V: Add to build system
  2018-11-14 17:27 ` [PATCH v3 09/10] RISC-V: Add to build system Alexander Graf
@ 2018-11-18 11:41   ` Bin Meng
  2018-11-25 23:06     ` Alexander Graf
  2018-11-21 16:09   ` Daniel Kiper
  1 sibling, 1 reply; 41+ messages in thread
From: Bin Meng @ 2018-11-18 11:41 UTC (permalink / raw)
  To: Alexander Graf
  Cc: grub-devel, Leif Lindholm, pjones, paul.walmsley,
	David Abdurachmanov, atish.patra, schwab, mchang,
	Alistair.Francis, Lukas Auer, greentime, rickchen36

Hi Alex,

On Thu, Nov 15, 2018 at 1:27 AM Alexander Graf <agraf@suse.de> wrote:
>
> This patch adds support for RISC-V to the grub build system. With this
> patch, I can successfully build grub on RISC-V as a UEFI application.
>
> Signed-off-by: Alexander Graf <agraf@suse.de>
> Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
>
> ---
>
> v2 -> v3:
>
>   - Fix riscv32 target
> ---
>  configure.ac                 | 28 ++++++++++++++++++++++++++--
>  gentpl.py                    | 11 +++++++----
>  grub-core/Makefile.am        | 12 ++++++++++++
>  grub-core/Makefile.core.def  | 29 +++++++++++++++++++++++++++++
>  grub-core/commands/file.c    | 14 +++++++++++++-
>  grub-core/kern/compiler-rt.c |  6 ++++--
>  grub-core/kern/efi/mm.c      |  2 +-
>  grub-core/kern/emu/cache.c   |  6 ++++++
>  grub-core/kern/emu/cache_s.S |  1 +
>  grub-core/kern/emu/lite.c    |  2 ++
>  grub-core/lib/efi/halt.c     |  3 ++-
>  grub-core/lib/setjmp.S       |  2 ++
>  include/grub/compiler-rt.h   | 12 ++++++++----
>  include/grub/efi/api.h       |  3 ++-
>  include/grub/efi/efi.h       |  2 +-
>  include/grub/misc.h          |  3 ++-
>  include/grub/util/install.h  |  2 ++
>  util/grub-install-common.c   |  2 ++
>  util/grub-install.c          | 28 ++++++++++++++++++++++++++++
>  util/grub-mknetdir.c         |  4 +++-
>  util/grub-mkrescue.c         | 16 +++++++++++++++-
>  util/mkimage.c               | 32 ++++++++++++++++++++++++++++++++
>  22 files changed, 200 insertions(+), 20 deletions(-)
>

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>

But please see one comment below:

> diff --git a/configure.ac b/configure.ac
> index 5e63c4af3..2cc2ffb2c 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -104,6 +104,12 @@ case "$target_cpu" in
>    aarch64*)
>                 target_cpu=arm64
>                 ;;
> +  riscv32*)
> +               target_cpu=riscv32
> +               ;;
> +  riscv64*)
> +               target_cpu=riscv64
> +               ;;
>  esac
>
>  # Specify the platform (such as firmware).
> @@ -127,6 +133,8 @@ if test "x$with_platform" = x; then
>      ia64-*) platform=efi ;;
>      arm-*) platform=uboot ;;
>      arm64-*) platform=efi ;;
> +    riscv32-*) platform=efi ;;
> +    riscv64-*) platform=efi ;;
>      *)
>        AC_MSG_WARN([unsupported CPU: "$target_cpu" - only building utilities])
>        platform=none
> @@ -174,6 +182,8 @@ case "$target_cpu"-"$platform" in
>    arm-coreboot) ;;
>    arm-efi) ;;
>    arm64-efi) ;;
> +  riscv32-efi) ;;
> +  riscv64-efi) ;;
>    *-emu) ;;
>    *-none) ;;
>    *) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;;
> @@ -826,6 +836,16 @@ if test x"$platform" != xemu ; then
>         AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
>                          [grub_cv_target_cc_soft_float="-mgeneral-regs-only"], [])
>      fi
> +    if test "x$target_cpu" = xriscv32; then
> +       CFLAGS="$TARGET_CFLAGS -march=rv32imac -mabi=ilp32 -Werror"
> +       AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
> +                        [grub_cv_target_cc_soft_float="-march=rv32imac -mabi=ilp32"], [])
> +    fi
> +    if test "x$target_cpu" = xriscv64; then
> +       CFLAGS="$TARGET_CFLAGS -march=rv64imac -mabi=lp64 -Werror"
> +       AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
> +                        [grub_cv_target_cc_soft_float="-march=rv64imac -mabi=lp64"], [])
> +    fi
>      if test "x$target_cpu" = xia64; then
>         CFLAGS="$TARGET_CFLAGS -mno-inline-float-divide -mno-inline-sqrt -Werror"
>         AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
> @@ -1141,7 +1161,7 @@ AC_SUBST(TARGET_LDFLAGS_OLDMAGIC)
>
>  LDFLAGS="$TARGET_LDFLAGS"
>
> -if test "$target_cpu" = x86_64 || test "$target_cpu" = sparc64 ; then
> +if test "$target_cpu" = x86_64 || test "$target_cpu" = sparc64 || test "$target_cpu" = riscv64 ; then
>    # Use large model to support 4G memory
>    AC_CACHE_CHECK([whether option -mcmodel=large works], grub_cv_cc_mcmodel, [
>      CFLAGS="$TARGET_CFLAGS -mcmodel=large"
> @@ -1151,7 +1171,7 @@ if test "$target_cpu" = x86_64 || test "$target_cpu" = sparc64 ; then
>    ])
>    if test "x$grub_cv_cc_mcmodel" = xyes; then
>      TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=large"
> -  elif test "$target_cpu" = sparc64; then
> +  elif test "$target_cpu" = sparc64 || test "$target_cpu" = riscv64; then
>      TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=medany"

The patch does not indicate the code model explicitly for riscv32.
It's better we pass the -mcmodel=medlow (suitable for riscv32) to the
compiler in case the compiler is configured with a different code
model by default.

>    fi
>  fi

[snip]

Regards,
Bin


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

* Re: [PATCH v3 10/10] fdt: Add device tree file type
  2018-11-14 17:27 ` [PATCH v3 10/10] fdt: Add device tree file type Alexander Graf
  2018-11-16 22:07   ` Alistair Francis
@ 2018-11-19 10:11   ` Andreas Schwab
  2018-11-19 17:56     ` Leif Lindholm
  2018-11-21 16:27   ` Daniel Kiper
  2 siblings, 1 reply; 41+ messages in thread
From: Andreas Schwab @ 2018-11-19 10:11 UTC (permalink / raw)
  To: Alexander Graf
  Cc: grub-devel, leif.lindholm, Peter Jones, Paul Walmsley,
	David Abdurachmanov, atish.patra, Michael Chang,
	Alistair Francis, Lukas Auer, greentime @ andestech . com,
	rickchen36 @ gmail . com, Bin Meng

On Nov 14 2018, Alexander Graf <agraf@suse.de> wrote:

> diff --git a/grub-core/loader/efi/fdt.c b/grub-core/loader/efi/fdt.c
> index a4c6e8036..d8ebe648e 100644
> --- a/grub-core/loader/efi/fdt.c
> +++ b/grub-core/loader/efi/fdt.c
> @@ -123,7 +123,7 @@ grub_cmd_devicetree (grub_command_t cmd __attribute__ ((unused)),
>        return GRUB_ERR_NONE;
>      }
>  
> -  dtb = grub_file_open (argv[0]);
> +  dtb = grub_file_open (argv[0], GRUB_FILE_TYPE_DEVICE_TREE);
>    if (!dtb)
>      goto out;
>  

Looks like this has been obsoleted by commit dfb1742aab?

Andreas.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."


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

* Re: [PATCH v3 10/10] fdt: Add device tree file type
  2018-11-19 10:11   ` Andreas Schwab
@ 2018-11-19 17:56     ` Leif Lindholm
  2018-11-21 16:36       ` Daniel Kiper
  0 siblings, 1 reply; 41+ messages in thread
From: Leif Lindholm @ 2018-11-19 17:56 UTC (permalink / raw)
  To: Andreas Schwab
  Cc: Alexander Graf, grub-devel, Peter Jones, Paul Walmsley,
	David Abdurachmanov, atish.patra, Michael Chang,
	Alistair Francis, Lukas Auer, greentime @ andestech . com,
	rickchen36 @ gmail . com, Bin Meng

On Mon, Nov 19, 2018 at 11:11:09AM +0100, Andreas Schwab wrote:
> On Nov 14 2018, Alexander Graf <agraf@suse.de> wrote:
> 
> > diff --git a/grub-core/loader/efi/fdt.c b/grub-core/loader/efi/fdt.c
> > index a4c6e8036..d8ebe648e 100644
> > --- a/grub-core/loader/efi/fdt.c
> > +++ b/grub-core/loader/efi/fdt.c
> > @@ -123,7 +123,7 @@ grub_cmd_devicetree (grub_command_t cmd __attribute__ ((unused)),
> >        return GRUB_ERR_NONE;
> >      }
> >  
> > -  dtb = grub_file_open (argv[0]);
> > +  dtb = grub_file_open (argv[0], GRUB_FILE_TYPE_DEVICE_TREE);
> >    if (!dtb)
> >      goto out;
> >  
> 
> Looks like this has been obsoleted by commit dfb1742aab?

Actually, that one does not do anything sensible in
grub-core/commands/efi/shim_lock.c
so that hunk would be worth considering including.

Treating DT and ACPI equally sounds sensible to me.

/
    Leif


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

* Re: [PATCH v3 04/10] RISC-V: Add setjmp implementation
  2018-11-14 17:27 ` [PATCH v3 04/10] RISC-V: Add setjmp implementation Alexander Graf
  2018-11-18 11:41   ` Bin Meng
@ 2018-11-21 15:31   ` Daniel Kiper
  1 sibling, 0 replies; 41+ messages in thread
From: Daniel Kiper @ 2018-11-21 15:31 UTC (permalink / raw)
  To: The development of GNU GRUB
  Cc: rickchen36 @ gmail . com, David Abdurachmanov, schwab,
	greentime @ andestech . com, leif.lindholm, atish.patra,
	Michael Chang, Alistair Francis, Lukas Auer, Paul Walmsley,
	Bin Meng

On Wed, Nov 14, 2018 at 06:27:33PM +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>
> ---
>  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.

s/2013/2018/ Please fix this here and in other places/patches.

Daniel


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

* Re: [PATCH v3 06/10] RISC-V: Add Linux load logic
  2018-11-14 17:27 ` [PATCH v3 06/10] RISC-V: Add Linux load logic Alexander Graf
  2018-11-16 22:18   ` Alistair Francis
@ 2018-11-21 15:43   ` Daniel Kiper
  1 sibling, 0 replies; 41+ messages in thread
From: Daniel Kiper @ 2018-11-21 15:43 UTC (permalink / raw)
  To: The development of GNU GRUB
  Cc: rickchen36 @ gmail . com, David Abdurachmanov, schwab,
	greentime @ andestech . com, leif.lindholm, atish.patra,
	Michael Chang, Alistair Francis, Lukas Auer, Paul Walmsley,
	Bin Meng

On Wed, Nov 14, 2018 at 06:27:35PM +0100, Alexander Graf wrote:
> We currently only support to run grub on RISC-V as UEFI payload. Ideally,
> we also only want to support running Linux underneath as UEFI payload.
>
> Prepare that with a Linux boot case that is not enabled in Linux yet. At
> least it will give people something to test against when they enable the
> Linux UEFI port.
>
> Signed-off-by: Alexander Graf <agraf@suse.de>
>
> ---
>
> v1 -> v2:
>
>   - adapt to new grub_open_file() API
>   - adapt to new grub_create_loader_cmdline() API
> ---
>  grub-core/loader/riscv/linux.c | 352 +++++++++++++++++++++++++++++++++++++++++
>  include/grub/riscv32/linux.h   |  41 +++++
>  include/grub/riscv64/linux.h   |  43 +++++
>  3 files changed, 436 insertions(+)
>  create mode 100644 grub-core/loader/riscv/linux.c
>  create mode 100644 include/grub/riscv32/linux.h
>  create mode 100644 include/grub/riscv64/linux.h
>
> diff --git a/grub-core/loader/riscv/linux.c b/grub-core/loader/riscv/linux.c
> new file mode 100644
> index 000000000..2527bb7fc
> --- /dev/null
> +++ b/grub-core/loader/riscv/linux.c
> @@ -0,0 +1,352 @@
> +/*
> + *  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/charset.h>
> +#include <grub/command.h>
> +#include <grub/err.h>
> +#include <grub/file.h>
> +#include <grub/fdt.h>
> +#include <grub/linux.h>
> +#include <grub/loader.h>
> +#include <grub/mm.h>
> +#include <grub/types.h>
> +#include <grub/cpu/linux.h>
> +#include <grub/efi/efi.h>
> +#include <grub/efi/fdtload.h>
> +#include <grub/efi/memory.h>
> +#include <grub/efi/pe32.h>
> +#include <grub/i18n.h>
> +#include <grub/lib/cmdline.h>
> +
> +GRUB_MOD_LICENSE ("GPLv3+");
> +
> +static grub_dl_t my_mod;
> +static int loaded;
> +
> +static void *kernel_addr;
> +static grub_uint64_t kernel_size;
> +
> +static char *linux_args;
> +static grub_uint32_t cmdline_size;
> +
> +static grub_addr_t initrd_start;
> +static grub_addr_t initrd_end;
> +
> +grub_err_t
> +grub_arch_efi_linux_check_image (struct linux_riscv_kernel_header * lh)
> +{
> +  if (lh->magic != GRUB_LINUX_RISCV_MAGIC_SIGNATURE)
> +    return grub_error(GRUB_ERR_BAD_OS, "invalid magic number");
> +
> +  if ((lh->code0 & 0xffff) != GRUB_PE32_MAGIC)
> +    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
> +		       N_("plain image kernel not supported - rebuild with CONFIG_(U)EFI_STUB enabled"));
> +
> +  grub_dprintf ("linux", "UEFI stub kernel:\n");
> +  grub_dprintf ("linux", "PE/COFF header @ %08x\n", lh->hdr_offset);
> +
> +  return GRUB_ERR_NONE;
> +}
> +
> +static grub_err_t
> +finalize_params_linux (void)
> +{
> +  int node, retval;
> +
> +  void *fdt;
> +
> +  fdt = grub_fdt_load (0x400);
> +
> +  if (!fdt)
> +    goto failure;
> +
> +  node = grub_fdt_find_subnode (fdt, 0, "chosen");
> +  if (node < 0)
> +    node = grub_fdt_add_subnode (fdt, 0, "chosen");
> +
> +  if (node < 1)
> +    goto failure;
> +
> +  /* Set initrd info */
> +  if (initrd_start && initrd_end > initrd_start)
> +    {
> +      grub_dprintf ("linux", "Initrd @ %p-%p\n",
> +		    (void *) initrd_start, (void *) initrd_end);
> +
> +      retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-start",
> +				    initrd_start);
> +      if (retval)
> +	goto failure;
> +      retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-end",
> +				    initrd_end);
> +      if (retval)
> +	goto failure;
> +    }
> +
> +  if (grub_fdt_install() != GRUB_ERR_NONE)
> +    goto failure;
> +
> +  return GRUB_ERR_NONE;
> +
> +failure:
> +  grub_fdt_unload();
> +  return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT");
> +}
> +
> +grub_err_t
> +grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args)
> +{
> +  grub_efi_memory_mapped_device_path_t *mempath;
> +  grub_efi_handle_t image_handle;
> +  grub_efi_boot_services_t *b;
> +  grub_efi_status_t status;
> +  grub_efi_loaded_image_t *loaded_image;
> +  int len;
> +
> +  mempath = grub_malloc (2 * sizeof (grub_efi_memory_mapped_device_path_t));
> +  if (!mempath)
> +    return grub_errno;
> +
> +  mempath[0].header.type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE;
> +  mempath[0].header.subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE;
> +  mempath[0].header.length = grub_cpu_to_le16_compile_time (sizeof (*mempath));
> +  mempath[0].memory_type = GRUB_EFI_LOADER_DATA;
> +  mempath[0].start_address = addr;
> +  mempath[0].end_address = addr + size;
> +
> +  mempath[1].header.type = GRUB_EFI_END_DEVICE_PATH_TYPE;
> +  mempath[1].header.subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
> +  mempath[1].header.length = sizeof (grub_efi_device_path_t);
> +
> +  b = grub_efi_system_table->boot_services;
> +  status = b->load_image (0, grub_efi_image_handle,
> +			  (grub_efi_device_path_t *) mempath,
> +			  (void *) addr, size, &image_handle);
> +  if (status != GRUB_EFI_SUCCESS)
> +    return grub_error (GRUB_ERR_BAD_OS, "cannot load image");
> +
> +  grub_dprintf ("linux", "linux command line: '%s'\n", args);
> +
> +  /* Convert command line to UCS-2 */
> +  loaded_image = grub_efi_get_loaded_image (image_handle);
> +  loaded_image->load_options_size = len =
> +    (grub_strlen (args) + 1) * sizeof (grub_efi_char16_t);
> +  loaded_image->load_options =
> +    grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size));
> +  if (!loaded_image->load_options)
> +    return grub_errno;
> +
> +  loaded_image->load_options_size =
> +    2 * grub_utf8_to_utf16 (loaded_image->load_options, len,
> +			    (grub_uint8_t *) args, len, NULL);
> +
> +  grub_dprintf ("linux", "starting image %p\n", image_handle);
> +  status = b->start_image (image_handle, 0, NULL);
> +
> +  /* When successful, not reached */
> +  b->unload_image (image_handle);
> +  grub_efi_free_pages ((grub_addr_t) loaded_image->load_options,
> +		       GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size));
> +
> +  return grub_errno;
> +}
> +
> +static grub_err_t
> +grub_linux_boot (void)
> +{
> +  if (finalize_params_linux () != GRUB_ERR_NONE)
> +    return grub_errno;
> +
> +  return (grub_arch_efi_linux_boot_image((grub_addr_t)kernel_addr,
> +                                         kernel_size, linux_args));
> +}
> +
> +static grub_err_t
> +grub_linux_unload (void)
> +{
> +  grub_dl_unref (my_mod);
> +  loaded = 0;
> +  if (initrd_start)
> +    grub_efi_free_pages ((grub_efi_physical_address_t) initrd_start,
> +			 GRUB_EFI_BYTES_TO_PAGES (initrd_end - initrd_start));
> +  initrd_start = initrd_end = 0;
> +  grub_free (linux_args);
> +  if (kernel_addr)
> +    grub_efi_free_pages ((grub_addr_t) kernel_addr,
> +			 GRUB_EFI_BYTES_TO_PAGES (kernel_size));
> +  grub_fdt_unload ();
> +  return GRUB_ERR_NONE;
> +}
> +
> +static grub_err_t
> +grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
> +		 int argc, char *argv[])
> +{
> +  struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 };
> +  int initrd_size, initrd_pages;
> +  void *initrd_mem = NULL;
> +
> +  if (argc == 0)
> +    {
> +      grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
> +      goto fail;
> +    }
> +
> +  if (!loaded)
> +    {
> +      grub_error (GRUB_ERR_BAD_ARGUMENT,
> +		  N_("you need to load the kernel first"));
> +      goto fail;
> +    }
> +
> +  if (grub_initrd_init (argc, argv, &initrd_ctx))
> +    goto fail;
> +
> +  initrd_size = grub_get_initrd_size (&initrd_ctx);
> +  grub_dprintf ("linux", "Loading initrd\n");
> +
> +  initrd_pages = (GRUB_EFI_BYTES_TO_PAGES (initrd_size));
> +  initrd_mem = grub_efi_allocate_any_pages (initrd_pages);
> +  if (!initrd_mem)
> +    {
> +      grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
> +      goto fail;
> +    }
> +
> +  if (grub_initrd_load (&initrd_ctx, argv, initrd_mem))
> +    goto fail;
> +
> +  initrd_start = (grub_addr_t) initrd_mem;
> +  initrd_end = initrd_start + initrd_size;
> +  grub_dprintf ("linux", "[addr=%p, size=0x%x]\n",
> +		(void *) initrd_start, initrd_size);
> +
> + fail:

Please be consistent and use labels with one space before them everywhere.

> +  grub_initrd_close (&initrd_ctx);
> +  if (initrd_mem && !initrd_start)
> +    grub_efi_free_pages ((grub_addr_t) initrd_mem, initrd_pages);
> +
> +  return grub_errno;
> +}
> +
> +static grub_err_t
> +grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
> +		int argc, char *argv[])
> +{
> +  grub_file_t file = 0;
> +  struct linux_riscv_kernel_header lh;
> +
> +  grub_dl_ref (my_mod);
> +
> +  if (argc == 0)
> +    {
> +      grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
> +      goto fail;
> +    }
> +
> +  file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL);
> +  if (!file)
> +    goto fail;
> +
> +  kernel_size = grub_file_size (file);
> +
> +  if (grub_file_read (file, &lh, sizeof (lh)) < (long) sizeof (lh))
> +    return grub_errno;
> +
> +  if (grub_arch_efi_linux_check_image (&lh) != GRUB_ERR_NONE)
> +    goto fail;
> +
> +  grub_loader_unset();
> +
> +  grub_dprintf ("linux", "kernel file size: %lld\n", (long long) kernel_size);
> +  kernel_addr = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (kernel_size));
> +  grub_dprintf ("linux", "kernel numpages: %lld\n",
> +		(long long) GRUB_EFI_BYTES_TO_PAGES (kernel_size));
> +  if (!kernel_addr)
> +    {
> +      grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
> +      goto fail;
> +    }
> +
> +  grub_file_seek (file, 0);
> +  if (grub_file_read (file, kernel_addr, kernel_size)
> +      < (grub_int64_t) kernel_size)
> +    {
> +      if (!grub_errno)
> +	grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), argv[0]);
> +      goto fail;
> +    }
> +
> +  grub_dprintf ("linux", "kernel @ %p\n", kernel_addr);
> +
> +  cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE);
> +  linux_args = grub_malloc (cmdline_size);
> +  if (!linux_args)
> +    {
> +      grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
> +      goto fail;
> +    }
> +  grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE));
> +  grub_create_loader_cmdline (argc, argv,
> +			      linux_args + sizeof (LINUX_IMAGE) - 1,
> +			      cmdline_size,
> +			      GRUB_VERIFY_KERNEL_CMDLINE);
> +
> +  if (grub_errno == GRUB_ERR_NONE)
> +    {
> +      grub_loader_set (grub_linux_boot, grub_linux_unload, 0);
> +      loaded = 1;
> +    }
> +
> +fail:
> +  if (file)
> +    grub_file_close (file);
> +
> +  if (grub_errno != GRUB_ERR_NONE)
> +    {
> +      grub_dl_unref (my_mod);
> +      loaded = 0;
> +    }
> +
> +  if (linux_args && !loaded)
> +    grub_free (linux_args);
> +
> +  if (kernel_addr && !loaded)
> +    grub_efi_free_pages ((grub_addr_t) kernel_addr,
> +			 GRUB_EFI_BYTES_TO_PAGES (kernel_size));
> +
> +  return grub_errno;
> +}
> +
> +

Please drop this extra empty line.

Daniel


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

* Re: [PATCH v3 07/10] RISC-V: Add awareness for RISC-V reloations
  2018-11-14 17:27 ` [PATCH v3 07/10] RISC-V: Add awareness for RISC-V reloations Alexander Graf
@ 2018-11-21 15:51   ` Daniel Kiper
  2018-11-21 16:08     ` Andreas Schwab
  2018-11-25 22:12     ` Alexander Graf
  0 siblings, 2 replies; 41+ messages in thread
From: Daniel Kiper @ 2018-11-21 15:51 UTC (permalink / raw)
  To: The development of GNU GRUB
  Cc: rickchen36 @ gmail . com, David Abdurachmanov, schwab,
	greentime @ andestech . com, leif.lindholm, atish.patra,
	Michael Chang, Alistair Francis, Lukas Auer, Paul Walmsley,
	Bin Meng

On Wed, Nov 14, 2018 at 06:27:36PM +0100, Alexander Graf wrote:
> This patch adds awareness of RISC-V relocations throughout the grub tools
> as well as dynamic linkage and elf->PE relocation conversion support.
>
> Signed-off-by: Alexander Graf <agraf@suse.de>
>
> ---
>
> v2 -> v3:
>
>   - Fix riscv32 target
> ---
>  grub-core/kern/dl.c         |   6 +-
>  grub-core/kern/riscv/dl.c   | 335 ++++++++++++++++++++++++++++++++++++++++++++
>  include/grub/dl.h           |   6 +-
>  util/grub-mkimagexx.c       | 268 +++++++++++++++++++++++++++++++++++
>  util/grub-module-verifier.c |  56 ++++++++
>  5 files changed, 666 insertions(+), 5 deletions(-)
>  create mode 100644 grub-core/kern/riscv/dl.c
>
> diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
> index f8d58f029..48eb5e7b6 100644
> --- a/grub-core/kern/dl.c
> +++ b/grub-core/kern/dl.c
> @@ -225,7 +225,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
>    unsigned i;
>    const Elf_Shdr *s;
>    grub_size_t tsize = 0, talign = 1;
> -#if !defined (__i386__) && !defined (__x86_64__)
> +#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv)

Could not we use __riscv__?

>    grub_size_t tramp;
>    grub_size_t got;
>    grub_err_t err;
> @@ -241,7 +241,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
>  	talign = s->sh_addralign;
>      }
>
> -#if !defined (__i386__) && !defined (__x86_64__)
> +#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv)
>    err = grub_arch_dl_get_tramp_got_size (e, &tramp, &got);
>    if (err)
>      return err;
> @@ -304,7 +304,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
>  	  mod->segment = seg;
>  	}
>      }
> -#if !defined (__i386__) && !defined (__x86_64__)
> +#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv)
>    ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_TRAMP_ALIGN);
>    mod->tramp = ptr;
>    mod->trampptr = ptr;
> diff --git a/grub-core/kern/riscv/dl.c b/grub-core/kern/riscv/dl.c
> new file mode 100644
> index 000000000..503b67df1
> --- /dev/null
> +++ b/grub-core/kern/riscv/dl.c
> @@ -0,0 +1,335 @@
> +/* dl.c - arch-dependent part of loadable module support */
> +/*
> + *  GRUB  --  GRand Unified Bootloader
> + *  Copyright (C) 2013  Free Software Foundation, Inc.

s/2013/2018/

> + *
> + *  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/dl.h>
> +#include <grub/elf.h>
> +#include <grub/misc.h>
> +#include <grub/err.h>
> +#include <grub/mm.h>
> +#include <grub/i18n.h>
> +
> +#define LDR 0x58000050
> +#define BR 0xd61f0200
> +
> +

Please drop this empty line.

> +/*
> + * Check if EHDR is a valid ELF header.
> + */
> +grub_err_t
> +grub_arch_dl_check_header (void *ehdr)
> +{
> +  Elf_Ehdr *e = ehdr;
> +
> +  /* Check the magic numbers.  */
> +  if (e->e_ident[EI_DATA] != ELFDATA2LSB || e->e_machine != EM_RISCV)
> +    return grub_error (GRUB_ERR_BAD_OS,
> +		       N_("invalid arch-dependent ELF magic"));
> +
> +  return GRUB_ERR_NONE;
> +}
> +
> +#pragma GCC diagnostic ignored "-Wcast-align"

Why? Could you add a comment here?

> +/* Relocate symbols. */
> +grub_err_t
> +grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
> +			       Elf_Shdr *s, grub_dl_segment_t seg)
> +{
> +  Elf_Rel *rel, *max;
> +
> +  for (rel = (Elf_Rel *) ((char *) ehdr + s->sh_offset),
> +	 max = (Elf_Rel *) ((char *) rel + s->sh_size);
> +       rel < max;
> +       rel = (Elf_Rel *) ((char *) rel + s->sh_entsize))
> +    {
> +      Elf_Sym *sym;
> +      void *place;
> +      grub_size_t sym_addr;
> +
> +      if (rel->r_offset >= seg->size)
> +	return grub_error (GRUB_ERR_BAD_MODULE,
> +			   "reloc offset is out of the segment");
> +
> +      sym = (Elf_Sym *) ((char *) mod->symtab
> +			 + mod->symsize * ELF_R_SYM (rel->r_info));
> +
> +      sym_addr = sym->st_value;
> +      if (s->sh_type == SHT_RELA)
> +	sym_addr += ((Elf_Rela *) rel)->r_addend;
> +
> +      place = (void *) ((grub_addr_t) seg->addr + rel->r_offset);
> +
> +      switch (ELF_R_TYPE (rel->r_info))
> +	{
> +	case R_RISCV_32:
> +	  {
> +	    grub_uint32_t *abs_place = place;
> +
> +	    grub_dprintf ("dl", "  reloc_abs32 %p => 0x%016llx\n",
> +			  place, (unsigned long long) sym_addr);
> +
> +	    *abs_place = (grub_uint32_t) sym_addr;
> +	  }
> +	  break;
> +	case R_RISCV_64:
> +	  {
> +	    grub_size_t *abs_place = place;
> +
> +	    grub_dprintf ("dl", "  reloc_abs64 %p => 0x%016llx\n",
> +			  place, (unsigned long long) sym_addr);
> +
> +	    *abs_place = (grub_size_t) sym_addr;
> +	  }
> +	  break;
> +
> +	case R_RISCV_ADD8:
> +	  {
> +	    grub_uint8_t *abs_place = place;
> +
> +	    *abs_place += (grub_uint8_t) sym_addr;
> +	  }
> +	  break;
> +	case R_RISCV_ADD16:
> +	  {
> +	    grub_uint16_t *abs_place = place;
> +
> +	    *abs_place += (grub_uint16_t) sym_addr;
> +	  }
> +	  break;
> +	case R_RISCV_ADD32:
> +	  {
> +	    grub_uint32_t *abs_place = place;
> +
> +	    *abs_place += (grub_uint32_t) sym_addr;
> +	  }
> +	  break;
> +	case R_RISCV_ADD64:
> +	  {
> +	    grub_size_t *abs_place = place;
> +
> +	    *abs_place += (grub_size_t) sym_addr;
> +	  }
> +	  break;
> +
> +	case R_RISCV_SUB8:
> +	  {
> +	    grub_uint8_t *abs_place = place;
> +
> +	    *abs_place -= (grub_uint8_t) sym_addr;
> +	  }
> +	  break;
> +	case R_RISCV_SUB16:
> +	  {
> +	    grub_uint16_t *abs_place = place;
> +
> +	    *abs_place -= (grub_uint16_t) sym_addr;
> +	  }
> +	  break;
> +	case R_RISCV_SUB32:
> +	  {
> +	    grub_uint32_t *abs_place = place;
> +
> +	    *abs_place -= (grub_uint32_t) sym_addr;
> +	  }
> +	  break;
> +	case R_RISCV_SUB64:
> +	  {
> +	    grub_size_t *abs_place = place;
> +
> +	    *abs_place -= (grub_size_t) sym_addr;
> +	  }
> +	  break;
> +
> +	case R_RISCV_BRANCH:
> +	  {
> +	    grub_uint32_t *abs_place = place;
> +	    grub_ssize_t off = sym_addr - (grub_addr_t) place;
> +	    grub_uint32_t imm12 = (off & 0x1000) << (31 - 12);
> +	    grub_uint32_t imm11 = (off & 0x800) >> (11 - 7);
> +	    grub_uint32_t imm10_5 = (off & 0x7e0) << (30 - 10);
> +	    grub_uint32_t imm4_1 = (off & 0x1e) << (11 - 4);
> +	    *abs_place = (*abs_place & 0x1fff07f)
> +			 | imm12 | imm11 | imm10_5 | imm4_1;

Could not we use some constants instead of numbers here?
If this does not make sense than please name the source of this numbers.

> +	  }
> +	  break;
> +
> +	case R_RISCV_JAL:
> +	  {
> +	    grub_uint32_t *abs_place = place;
> +	    grub_ssize_t off = sym_addr - (grub_addr_t) place;
> +	    grub_uint32_t imm20 = (off & 0x100000) << (31 - 20);
> +	    grub_uint32_t imm19_12 = (off & 0xff000);
> +	    grub_uint32_t imm11 = (off & 0x800) << (20 - 11);
> +	    grub_uint32_t imm10_1 = (off & 0x7fe) << (30 - 10);
> +	    *abs_place = (*abs_place & 0xfff)
> +			 | imm20 | imm19_12 | imm11 | imm10_1;

Ditto.

> +	  }
> +	  break;
> +
> +	case R_RISCV_CALL:
> +	  {
> +	    grub_uint32_t *abs_place = place;
> +	    grub_ssize_t off = sym_addr - (grub_addr_t) place;
> +	    grub_uint32_t hi20, lo12;
> +
> +	    if (off != (grub_int32_t) off)
> +	      return grub_error (GRUB_ERR_BAD_MODULE, "relocation overflow");
> +
> +	    hi20 = (off + 0x800) & 0xfffff000;
> +	    lo12 = (off - hi20) & 0xfff;
> +	    abs_place[0] = (abs_place[0] & 0xfff) | hi20;
> +	    abs_place[1] = (abs_place[1] & 0xfffff) | (lo12 << 20);

Ditto and below...

> +	  }
> +	  break;
> +
> +	case R_RISCV_RVC_BRANCH:
> +	  {
> +	    grub_uint16_t *abs_place = place;
> +	    grub_ssize_t off = sym_addr - (grub_addr_t) place;
> +	    grub_uint16_t imm8 = (off & 0x100) << (12 - 8);
> +	    grub_uint16_t imm7_6 = (off & 0xc0) >> (6 - 5);
> +	    grub_uint16_t imm5 = (off & 0x20) >> (5 - 2);
> +	    grub_uint16_t imm4_3 = (off & 0x18) << (12 - 5);
> +	    grub_uint16_t imm2_1 = (off & 0x6) << (12 - 10);
> +	    *abs_place = (*abs_place & 0xe383)
> +			 | imm8 | imm7_6 | imm5 | imm4_3 | imm2_1;
> +	  }
> +	  break;
> +
> +	case R_RISCV_RVC_JUMP:
> +	  {
> +	    grub_uint16_t *abs_place = place;
> +	    grub_ssize_t off = sym_addr - (grub_addr_t) place;
> +	    grub_uint16_t imm11 = (off & 0x800) << (12 - 11);
> +	    grub_uint16_t imm10 = (off & 0x400) >> (10 - 8);
> +	    grub_uint16_t imm9_8 = (off & 0x300) << (12 - 11);
> +	    grub_uint16_t imm7 = (off & 0x80) >> (7 - 6);
> +	    grub_uint16_t imm6 = (off & 0x40) << (12 - 11);
> +	    grub_uint16_t imm5 = (off & 0x20) >> (5 - 2);
> +	    grub_uint16_t imm4 = (off & 0x10) << (12 - 5);
> +	    grub_uint16_t imm3_1 = (off & 0xe) << (12 - 10);
> +	    *abs_place = ((*abs_place & 0xe003)
> +			  | imm11 | imm10 | imm9_8 | imm7 | imm6
> +			  | imm5 | imm4 | imm3_1);
> +	  }
> +	  break;
> +
> +	case R_RISCV_PCREL_HI20:
> +	  {
> +	    grub_uint32_t *abs_place = place;
> +	    grub_ssize_t off = sym_addr - (grub_addr_t) place;
> +	    grub_int32_t hi20;
> +
> +	    if (off != (grub_int32_t)off)
> +	      return grub_error (GRUB_ERR_BAD_MODULE, "relocation overflow");
> +
> +	    hi20 = (off + 0x800) & 0xfffff000;
> +	    *abs_place = (*abs_place & 0xfff) | hi20;
> +	  }
> +	break;
> +
> +	case R_RISCV_PCREL_LO12_I:
> +	case R_RISCV_PCREL_LO12_S:
> +	  {
> +	    grub_uint32_t *t32 = place;
> +	    Elf_Rela *rel2;
> +	    /* Search backwards for matching HI20 reloc.  */

Why "backwards"?

> +	    for (rel2 = (Elf_Rela *) ((char *) rel - s->sh_entsize);
> +		    (unsigned long)rel2 >= ((unsigned long)ehdr + s->sh_offset);
> +		    rel2 = (Elf_Rela *) ((char *) rel2 - s->sh_entsize))
> +	      {
> +		Elf_Addr rel2_info;
> +		Elf_Addr rel2_offset;
> +		Elf_Addr rel2_sym_addr;
> +		Elf_Addr rel2_loc;
> +		grub_ssize_t rel2_off;
> +		grub_ssize_t off;
> +		Elf_Sym *sym2;
> +
> +		rel2_offset = rel2->r_offset;
> +		rel2_info = rel2->r_info;
> +		rel2_loc = (grub_addr_t) seg->addr + rel2_offset;
> +
> +		if (ELF_R_TYPE (rel2_info) == R_RISCV_PCREL_HI20
> +		    && rel2_loc == sym_addr)
> +		  {
> +		    sym2 = (Elf_Sym *) ((char *) mod->symtab
> +				+ mod->symsize * ELF_R_SYM (rel2->r_info));
> +		    rel2_sym_addr = sym2->st_value;
> +		    if (s->sh_type == SHT_RELA)
> +		      rel2_sym_addr += ((Elf_Rela *) rel2)->r_addend;
> +
> +		    rel2_off = rel2_sym_addr - rel2_loc;
> +		    off = rel2_off - ((rel2_off + 0x800) & 0xfffff000);
> +
> +		    if (ELF_R_TYPE (rel->r_info) == R_RISCV_PCREL_LO12_I)
> +		      *t32 = (*t32 & 0xfffff) | (off & 0xfff) << 20;
> +		    else
> +		      {
> +			grub_uint32_t imm11_5 = (off & 0xfe0) << (31 - 11);
> +			grub_uint32_t imm4_0 = (off & 0x1f) << (11 - 4);
> +			*t32 = (*t32 & 0x1fff07f) | imm11_5 | imm4_0;
> +		      }
> +		    break;
> +		  }
> +	      }
> +	    if ((unsigned long)rel2 < ((unsigned long)ehdr + s->sh_offset))
> +	      return grub_error (GRUB_ERR_BAD_MODULE, "cannot find matching HI20 relocation");
> +	  }
> +	  break;
> +
> +	case R_RISCV_HI20:
> +	  {
> +	    grub_uint32_t *abs_place = place;
> +	    *abs_place = (*abs_place & 0xfff) |
> +			 (((grub_int32_t) sym_addr + 0x800) & 0xfffff000);
> +	  }
> +	  break;
> +
> +	case R_RISCV_LO12_I:
> +	  {
> +	    grub_uint32_t *abs_place = place;
> +	    grub_int32_t lo12 = (grub_int32_t) sym_addr -
> +				(((grub_int32_t) sym_addr + 0x800) & 0xfffff000);
> +	    *abs_place = (*abs_place & 0xfffff) | ((lo12 & 0xfff) << 20);
> +	  }
> +	  break;
> +
> +	case R_RISCV_LO12_S:
> +	  {
> +	    grub_uint32_t *abs_place = place;
> +	    grub_int32_t lo12 = (grub_int32_t) sym_addr -
> +				(((grub_int32_t) sym_addr + 0x800) & 0xfffff000);
> +	    grub_uint32_t imm11_5 = (lo12 & 0xfe0) << (31 - 11);
> +	    grub_uint32_t imm4_0 = (lo12 & 0x1f) << (11 - 4);
> +	    *abs_place = (*abs_place & 0x1fff07f) | imm11_5 | imm4_0;

Again, why not constants? And below...

Daniel


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

* Re: [PATCH v3 08/10] RISC-V: Add auxiliary files
  2018-11-14 17:27 ` [PATCH v3 08/10] RISC-V: Add auxiliary files Alexander Graf
  2018-11-17 22:51   ` Auer, Lukas
@ 2018-11-21 16:02   ` Daniel Kiper
  2018-11-25 22:21     ` Alexander Graf
  1 sibling, 1 reply; 41+ messages in thread
From: Daniel Kiper @ 2018-11-21 16:02 UTC (permalink / raw)
  To: Alexander Graf
  Cc: grub-devel, rickchen36 @ gmail . com, David Abdurachmanov,
	schwab, greentime @ andestech . com, leif.lindholm, atish.patra,
	Michael Chang, Alistair Francis, Lukas Auer, Paul Walmsley,
	Bin Meng

On Wed, Nov 14, 2018 at 06:27:37PM +0100, Alexander Graf wrote:
> To support a new architecture we need to provide a few helper functions
> for memory, cache, timer, etc support.
>
> This patch adds the remainders of those. Some bits are still disabled,
> as I couldn't guarantee that we're always running on models / in modes
> where the respective hardware is available.
>
> Signed-off-by: Alexander Graf <agraf@suse.de>
>
> ---
>
> v2 -> v3:
>
>   - Fix riscv32 target
> ---
>  grub-core/kern/riscv/cache.c       | 64 +++++++++++++++++++++++++++++
>  grub-core/kern/riscv/cache_flush.S | 40 +++++++++++++++++++
>  grub-core/kern/riscv/efi/init.c    | 82 ++++++++++++++++++++++++++++++++++++++
>  include/grub/riscv32/efi/memory.h  |  6 +++
>  include/grub/riscv32/time.h        | 28 +++++++++++++
>  include/grub/riscv32/types.h       | 34 ++++++++++++++++
>  include/grub/riscv64/efi/memory.h  |  6 +++
>  include/grub/riscv64/time.h        | 28 +++++++++++++
>  include/grub/riscv64/types.h       | 34 ++++++++++++++++
>  9 files changed, 322 insertions(+)
>  create mode 100644 grub-core/kern/riscv/cache.c
>  create mode 100644 grub-core/kern/riscv/cache_flush.S
>  create mode 100644 grub-core/kern/riscv/efi/init.c
>  create mode 100644 include/grub/riscv32/efi/memory.h
>  create mode 100644 include/grub/riscv32/time.h
>  create mode 100644 include/grub/riscv32/types.h
>  create mode 100644 include/grub/riscv64/efi/memory.h
>  create mode 100644 include/grub/riscv64/time.h
>  create mode 100644 include/grub/riscv64/types.h
>
> diff --git a/grub-core/kern/riscv/cache.c b/grub-core/kern/riscv/cache.c
> new file mode 100644
> index 000000000..15dbe6927
> --- /dev/null
> +++ b/grub-core/kern/riscv/cache.c
> @@ -0,0 +1,64 @@
> +/*
> + *  GRUB  --  GRand Unified Bootloader
> + *  Copyright (C) 2013  Free Software Foundation, Inc.

s/2013/2018/

> + *
> + *  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/cache.h>
> +#include <grub/misc.h>
> +
> +static grub_int64_t dlinesz;
> +static grub_int64_t ilinesz;
> +
> +/* Prototypes for asm functions. */
> +void grub_arch_clean_dcache_range (grub_addr_t beg, grub_addr_t end,
> +				   grub_size_t line_size);
> +void grub_arch_invalidate_icache_range (grub_addr_t beg, grub_addr_t end,
> +					grub_size_t line_size);
> +
> +static void
> +probe_caches (void)
> +{
> +  /* TODO */
> +  dlinesz = 32;
> +  ilinesz = 32;
> +}
> +
> +void
> +grub_arch_sync_caches (void *address, grub_size_t len)
> +{
> +  grub_size_t start, end, max_align;
> +
> +  if (dlinesz == 0)
> +    probe_caches();
> +  if (dlinesz == 0)
> +    grub_fatal ("Unknown cache line size!");
> +
> +  max_align = dlinesz > ilinesz ? dlinesz : ilinesz;
> +
> +  start = ALIGN_DOWN ((grub_size_t) address, max_align);
> +  end = ALIGN_UP ((grub_size_t) address + len, max_align);
> +
> +  grub_arch_clean_dcache_range (start, end, dlinesz);
> +  grub_arch_invalidate_icache_range (start, end, ilinesz);
> +}
> +
> +void
> +grub_arch_sync_dma_caches (volatile void *address, grub_size_t len)
> +{
> +  /* DMA incoherent devices not supported yet */
> +  if (address || len || 1)
> +    return;

I think that you can drop the code and leave the comment here.

> +}
> diff --git a/grub-core/kern/riscv/cache_flush.S b/grub-core/kern/riscv/cache_flush.S
> new file mode 100644
> index 000000000..033a8aac3
> --- /dev/null
> +++ b/grub-core/kern/riscv/cache_flush.S
> @@ -0,0 +1,40 @@
> +/*
> + *  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>
> +
> +	.file	"cache_flush.S"
> +	.text
> +
> +/*
> + * Simple cache maintenance functions
> + */
> +
> +// a0 - *beg (inclusive)
> +// a1 - *end (exclusive)
> +// a2 - line size

Please do not use "//" for comments.

> +FUNCTION(grub_arch_clean_dcache_range)
> +	// TODO
> +	ret
> +
> +// a0 - *beg (inclusive)
> +// a1 - *end (exclusive)
> +// a2 - line size

Ditto.

> +FUNCTION(grub_arch_invalidate_icache_range)
> +	// TODO

Ditto.

> +	ret
> diff --git a/grub-core/kern/riscv/efi/init.c b/grub-core/kern/riscv/efi/init.c
> new file mode 100644
> index 000000000..199de08a7
> --- /dev/null
> +++ b/grub-core/kern/riscv/efi/init.c
> @@ -0,0 +1,82 @@
> +/* init.c - initialize a riscv-based EFI system */
> +/*
> + *  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/env.h>
> +#include <grub/kernel.h>
> +#include <grub/misc.h>
> +#include <grub/mm.h>
> +#include <grub/time.h>
> +#include <grub/efi/efi.h>
> +#include <grub/loader.h>
> +
> +static grub_uint64_t timer_frequency_in_khz;
> +
> +static grub_uint64_t
> +grub_efi_get_time_ms (void)
> +{
> +  grub_uint64_t tmr;
> +
> +#if 0
> +#if __riscv_xlen == 64
> +  asm volatile ("rdtime %0" : "=r" (tmr));
> +#else
> +  grub_uint32_t lo, hi, tmp;
> +  asm volatile (
> +    "1:\n"
> +    "rdtimeh %0\n"
> +    "rdtime %1\n"
> +    "rdtimeh %2\n"
> +    "bne %0, %2, 1b"
> +    : "=&r" (hi), "=&r" (lo), "=&r" (tmp));
> +  tmr = ((u64)hi << 32) | lo;
> +#endif

I would drop this piece of dead code.

> +#else
> +  static grub_uint64_t val;
> +  tmr = val++;
> +#endif
> +
> +  return tmr / timer_frequency_in_khz;

Could not you use val instead of tmr here?

Daniel


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

* Re: [PATCH v3 07/10] RISC-V: Add awareness for RISC-V reloations
  2018-11-21 15:51   ` Daniel Kiper
@ 2018-11-21 16:08     ` Andreas Schwab
  2018-11-21 16:31       ` Daniel Kiper
  2018-11-25 22:12     ` Alexander Graf
  1 sibling, 1 reply; 41+ messages in thread
From: Andreas Schwab @ 2018-11-21 16:08 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: The development of GNU GRUB, rickchen36 @ gmail . com,
	David Abdurachmanov, greentime @ andestech . com, leif.lindholm,
	atish.patra, Michael Chang, Alistair Francis, Lukas Auer,
	Paul Walmsley, Bin Meng

On Nov 21 2018, Daniel Kiper <dkiper@net-space.pl> wrote:

>> +	case R_RISCV_BRANCH:
>> +	  {
>> +	    grub_uint32_t *abs_place = place;
>> +	    grub_ssize_t off = sym_addr - (grub_addr_t) place;
>> +	    grub_uint32_t imm12 = (off & 0x1000) << (31 - 12);
>> +	    grub_uint32_t imm11 = (off & 0x800) >> (11 - 7);
>> +	    grub_uint32_t imm10_5 = (off & 0x7e0) << (30 - 10);
>> +	    grub_uint32_t imm4_1 = (off & 0x1e) << (11 - 4);
>> +	    *abs_place = (*abs_place & 0x1fff07f)
>> +			 | imm12 | imm11 | imm10_5 | imm4_1;
>
> Could not we use some constants instead of numbers here?

These are just where the insn encoding puts the bits.

> If this does not make sense than please name the source of this numbers.

https://github.com/riscv/riscv-isa-manual/blob/master/release/riscv-spec-v2.2.pdf

Andreas.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."


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

* Re: [PATCH v3 09/10] RISC-V: Add to build system
  2018-11-14 17:27 ` [PATCH v3 09/10] RISC-V: Add to build system Alexander Graf
  2018-11-18 11:41   ` Bin Meng
@ 2018-11-21 16:09   ` Daniel Kiper
  2018-11-21 16:26     ` Andreas Schwab
  1 sibling, 1 reply; 41+ messages in thread
From: Daniel Kiper @ 2018-11-21 16:09 UTC (permalink / raw)
  To: Alexander Graf
  Cc: grub-devel, rickchen36 @ gmail . com, David Abdurachmanov,
	schwab, greentime @ andestech . com, leif.lindholm, atish.patra,
	Michael Chang, Alistair Francis, Lukas Auer, Paul Walmsley,
	Bin Meng

On Wed, Nov 14, 2018 at 06:27:38PM +0100, Alexander Graf wrote:
> This patch adds support for RISC-V to the grub build system. With this
> patch, I can successfully build grub on RISC-V as a UEFI application.
>
> Signed-off-by: Alexander Graf <agraf@suse.de>
> Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

[...]

> diff --git a/grub-core/kern/compiler-rt.c b/grub-core/kern/compiler-rt.c
> index 5cfcb3907..6ae1c6844 100644
> --- a/grub-core/kern/compiler-rt.c
> +++ b/grub-core/kern/compiler-rt.c
> @@ -237,7 +237,8 @@ union component64
>    };
>  };
>
> -#if defined (__powerpc__) || defined (__arm__) || defined(__mips__)
> +#if defined (__powerpc__) || defined (__arm__) || defined(__mips__) || \
> +    (defined(__riscv) && (__riscv_xlen == 32))

s/__riscv/__riscv__/? and s/__riscv_xlen/__riscv_xlen__/?

Here and in other places if possible.

Daniel


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

* Re: [PATCH v3 09/10] RISC-V: Add to build system
  2018-11-21 16:09   ` Daniel Kiper
@ 2018-11-21 16:26     ` Andreas Schwab
  2018-11-21 16:34       ` Daniel Kiper
  0 siblings, 1 reply; 41+ messages in thread
From: Andreas Schwab @ 2018-11-21 16:26 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Alexander Graf, grub-devel, rickchen36 @ gmail . com,
	David Abdurachmanov, greentime @ andestech . com, leif.lindholm,
	atish.patra, Michael Chang, Alistair Francis, Lukas Auer,
	Paul Walmsley, Bin Meng

On Nov 21 2018, Daniel Kiper <dkiper@net-space.pl> wrote:

> s/__riscv/__riscv__/? and s/__riscv_xlen/__riscv_xlen__/?

The latter aren't defined.

Andreas.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."


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

* Re: [PATCH v3 10/10] fdt: Add device tree file type
  2018-11-14 17:27 ` [PATCH v3 10/10] fdt: Add device tree file type Alexander Graf
  2018-11-16 22:07   ` Alistair Francis
  2018-11-19 10:11   ` Andreas Schwab
@ 2018-11-21 16:27   ` Daniel Kiper
  2 siblings, 0 replies; 41+ messages in thread
From: Daniel Kiper @ 2018-11-21 16:27 UTC (permalink / raw)
  To: The development of GNU GRUB
  Cc: rickchen36 @ gmail . com, David Abdurachmanov, schwab,
	greentime @ andestech . com, leif.lindholm, atish.patra,
	Michael Chang, Alistair Francis, Lukas Auer, Paul Walmsley,
	Bin Meng

On Wed, Nov 14, 2018 at 06:27:39PM +0100, Alexander Graf wrote:
> We now have signature check logic in grub which allows us to treat
> files differently depending on their file type.
>
> Mark a loaded device tree as such and treat it like an overlayed ACPI
> table. Both describe hardware, so I suppose their threat level is the
> same.
>
> Signed-off-by: Alexander Graf <agraf@suse.de>
> ---
>  grub-core/commands/efi/shim_lock.c | 1 +
>  grub-core/loader/efi/fdt.c         | 2 +-
>  include/grub/file.h                | 2 ++
>  3 files changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/grub-core/commands/efi/shim_lock.c b/grub-core/commands/efi/shim_lock.c
> index 01246b0fc..90dccb0c7 100644
> --- a/grub-core/commands/efi/shim_lock.c
> +++ b/grub-core/commands/efi/shim_lock.c
> @@ -81,6 +81,7 @@ shim_lock_init (grub_file_t io, enum grub_file_type type,
>        /* Fall through. */
>
>      case GRUB_FILE_TYPE_ACPI_TABLE:
> +    case GRUB_FILE_TYPE_DEVICE_TREE:
>        *flags = GRUB_VERIFY_FLAGS_DEFER_AUTH;
>
>        return GRUB_ERR_NONE;
> diff --git a/grub-core/loader/efi/fdt.c b/grub-core/loader/efi/fdt.c
> index a4c6e8036..d8ebe648e 100644
> --- a/grub-core/loader/efi/fdt.c
> +++ b/grub-core/loader/efi/fdt.c
> @@ -123,7 +123,7 @@ grub_cmd_devicetree (grub_command_t cmd __attribute__ ((unused)),
>        return GRUB_ERR_NONE;
>      }
>
> -  dtb = grub_file_open (argv[0]);
> +  dtb = grub_file_open (argv[0], GRUB_FILE_TYPE_DEVICE_TREE);
>    if (!dtb)
>      goto out;
>
> diff --git a/include/grub/file.h b/include/grub/file.h
> index 19dda67f6..b8fb13017 100644
> --- a/include/grub/file.h
> +++ b/include/grub/file.h
> @@ -93,6 +93,8 @@ enum grub_file_type
>      GRUB_FILE_TYPE_FILE_ID,
>      /* File holding ACPI table.  */
>      GRUB_FILE_TYPE_ACPI_TABLE,
> +    /* File holding Device Tree.  */
> +    GRUB_FILE_TYPE_DEVICE_TREE,
>      /* File we intend show to user.  */
>      GRUB_FILE_TYPE_CAT,
>      GRUB_FILE_TYPE_HEXCAT,

You have to rebase this patch set on latest master. It has
GRUB_FILE_TYPE_DEVICE_TREE_IMAGE instead of GRUB_FILE_TYPE_DEVICE_TREE.
Please use it. If you wish you can move it behind GRUB_FILE_TYPE_ACPI_TABLE
in grub_file_type.

Daniel


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

* Re: [PATCH v3 07/10] RISC-V: Add awareness for RISC-V reloations
  2018-11-21 16:08     ` Andreas Schwab
@ 2018-11-21 16:31       ` Daniel Kiper
  0 siblings, 0 replies; 41+ messages in thread
From: Daniel Kiper @ 2018-11-21 16:31 UTC (permalink / raw)
  To: The development of GNU GRUB
  Cc: David Abdurachmanov, greentime @ andestech . com, leif.lindholm,
	atish.patra, Michael Chang, Alistair Francis, Lukas Auer,
	Paul Walmsley, rickchen36 @ gmail . com, Bin Meng

On Wed, Nov 21, 2018 at 05:08:09PM +0100, Andreas Schwab wrote:
> On Nov 21 2018, Daniel Kiper <dkiper@net-space.pl> wrote:
>
> >> +	case R_RISCV_BRANCH:
> >> +	  {
> >> +	    grub_uint32_t *abs_place = place;
> >> +	    grub_ssize_t off = sym_addr - (grub_addr_t) place;
> >> +	    grub_uint32_t imm12 = (off & 0x1000) << (31 - 12);
> >> +	    grub_uint32_t imm11 = (off & 0x800) >> (11 - 7);
> >> +	    grub_uint32_t imm10_5 = (off & 0x7e0) << (30 - 10);
> >> +	    grub_uint32_t imm4_1 = (off & 0x1e) << (11 - 4);
> >> +	    *abs_place = (*abs_place & 0x1fff07f)
> >> +			 | imm12 | imm11 | imm10_5 | imm4_1;
> >
> > Could not we use some constants instead of numbers here?
>
> These are just where the insn encoding puts the bits.
>
> > If this does not make sense than please name the source of this numbers.
>
> https://github.com/riscv/riscv-isa-manual/blob/master/release/riscv-spec-v2.2.pdf

OK, please add the document title and link to it into relevant source files.

Daniel


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

* Re: [PATCH v3 09/10] RISC-V: Add to build system
  2018-11-21 16:26     ` Andreas Schwab
@ 2018-11-21 16:34       ` Daniel Kiper
  2018-11-21 16:54         ` Andreas Schwab
  0 siblings, 1 reply; 41+ messages in thread
From: Daniel Kiper @ 2018-11-21 16:34 UTC (permalink / raw)
  To: Andreas Schwab
  Cc: grub-devel, David Abdurachmanov, greentime @ andestech . com,
	Alexander Graf, leif.lindholm, atish.patra, Michael Chang,
	Alistair Francis, Lukas Auer, Paul Walmsley,
	rickchen36 @ gmail . com, Bin Meng

On Wed, Nov 21, 2018 at 05:26:25PM +0100, Andreas Schwab wrote:
> On Nov 21 2018, Daniel Kiper <dkiper@net-space.pl> wrote:
>
> > s/__riscv/__riscv__/? and s/__riscv_xlen/__riscv_xlen__/?
>
> The latter aren't defined.

Both __riscv__ and __riscv_xlen__ are not defined?

Daniel


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

* Re: [PATCH v3 10/10] fdt: Add device tree file type
  2018-11-19 17:56     ` Leif Lindholm
@ 2018-11-21 16:36       ` Daniel Kiper
  0 siblings, 0 replies; 41+ messages in thread
From: Daniel Kiper @ 2018-11-21 16:36 UTC (permalink / raw)
  To: Leif Lindholm
  Cc: Andreas Schwab, grub-devel, David Abdurachmanov,
	greentime @ andestech . com, Alexander Graf, atish.patra,
	Michael Chang, Alistair Francis, Lukas Auer, Paul Walmsley,
	rickchen36 @ gmail . com, Bin Meng

On Mon, Nov 19, 2018 at 05:56:36PM +0000, Leif Lindholm wrote:
> On Mon, Nov 19, 2018 at 11:11:09AM +0100, Andreas Schwab wrote:
> > On Nov 14 2018, Alexander Graf <agraf@suse.de> wrote:
> > 
> > > diff --git a/grub-core/loader/efi/fdt.c b/grub-core/loader/efi/fdt.c
> > > index a4c6e8036..d8ebe648e 100644
> > > --- a/grub-core/loader/efi/fdt.c
> > > +++ b/grub-core/loader/efi/fdt.c
> > > @@ -123,7 +123,7 @@ grub_cmd_devicetree (grub_command_t cmd __attribute__ ((unused)),
> > >        return GRUB_ERR_NONE;
> > >      }
> > >  
> > > -  dtb = grub_file_open (argv[0]);
> > > +  dtb = grub_file_open (argv[0], GRUB_FILE_TYPE_DEVICE_TREE);
> > >    if (!dtb)
> > >      goto out;
> > >  
> > 
> > Looks like this has been obsoleted by commit dfb1742aab?
> 
> Actually, that one does not do anything sensible in
> grub-core/commands/efi/shim_lock.c
> so that hunk would be worth considering including.
> 
> Treating DT and ACPI equally sounds sensible to me.

Yep, that make sense for me too.

Daniel


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

* Re: [PATCH v3 09/10] RISC-V: Add to build system
  2018-11-21 16:34       ` Daniel Kiper
@ 2018-11-21 16:54         ` Andreas Schwab
  2018-11-21 16:56           ` Daniel Kiper
  0 siblings, 1 reply; 41+ messages in thread
From: Andreas Schwab @ 2018-11-21 16:54 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: grub-devel, David Abdurachmanov, greentime @ andestech . com,
	Alexander Graf, leif.lindholm, atish.patra, Michael Chang,
	Alistair Francis, Lukas Auer, Paul Walmsley,
	rickchen36 @ gmail . com, Bin Meng

On Nov 21 2018, Daniel Kiper <dkiper@net-space.pl> wrote:

> On Wed, Nov 21, 2018 at 05:26:25PM +0100, Andreas Schwab wrote:
>> On Nov 21 2018, Daniel Kiper <dkiper@net-space.pl> wrote:
>>
>> > s/__riscv/__riscv__/? and s/__riscv_xlen/__riscv_xlen__/?
>>
>> The latter aren't defined.
>
> Both __riscv__ and __riscv_xlen__ are not defined?

Yes.

Andreas.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."


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

* Re: [PATCH v3 09/10] RISC-V: Add to build system
  2018-11-21 16:54         ` Andreas Schwab
@ 2018-11-21 16:56           ` Daniel Kiper
  0 siblings, 0 replies; 41+ messages in thread
From: Daniel Kiper @ 2018-11-21 16:56 UTC (permalink / raw)
  To: Andreas Schwab
  Cc: grub-devel, greentime @ andestech . com, David Abdurachmanov,
	Alexander Graf, leif.lindholm, atish.patra, Michael Chang,
	Alistair Francis, Lukas Auer, Paul Walmsley,
	rickchen36 @ gmail . com, Bin Meng

On Wed, Nov 21, 2018 at 05:54:41PM +0100, Andreas Schwab wrote:
> On Nov 21 2018, Daniel Kiper <dkiper@net-space.pl> wrote:
>
> > On Wed, Nov 21, 2018 at 05:26:25PM +0100, Andreas Schwab wrote:
> >> On Nov 21 2018, Daniel Kiper <dkiper@net-space.pl> wrote:
> >>
> >> > s/__riscv/__riscv__/? and s/__riscv_xlen/__riscv_xlen__/?
> >>
> >> The latter aren't defined.
> >
> > Both __riscv__ and __riscv_xlen__ are not defined?
>
> Yes.

OK, then we have to live with __riscv and __riscv_xlen.

Daniel


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

* Re: [PATCH v3 07/10] RISC-V: Add awareness for RISC-V reloations
  2018-11-21 15:51   ` Daniel Kiper
  2018-11-21 16:08     ` Andreas Schwab
@ 2018-11-25 22:12     ` Alexander Graf
  1 sibling, 0 replies; 41+ messages in thread
From: Alexander Graf @ 2018-11-25 22:12 UTC (permalink / raw)
  To: The development of GNU GRUB, Daniel Kiper
  Cc: rickchen36 @ gmail . com, greentime @ andestech . com, schwab,
	David Abdurachmanov, leif.lindholm, atish.patra, Michael Chang,
	Alistair Francis, Lukas Auer, Paul Walmsley, Bin Meng



On 21.11.18 16:51, Daniel Kiper wrote:
> On Wed, Nov 14, 2018 at 06:27:36PM +0100, Alexander Graf wrote:
>> This patch adds awareness of RISC-V relocations throughout the grub tools
>> as well as dynamic linkage and elf->PE relocation conversion support.
>>
>> Signed-off-by: Alexander Graf <agraf@suse.de>
>>
>> ---
>>
>> v2 -> v3:
>>
>>   - Fix riscv32 target
>> ---
>>  grub-core/kern/dl.c         |   6 +-
>>  grub-core/kern/riscv/dl.c   | 335 ++++++++++++++++++++++++++++++++++++++++++++
>>  include/grub/dl.h           |   6 +-
>>  util/grub-mkimagexx.c       | 268 +++++++++++++++++++++++++++++++++++
>>  util/grub-module-verifier.c |  56 ++++++++
>>  5 files changed, 666 insertions(+), 5 deletions(-)
>>  create mode 100644 grub-core/kern/riscv/dl.c
>>
>> diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
>> index f8d58f029..48eb5e7b6 100644
>> --- a/grub-core/kern/dl.c
>> +++ b/grub-core/kern/dl.c
>> @@ -225,7 +225,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
>>    unsigned i;
>>    const Elf_Shdr *s;
>>    grub_size_t tsize = 0, talign = 1;
>> -#if !defined (__i386__) && !defined (__x86_64__)
>> +#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv)
> 
> Could not we use __riscv__?

Unfortunately __riscv__ is not defined in recent versions of gcc:


https://github.com/riscv/riscv-toolchain-conventions#cc-preprocessor-definitions

> 
>>    grub_size_t tramp;
>>    grub_size_t got;
>>    grub_err_t err;
>> @@ -241,7 +241,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
>>  	talign = s->sh_addralign;
>>      }
>>
>> -#if !defined (__i386__) && !defined (__x86_64__)
>> +#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv)
>>    err = grub_arch_dl_get_tramp_got_size (e, &tramp, &got);
>>    if (err)
>>      return err;
>> @@ -304,7 +304,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
>>  	  mod->segment = seg;
>>  	}
>>      }
>> -#if !defined (__i386__) && !defined (__x86_64__)
>> +#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv)
>>    ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_TRAMP_ALIGN);
>>    mod->tramp = ptr;
>>    mod->trampptr = ptr;
>> diff --git a/grub-core/kern/riscv/dl.c b/grub-core/kern/riscv/dl.c
>> new file mode 100644
>> index 000000000..503b67df1
>> --- /dev/null
>> +++ b/grub-core/kern/riscv/dl.c
>> @@ -0,0 +1,335 @@
>> +/* dl.c - arch-dependent part of loadable module support */
>> +/*
>> + *  GRUB  --  GRand Unified Bootloader
>> + *  Copyright (C) 2013  Free Software Foundation, Inc.
> 
> s/2013/2018/
> 
>> + *
>> + *  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/dl.h>
>> +#include <grub/elf.h>
>> +#include <grub/misc.h>
>> +#include <grub/err.h>
>> +#include <grub/mm.h>
>> +#include <grub/i18n.h>
>> +
>> +#define LDR 0x58000050
>> +#define BR 0xd61f0200
>> +
>> +
> 
> Please drop this empty line.
> 
>> +/*
>> + * Check if EHDR is a valid ELF header.
>> + */
>> +grub_err_t
>> +grub_arch_dl_check_header (void *ehdr)
>> +{
>> +  Elf_Ehdr *e = ehdr;
>> +
>> +  /* Check the magic numbers.  */
>> +  if (e->e_ident[EI_DATA] != ELFDATA2LSB || e->e_machine != EM_RISCV)
>> +    return grub_error (GRUB_ERR_BAD_OS,
>> +		       N_("invalid arch-dependent ELF magic"));
>> +
>> +  return GRUB_ERR_NONE;
>> +}
>> +
>> +#pragma GCC diagnostic ignored "-Wcast-align"
> 
> Why? Could you add a comment here?

Mostly because all other targets have that as well?

I assume it's to silence warnings that the alignment could be mismatched
now, because offsets to elf data pointers could potentially be odd. In
practice, it never is though.

If I remove it, I get the following compile errors:

kern/riscv/dl.c: In function ‘grub_arch_dl_relocate_symbols’:
kern/riscv/dl.c:59:14: error: cast increases required alignment of
target type [-Werror=cast-align]
   for (rel = (Elf_Rel *) ((char *) ehdr + s->sh_offset),
              ^
kern/riscv/dl.c:60:9: error: cast increases required alignment of target
type [-Werror=cast-align]
   max = (Elf_Rel *) ((char *) rel + s->sh_size);
         ^
kern/riscv/dl.c:62:14: error: cast increases required alignment of
target type [-Werror=cast-align]
        rel = (Elf_Rel *) ((char *) rel + s->sh_entsize))
              ^
kern/riscv/dl.c:72:13: error: cast increases required alignment of
target type [-Werror=cast-align]
       sym = (Elf_Sym *) ((char *) mod->symtab
             ^
kern/riscv/dl.c:256:18: error: cast increases required alignment of
target type [-Werror=cast-align]
      for (rel2 = (Elf_Rela *) ((char *) rel - s->sh_entsize);
                  ^
kern/riscv/dl.c:258:14: error: cast increases required alignment of
target type [-Werror=cast-align]
       rel2 = (Elf_Rela *) ((char *) rel2 - s->sh_entsize))
              ^
kern/riscv/dl.c:275:14: error: cast increases required alignment of
target type [-Werror=cast-align]
       sym2 = (Elf_Sym *) ((char *) mod->symtab
              ^

> 
>> +/* Relocate symbols. */
>> +grub_err_t
>> +grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
>> +			       Elf_Shdr *s, grub_dl_segment_t seg)
>> +{
>> +  Elf_Rel *rel, *max;
>> +
>> +  for (rel = (Elf_Rel *) ((char *) ehdr + s->sh_offset),
>> +	 max = (Elf_Rel *) ((char *) rel + s->sh_size);
>> +       rel < max;
>> +       rel = (Elf_Rel *) ((char *) rel + s->sh_entsize))
>> +    {
>> +      Elf_Sym *sym;
>> +      void *place;
>> +      grub_size_t sym_addr;
>> +
>> +      if (rel->r_offset >= seg->size)
>> +	return grub_error (GRUB_ERR_BAD_MODULE,
>> +			   "reloc offset is out of the segment");
>> +
>> +      sym = (Elf_Sym *) ((char *) mod->symtab
>> +			 + mod->symsize * ELF_R_SYM (rel->r_info));
>> +
>> +      sym_addr = sym->st_value;
>> +      if (s->sh_type == SHT_RELA)
>> +	sym_addr += ((Elf_Rela *) rel)->r_addend;
>> +
>> +      place = (void *) ((grub_addr_t) seg->addr + rel->r_offset);
>> +
>> +      switch (ELF_R_TYPE (rel->r_info))
>> +	{
>> +	case R_RISCV_32:
>> +	  {
>> +	    grub_uint32_t *abs_place = place;
>> +
>> +	    grub_dprintf ("dl", "  reloc_abs32 %p => 0x%016llx\n",
>> +			  place, (unsigned long long) sym_addr);
>> +
>> +	    *abs_place = (grub_uint32_t) sym_addr;
>> +	  }
>> +	  break;
>> +	case R_RISCV_64:
>> +	  {
>> +	    grub_size_t *abs_place = place;
>> +
>> +	    grub_dprintf ("dl", "  reloc_abs64 %p => 0x%016llx\n",
>> +			  place, (unsigned long long) sym_addr);
>> +
>> +	    *abs_place = (grub_size_t) sym_addr;
>> +	  }
>> +	  break;
>> +
>> +	case R_RISCV_ADD8:
>> +	  {
>> +	    grub_uint8_t *abs_place = place;
>> +
>> +	    *abs_place += (grub_uint8_t) sym_addr;
>> +	  }
>> +	  break;
>> +	case R_RISCV_ADD16:
>> +	  {
>> +	    grub_uint16_t *abs_place = place;
>> +
>> +	    *abs_place += (grub_uint16_t) sym_addr;
>> +	  }
>> +	  break;
>> +	case R_RISCV_ADD32:
>> +	  {
>> +	    grub_uint32_t *abs_place = place;
>> +
>> +	    *abs_place += (grub_uint32_t) sym_addr;
>> +	  }
>> +	  break;
>> +	case R_RISCV_ADD64:
>> +	  {
>> +	    grub_size_t *abs_place = place;
>> +
>> +	    *abs_place += (grub_size_t) sym_addr;
>> +	  }
>> +	  break;
>> +
>> +	case R_RISCV_SUB8:
>> +	  {
>> +	    grub_uint8_t *abs_place = place;
>> +
>> +	    *abs_place -= (grub_uint8_t) sym_addr;
>> +	  }
>> +	  break;
>> +	case R_RISCV_SUB16:
>> +	  {
>> +	    grub_uint16_t *abs_place = place;
>> +
>> +	    *abs_place -= (grub_uint16_t) sym_addr;
>> +	  }
>> +	  break;
>> +	case R_RISCV_SUB32:
>> +	  {
>> +	    grub_uint32_t *abs_place = place;
>> +
>> +	    *abs_place -= (grub_uint32_t) sym_addr;
>> +	  }
>> +	  break;
>> +	case R_RISCV_SUB64:
>> +	  {
>> +	    grub_size_t *abs_place = place;
>> +
>> +	    *abs_place -= (grub_size_t) sym_addr;
>> +	  }
>> +	  break;
>> +
>> +	case R_RISCV_BRANCH:
>> +	  {
>> +	    grub_uint32_t *abs_place = place;
>> +	    grub_ssize_t off = sym_addr - (grub_addr_t) place;
>> +	    grub_uint32_t imm12 = (off & 0x1000) << (31 - 12);
>> +	    grub_uint32_t imm11 = (off & 0x800) >> (11 - 7);
>> +	    grub_uint32_t imm10_5 = (off & 0x7e0) << (30 - 10);
>> +	    grub_uint32_t imm4_1 = (off & 0x1e) << (11 - 4);
>> +	    *abs_place = (*abs_place & 0x1fff07f)
>> +			 | imm12 | imm11 | imm10_5 | imm4_1;
> 
> Could not we use some constants instead of numbers here?
> If this does not make sense than please name the source of this numbers.

As Andreas already mentioned, these are just taken from the spec. I
agree that it looks quite unreadable, but putting the numbers into
constants would only make things worse I guess.

I'll add the spec reference into the head of this file.

> 
>> +	  }
>> +	  break;
>> +
>> +	case R_RISCV_JAL:
>> +	  {
>> +	    grub_uint32_t *abs_place = place;
>> +	    grub_ssize_t off = sym_addr - (grub_addr_t) place;
>> +	    grub_uint32_t imm20 = (off & 0x100000) << (31 - 20);
>> +	    grub_uint32_t imm19_12 = (off & 0xff000);
>> +	    grub_uint32_t imm11 = (off & 0x800) << (20 - 11);
>> +	    grub_uint32_t imm10_1 = (off & 0x7fe) << (30 - 10);
>> +	    *abs_place = (*abs_place & 0xfff)
>> +			 | imm20 | imm19_12 | imm11 | imm10_1;
> 
> Ditto.
> 
>> +	  }
>> +	  break;
>> +
>> +	case R_RISCV_CALL:
>> +	  {
>> +	    grub_uint32_t *abs_place = place;
>> +	    grub_ssize_t off = sym_addr - (grub_addr_t) place;
>> +	    grub_uint32_t hi20, lo12;
>> +
>> +	    if (off != (grub_int32_t) off)
>> +	      return grub_error (GRUB_ERR_BAD_MODULE, "relocation overflow");
>> +
>> +	    hi20 = (off + 0x800) & 0xfffff000;
>> +	    lo12 = (off - hi20) & 0xfff;
>> +	    abs_place[0] = (abs_place[0] & 0xfff) | hi20;
>> +	    abs_place[1] = (abs_place[1] & 0xfffff) | (lo12 << 20);
> 
> Ditto and below...
> 
>> +	  }
>> +	  break;
>> +
>> +	case R_RISCV_RVC_BRANCH:
>> +	  {
>> +	    grub_uint16_t *abs_place = place;
>> +	    grub_ssize_t off = sym_addr - (grub_addr_t) place;
>> +	    grub_uint16_t imm8 = (off & 0x100) << (12 - 8);
>> +	    grub_uint16_t imm7_6 = (off & 0xc0) >> (6 - 5);
>> +	    grub_uint16_t imm5 = (off & 0x20) >> (5 - 2);
>> +	    grub_uint16_t imm4_3 = (off & 0x18) << (12 - 5);
>> +	    grub_uint16_t imm2_1 = (off & 0x6) << (12 - 10);
>> +	    *abs_place = (*abs_place & 0xe383)
>> +			 | imm8 | imm7_6 | imm5 | imm4_3 | imm2_1;
>> +	  }
>> +	  break;
>> +
>> +	case R_RISCV_RVC_JUMP:
>> +	  {
>> +	    grub_uint16_t *abs_place = place;
>> +	    grub_ssize_t off = sym_addr - (grub_addr_t) place;
>> +	    grub_uint16_t imm11 = (off & 0x800) << (12 - 11);
>> +	    grub_uint16_t imm10 = (off & 0x400) >> (10 - 8);
>> +	    grub_uint16_t imm9_8 = (off & 0x300) << (12 - 11);
>> +	    grub_uint16_t imm7 = (off & 0x80) >> (7 - 6);
>> +	    grub_uint16_t imm6 = (off & 0x40) << (12 - 11);
>> +	    grub_uint16_t imm5 = (off & 0x20) >> (5 - 2);
>> +	    grub_uint16_t imm4 = (off & 0x10) << (12 - 5);
>> +	    grub_uint16_t imm3_1 = (off & 0xe) << (12 - 10);
>> +	    *abs_place = ((*abs_place & 0xe003)
>> +			  | imm11 | imm10 | imm9_8 | imm7 | imm6
>> +			  | imm5 | imm4 | imm3_1);
>> +	  }
>> +	  break;
>> +
>> +	case R_RISCV_PCREL_HI20:
>> +	  {
>> +	    grub_uint32_t *abs_place = place;
>> +	    grub_ssize_t off = sym_addr - (grub_addr_t) place;
>> +	    grub_int32_t hi20;
>> +
>> +	    if (off != (grub_int32_t)off)
>> +	      return grub_error (GRUB_ERR_BAD_MODULE, "relocation overflow");
>> +
>> +	    hi20 = (off + 0x800) & 0xfffff000;
>> +	    *abs_place = (*abs_place & 0xfff) | hi20;
>> +	  }
>> +	break;
>> +
>> +	case R_RISCV_PCREL_LO12_I:
>> +	case R_RISCV_PCREL_LO12_S:
>> +	  {
>> +	    grub_uint32_t *t32 = place;
>> +	    Elf_Rela *rel2;
>> +	    /* Search backwards for matching HI20 reloc.  */
> 
> Why "backwards"?

Because then the chance is higher that we hit a matching relocation
quickly :).


Alex


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

* Re: [PATCH v3 08/10] RISC-V: Add auxiliary files
  2018-11-21 16:02   ` Daniel Kiper
@ 2018-11-25 22:21     ` Alexander Graf
  0 siblings, 0 replies; 41+ messages in thread
From: Alexander Graf @ 2018-11-25 22:21 UTC (permalink / raw)
  To: The development of GNU GRUB, Daniel Kiper
  Cc: David Abdurachmanov, schwab, greentime @ andestech . com,
	leif.lindholm, atish.patra, Michael Chang, Alistair Francis,
	Lukas Auer, Paul Walmsley, rickchen36 @ gmail . com, Bin Meng



On 21.11.18 17:02, Daniel Kiper wrote:
> On Wed, Nov 14, 2018 at 06:27:37PM +0100, Alexander Graf wrote:
>> To support a new architecture we need to provide a few helper functions
>> for memory, cache, timer, etc support.
>>
>> This patch adds the remainders of those. Some bits are still disabled,
>> as I couldn't guarantee that we're always running on models / in modes
>> where the respective hardware is available.
>>
>> Signed-off-by: Alexander Graf <agraf@suse.de>
>>
>> ---
>>
>> v2 -> v3:
>>
>>   - Fix riscv32 target
>> ---
>>  grub-core/kern/riscv/cache.c       | 64 +++++++++++++++++++++++++++++
>>  grub-core/kern/riscv/cache_flush.S | 40 +++++++++++++++++++
>>  grub-core/kern/riscv/efi/init.c    | 82 ++++++++++++++++++++++++++++++++++++++
>>  include/grub/riscv32/efi/memory.h  |  6 +++
>>  include/grub/riscv32/time.h        | 28 +++++++++++++
>>  include/grub/riscv32/types.h       | 34 ++++++++++++++++
>>  include/grub/riscv64/efi/memory.h  |  6 +++
>>  include/grub/riscv64/time.h        | 28 +++++++++++++
>>  include/grub/riscv64/types.h       | 34 ++++++++++++++++
>>  9 files changed, 322 insertions(+)
>>  create mode 100644 grub-core/kern/riscv/cache.c
>>  create mode 100644 grub-core/kern/riscv/cache_flush.S
>>  create mode 100644 grub-core/kern/riscv/efi/init.c
>>  create mode 100644 include/grub/riscv32/efi/memory.h
>>  create mode 100644 include/grub/riscv32/time.h
>>  create mode 100644 include/grub/riscv32/types.h
>>  create mode 100644 include/grub/riscv64/efi/memory.h
>>  create mode 100644 include/grub/riscv64/time.h
>>  create mode 100644 include/grub/riscv64/types.h
>>
>> diff --git a/grub-core/kern/riscv/cache.c b/grub-core/kern/riscv/cache.c
>> new file mode 100644
>> index 000000000..15dbe6927
>> --- /dev/null
>> +++ b/grub-core/kern/riscv/cache.c
>> @@ -0,0 +1,64 @@
>> +/*
>> + *  GRUB  --  GRand Unified Bootloader
>> + *  Copyright (C) 2013  Free Software Foundation, Inc.
> 
> s/2013/2018/
> 
>> + *
>> + *  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/cache.h>
>> +#include <grub/misc.h>
>> +
>> +static grub_int64_t dlinesz;
>> +static grub_int64_t ilinesz;
>> +
>> +/* Prototypes for asm functions. */
>> +void grub_arch_clean_dcache_range (grub_addr_t beg, grub_addr_t end,
>> +				   grub_size_t line_size);
>> +void grub_arch_invalidate_icache_range (grub_addr_t beg, grub_addr_t end,
>> +					grub_size_t line_size);
>> +
>> +static void
>> +probe_caches (void)
>> +{
>> +  /* TODO */
>> +  dlinesz = 32;
>> +  ilinesz = 32;
>> +}
>> +
>> +void
>> +grub_arch_sync_caches (void *address, grub_size_t len)
>> +{
>> +  grub_size_t start, end, max_align;
>> +
>> +  if (dlinesz == 0)
>> +    probe_caches();
>> +  if (dlinesz == 0)
>> +    grub_fatal ("Unknown cache line size!");
>> +
>> +  max_align = dlinesz > ilinesz ? dlinesz : ilinesz;
>> +
>> +  start = ALIGN_DOWN ((grub_size_t) address, max_align);
>> +  end = ALIGN_UP ((grub_size_t) address + len, max_align);
>> +
>> +  grub_arch_clean_dcache_range (start, end, dlinesz);
>> +  grub_arch_invalidate_icache_range (start, end, ilinesz);
>> +}
>> +
>> +void
>> +grub_arch_sync_dma_caches (volatile void *address, grub_size_t len)
>> +{
>> +  /* DMA incoherent devices not supported yet */
>> +  if (address || len || 1)
>> +    return;
> 
> I think that you can drop the code and leave the comment here.

IIRC I had issues with some gcc versions that complained about unused
arguments in that case.

> 
>> +}
>> diff --git a/grub-core/kern/riscv/cache_flush.S b/grub-core/kern/riscv/cache_flush.S
>> new file mode 100644
>> index 000000000..033a8aac3
>> --- /dev/null
>> +++ b/grub-core/kern/riscv/cache_flush.S
>> @@ -0,0 +1,40 @@
>> +/*
>> + *  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>
>> +
>> +	.file	"cache_flush.S"
>> +	.text
>> +
>> +/*
>> + * Simple cache maintenance functions
>> + */
>> +
>> +// a0 - *beg (inclusive)
>> +// a1 - *end (exclusive)
>> +// a2 - line size
> 
> Please do not use "//" for comments.

Ok.

> 
>> +FUNCTION(grub_arch_clean_dcache_range)
>> +	// TODO
>> +	ret
>> +
>> +// a0 - *beg (inclusive)
>> +// a1 - *end (exclusive)
>> +// a2 - line size
> 
> Ditto.
> 
>> +FUNCTION(grub_arch_invalidate_icache_range)
>> +	// TODO
> 
> Ditto.
> 
>> +	ret
>> diff --git a/grub-core/kern/riscv/efi/init.c b/grub-core/kern/riscv/efi/init.c
>> new file mode 100644
>> index 000000000..199de08a7
>> --- /dev/null
>> +++ b/grub-core/kern/riscv/efi/init.c
>> @@ -0,0 +1,82 @@
>> +/* init.c - initialize a riscv-based EFI system */
>> +/*
>> + *  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/env.h>
>> +#include <grub/kernel.h>
>> +#include <grub/misc.h>
>> +#include <grub/mm.h>
>> +#include <grub/time.h>
>> +#include <grub/efi/efi.h>
>> +#include <grub/loader.h>
>> +
>> +static grub_uint64_t timer_frequency_in_khz;
>> +
>> +static grub_uint64_t
>> +grub_efi_get_time_ms (void)
>> +{
>> +  grub_uint64_t tmr;
>> +
>> +#if 0
>> +#if __riscv_xlen == 64
>> +  asm volatile ("rdtime %0" : "=r" (tmr));
>> +#else
>> +  grub_uint32_t lo, hi, tmp;
>> +  asm volatile (
>> +    "1:\n"
>> +    "rdtimeh %0\n"
>> +    "rdtime %1\n"
>> +    "rdtimeh %2\n"
>> +    "bne %0, %2, 1b"
>> +    : "=&r" (hi), "=&r" (lo), "=&r" (tmp));
>> +  tmr = ((u64)hi << 32) | lo;
>> +#endif
> 
> I would drop this piece of dead code.

I'd much rather revive the dead code and drop the hack :). Thanks for
spotting it!

Alex


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

* Re: [PATCH v3 08/10] RISC-V: Add auxiliary files
  2018-11-17 22:51   ` Auer, Lukas
@ 2018-11-25 23:01     ` Alexander Graf
  2018-11-26 22:39       ` Auer, Lukas
  0 siblings, 1 reply; 41+ messages in thread
From: Alexander Graf @ 2018-11-25 23:01 UTC (permalink / raw)
  To: Auer, Lukas, grub-devel
  Cc: pjones, paul.walmsley, Alistair.Francis, bmeng.cn, greentime,
	schwab, mchang, leif.lindholm, david.abdurachmanov, atish.patra,
	rickchen36



On 17.11.18 23:51, Auer, Lukas wrote:
> On Wed, 2018-11-14 at 18:27 +0100, Alexander Graf wrote:
>> To support a new architecture we need to provide a few helper
>> functions
>> for memory, cache, timer, etc support.
>>
>> This patch adds the remainders of those. Some bits are still
>> disabled,
>> as I couldn't guarantee that we're always running on models / in
>> modes
>> where the respective hardware is available.
>>
>> Signed-off-by: Alexander Graf <agraf@suse.de>
>>
>> ---
>>
>> v2 -> v3:
>>
>>   - Fix riscv32 target
>> ---
>>  grub-core/kern/riscv/cache.c       | 64
>> +++++++++++++++++++++++++++++
>>  grub-core/kern/riscv/cache_flush.S | 40 +++++++++++++++++++
>>  grub-core/kern/riscv/efi/init.c    | 82
>> ++++++++++++++++++++++++++++++++++++++
>>  include/grub/riscv32/efi/memory.h  |  6 +++
>>  include/grub/riscv32/time.h        | 28 +++++++++++++
>>  include/grub/riscv32/types.h       | 34 ++++++++++++++++
>>  include/grub/riscv64/efi/memory.h  |  6 +++
>>  include/grub/riscv64/time.h        | 28 +++++++++++++
>>  include/grub/riscv64/types.h       | 34 ++++++++++++++++
>>  9 files changed, 322 insertions(+)
>>  create mode 100644 grub-core/kern/riscv/cache.c
>>  create mode 100644 grub-core/kern/riscv/cache_flush.S
>>  create mode 100644 grub-core/kern/riscv/efi/init.c
>>  create mode 100644 include/grub/riscv32/efi/memory.h
>>  create mode 100644 include/grub/riscv32/time.h
>>  create mode 100644 include/grub/riscv32/types.h
>>  create mode 100644 include/grub/riscv64/efi/memory.h
>>  create mode 100644 include/grub/riscv64/time.h
>>  create mode 100644 include/grub/riscv64/types.h
>>
>> diff --git a/grub-core/kern/riscv/cache.c b/grub-
>> core/kern/riscv/cache.c
>> new file mode 100644
>> index 000000000..15dbe6927
>> --- /dev/null
>> +++ b/grub-core/kern/riscv/cache.c
>> @@ -0,0 +1,64 @@
>> +/*
>> + *  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/cache.h>
>> +#include <grub/misc.h>
>> +
>> +static grub_int64_t dlinesz;
>> +static grub_int64_t ilinesz;
>> +
>> +/* Prototypes for asm functions. */
>> +void grub_arch_clean_dcache_range (grub_addr_t beg, grub_addr_t end,
>> +				   grub_size_t line_size);
>> +void grub_arch_invalidate_icache_range (grub_addr_t beg, grub_addr_t
>> end,
>> +					grub_size_t line_size);
>> +
>> +static void
>> +probe_caches (void)
>> +{
>> +  /* TODO */
>> +  dlinesz = 32;
>> +  ilinesz = 32;
>> +}
>> +
>> +void
>> +grub_arch_sync_caches (void *address, grub_size_t len)
>> +{
>> +  grub_size_t start, end, max_align;
>> +
>> +  if (dlinesz == 0)
>> +    probe_caches();
>> +  if (dlinesz == 0)
>> +    grub_fatal ("Unknown cache line size!");
>> +
>> +  max_align = dlinesz > ilinesz ? dlinesz : ilinesz;
>> +
>> +  start = ALIGN_DOWN ((grub_size_t) address, max_align);
>> +  end = ALIGN_UP ((grub_size_t) address + len, max_align);
>> +
>> +  grub_arch_clean_dcache_range (start, end, dlinesz);
>> +  grub_arch_invalidate_icache_range (start, end, ilinesz);
>> +}
>> +
>> +void
>> +grub_arch_sync_dma_caches (volatile void *address, grub_size_t len)
>> +{
>> +  /* DMA incoherent devices not supported yet */
>> +  if (address || len || 1)
>> +    return;
>> +}
>> diff --git a/grub-core/kern/riscv/cache_flush.S b/grub-
>> core/kern/riscv/cache_flush.S
>> new file mode 100644
>> index 000000000..033a8aac3
>> --- /dev/null
>> +++ b/grub-core/kern/riscv/cache_flush.S
>> @@ -0,0 +1,40 @@
>> +/*
>> + *  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>
>> +
>> +	.file	"cache_flush.S"
>> +	.text
>> +
>> +/*
>> + * Simple cache maintenance functions
>> + */
>> +
>> +// a0 - *beg (inclusive)
>> +// a1 - *end (exclusive)
>> +// a2 - line size
>> +FUNCTION(grub_arch_clean_dcache_range)
>> +	// TODO
>> +	ret
>> +
>> +// a0 - *beg (inclusive)
>> +// a1 - *end (exclusive)
>> +// a2 - line size
>> +FUNCTION(grub_arch_invalidate_icache_range)
>> +	// TODO
>> +	ret
> 
> You can use fence.i here to synchronize writes to instruction memory
> with instruction fetches. Essentially a instruction cache flush, but
> different processors may choose different implementations for it.

I suppose that one is implemented by every reasonable core? I'll add it
then :).


Thanks!

Alex


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

* Re: [PATCH v3 09/10] RISC-V: Add to build system
  2018-11-18 11:41   ` Bin Meng
@ 2018-11-25 23:06     ` Alexander Graf
  2018-11-26  1:08       ` Bin Meng
  0 siblings, 1 reply; 41+ messages in thread
From: Alexander Graf @ 2018-11-25 23:06 UTC (permalink / raw)
  To: Bin Meng
  Cc: grub-devel, Leif Lindholm, pjones, paul.walmsley,
	David Abdurachmanov, atish.patra, schwab, mchang,
	Alistair.Francis, Lukas Auer, greentime, rickchen36



On 18.11.18 12:41, Bin Meng wrote:
> Hi Alex,
> 
> On Thu, Nov 15, 2018 at 1:27 AM Alexander Graf <agraf@suse.de> wrote:
>>
>> This patch adds support for RISC-V to the grub build system. With this
>> patch, I can successfully build grub on RISC-V as a UEFI application.
>>
>> Signed-off-by: Alexander Graf <agraf@suse.de>
>> Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
>>
>> ---
>>
>> v2 -> v3:
>>
>>   - Fix riscv32 target
>> ---
>>  configure.ac                 | 28 ++++++++++++++++++++++++++--
>>  gentpl.py                    | 11 +++++++----
>>  grub-core/Makefile.am        | 12 ++++++++++++
>>  grub-core/Makefile.core.def  | 29 +++++++++++++++++++++++++++++
>>  grub-core/commands/file.c    | 14 +++++++++++++-
>>  grub-core/kern/compiler-rt.c |  6 ++++--
>>  grub-core/kern/efi/mm.c      |  2 +-
>>  grub-core/kern/emu/cache.c   |  6 ++++++
>>  grub-core/kern/emu/cache_s.S |  1 +
>>  grub-core/kern/emu/lite.c    |  2 ++
>>  grub-core/lib/efi/halt.c     |  3 ++-
>>  grub-core/lib/setjmp.S       |  2 ++
>>  include/grub/compiler-rt.h   | 12 ++++++++----
>>  include/grub/efi/api.h       |  3 ++-
>>  include/grub/efi/efi.h       |  2 +-
>>  include/grub/misc.h          |  3 ++-
>>  include/grub/util/install.h  |  2 ++
>>  util/grub-install-common.c   |  2 ++
>>  util/grub-install.c          | 28 ++++++++++++++++++++++++++++
>>  util/grub-mknetdir.c         |  4 +++-
>>  util/grub-mkrescue.c         | 16 +++++++++++++++-
>>  util/mkimage.c               | 32 ++++++++++++++++++++++++++++++++
>>  22 files changed, 200 insertions(+), 20 deletions(-)
>>
> 
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> Tested-by: Bin Meng <bmeng.cn@gmail.com>
> 
> But please see one comment below:
> 
>> diff --git a/configure.ac b/configure.ac
>> index 5e63c4af3..2cc2ffb2c 100644
>> --- a/configure.ac
>> +++ b/configure.ac
>> @@ -104,6 +104,12 @@ case "$target_cpu" in
>>    aarch64*)
>>                 target_cpu=arm64
>>                 ;;
>> +  riscv32*)
>> +               target_cpu=riscv32
>> +               ;;
>> +  riscv64*)
>> +               target_cpu=riscv64
>> +               ;;
>>  esac
>>
>>  # Specify the platform (such as firmware).
>> @@ -127,6 +133,8 @@ if test "x$with_platform" = x; then
>>      ia64-*) platform=efi ;;
>>      arm-*) platform=uboot ;;
>>      arm64-*) platform=efi ;;
>> +    riscv32-*) platform=efi ;;
>> +    riscv64-*) platform=efi ;;
>>      *)
>>        AC_MSG_WARN([unsupported CPU: "$target_cpu" - only building utilities])
>>        platform=none
>> @@ -174,6 +182,8 @@ case "$target_cpu"-"$platform" in
>>    arm-coreboot) ;;
>>    arm-efi) ;;
>>    arm64-efi) ;;
>> +  riscv32-efi) ;;
>> +  riscv64-efi) ;;
>>    *-emu) ;;
>>    *-none) ;;
>>    *) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;;
>> @@ -826,6 +836,16 @@ if test x"$platform" != xemu ; then
>>         AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
>>                          [grub_cv_target_cc_soft_float="-mgeneral-regs-only"], [])
>>      fi
>> +    if test "x$target_cpu" = xriscv32; then
>> +       CFLAGS="$TARGET_CFLAGS -march=rv32imac -mabi=ilp32 -Werror"
>> +       AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
>> +                        [grub_cv_target_cc_soft_float="-march=rv32imac -mabi=ilp32"], [])
>> +    fi
>> +    if test "x$target_cpu" = xriscv64; then
>> +       CFLAGS="$TARGET_CFLAGS -march=rv64imac -mabi=lp64 -Werror"
>> +       AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
>> +                        [grub_cv_target_cc_soft_float="-march=rv64imac -mabi=lp64"], [])
>> +    fi
>>      if test "x$target_cpu" = xia64; then
>>         CFLAGS="$TARGET_CFLAGS -mno-inline-float-divide -mno-inline-sqrt -Werror"
>>         AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
>> @@ -1141,7 +1161,7 @@ AC_SUBST(TARGET_LDFLAGS_OLDMAGIC)
>>
>>  LDFLAGS="$TARGET_LDFLAGS"
>>
>> -if test "$target_cpu" = x86_64 || test "$target_cpu" = sparc64 ; then
>> +if test "$target_cpu" = x86_64 || test "$target_cpu" = sparc64 || test "$target_cpu" = riscv64 ; then
>>    # Use large model to support 4G memory
>>    AC_CACHE_CHECK([whether option -mcmodel=large works], grub_cv_cc_mcmodel, [
>>      CFLAGS="$TARGET_CFLAGS -mcmodel=large"
>> @@ -1151,7 +1171,7 @@ if test "$target_cpu" = x86_64 || test "$target_cpu" = sparc64 ; then
>>    ])
>>    if test "x$grub_cv_cc_mcmodel" = xyes; then
>>      TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=large"
>> -  elif test "$target_cpu" = sparc64; then
>> +  elif test "$target_cpu" = sparc64 || test "$target_cpu" = riscv64; then
>>      TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=medany"
> 
> The patch does not indicate the code model explicitly for riscv32.
> It's better we pass the -mcmodel=medlow (suitable for riscv32) to the
> compiler in case the compiler is configured with a different code
> model by default.

I'm afraid there is no other model?

  https://gcc.gnu.org/onlinedocs/gcc/RISC-V-Options.html


Alex


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

* Re: [PATCH v3 09/10] RISC-V: Add to build system
  2018-11-25 23:06     ` Alexander Graf
@ 2018-11-26  1:08       ` Bin Meng
  0 siblings, 0 replies; 41+ messages in thread
From: Bin Meng @ 2018-11-26  1:08 UTC (permalink / raw)
  To: Alexander Graf
  Cc: grub-devel, Leif Lindholm, pjones, paul.walmsley,
	David Abdurachmanov, atish.patra, schwab, mchang,
	Alistair.Francis, Lukas Auer, greentime, rickchen36

Hi Alex,

On Mon, Nov 26, 2018 at 7:06 AM Alexander Graf <agraf@suse.de> wrote:
>
>
>
> On 18.11.18 12:41, Bin Meng wrote:
> > Hi Alex,
> >
> > On Thu, Nov 15, 2018 at 1:27 AM Alexander Graf <agraf@suse.de> wrote:
> >>
> >> This patch adds support for RISC-V to the grub build system. With this
> >> patch, I can successfully build grub on RISC-V as a UEFI application.
> >>
> >> Signed-off-by: Alexander Graf <agraf@suse.de>
> >> Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
> >>
> >> ---
> >>
> >> v2 -> v3:
> >>
> >>   - Fix riscv32 target
> >> ---
> >>  configure.ac                 | 28 ++++++++++++++++++++++++++--
> >>  gentpl.py                    | 11 +++++++----
> >>  grub-core/Makefile.am        | 12 ++++++++++++
> >>  grub-core/Makefile.core.def  | 29 +++++++++++++++++++++++++++++
> >>  grub-core/commands/file.c    | 14 +++++++++++++-
> >>  grub-core/kern/compiler-rt.c |  6 ++++--
> >>  grub-core/kern/efi/mm.c      |  2 +-
> >>  grub-core/kern/emu/cache.c   |  6 ++++++
> >>  grub-core/kern/emu/cache_s.S |  1 +
> >>  grub-core/kern/emu/lite.c    |  2 ++
> >>  grub-core/lib/efi/halt.c     |  3 ++-
> >>  grub-core/lib/setjmp.S       |  2 ++
> >>  include/grub/compiler-rt.h   | 12 ++++++++----
> >>  include/grub/efi/api.h       |  3 ++-
> >>  include/grub/efi/efi.h       |  2 +-
> >>  include/grub/misc.h          |  3 ++-
> >>  include/grub/util/install.h  |  2 ++
> >>  util/grub-install-common.c   |  2 ++
> >>  util/grub-install.c          | 28 ++++++++++++++++++++++++++++
> >>  util/grub-mknetdir.c         |  4 +++-
> >>  util/grub-mkrescue.c         | 16 +++++++++++++++-
> >>  util/mkimage.c               | 32 ++++++++++++++++++++++++++++++++
> >>  22 files changed, 200 insertions(+), 20 deletions(-)
> >>
> >
> > Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> > Tested-by: Bin Meng <bmeng.cn@gmail.com>
> >
> > But please see one comment below:
> >
> >> diff --git a/configure.ac b/configure.ac
> >> index 5e63c4af3..2cc2ffb2c 100644
> >> --- a/configure.ac
> >> +++ b/configure.ac
> >> @@ -104,6 +104,12 @@ case "$target_cpu" in
> >>    aarch64*)
> >>                 target_cpu=arm64
> >>                 ;;
> >> +  riscv32*)
> >> +               target_cpu=riscv32
> >> +               ;;
> >> +  riscv64*)
> >> +               target_cpu=riscv64
> >> +               ;;
> >>  esac
> >>
> >>  # Specify the platform (such as firmware).
> >> @@ -127,6 +133,8 @@ if test "x$with_platform" = x; then
> >>      ia64-*) platform=efi ;;
> >>      arm-*) platform=uboot ;;
> >>      arm64-*) platform=efi ;;
> >> +    riscv32-*) platform=efi ;;
> >> +    riscv64-*) platform=efi ;;
> >>      *)
> >>        AC_MSG_WARN([unsupported CPU: "$target_cpu" - only building utilities])
> >>        platform=none
> >> @@ -174,6 +182,8 @@ case "$target_cpu"-"$platform" in
> >>    arm-coreboot) ;;
> >>    arm-efi) ;;
> >>    arm64-efi) ;;
> >> +  riscv32-efi) ;;
> >> +  riscv64-efi) ;;
> >>    *-emu) ;;
> >>    *-none) ;;
> >>    *) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;;
> >> @@ -826,6 +836,16 @@ if test x"$platform" != xemu ; then
> >>         AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
> >>                          [grub_cv_target_cc_soft_float="-mgeneral-regs-only"], [])
> >>      fi
> >> +    if test "x$target_cpu" = xriscv32; then
> >> +       CFLAGS="$TARGET_CFLAGS -march=rv32imac -mabi=ilp32 -Werror"
> >> +       AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
> >> +                        [grub_cv_target_cc_soft_float="-march=rv32imac -mabi=ilp32"], [])
> >> +    fi
> >> +    if test "x$target_cpu" = xriscv64; then
> >> +       CFLAGS="$TARGET_CFLAGS -march=rv64imac -mabi=lp64 -Werror"
> >> +       AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
> >> +                        [grub_cv_target_cc_soft_float="-march=rv64imac -mabi=lp64"], [])
> >> +    fi
> >>      if test "x$target_cpu" = xia64; then
> >>         CFLAGS="$TARGET_CFLAGS -mno-inline-float-divide -mno-inline-sqrt -Werror"
> >>         AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
> >> @@ -1141,7 +1161,7 @@ AC_SUBST(TARGET_LDFLAGS_OLDMAGIC)
> >>
> >>  LDFLAGS="$TARGET_LDFLAGS"
> >>
> >> -if test "$target_cpu" = x86_64 || test "$target_cpu" = sparc64 ; then
> >> +if test "$target_cpu" = x86_64 || test "$target_cpu" = sparc64 || test "$target_cpu" = riscv64 ; then
> >>    # Use large model to support 4G memory
> >>    AC_CACHE_CHECK([whether option -mcmodel=large works], grub_cv_cc_mcmodel, [
> >>      CFLAGS="$TARGET_CFLAGS -mcmodel=large"
> >> @@ -1151,7 +1171,7 @@ if test "$target_cpu" = x86_64 || test "$target_cpu" = sparc64 ; then
> >>    ])
> >>    if test "x$grub_cv_cc_mcmodel" = xyes; then
> >>      TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=large"
> >> -  elif test "$target_cpu" = sparc64; then
> >> +  elif test "$target_cpu" = sparc64 || test "$target_cpu" = riscv64; then
> >>      TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=medany"
> >
> > The patch does not indicate the code model explicitly for riscv32.
> > It's better we pass the -mcmodel=medlow (suitable for riscv32) to the
> > compiler in case the compiler is configured with a different code
> > model by default.
>
> I'm afraid there is no other model?
>
>   https://gcc.gnu.org/onlinedocs/gcc/RISC-V-Options.html
>

Correct. However my comments were to request we explicitly pass GCC
the code model for 32-bit build too. Your patch only did such for
64-bit. We should do the same for 32-bit.

Regards,
Bin


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

* Re: [PATCH v3 08/10] RISC-V: Add auxiliary files
  2018-11-25 23:01     ` Alexander Graf
@ 2018-11-26 22:39       ` Auer, Lukas
  0 siblings, 0 replies; 41+ messages in thread
From: Auer, Lukas @ 2018-11-26 22:39 UTC (permalink / raw)
  To: grub-devel, agraf
  Cc: pjones, paul.walmsley, Alistair.Francis, bmeng.cn, greentime,
	schwab, mchang, leif.lindholm, david.abdurachmanov, atish.patra,
	rickchen36

On Mon, 2018-11-26 at 00:01 +0100, Alexander Graf wrote:
> 
> On 17.11.18 23:51, Auer, Lukas wrote:
> > On Wed, 2018-11-14 at 18:27 +0100, Alexander Graf wrote:
> > > To support a new architecture we need to provide a few helper
> > > functions
> > > for memory, cache, timer, etc support.
> > > 
> > > This patch adds the remainders of those. Some bits are still
> > > disabled,
> > > as I couldn't guarantee that we're always running on models / in
> > > modes
> > > where the respective hardware is available.
> > > 
> > > Signed-off-by: Alexander Graf <agraf@suse.de>
> > > 
> > > ---
> > > 
> > > v2 -> v3:
> > > 
> > >   - Fix riscv32 target
> > > ---
> > >  grub-core/kern/riscv/cache.c       | 64
> > > +++++++++++++++++++++++++++++
> > >  grub-core/kern/riscv/cache_flush.S | 40 +++++++++++++++++++
> > >  grub-core/kern/riscv/efi/init.c    | 82
> > > ++++++++++++++++++++++++++++++++++++++
> > >  include/grub/riscv32/efi/memory.h  |  6 +++
> > >  include/grub/riscv32/time.h        | 28 +++++++++++++
> > >  include/grub/riscv32/types.h       | 34 ++++++++++++++++
> > >  include/grub/riscv64/efi/memory.h  |  6 +++
> > >  include/grub/riscv64/time.h        | 28 +++++++++++++
> > >  include/grub/riscv64/types.h       | 34 ++++++++++++++++
> > >  9 files changed, 322 insertions(+)
> > >  create mode 100644 grub-core/kern/riscv/cache.c
> > >  create mode 100644 grub-core/kern/riscv/cache_flush.S
> > >  create mode 100644 grub-core/kern/riscv/efi/init.c
> > >  create mode 100644 include/grub/riscv32/efi/memory.h
> > >  create mode 100644 include/grub/riscv32/time.h
> > >  create mode 100644 include/grub/riscv32/types.h
> > >  create mode 100644 include/grub/riscv64/efi/memory.h
> > >  create mode 100644 include/grub/riscv64/time.h
> > >  create mode 100644 include/grub/riscv64/types.h
> > > 
> > > diff --git a/grub-core/kern/riscv/cache.c b/grub-
> > > core/kern/riscv/cache.c
> > > new file mode 100644
> > > index 000000000..15dbe6927
> > > --- /dev/null
> > > +++ b/grub-core/kern/riscv/cache.c
> > > @@ -0,0 +1,64 @@
> > > +/*
> > > + *  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/cache.h>
> > > +#include <grub/misc.h>
> > > +
> > > +static grub_int64_t dlinesz;
> > > +static grub_int64_t ilinesz;
> > > +
> > > +/* Prototypes for asm functions. */
> > > +void grub_arch_clean_dcache_range (grub_addr_t beg, grub_addr_t
> > > end,
> > > +				   grub_size_t line_size);
> > > +void grub_arch_invalidate_icache_range (grub_addr_t beg,
> > > grub_addr_t
> > > end,
> > > +					grub_size_t line_size);
> > > +
> > > +static void
> > > +probe_caches (void)
> > > +{
> > > +  /* TODO */
> > > +  dlinesz = 32;
> > > +  ilinesz = 32;
> > > +}
> > > +
> > > +void
> > > +grub_arch_sync_caches (void *address, grub_size_t len)
> > > +{
> > > +  grub_size_t start, end, max_align;
> > > +
> > > +  if (dlinesz == 0)
> > > +    probe_caches();
> > > +  if (dlinesz == 0)
> > > +    grub_fatal ("Unknown cache line size!");
> > > +
> > > +  max_align = dlinesz > ilinesz ? dlinesz : ilinesz;
> > > +
> > > +  start = ALIGN_DOWN ((grub_size_t) address, max_align);
> > > +  end = ALIGN_UP ((grub_size_t) address + len, max_align);
> > > +
> > > +  grub_arch_clean_dcache_range (start, end, dlinesz);
> > > +  grub_arch_invalidate_icache_range (start, end, ilinesz);
> > > +}
> > > +
> > > +void
> > > +grub_arch_sync_dma_caches (volatile void *address, grub_size_t
> > > len)
> > > +{
> > > +  /* DMA incoherent devices not supported yet */
> > > +  if (address || len || 1)
> > > +    return;
> > > +}
> > > diff --git a/grub-core/kern/riscv/cache_flush.S b/grub-
> > > core/kern/riscv/cache_flush.S
> > > new file mode 100644
> > > index 000000000..033a8aac3
> > > --- /dev/null
> > > +++ b/grub-core/kern/riscv/cache_flush.S
> > > @@ -0,0 +1,40 @@
> > > +/*
> > > + *  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>
> > > +
> > > +	.file	"cache_flush.S"
> > > +	.text
> > > +
> > > +/*
> > > + * Simple cache maintenance functions
> > > + */
> > > +
> > > +// a0 - *beg (inclusive)
> > > +// a1 - *end (exclusive)
> > > +// a2 - line size
> > > +FUNCTION(grub_arch_clean_dcache_range)
> > > +	// TODO
> > > +	ret
> > > +
> > > +// a0 - *beg (inclusive)
> > > +// a1 - *end (exclusive)
> > > +// a2 - line size
> > > +FUNCTION(grub_arch_invalidate_icache_range)
> > > +	// TODO
> > > +	ret
> > 
> > You can use fence.i here to synchronize writes to instruction
> > memory
> > with instruction fetches. Essentially a instruction cache flush,
> > but
> > different processors may choose different implementations for it.
> 
> I suppose that one is implemented by every reasonable core? I'll add
> it
> then :).
> 
> 
> Thanks!
> 
> Alex

Yes definitely, the RISC-V Linux kernel would not work without it.

Lukas

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

end of thread, other threads:[~2018-11-26 22:40 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-14 17:27 [PATCH v3 00/10] Add RISC-V support Alexander Graf
2018-11-14 17:27 ` [PATCH v3 01/10] efi: Rename armxx to arch Alexander Graf
2018-11-18 11:41   ` Bin Meng
2018-11-14 17:27 ` [PATCH v3 02/10] PE: Add RISC-V definitions Alexander Graf
2018-11-18 11:41   ` Bin Meng
2018-11-14 17:27 ` [PATCH v3 03/10] elf.h: " Alexander Graf
2018-11-18 11:41   ` Bin Meng
2018-11-14 17:27 ` [PATCH v3 04/10] RISC-V: Add setjmp implementation Alexander Graf
2018-11-18 11:41   ` Bin Meng
2018-11-21 15:31   ` Daniel Kiper
2018-11-14 17:27 ` [PATCH v3 05/10] RISC-V: Add early startup code Alexander Graf
2018-11-18 11:41   ` Bin Meng
2018-11-14 17:27 ` [PATCH v3 06/10] RISC-V: Add Linux load logic Alexander Graf
2018-11-16 22:18   ` Alistair Francis
2018-11-21 15:43   ` Daniel Kiper
2018-11-14 17:27 ` [PATCH v3 07/10] RISC-V: Add awareness for RISC-V reloations Alexander Graf
2018-11-21 15:51   ` Daniel Kiper
2018-11-21 16:08     ` Andreas Schwab
2018-11-21 16:31       ` Daniel Kiper
2018-11-25 22:12     ` Alexander Graf
2018-11-14 17:27 ` [PATCH v3 08/10] RISC-V: Add auxiliary files Alexander Graf
2018-11-17 22:51   ` Auer, Lukas
2018-11-25 23:01     ` Alexander Graf
2018-11-26 22:39       ` Auer, Lukas
2018-11-21 16:02   ` Daniel Kiper
2018-11-25 22:21     ` Alexander Graf
2018-11-14 17:27 ` [PATCH v3 09/10] RISC-V: Add to build system Alexander Graf
2018-11-18 11:41   ` Bin Meng
2018-11-25 23:06     ` Alexander Graf
2018-11-26  1:08       ` Bin Meng
2018-11-21 16:09   ` Daniel Kiper
2018-11-21 16:26     ` Andreas Schwab
2018-11-21 16:34       ` Daniel Kiper
2018-11-21 16:54         ` Andreas Schwab
2018-11-21 16:56           ` Daniel Kiper
2018-11-14 17:27 ` [PATCH v3 10/10] fdt: Add device tree file type Alexander Graf
2018-11-16 22:07   ` Alistair Francis
2018-11-19 10:11   ` Andreas Schwab
2018-11-19 17:56     ` Leif Lindholm
2018-11-21 16:36       ` Daniel Kiper
2018-11-21 16:27   ` Daniel Kiper

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.