[Merge] ~adrianoco/grub/+git/ubuntu:unapplied/profile into ~ubuntu-core-dev/grub/+git/ubuntu:ubuntu
Heinrich Schuchardt
mp+488194 at code.launchpad.net
Wed Jul 2 15:05:24 UTC 2025
See review comments below
Diff comments:
> diff --git a/debian/patches/0203-include-acpi.h-Add-RHCT-table-definition.patch b/debian/patches/0203-include-acpi.h-Add-RHCT-table-definition.patch
> new file mode 100644
> index 0000000..7bbb6a5
> --- /dev/null
> +++ b/debian/patches/0203-include-acpi.h-Add-RHCT-table-definition.patch
> @@ -0,0 +1,56 @@
> +From: Adriano Cordova <adriano.cordova at canonical.com>
> +Date: Mon, 23 Jun 2025 10:43:16 -0400
> +Subject: include/acpi.h: Add RHCT table definition
> +
> +Add RISC-V Hart Capabilities Table definition. This table is
> +added to get the ISA string and check compatibility for RVA23
> +compatibility.
> +
> +Signed-off-by: Adriano Cordova <adriano.cordova at canonical.com>
> +---
> + include/grub/acpi.h | 34 ++++++++++++++++++++++++++++++++++
> + 1 file changed, 34 insertions(+)
> +
> +diff --git a/include/grub/acpi.h b/include/grub/acpi.h
> +index 17aadb8..ec93826 100644
> +--- a/include/grub/acpi.h
> ++++ b/include/grub/acpi.h
> +@@ -298,4 +298,38 @@ EXPORT_FUNC(grub_acpi_find_fadt) (void);
> + void *
> + EXPORT_FUNC(grub_acpi_find_table) (const char *sig);
> +
> ++#define GRUB_ACPI_RHCT_SIGNATURE "RHCT"
> ++
> ++struct grub_acpi_rhct_node_header
> ++{
> ++ grub_uint16_t type;
> ++ grub_uint16_t length;
> ++ grub_uint16_t revision;
> ++} GRUB_PACKED;
> ++
> ++struct grub_acpi_rhct
> ++{
> ++ struct grub_acpi_table_header header;
> ++ grub_uint32_t flags;
> ++ grub_uint8_t time_base_freq[8];
Reading the ACPI 6.6 specification I think this field should be uint64_t.
> ++ grub_uint32_t num_nodes;
> ++ grub_uint32_t offset_first_node;
> ++ struct grub_acpi_rhct_node_header nodes[];
> ++} GRUB_PACKED;
> ++
> ++enum
> ++ {
> ++ GRUB_ACPI_RHCT_NODE_TYPE_ISA_STRING = 0,
> ++ GRUB_ACPI_RHCT_NODE_TYPE_CMO = 1,
> ++ GRUB_ACPI_RHCT_NODE_TYPE_MMU = 2,
> ++ GRUB_ACPI_RHCT_NODE_TYPE_HART_INFO = 65535
> ++ };
> ++
> ++struct grub_acpi_rhct_node_isa_string
> ++{
> ++ struct grub_acpi_rhct_node_header header;
> ++ grub_uint16_t isa_len;
> ++ char isa_string[];
> ++} GRUB_PACKED;
> ++
> + #endif /* ! GRUB_ACPI_HEADER */
> diff --git a/debian/patches/0210-efi-api.h-Add-RISCV_EFI_BOOT_PROTOCOL-defiinition.patch b/debian/patches/0210-efi-api.h-Add-RISCV_EFI_BOOT_PROTOCOL-defiinition.patch
> new file mode 100644
> index 0000000..168d219
> --- /dev/null
> +++ b/debian/patches/0210-efi-api.h-Add-RISCV_EFI_BOOT_PROTOCOL-defiinition.patch
> @@ -0,0 +1,43 @@
> +From: Adriano Cordova <adriano.cordova at canonical.com>
> +Date: Wed, 11 Jun 2025 16:34:11 -0400
> +Subject: efi/api.h: Add RISCV_EFI_BOOT_PROTOCOL defiinition
> +
%s/defiinition/definition/
> +This protocol is provided by firmware and used to determine
> +the boot hart id. This is added as it will be used to determine
> +if hardware is RVA23 compliant.
Maybe add:
According to the server platform specification all harts exposed to the operating system should have the same set of extensions. It is therefore sufficient to check the compatibility of the boot hart.
> +
> +Signed-off-by: Adriano Cordova <adriano.cordova at canonical.com>
> +---
> + include/grub/efi/api.h | 14 ++++++++++++++
> + 1 file changed, 14 insertions(+)
> +
> +diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
> +index 699bccf..18e5cad 100644
> +--- a/include/grub/efi/api.h
> ++++ b/include/grub/efi/api.h
> +@@ -398,6 +398,11 @@
> + { 0xa1, 0x92, 0xbf, 0x1d, 0x57, 0xd0, 0xb1, 0x89 } \
> + }
> +
> ++#define GRUB_EFI_RISCV_EFI_BOOT_PROTOCOL_GUID \
> ++ { 0xccd15fec, 0x6f73, 0x4eec, \
> ++ { 0x83, 0x95, 0x3e, 0x69, 0xe4, 0xb9, 0x40, 0xbf } \
> ++ }
> ++
> + struct grub_efi_sal_system_table
> + {
> + grub_uint32_t signature;
> +@@ -2239,4 +2244,13 @@ struct grub_efi_memory_attribute_protocol
> + };
> + typedef struct grub_efi_memory_attribute_protocol grub_efi_memory_attribute_protocol_t;
> +
> ++struct grub_efi_riscv_efi_boot_protocol
> ++{
> ++ grub_efi_uint64_t revision;
> ++ grub_efi_status_t (__grub_efi_api *grub_efi_get_boot_hartid) (
> ++ struct grub_efi_riscv_efi_boot_protocol *this,
> ++ grub_efi_uintn_t *boot_hart_id);
> ++};
> ++typedef struct grub_efi_riscv_efi_boot_protocol grub_efi_riscv_efi_boot_protocol_t;
> ++
> + #endif /* ! GRUB_EFI_API_HEADER */
> diff --git a/debian/patches/0211-Add-profile-parsing-in-progress.patch b/debian/patches/0211-Add-profile-parsing-in-progress.patch
> new file mode 100644
> index 0000000..bc195ef
> --- /dev/null
> +++ b/debian/patches/0211-Add-profile-parsing-in-progress.patch
> @@ -0,0 +1,560 @@
> +From: Adriano Cordova <adriano.cordova at canonical.com>
> +Date: Wed, 11 Jun 2025 18:34:59 -0400
> +Subject: Add profile parsing
> +
> +Signed-off-by: Adriano Cordova <adriano.cordova at canonical.com>
> +---
> + grub-core/Makefile.core.def | 2 +
> + grub-core/kern/riscv/efi/init.c | 4 +
> + grub-core/kern/riscv/efi/profile.c | 504 +++++++++++++++++++++++++++++++++++++
> + 3 files changed, 510 insertions(+)
> + create mode 100644 grub-core/kern/riscv/efi/profile.c
> +
> +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
> +index 97d2d37..1abc15a 100644
> +--- a/grub-core/Makefile.core.def
> ++++ b/grub-core/Makefile.core.def
> +@@ -274,9 +274,11 @@ kernel = {
> +
> + riscv32_efi = kern/riscv/efi/init.c;
> + riscv32_efi = kern/efi/fdt.c;
> ++ riscv32_efi = lib/fdt.c;
> +
> + riscv64_efi = kern/riscv/efi/init.c;
> + riscv64_efi = kern/efi/fdt.c;
> ++ riscv64_efi = lib/fdt.c;
> +
> + i386_pc = kern/i386/pc/init.c;
> + i386_pc = kern/i386/pc/mmap.c;
> +diff --git a/grub-core/kern/riscv/efi/init.c b/grub-core/kern/riscv/efi/init.c
> +index 519e462..676b4c8 100644
> +--- a/grub-core/kern/riscv/efi/init.c
> ++++ b/grub-core/kern/riscv/efi/init.c
> +@@ -25,6 +25,8 @@
> + #include <grub/efi/efi.h>
> + #include <grub/loader.h>
> +
> ++#include "profile.c"
> ++
> + static grub_uint64_t timer_frequency_in_khz;
> +
> + static grub_uint64_t
> +@@ -55,6 +57,8 @@ grub_machine_init (void)
> +
> + grub_efi_init ();
> +
> ++ grub_arch_check_profile ();
> ++
> + /* Calculate timer frequency */
> + timer_frequency_in_khz = 1;
> + time_before = grub_efi_get_time_ms();
> +diff --git a/grub-core/kern/riscv/efi/profile.c b/grub-core/kern/riscv/efi/profile.c
> +new file mode 100644
> +index 0000000..a081db8
> +--- /dev/null
> ++++ b/grub-core/kern/riscv/efi/profile.c
> +@@ -0,0 +1,504 @@
> ++#include <grub/acpi.h>
> ++#include <grub/err.h>
> ++#include <grub/fdt.h>
> ++#include <grub/list.h>
> ++#include <grub/misc.h>
> ++
> ++static grub_guid_t riscv_efi_boot_protocol_guid
> ++ = GRUB_EFI_RISCV_EFI_BOOT_PROTOCOL_GUID;
> ++
> ++struct grub_isa_extension
> ++{
> ++ struct grub_isa_extension *next;
> ++ struct grub_isa_extension **prev;
> ++ char *name;
> ++ grub_uint32_t name_len;
> ++};
> ++
> ++static grub_named_list_t cpu_ext_list = NULL;
> ++static grub_named_list_t rva23_ext_list = NULL;
> ++
> ++static const char *rva23_required_exts[]
> ++ = { "i", "m", "a", "f", "d", "c",
> ++ "b", "v", "zic64b", "zicbom", "zicbop", "zicboz",
> ++ "ziccamoa", "ziccif", "zicclsm", "ziccrse", "zicntr", "zicond",
> ++ "zicsr", "zihintntl", "zihintpause", "zihpm", "zimop", "za64rs",
> ++ "zawrs", "zfa", "zfhmin", "zcb", "zcmop", "zvbb",
> ++ "zvfhmin", "zvkt", "zkt", "supm", NULL };
> ++
> ++static const struct
> ++{
> ++ const char *key;
> ++ const char *values[8];
> ++} implies[] = { { "m", { "zmmul", NULL } }, { "a", { "zaamo", NULL } },
> ++ { "f", { "zicsr", NULL } }, { "d", { "f", NULL } },
> ++ { "q", { "d", NULL } }, { "v", { "d", NULL } },
> ++ { "zfh", { "zfhmin", NULL } }, { NULL, { NULL } } };
> ++
> ++static const struct
> ++{
> ++ const char *key;
> ++ const char *values[8];
> ++} shorthand[]
> ++ = { { "b", { "zba", "zbb", "zbs", NULL } },
> ++ { "g", { "i", "m", "a", "f", "d", "zicsr", "zifencei", NULL } },
> ++ { "zk", { "zkn", "zkr", "zkt", NULL } },
> ++ { "zkn", { "zbkb", "zbkc", "zbkx", "zkne", "zknd", "zknh", NULL } },
> ++ { "zks", { "zbkb", "zbkc", "zbkx", "zksed", "zksh", NULL } },
> ++ { "zvkn", { "zvkned", "zvknhb", "zvkb", "zvkt", NULL } },
> ++ { "zvknc", { "zvkn", "zvbc", NULL } },
> ++ { "zvkng", { "zvkn", "zvkg", NULL } },
> ++ { "zvks", { "zvksed", "zvksh", "zvkb", "zvkt", NULL } },
> ++ { "zvksc", { "zvks", "zvbc", NULL } },
> ++ { "zvksg", { "zvks", "zvkg", NULL } },
> ++ { NULL, { NULL } } };
> ++
> ++static void
> ++init_ext_list (grub_named_list_t *list)
The function name sounds a bit misleading.
Should this be empty_ext_list() as it is actually emptying the list?
> ++{
> ++ struct grub_isa_extension *ext, *next;
> ++
> ++ FOR_LIST_ELEMENTS_SAFE (ext, next, *(struct grub_isa_extension **)list)
> ++ {
> ++ grub_list_remove (GRUB_AS_LIST (ext));
> ++ grub_free (ext->name);
> ++ grub_free (ext);
> ++ }
> ++ *list = NULL;
> ++}
> ++
> ++static struct grub_isa_extension *
> ++find_in_list (grub_named_list_t list, const char *ext, grub_uint32_t ext_len)
> ++{
> ++ struct grub_isa_extension *item;
> ++
> ++ if (!ext || ext_len == 0)
> ++ return NULL;
> ++
> ++ FOR_LIST_ELEMENTS (item, (struct grub_isa_extension *)list)
> ++ {
> ++ if (item->name_len == ext_len
> ++ && grub_memcmp (item->name, ext, ext_len) == 0)
> ++ return item;
> ++ }
> ++ return NULL;
> ++}
> ++
> ++static void
> ++add_to_list (grub_named_list_t *list, const char *ext, grub_uint32_t ext_len)
> ++{
> ++ struct grub_isa_extension *item;
> ++
> ++ if (!ext || ext_len == 0)
> ++ return;
> ++
> ++ if (find_in_list (*list, ext, ext_len))
> ++ return;
> ++
> ++ item = grub_malloc (sizeof (*item));
> ++ if (!item)
> ++ grub_fatal ("Failed to allocate memory for extension struct");
> ++
> ++ item->name = grub_malloc (ext_len + 1);
> ++ if (!item->name)
I guess grub_strdup() is the function you could use here.
> ++ grub_fatal ("Failed to allocate memory for extension name");
> ++
> ++ grub_memcpy (item->name, ext, ext_len);
> ++ item->name[ext_len] = '\0';
> ++ item->name_len = ext_len;
> ++
> ++ grub_list_push (GRUB_AS_LIST_P (list), GRUB_AS_LIST (item));
> ++}
> ++
> ++static void
> ++rm_from_list (grub_named_list_t *list, const char *ext, grub_uint32_t ext_len)
> ++{
> ++ struct grub_isa_extension *item;
> ++
> ++ if (!ext || ext_len == 0)
> ++ return;
> ++
> ++ item = find_in_list (*list, ext, ext_len);
> ++ if (!item)
> ++ return;
> ++
> ++ grub_list_remove (GRUB_AS_LIST (item));
> ++ grub_free (item->name);
> ++ grub_free (item);
> ++}
> ++
> ++static bool
> ++sublist_in_list (grub_named_list_t sublist, grub_named_list_t list)
> ++{
> ++ struct grub_isa_extension *ext;
> ++
> ++ FOR_LIST_ELEMENTS (ext, (struct grub_isa_extension *)sublist)
> ++ {
> ++ if (!find_in_list (list, ext->name, ext->name_len))
> ++ return false;
> ++ }
> ++ return true;
> ++}
> ++
> ++static void
> ++print_reversed_ext_list_helper (grub_named_list_t list)
> ++{
> ++ struct grub_isa_extension *ext;
> ++
> ++ ext = (struct grub_isa_extension *)list;
> ++ if (!ext)
> ++ return;
> ++ print_reversed_ext_list_helper ((grub_named_list_t)ext->next);
> ++ grub_printf ("%s, ", ext->name);
> ++}
> ++
> ++static void
> ++print_reversed_ext_list (grub_named_list_t list)
> ++{
> ++ struct grub_isa_extension *ext;
> ++
> ++ ext = (struct grub_isa_extension *)list;
> ++ if (!ext)
> ++ return;
> ++ print_reversed_ext_list_helper ((grub_named_list_t)ext->next);
> ++ grub_printf ("%s.\n", ext->name);
> ++}
> ++
> ++static void
> ++process_shorthand_extensions (grub_named_list_t *list)
> ++{
> ++ bool changed;
> ++
> ++ do
> ++ {
> ++ changed = false;
> ++
> ++ for (int s = 0; shorthand[s].key; s++)
> ++ {
> ++ if (find_in_list (*list, shorthand[s].key,
> ++ grub_strlen (shorthand[s].key)))
> ++ {
> ++ rm_from_list (list, shorthand[s].key,
> ++ grub_strlen (shorthand[s].key));
> ++ for (const char *const *impl = shorthand[s].values; *impl;
> ++ impl++)
> ++ add_to_list (list, *impl, grub_strlen (*impl));
> ++ changed = true;
> ++ break;
> ++ }
> ++ }
> ++ }
> ++ while (changed);
> ++}
> ++
> ++static void
> ++process_implied_extensions (grub_named_list_t *list)
> ++{
> ++ bool changed;
> ++
> ++ do
> ++ {
> ++ changed = false;
> ++
> ++ for (int j = 0; implies[j].key; j++)
> ++ {
> ++ if (find_in_list (*list, implies[j].key,
> ++ grub_strlen (implies[j].key)))
> ++ {
> ++
> ++ for (const char *const *impl = implies[j].values; *impl; impl++)
> ++ {
> ++ if (!find_in_list (*list, *impl, grub_strlen (*impl)))
> ++ {
> ++ add_to_list (list, *impl, grub_strlen (*impl));
> ++ changed = true;
> ++ }
> ++ }
> ++
> ++ if (changed)
> ++ break;
> ++ }
> ++ }
> ++ }
> ++ while (changed);
> ++}
> ++
> ++static void
> ++add_implied_extensions (grub_named_list_t *list)
> ++{
> ++ process_shorthand_extensions (list);
> ++ process_implied_extensions (list);
> ++}
> ++
> ++static void
> ++grub_arch_check_rva23 (void)
> ++{
> ++ init_ext_list (&rva23_ext_list);
> ++ for (const char **ext = rva23_required_exts; *ext; ext++)
> ++ {
> ++ add_to_list (&rva23_ext_list, *ext, grub_strlen (*ext));
> ++ }
> ++
> ++ add_implied_extensions (&rva23_ext_list);
> ++
> ++ if (!sublist_in_list (rva23_ext_list, cpu_ext_list))
> ++ {
> ++ grub_printf ("\nExtensions provided by the boot hart:\n");
> ++ print_reversed_ext_list (cpu_ext_list);
> ++ grub_printf ("Extensions required for the rva23u64 profile:\n");
> ++ print_reversed_ext_list (rva23_ext_list);
> ++ grub_fatal ("This version of Ubuntu is built for the rva23s64 profile. "
> ++ "Your CPU lacks some required extensions and hence cannot "
> ++ "be used with this version of Ubuntu.\n");
> ++ }
> ++}
> ++
> ++static void
> ++match_version (const char *ext, grub_uint32_t *len)
Most GRUB contributors will not know how a RISC-V extension is formatted. This function needs a comment.
> ++{
> ++ grub_uint32_t i = 0;
> ++
> ++ while (i < *len)
> ++ {
> ++ if (ext[i] >= '0' && ext[i] <= '9')
> ++ {
> ++ grub_uint32_t j = i + 1;
> ++
> ++ while (j < *len && ext[j] >= '0' && ext[j] <= '9')
> ++ j++;
> ++
> ++ if (j == *len)
> ++ {
> ++ *len = i;
> ++ break;
> ++ }
> ++
> ++ if (j + 1 < *len && ext[j] == 'p' && ext[j + 1] >= '0'
> ++ && ext[j + 1] <= '9')
> ++ j += 2;
> ++
> ++ while (j < *len && ext[j] >= '0' && ext[j] <= '9')
> ++ j++;
> ++
> ++ if (j == *len)
> ++ {
> ++ *len = i;
> ++ break;
> ++ }
> ++ }
> ++ i++;
> ++ }
> ++}
> ++
> ++static void
> ++grub_arch_parse_isa_base (const char *isa_base, grub_uint32_t isa_base_len)
> ++{
This functions needs a description.
Please, add a link to the specification of the ISA string format.
> ++ if (!isa_base || isa_base_len <= 4)
> ++ return;
> ++
> ++ const char *p = isa_base + 4;
> ++ grub_uint32_t remaining = isa_base_len - 4;
> ++
> ++ while (remaining > 0)
> ++ {
> ++ if (*p == '_' || *p == '\0')
> ++ {
> ++ p++;
> ++ remaining--;
> ++ continue;
> ++ }
> ++
> ++ grub_uint32_t ext_orig_len = 0;
> ++ const char *end = p;
> ++ if (*p == 's' || *p == 'x' || *p == 'z')
> ++ {
> ++ while (remaining > 0 && *end != '_' && *end != '\0')
> ++ {
> ++ end++;
> ++ remaining--;
> ++ }
> ++ }
> ++ else
> ++ {
> ++ end++;
> ++ remaining--;
> ++ while (remaining > 0 && *end >= '0' && *end - '0' < 10)
> ++ {
> ++ end++;
> ++ remaining--;
> ++ }
> ++ if (remaining > 1 && *end == 'p' && *(end + 1) >= '0'
> ++ && *(end + 1) - '0' < 10)
> ++ {
> ++ end++;
> ++ remaining--;
> ++ while (remaining > 0 && *end >= '0' && *end - '0' < 10)
> ++ {
> ++ end++;
> ++ remaining--;
> ++ }
> ++ }
> ++ }
> ++ ext_orig_len = end - p;
> ++ if (ext_orig_len > 0)
> ++ {
> ++ grub_uint32_t ext_len = ext_orig_len;
> ++ if (!(ext_orig_len >= 4 && *p == 's' && *(p + 1) == 'v'
> ++ && ((*(p + 2) == '3' && *(p + 3) == '2')
> ++ || (*(p + 2) == '3' && *(p + 3) == '9')
> ++ || (*(p + 2) == '4' && *(p + 3) == '8')
> ++ || (*(p + 2) == '5' && *(p + 3) == '9'))))
> ++ match_version (p, &ext_len);
> ++
> ++ add_to_list (&cpu_ext_list, p, ext_len);
> ++ p += ext_orig_len;
> ++ }
> ++ }
> ++}
> ++
> ++static void
> ++grub_arch_parse_isa_exts (const char *isa_exts, grub_uint32_t isa_exts_len)
> ++{
> ++ if (!isa_exts || isa_exts_len <= 0)
> ++ return;
> ++
> ++ const char *ext = isa_exts;
> ++ grub_uint32_t remaining = isa_exts_len;
> ++
> ++ while (remaining > 0)
> ++ {
> ++ if (*ext == '\0')
> ++ {
> ++ ext++;
> ++ remaining--;
> ++ continue;
> ++ }
> ++ grub_uint32_t ext_len = grub_strlen (ext);
> ++ if (ext_len == 0)
> ++ break;
> ++
> ++ grub_uint32_t ext_orig_len = ext_len;
> ++ if (!(ext_orig_len >= 4 && *ext == 's' && *(ext + 1) == 'v'
> ++ && ((*(ext + 2) == '3' && *(ext + 3) == '2')
There are extensions Sv39, Sv48, Sv57. It is unclear how the code here is related to these. The Linux kernel copes with any of the 3 extensions.
> ++ || (*(ext + 2) == '3' && *(ext + 3) == '9')
> ++ || (*(ext + 2) == '4' && *(ext + 3) == '8')
> ++ || (*(ext + 2) == '5' && *(ext + 3) == '9'))))
> ++ match_version (ext, &ext_len);
> ++
> ++ add_to_list (&cpu_ext_list, ext, ext_len);
> ++ ext += ext_orig_len;
> ++ remaining -= ext_orig_len;
> ++ }
> ++}
> ++
> ++static void
> ++grub_arch_parse_isa (const void *fdt, grub_efi_uintn_t id)
> ++{
> ++ int node, cpus_node = 0;
> ++ const char *isa = NULL, *isa_base = NULL, *isa_exts = NULL;
> ++ grub_uint32_t isa_len = 0, isa_base_len = 0, isa_exts_len = 0;
> ++ const grub_uint32_t *prop;
> ++ struct grub_acpi_rhct *rhct;
> ++ const grub_uint8_t *current_node;
> ++ grub_uint32_t nodes_remaining;
> ++
> ++ if (fdt)
> ++ {
> ++ cpus_node = grub_fdt_find_subnode (fdt, 0, "cpus");
> ++ if (cpus_node < 0)
> ++ grub_fatal ("Firmware FDT has no /cpus node!");
> ++
> ++ for (node = grub_fdt_first_node (fdt, cpus_node); node >= 0;
> ++ node = grub_fdt_next_node (fdt, node))
> ++ {
> ++ prop
> ++ = (const grub_uint32_t *)grub_fdt_get_prop (fdt, node, "reg", 0);
> ++ if (prop && grub_be_to_cpu32 (*prop) == id)
> ++ {
> ++ isa = grub_fdt_get_prop (fdt, node, "riscv,isa", &isa_len);
> ++ isa_base = grub_fdt_get_prop (fdt, node, "riscv,isa-base",
> ++ &isa_base_len);
> ++ isa_exts = grub_fdt_get_prop (fdt, node, "riscv,isa-extensions",
> ++ &isa_exts_len);
> ++ break;
> ++ }
> ++ }
> ++ }
> ++ else
> ++ {
> ++ rhct = grub_acpi_find_table (GRUB_ACPI_RHCT_SIGNATURE);
> ++ if (!rhct)
> ++ grub_fatal ("No FDT nor ACPI RHCT provided!");
> ++
> ++ current_node = (const grub_uint8_t *)rhct->nodes;
> ++ nodes_remaining = rhct->num_nodes;
> ++
> ++ while (nodes_remaining--)
> ++ {
> ++ const struct grub_acpi_rhct_node_header *hdr
> ++ = (const struct grub_acpi_rhct_node_header *)current_node;
> ++
> ++ if (hdr->type == GRUB_ACPI_RHCT_NODE_TYPE_ISA_STRING)
> ++ {
> ++ const struct grub_acpi_rhct_node_isa_string *isa_node
> ++ = (const struct grub_acpi_rhct_node_isa_string *)
> ++ current_node;
> ++
> ++ isa_len = (grub_uint32_t)isa_node->isa_len;
> ++ isa = isa_node->isa_string;
> ++ break;
> ++ }
> ++
> ++ current_node += hdr->length;
> ++ }
> ++ }
> ++
> ++ if (!isa && !isa_base)
> ++ grub_fatal ("No ISA string found for boot hart");
> ++
> ++ if ((isa_base && !isa_exts) || (!isa_base && isa_exts))
> ++ grub_fatal ("Only one of ISA base and ISA extensions is provided");
> ++
> ++ if (!isa_exts)
> ++ {
> ++ isa_base = isa;
> ++ isa_base_len = isa_len;
> ++ }
> ++
> ++ init_ext_list (&cpu_ext_list);
> ++ grub_arch_parse_isa_base (isa_base, isa_base_len);
> ++ if (isa_exts)
> ++ grub_arch_parse_isa_exts (isa_exts, isa_exts_len);
> ++ add_implied_extensions (&cpu_ext_list);
> ++}
> ++
> ++static grub_efi_status_t
> ++grub_arch_get_boothart (grub_efi_uintn_t *boot_hart_id)
> ++{
> ++ grub_efi_riscv_efi_boot_protocol_t *boot;
> ++ grub_efi_status_t status;
> ++
> ++ boot = grub_efi_locate_protocol (&riscv_efi_boot_protocol_guid, NULL);
> ++ if (!boot)
> ++ grub_fatal ("RISC-V EFI boot protocol not provided!");
> ++
> ++ status = boot->grub_efi_get_boot_hartid (boot, boot_hart_id);
> ++ return status;
> ++}
> ++
> ++static void
> ++grub_arch_check_profile (void)
> ++{
> ++ grub_efi_uintn_t boot_hart_id;
> ++ grub_efi_status_t status;
> ++ void *fw_fdt;
> ++
> ++ status = grub_arch_get_boothart (&boot_hart_id);
> ++ if (status != GRUB_EFI_SUCCESS)
> ++ grub_fatal ("Can't determine boot hart ID!");
> ++
> ++ fw_fdt = grub_efi_get_firmware_fdt ();
> ++
> ++ grub_arch_parse_isa (fw_fdt, boot_hart_id);
> ++ grub_arch_check_rva23 ();
> ++}
--
https://code.launchpad.net/~adrianoco/grub/+git/ubuntu/+merge/488194
Your team Ubuntu Core Development Team is subscribed to branch ~ubuntu-core-dev/grub/+git/ubuntu:ubuntu.
More information about the Ubuntu-reviews
mailing list