On 11/3/26 12:59, Djordje Todorovic wrote:
Add riscv_is_big_endian() helper that checks the hart's big-endian CPU
property and use it throughout the boot code:

- ELF loading: pass ELFDATA2MSB or ELFDATA2LSB based on endianness
- Firmware dynamic info: use cpu_to_be* or cpu_to_le* based on endianness
- Reset vector: instructions (entries 0-5) remain always little-endian,
   data words (entries 6-9) use target data endianness. For RV64 BE, the
   hi/lo word pairs within each dword are swapped since LD reads as BE.

This is part of the runtime big-endian support series which avoids
separate BE binaries by handling endianness as a CPU property.
---
  hw/riscv/boot.c         | 68 +++++++++++++++++++++++++++++++++--------
  include/hw/riscv/boot.h |  2 ++
  2 files changed, 58 insertions(+), 12 deletions(-)


@@ -474,10 +493,35 @@ void riscv_setup_rom_reset_vec(MachineState *machine, 
RISCVHartArrayState *harts
          reset_vec[2] = 0x00000013;   /*     addi   x0, x0, 0 */
      }
- /* copy in the reset vector in little_endian byte order */
-    for (i = 0; i < ARRAY_SIZE(reset_vec); i++) {
+    /* RISC-V instructions are always little-endian */
+    for (i = 0; i < 6; i++) {
          reset_vec[i] = cpu_to_le32(reset_vec[i]);
      }
+
+    /*
+     * Data words (addresses at entries 6-9) must match the firmware's data
+     * endianness. For 64-bit big-endian, the high/low word order within
+     * each dword must also be swapped since LD interprets bytes as BE.
+     */
+    if (riscv_is_big_endian(harts)) {

Do not consider endianness as an exceptional case. Please re-order
as:

       for(...) {
          if (32bit) {
              if (big_endian) {

Even clearer if you add a riscv_boot_swap_data64() helper:

      for(...) {
          riscv_boot_swap_data64();
      }

+        if (!riscv_is_32bit(harts)) {
+            uint32_t tmp;
+            tmp = reset_vec[6];
+            reset_vec[6] = cpu_to_be32(reset_vec[7]);
+            reset_vec[7] = cpu_to_be32(tmp);
+            tmp = reset_vec[8];
+            reset_vec[8] = cpu_to_be32(reset_vec[9]);
+            reset_vec[9] = cpu_to_be32(tmp);
+        } else {
+            for (i = 6; i < ARRAY_SIZE(reset_vec); i++) {
+                reset_vec[i] = cpu_to_be32(reset_vec[i]);
+            }
+        }
+    } else {
+        for (i = 6; i < ARRAY_SIZE(reset_vec); i++) {
+            reset_vec[i] = cpu_to_le32(reset_vec[i]);
+        }
+    }

Reply via email to