From 7fa6e927bb69cb8a8adef0bb755c2280c77f6435 Mon Sep 17 00:00:00 2001 From: yangqiming Date: Thu, 23 Jun 2022 02:49:54 -0400 Subject: [PATCH] LoongArch64 support FDT and phy-addr BIOS --- ...arch64-support-fdt-and-phy-addr-BIOS.patch | 2228 +++++++++++++++++ grub.patches | 3 +- grub2.spec | 5 +- 3 files changed, 2234 insertions(+), 2 deletions(-) create mode 100644 1002-loongarch64-support-fdt-and-phy-addr-BIOS.patch diff --git a/1002-loongarch64-support-fdt-and-phy-addr-BIOS.patch b/1002-loongarch64-support-fdt-and-phy-addr-BIOS.patch new file mode 100644 index 0000000..cdbaa9c --- /dev/null +++ b/1002-loongarch64-support-fdt-and-phy-addr-BIOS.patch @@ -0,0 +1,2228 @@ +From 05687fe4c7d67c07ae33f0609f2ef5a627ea0bc7 Mon Sep 17 00:00:00 2001 +From: yangqiming +Date: Thu, 23 Jun 2022 11:18:06 +0800 +Subject: [PATCH] Add fdt and phy-bios support + + +diff --git a/conf/Makefile.common b/conf/Makefile.common +index cc1d190..d9f058b 100644 +--- a/conf/Makefile.common ++++ b/conf/Makefile.common +@@ -21,8 +21,8 @@ if COND_powerpc_ieee1275 + CFLAGS_PLATFORM += -mcpu=powerpc + endif + if COND_loongarch64 +- CFLAGS_PLATFORM += -fno-strict-aliasing -march=loongarch64 -mabi=lp64 -fno-plt -Wa,-mla-global-with-pcrel +- CPPFLAGS_PLATFORM = -fno-strict-aliasing -march=loongarch64 -mabi=lp64 -fno-plt -Wa,-mla-global-with-pcrel ++ CFLAGS_PLATFORM += -fno-strict-aliasing -march=loongarch64 -mabi=lp64 -fno-plt -Wa,-mla-global-with-abs -mcmodel=large ++ CPPFLAGS_PLATFORM = -fno-strict-aliasing -march=loongarch64 -mabi=lp64 -fno-plt -Wa,-mla-global-with-abs -mcmodel=large + endif + + # Other options +diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am +index 24e2ac3..a976fad 100644 +--- a/grub-core/Makefile.am ++++ b/grub-core/Makefile.am +@@ -226,6 +226,7 @@ if COND_loongarch64_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 ++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fdt.h + KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/loongson.h + endif + +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index 74e66d3..54f6bf0 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -303,9 +303,10 @@ kernel = { + loongarch64 = kern/loongarch64/dl.c; + loongarch64 = kern/loongarch64/cache.S; + loongarch64 = kern/generic/rtc_get_time_ms.c; ++ loongarch64 = kern/efi/fdt.c; ++ loongarch64 = lib/fdt.c; + loongarch64_efi = kern/loongarch64/efi/init.c; + loongarch64_efi = lib/loongarch64/efi/loongson.c; +- loongarch64_efi = lib/loongarch64/efi/loongson_asm.S; + + powerpc_ieee1275 = kern/powerpc/cache.S; + powerpc_ieee1275 = kern/powerpc/dl.c; +diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c +index fb087e3..0a1341f 100644 +--- a/grub-core/kern/efi/mm.c ++++ b/grub-core/kern/efi/mm.c +@@ -121,8 +121,11 @@ grub_efi_allocate_pages_max (grub_efi_physical_address_t max, + grub_efi_status_t status; + grub_efi_boot_services_t *b; + grub_efi_physical_address_t address = max; +- ++#ifdef GRUB_CPU_LOONGARCH64 ++ if (max > grub_efi_max_usable_address()) ++#else + if (max > GRUB_EFI_MAX_USABLE_ADDRESS) ++#endif + return 0; + + b = grub_efi_system_table->boot_services; +@@ -164,8 +167,8 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address, + #endif + { + grub_error (GRUB_ERR_BAD_ARGUMENT, +- N_("invalid memory address (0x%llx > 0x%llx)"), +- address, GRUB_EFI_MAX_USABLE_ADDRESS); ++ N_("invalid memory address 0x%llx"), ++ address); + return NULL; + } + +@@ -210,7 +213,8 @@ grub_efi_allocate_any_pages (grub_efi_uintn_t pages) + #else + return grub_efi_allocate_pages_real (GRUB_EFI_MAX_USABLE_ADDRESS, + pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, +-#endif GRUB_EFI_LOADER_DATA); ++ GRUB_EFI_LOADER_DATA); ++#endif + } + + void * +@@ -501,6 +505,7 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map, + - desc->physical_start); + desc->physical_start = 0x100000; + } ++ + #ifdef GRUB_CPU_LOONGARCH64 + if (BYTES_TO_PAGES (filtered_desc->physical_start) + + filtered_desc->num_pages +@@ -708,7 +713,7 @@ grub_efi_mm_init (void) + 2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE)); + } + +-#if defined (__aarch64__) || defined (__arm__) ++#if defined (__aarch64__) || defined (__arm__) || defined (__loongarch__) + grub_err_t + grub_efi_get_ram_base(grub_addr_t *base_addr) + { +@@ -727,9 +732,15 @@ grub_efi_get_ram_base(grub_addr_t *base_addr) + if (ret < 1) + return GRUB_ERR_BUG; + ++#ifdef GRUB_CPU_LOONGARCH64 ++ for (desc = memory_map, *base_addr = grub_efi_max_usable_address(); ++ (grub_addr_t) desc < ((grub_addr_t) memory_map + memory_map_size); ++ desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) ++#else + for (desc = memory_map, *base_addr = GRUB_EFI_MAX_USABLE_ADDRESS; + (grub_addr_t) desc < ((grub_addr_t) memory_map + memory_map_size); + desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) ++#endif + { + if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY && + (desc->attribute & GRUB_EFI_MEMORY_WB)) +@@ -743,7 +754,11 @@ grub_efi_get_ram_base(grub_addr_t *base_addr) + } + } + ++#ifdef GRUB_CPU_LOONGARCH64 ++ if (*base_addr == grub_efi_max_usable_address()) ++#else + if (*base_addr == GRUB_EFI_MAX_USABLE_ADDRESS) ++#endif + grub_dprintf ("efi", "base_addr 0x%016lx is probably wrong.\n", *base_addr); + + grub_free(memory_map); +diff --git a/grub-core/kern/elfXX.c b/grub-core/kern/elfXX.c +index 8b1dce9..1859d18 100644 +--- a/grub-core/kern/elfXX.c ++++ b/grub-core/kern/elfXX.c +@@ -134,12 +134,6 @@ grub_elfXX_load (grub_elf_t elf, const char *filename, + load_addr &= 0x3FFFFFFFFFFFFFFFULL; + break; + } +-#ifdef GRUB_CPU_LOONGARCH64 +- grub_uint64_t addr; +- asm volatile ("csrrd %0, 0x181" : "=r" (addr)); +- if ((load_addr >> 48) != (addr >> 48)) +- return grub_error (GRUB_ERR_BAD_OS, "bad address space"); +-#endif + load_addr += (grub_addr_t) load_offset; + + if (load_addr < load_base) +diff --git a/grub-core/kern/loongarch64/efi/init.c b/grub-core/kern/loongarch64/efi/init.c +index b21d4f1..632c39a 100644 +--- a/grub-core/kern/loongarch64/efi/init.c ++++ b/grub-core/kern/loongarch64/efi/init.c +@@ -21,7 +21,7 @@ + #include + #include + #include +-#include ++#include + #include + #include + #include +@@ -42,15 +42,13 @@ grub_loongson_increment_timer (grub_efi_event_t event __attribute__ ((unused)), + tmr += 10; + } + +- +- + void + grub_machine_init (void) + { + grub_efi_boot_services_t *b; + + grub_efi_init (); +- ++ + b = grub_efi_system_table->boot_services; + efi_call_5 (b->create_event, GRUB_EFI_EVT_TIMER | GRUB_EFI_EVT_NOTIFY_SIGNAL, + GRUB_EFI_TPL_CALLBACK, grub_loongson_increment_timer, NULL, &tmr_evt); +diff --git a/grub-core/lib/loongarch64/efi/loongson.c b/grub-core/lib/loongarch64/efi/loongson.c +index 8b60d82..eda1e1c 100644 +--- a/grub-core/lib/loongarch64/efi/loongson.c ++++ b/grub-core/lib/loongarch64/efi/loongson.c +@@ -23,400 +23,14 @@ + #include + #include + +-#define loongson_params (&loongson_boot_params->boot_params.efi.smbios.lp) +-#define loongson_boot_params_size ALIGN_UP (sizeof (*loongson_boot_params), 8) +-#define loongson_reset_code_size (&grub_efi_loongson_reset_end - &grub_efi_loongson_reset_start) +- +-extern grub_uint8_t grub_efi_loongson_reset_start; +-extern grub_uint8_t grub_efi_loongson_reset_end; +- +-static struct +-{ +- grub_efi_loongson_boot_params boot_params; +- grub_efi_loongson_memory_map memory_map; +- grub_efi_loongson_cpu_info cpu_info; +- grub_efi_loongson_system_info system_info; +- grub_efi_loongson_irq_src_routing_table irq_src_routing_table; +- grub_efi_loongson_interface_info interface_info; +- grub_efi_loongson_special_attribute special_attribute; +- grub_efi_loongson_board_devices board_devices; +-} GRUB_PACKED +-* loongson_boot_params; +- +-static void +-grub_efi_loongson_init_reset_system (void) +-{ +- grub_efi_loongson_boot_params *boot_params; +- grub_uint8_t *reset_code_addr = (grub_uint8_t *) loongson_boot_params + +- loongson_boot_params_size; +- +- boot_params = &loongson_boot_params->boot_params; +- grub_efi_loongson_reset_system_addr = +- (grub_uint64_t) grub_efi_system_table->runtime_services->reset_system; +- grub_memcpy (reset_code_addr, &grub_efi_loongson_reset_start, loongson_reset_code_size); +- grub_arch_sync_caches (reset_code_addr, loongson_reset_code_size); +- +- boot_params->reset_system.reset_cold = (grub_uint64_t) reset_code_addr + +- ((grub_uint64_t) &grub_efi_loongson_reset_cold - +- (grub_uint64_t) &grub_efi_loongson_reset_start); +- boot_params->reset_system.reset_warm = (grub_uint64_t) reset_code_addr + +- ((grub_uint64_t) &grub_efi_loongson_reset_warm - +- (grub_uint64_t) &grub_efi_loongson_reset_start); +- boot_params->reset_system.shutdown = (grub_uint64_t) reset_code_addr + +- ((grub_uint64_t) &grub_efi_loongson_reset_shutdown - +- (grub_uint64_t) &grub_efi_loongson_reset_start); +- boot_params->reset_system.do_suspend = (grub_uint64_t) reset_code_addr + +- ((grub_uint64_t) &grub_efi_loongson_reset_suspend - +- (grub_uint64_t) &grub_efi_loongson_reset_start); +-} +- +-static void +-grub_efi_loongson_init_smbios (grub_efi_loongson_smbios_table *smbios_table) ++unsigned long ++grub_efi_get_bpi_version (const char *str) + { +- grub_efi_loongson_smbios_table *dst = &loongson_boot_params->boot_params.efi.smbios; ++ unsigned long version = GRUB_EFI_BPI_VER_NONE; + +- dst->vers = smbios_table->vers; +- dst->vga_bios = smbios_table->vga_bios; +-} ++ version = grub_strtoul (str + 4, 0, 0); + +-static void +-grub_efi_loongson_init_cpu_info (grub_efi_loongson_smbios_table *smbios_table) +-{ +- grub_efi_loongson_cpu_info *src = (void *) smbios_table->lp.cpu_offset; +- grub_efi_loongson_cpu_info *dst = &loongson_boot_params->cpu_info; +- +- if (!src) +- return; +- +- grub_memcpy (dst, src, sizeof (grub_efi_loongson_cpu_info)); +- loongson_params->cpu_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; +-} +- +-static void +-grub_efi_loongson_init_system_info (grub_efi_loongson_smbios_table *smbios_table) +-{ +- grub_efi_loongson_system_info *src = (void *) smbios_table->lp.system_offset; +- grub_efi_loongson_system_info *dst = &loongson_boot_params->system_info; +- +- if (!src) +- return; +- +- grub_memcpy (dst, src, sizeof (grub_efi_loongson_system_info)); +- loongson_params->system_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; +-} +- +-static void +-grub_efi_loongson_init_irq_src_routing_table (grub_efi_loongson_smbios_table *smbios_table) +-{ +- grub_efi_loongson_irq_src_routing_table *src = (void *) smbios_table->lp.irq_offset; +- grub_efi_loongson_irq_src_routing_table *dst = &loongson_boot_params->irq_src_routing_table; +- +- if (!src) +- return; +- +- grub_memcpy (dst, src, sizeof (grub_efi_loongson_irq_src_routing_table)); +- loongson_params->irq_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; +-} +- +-static void +-grub_efi_loongson_init_interface_info (grub_efi_loongson_smbios_table *smbios_table) +-{ +- grub_efi_loongson_interface_info *src = (void *) smbios_table->lp.interface_offset; +- grub_efi_loongson_interface_info *dst = &loongson_boot_params->interface_info; +- +- if (!src) +- return; +- +- grub_memcpy (dst, src, sizeof (grub_efi_loongson_interface_info)); +- loongson_params->interface_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; +-} +- +-static void +-grub_efi_loongson_init_special_attribute (grub_efi_loongson_smbios_table *smbios_table) +-{ +- grub_efi_loongson_special_attribute *src = (void *) smbios_table->lp.special_offset; +- grub_efi_loongson_special_attribute *dst = &loongson_boot_params->special_attribute; +- +- if (!src) +- return; +- +- grub_memcpy (dst, src, sizeof (grub_efi_loongson_special_attribute)); +- loongson_params->special_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; +-} +- +-static void +-grub_efi_loongson_init_board_devices (grub_efi_loongson_smbios_table *smbios_table) +-{ +- grub_efi_loongson_board_devices *src = (void *) smbios_table->lp.boarddev_table_offset; +- grub_efi_loongson_board_devices *dst = &loongson_boot_params->board_devices; +- +- if (!src) +- return; +- +- grub_memcpy (dst, src, sizeof (grub_efi_loongson_board_devices)); +- loongson_params->boarddev_table_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; +-} +- +-#define ADD_MEMORY_DESCRIPTOR(desc, size) \ +- ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size))) +- +-static void +-grub_efi_loongson_init_memory_map (grub_efi_loongson_smbios_table *smbios_table, +- grub_efi_memory_descriptor_t *mmap_buf, +- grub_efi_uintn_t mmap_size, +- grub_efi_uintn_t desc_size) +-{ +- grub_efi_loongson_memory_map *src = (void *) smbios_table->lp.memory_offset; +- grub_efi_loongson_memory_map *dst = &loongson_boot_params->memory_map; +- grub_efi_memory_descriptor_t *mmap_end; +- grub_efi_memory_descriptor_t *desc; +- grub_efi_memory_descriptor_t *desc_next; +- grub_efi_uint32_t mem_types_reserved[] = +- { +- 1, // GRUB_EFI_RESERVED_MEMORY_TYPE +- 0, // GRUB_EFI_LOADER_CODE +- 0, // GRUB_EFI_LOADER_DATA +- 0, // GRUB_EFI_BOOT_SERVICES_CODE +- 0, // GRUB_EFI_BOOT_SERVICES_DATA +- 1, // GRUB_EFI_RUNTIME_SERVICES_CODE +- 1, // GRUB_EFI_RUNTIME_SERVICES_DATA +- 0, // GRUB_EFI_CONVENTIONAL_MEMORY +- 1, // GRUB_EFI_UNUSABLE_MEMORY +- 0, // GRUB_EFI_ACPI_RECLAIM_MEMORY +- 0, // GRUB_EFI_ACPI_MEMORY_NVS +- 1, // GRUB_EFI_MEMORY_MAPPED_IO +- 1, // GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE +- 1, // GRUB_EFI_PAL_CODE +- 1, // GRUB_EFI_PERSISTENT_MEMORY +- }; +- grub_uint32_t need_sort = 1; +- +- if (!src) +- return; +- +- dst->vers = src->vers; +- dst->nr_map = 0; +- dst->mem_freq = src->mem_freq; +- loongson_params->memory_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; +- +- if (!mmap_buf || !mmap_size || !desc_size) +- return; +- +- mmap_end = ADD_MEMORY_DESCRIPTOR (mmap_buf, mmap_size); +- +- /* drop reserved */ +- for (desc = mmap_buf, +- desc_next = desc; +- desc < mmap_end; +- desc = ADD_MEMORY_DESCRIPTOR (desc, desc_size)) +- { +- desc->type = mem_types_reserved[desc->type]; +- if (desc->type) +- continue; +- +- if (desc != desc_next) +- *desc_next = *desc; +- desc_next = ADD_MEMORY_DESCRIPTOR (desc_next, desc_size); +- } +- mmap_end = desc_next; +- +- /* sort: low->high */ +- while (need_sort) +- { +- need_sort = 0; +- +- for (desc = mmap_buf, +- desc_next = ADD_MEMORY_DESCRIPTOR (desc, desc_size); +- (desc < mmap_end) && (desc_next < mmap_end); +- desc = desc_next, +- desc_next = ADD_MEMORY_DESCRIPTOR (desc, desc_size)) +- { +- grub_efi_memory_descriptor_t tmp; +- +- if (desc->physical_start <= desc_next->physical_start) +- continue; +- +- tmp = *desc; +- *desc = *desc_next; +- *desc_next = tmp; +- need_sort = 1; +- } +- } +- +- /* combine continuous memory map */ +- for (desc = mmap_buf, +- desc_next = ADD_MEMORY_DESCRIPTOR (desc, desc_size); +- desc_next < mmap_end; +- desc_next = ADD_MEMORY_DESCRIPTOR (desc_next, desc_size)) +- { +- grub_efi_physical_address_t prev_end = desc->physical_start + (desc->num_pages << 12); +- +- if (prev_end == desc_next->physical_start) +- { +- desc->num_pages += desc_next->num_pages; +- continue; +- } +- +- desc = ADD_MEMORY_DESCRIPTOR (desc, desc_size); +- grub_memcpy (desc, desc_next, desc_size); +- } +- mmap_end = ADD_MEMORY_DESCRIPTOR (desc, desc_size); +- +- /* write to loongson memory map */ +- for (desc = mmap_buf; +- desc < mmap_end; +- desc = ADD_MEMORY_DESCRIPTOR (desc, desc_size)) +- { +- grub_efi_physical_address_t physical_start = grub_vtop ((void *) desc->physical_start); +- grub_efi_physical_address_t physical_end = physical_start + (desc->num_pages << 12); +- +- physical_start = ALIGN_UP (physical_start, 0x100000); +- physical_end = ALIGN_DOWN (physical_end, 0x100000); +- +- if (physical_start >= physical_end || (physical_end - physical_start) < 0x100000) +- continue; +- +- dst->map[dst->nr_map].node_id = (desc->physical_start >> 44) & 0xf; +- dst->map[dst->nr_map].mem_type = GRUB_EFI_LOONGSON_SYSTEM_RAM; +- dst->map[dst->nr_map].mem_start = physical_start; +- dst->map[dst->nr_map].mem_size = (physical_end - physical_start) >> 20; +- +- grub_dprintf ("loongson", "memory map %03u: 0x%016lx 0x%016lx @ %u\n", +- dst->nr_map, physical_start, physical_end - physical_start, +- dst->map[dst->nr_map].node_id); +- +- dst->nr_map ++; +- } +-} +- +-#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12) +-#define SUB_MEMORY_DESCRIPTOR(desc, size) \ +- ((grub_efi_memory_descriptor_t *) ((char *) (desc) - (size))) +- +-void +-grub_efi_loongson_alloc_boot_params (void) +-{ +- grub_efi_memory_descriptor_t *mmap_buf; +- grub_efi_memory_descriptor_t *mmap_end; +- grub_efi_memory_descriptor_t *desc; +- grub_efi_uintn_t mmap_size; +- grub_efi_uintn_t desc_size; +- grub_efi_physical_address_t address; +- grub_efi_allocate_type_t type; +- grub_efi_uintn_t pages; +- grub_efi_status_t status; +- grub_efi_boot_services_t *b; +- int mm_status; +- +- type = GRUB_EFI_ALLOCATE_ADDRESS; +- pages = BYTES_TO_PAGES (loongson_boot_params_size + loongson_reset_code_size); +- +- mmap_size = (1 << 12); +- mmap_buf = grub_malloc (mmap_size); +- if (!mmap_buf) +- grub_fatal ("out of memory!"); +- +- mm_status = grub_efi_get_memory_map (&mmap_size, mmap_buf, 0, &desc_size, 0); +- if (mm_status == 0) +- { +- grub_free (mmap_buf); +- mmap_size += desc_size * 32; +- +- mmap_buf = grub_malloc (mmap_size); +- if (!mmap_buf) +- grub_fatal ("out of memory!"); +- +- mm_status = grub_efi_get_memory_map (&mmap_size, mmap_buf, 0, &desc_size, 0); +- } +- +- if (mm_status < 0) +- grub_fatal ("cannot get memory map!"); +- +- mmap_end = ADD_MEMORY_DESCRIPTOR (mmap_buf, mmap_size); +- +- for (desc = SUB_MEMORY_DESCRIPTOR (mmap_end, desc_size); +- desc >= mmap_buf; +- desc = SUB_MEMORY_DESCRIPTOR (desc, desc_size)) +- { +- if (desc->type != GRUB_EFI_CONVENTIONAL_MEMORY) +- continue; +- if (desc->physical_start >= grub_efi_max_usable_address()) +- continue; +- if (desc->num_pages < pages) +- continue; +- +- address = desc->physical_start; +- break; +- } +- +- grub_free (mmap_buf); +- +- b = grub_efi_system_table->boot_services; +- status = efi_call_4 (b->allocate_pages, type, GRUB_EFI_RUNTIME_SERVICES_DATA, pages, &address); +- if (status != GRUB_EFI_SUCCESS) +- grub_fatal ("cannot allocate Loongson boot parameters!"); +- +- loongson_boot_params = (void *) ((grub_addr_t) address); +-} +- +-void +-grub_efi_loongson_free_boot_params (void) +-{ +- grub_efi_free_pages ((grub_addr_t) loongson_boot_params, +- BYTES_TO_PAGES (loongson_boot_params_size + loongson_reset_code_size)); +-} +- +-void * +-grub_efi_loongson_get_smbios_table (void) +-{ +- static grub_efi_loongson_smbios_table *smbios_table; +- grub_efi_loongson_boot_params *old_boot_params; +- struct bootparamsinterface* boot_params; +- void * tmp_boot_params = NULL; +- char * p = NULL; +- if(smbios_table) +- return smbios_table; +- +- tmp_boot_params = grub_efi_loongson_get_boot_params(); +- if(tmp_boot_params == NULL) +- { +- grub_dprintf("loongson", "tmp_boot_params is NULL\n"); +- return tmp_boot_params; +- } +- +- boot_params = (struct bootparamsinterface *)tmp_boot_params; +- p = (char *)&(boot_params->signature); +- if(grub_strncmp(p, "BPI", 3) == 0) +- { +- grub_dprintf("loongson", "find new bpi\n"); +- return boot_params ? boot_params : 0; +- } +- else +- { +- old_boot_params = (grub_efi_loongson_boot_params *)tmp_boot_params; +- /* +- { +- grub_dprintf("loongson", "smbios addr%llx\n", &old_boot_params->efi.smbios); +- grub_dprintf("loongson", "smbios vers%d\n", (grub_uint16_t)(&old_boot_params->efi.smbios.vers)); +- grub_dprintf("loongson", "smbios vga_bios%d\n", &old_boot_params->efi.smbios.vga_bios); +- grub_dprintf("loongson", "lp memory offset %llx\n", &old_boot_params->efi.smbios.lp.memory_offset); +- grub_dprintf("loongson", "lp cpu offset %llx\n", &old_boot_params->efi.smbios.lp.cpu_offset); +- grub_dprintf("loongson", "lp system offset %llx\n", &old_boot_params->efi.smbios.lp.system_offset); +- grub_dprintf("loongson", "lp irq offset %llx\n", &old_boot_params->efi.smbios.lp.irq_offset); +- grub_dprintf("loongson", "lp interface offset %llx\n", &old_boot_params->efi.smbios.p.interface_offset); +- grub_dprintf("loongson", "lp special offset %llx\n", &old_boot_params->efi.smbios.lp.special_offset); +- grub_dprintf("loongson", "lp boarddev table offset %llx\n", &old_boot_params->efi.smbios.lp.boarddev_table_offset); +- } +- */ +- return old_boot_params ? &old_boot_params->efi.smbios : 0; +- } +- +-} +- +-int +-grub_efi_is_loongson (void) +-{ +- return grub_efi_loongson_get_smbios_table () ? 1 : 0; ++ return version; + } + + void * +@@ -424,20 +38,20 @@ grub_efi_loongson_get_boot_params (void) + { + static void * boot_params = NULL; + grub_efi_configuration_table_t *tables; +- grub_efi_guid_t smbios_guid = GRUB_EFI_LOONGSON_SMBIOS_TABLE_GUID; ++ grub_efi_guid_t loongson_bpi_guid = GRUB_EFI_LOONGSON_BPI_TABLE_GUID; + unsigned int i; + + if (boot_params) + return boot_params; + +- /* Look for Loongson SMBIOS in UEFI config tables. */ ++ /* Look for Loongson boot params interface in UEFI config tables. */ + tables = grub_efi_system_table->configuration_table; + + for (i = 0; i < grub_efi_system_table->num_table_entries; i++) +- if (grub_memcmp (&tables[i].vendor_guid, &smbios_guid, sizeof (smbios_guid)) == 0) ++ if (grub_memcmp (&tables[i].vendor_guid, &loongson_bpi_guid, sizeof (loongson_bpi_guid)) == 0) + { + boot_params= tables[i].vendor_table; +- grub_dprintf ("loongson", "found registered SMBIOS @ %p\n", boot_params); ++ grub_dprintf ("loongson", "found registered BPI @ %p\n", boot_params); + break; + } + return boot_params; +@@ -467,8 +81,9 @@ grub_efi_loongson_grub_calculatechecksum8 (const grub_uint8_t *buffer, grub_efi_ + } + + +-grub_uint32_t +-grub_efi_loongson_memmap_sort(struct memmap array[], grub_uint32_t length, mem_map * bpmem, grub_uint32_t index, grub_uint32_t memtype) ++grub_uint32_t ++grub_efi_loongson_memmap_v1_sort(struct memmap_v1 array[], grub_uint32_t length, ++ mem_map_v1 * bpmem, grub_uint32_t index, grub_uint32_t memtype) + { + grub_uint64_t tempmemsize = 0; + grub_uint32_t j = 0; +@@ -479,19 +94,19 @@ grub_efi_loongson_memmap_sort(struct memmap array[], grub_uint32_t length, mem_m + tempmemsize = array[j].memsize; + for(t = j + 1; t < length; t++) + { +- if(array[j].memstart + tempmemsize == array[t].memstart) ++ if(array[j].memstart + tempmemsize == array[t].memstart) + { + tempmemsize += array[t].memsize; + } + else +- { ++ { + break; + } + } + bpmem->map[index].memtype = memtype; + bpmem->map[index].memstart = array[j].memstart; + bpmem->map[index].memsize = tempmemsize; +- grub_dprintf("loongson", "map[%d]:type %x, start 0x%llx, end 0x%llx\n", ++ grub_dprintf("loongson", "v1 map[%d]:type %x, start 0x%lx, end 0x%lx\n", + index, + bpmem->map[index].memtype, + bpmem->map[index].memstart, +@@ -502,4 +117,3 @@ grub_efi_loongson_memmap_sort(struct memmap array[], grub_uint32_t length, mem_m + } + return index; + } +- +diff --git a/grub-core/lib/loongarch64/efi/loongson_asm.S b/grub-core/lib/loongarch64/efi/loongson_asm.S +deleted file mode 100644 +index 4a04d34..0000000 +--- a/grub-core/lib/loongarch64/efi/loongson_asm.S ++++ /dev/null +@@ -1,58 +0,0 @@ +-/* +- * GRUB -- GRand Unified Bootloader +- * Copyright (C) 2017 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 . +- */ +- +-#include +- +- .file "loongson_asm.S" +- .text +- +- .align 4 +- +-VARIABLE (grub_efi_loongson_reset_start) +- +-VARIABLE (grub_efi_loongson_reset_system_addr) +- .dword 0 +- +-reset_system: +- bl 1f +- move $a1, $zero +-1: +- ld.d $t8, $ra, -16 +- move $a2, $zero +- jr $t8 +- move $a3, $zero +- +-FUNCTION(grub_efi_loongson_reset_cold) +- b reset_system +- li.w $a0, 0 +- +-FUNCTION(grub_efi_loongson_reset_warm) +- b reset_system +- li.w $a0, 1 +- +-FUNCTION(grub_efi_loongson_reset_shutdown) +- b reset_system +- li.w $a0, 2 +- +-FUNCTION(grub_efi_loongson_reset_suspend) +- b reset_system +- li.w $a0, 3 +- +-VARIABLE (grub_efi_loongson_reset_end) +- +- +diff --git a/grub-core/lib/loongarch64/relocator.c b/grub-core/lib/loongarch64/relocator.c +index f6c1b01..4b253ca 100644 +--- a/grub-core/lib/loongarch64/relocator.c ++++ b/grub-core/lib/loongarch64/relocator.c +@@ -72,12 +72,9 @@ write_reg (int regn, grub_uint64_t val, void **target) + static void + write_jump (int regn, void **target) + { +- grub_uint32_t andi=0x4c000000; +- grub_uint32_t nop=0x03400000; ++ grub_uint32_t jirl=0x4c000000; + +- *(grub_uint32_t *) *target = (andi | (grub_uint32_t)(regn<<5)); +- *target = ((grub_uint32_t *) *target) + 1; +- *(grub_uint32_t *) *target = nop; ++ *(grub_uint32_t *) *target = (jirl | (grub_uint32_t)(regn<<5)); + *target = ((grub_uint32_t *) *target) + 1; + } + +@@ -147,6 +144,9 @@ grub_relocator64_boot (struct grub_relocator *rel, + + grub_arch_sync_caches ((void *) relst, relsize); + ++ asm volatile ( ++ "ibar 0 \n"); ++ + grub_uint64_t val; + __asm__ __volatile__( + "li.w %0, 0x4\n\t" +diff --git a/grub-core/loader/loongarch64/linux.c b/grub-core/loader/loongarch64/linux.c +index c769bb2..7594ca2 100644 +--- a/grub-core/loader/loongarch64/linux.c ++++ b/grub-core/loader/loongarch64/linux.c +@@ -29,10 +29,12 @@ + #include + #include + #include ++#include + #include + #include + #include +- ++#include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -40,253 +42,302 @@ GRUB_MOD_LICENSE ("GPLv3+"); + + typedef unsigned long size_t; + +-static grub_dl_t my_mod; ++#define FDT_ADDR_CELLS_STRING "#address-cells" ++#define FDT_SIZE_CELLS_STRING "#size-cells" ++#define FDT_ADDR_SIZE_EXTRA ((2 * grub_fdt_prop_entry_size (sizeof(grub_uint32_t))) + \ ++ sizeof (FDT_ADDR_CELLS_STRING) + \ ++ sizeof (FDT_SIZE_CELLS_STRING)) + ++static grub_dl_t my_mod; + static int loaded; +- +-static grub_uint32_t tmp_index = 0; ++static int initrd_loaded = 0; + static grub_size_t linux_size; + + static struct grub_relocator *relocator; + static grub_addr_t target_addr, entry_addr; + static int linux_argc; + static grub_uint8_t *linux_args_addr; +-static grub_off_t rd_addr_arg_off, rd_size_arg_off; +-static grub_off_t initrd_addr_arg_off; +-static int initrd_loaded = 0; ++static grub_off_t rd_addr_arg_off, rd_size_arg_off, initrd_addr_arg_off; + ++static void *fdt; ++static int is_fdt_boot; ++static grub_addr_t initrd_start, initrd_end; ++static char *fdt_linux_args; + +-static grub_uint32_t j = 0; +-static grub_uint32_t t = 0; +-grub_uint64_t tempMemsize = 0; +-grub_uint32_t free_index = 0; +-grub_uint32_t reserve_index = 0; +-grub_uint32_t acpi_table_index = 0; +-grub_uint32_t acpi_nvs_index = 0; +- +-static inline grub_size_t +-page_align (grub_size_t size) ++static grub_err_t ++allocate_fdt_and_exit_boot (void) + { +- return (size + (1 << 12) - 1) & (~((1 << 12) - 1)); +-} ++ int node, retval; ++ grub_err_t err; ++ unsigned int size; ++ grub_efi_uintn_t mmap_size; ++ grub_efi_uintn_t desc_size; ++ grub_efi_uint32_t desc_version; ++ grub_efi_memory_descriptor_t *mmap_buf; ++ ++ size = GRUB_FDT_EMPTY_TREE_SZ + FDT_ADDR_SIZE_EXTRA + GRUB_EFI_LINUX_FDT_EXTRA_SPACE; ++ ++ fdt = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (size)); ++ if (!fdt) ++ return GRUB_ERR_OUT_OF_MEMORY; ++ ++ grub_fdt_create_empty_tree (fdt, size); ++ grub_fdt_set_prop32 (fdt, 0, FDT_ADDR_CELLS_STRING, 2); ++ grub_fdt_set_prop32 (fdt, 0, FDT_SIZE_CELLS_STRING, 2); ++ ++ node = grub_fdt_find_subnode (fdt, 0, "chosen"); ++ if (node < 0) ++ node = grub_fdt_add_subnode (fdt, 0, "chosen"); ++ if (node < 1) ++ goto failure; ++ ++ grub_dprintf ("loongson", "command_line %s, len %ld\n", ++ fdt_linux_args, grub_strlen(fdt_linux_args) + 1); ++ if ((fdt_linux_args != NULL) && (grub_strlen(fdt_linux_args) > 0)) { ++ retval = grub_fdt_set_prop (fdt, node, "bootargs", fdt_linux_args, ++ grub_strlen(fdt_linux_args) + 1); ++ if (retval) ++ goto failure; ++ } + +-/* Find the optimal number of pages for the memory map. Is it better to +- move this code to efi/mm.c? */ +-static grub_efi_uintn_t +-find_mmap_size (void) +-{ +- static grub_efi_uintn_t mmap_size = 0; ++ /* 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 (mmap_size != 0) +- return mmap_size; ++ node = grub_fdt_find_subnode (fdt, 0, "chosen"); ++ retval = grub_fdt_set_prop64 (fdt, node, "linux,uefi-system-table", ++ (grub_uint64_t)grub_efi_system_table); ++ if (retval) ++ goto failure; + +- mmap_size = (1 << 12); +- while (1) +- { +- int ret; +- grub_efi_memory_descriptor_t *mmap; +- grub_efi_uintn_t desc_size; ++ mmap_size = grub_efi_find_mmap_size (); ++ if (! mmap_size) ++ return grub_errno; ++ mmap_buf = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (mmap_size)); ++ if (! mmap_buf) ++ return grub_error (GRUB_ERR_IO, "cannot allocate memory map"); ++ err = grub_efi_finish_boot_services (&mmap_size, mmap_buf, NULL, ++ &desc_size, &desc_version); ++ if (err) ++ return err; + +- mmap = grub_malloc (mmap_size); +- if (! mmap) +- return 0; ++ if (!mmap_buf || !mmap_size || !desc_size) ++ return GRUB_ERR_BAD_ARGUMENT; + +- ret = grub_efi_get_memory_map (&mmap_size, mmap, 0, &desc_size, 0); +- grub_free (mmap); ++ retval = grub_fdt_set_prop64 (fdt, node, "linux,uefi-mmap-start", ++ (grub_uint64_t)mmap_buf); ++ if (retval) ++ goto failure; + +- if (ret < 0) +- { +- grub_error (GRUB_ERR_IO, "cannot get memory map"); +- return 0; +- } +- else if (ret > 0) +- break; ++ retval = grub_fdt_set_prop32 (fdt, node, "linux,uefi-mmap-size", ++ mmap_size); ++ if (retval) ++ goto failure; + +- mmap_size += (1 << 12); +- } ++ retval = grub_fdt_set_prop32 (fdt, node, "linux,uefi-mmap-desc-size", ++ desc_size); ++ if (retval) ++ goto failure; + ++ retval = grub_fdt_set_prop32 (fdt, node, "linux,uefi-mmap-desc-ver", ++ desc_version); ++ if (retval) ++ goto failure; + +- /* Increase the size a bit for safety, because GRUB allocates more on +- later, and EFI itself may allocate more. */ +- mmap_size += (1 << 12); ++ return GRUB_ERR_NONE; + +- return page_align (mmap_size); ++failure: ++ if (!fdt) { ++ return GRUB_ERR_BAD_OS; ++ } ++ grub_efi_free_pages ((grub_addr_t) fdt, ++ GRUB_EFI_BYTES_TO_PAGES (grub_fdt_get_totalsize (fdt))); ++ fdt = NULL; ++ return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT"); + } + + static grub_err_t +-grub_linux_boot (void) ++allocate_boot_params_and_exit_boot (void) + { +- struct grub_relocator64_state state; +- grub_int8_t checksum = 0; ++ grub_efi_uintn_t mmap_size; ++ grub_efi_uintn_t desc_size; ++ grub_efi_uint32_t desc_version; ++ grub_efi_memory_descriptor_t *mmap_buf; + grub_efi_memory_descriptor_t * lsdesc = NULL; +- +- grub_memset (&state, 0, sizeof (state)); +- +- /* Boot the kernel. */ +- state.gpr[1] = entry_addr; +- grub_dprintf("loongson", "entry_addr is %p\n", state.gpr[1]); +- state.gpr[4] = linux_argc; +- grub_dprintf("loongson", "linux_argc is %d\n", state.gpr[4]); +- state.gpr[5] = (grub_addr_t) linux_args_addr; +- grub_dprintf("loongson", "args_addr is %p\n", state.gpr[5]); +- +- if(grub_efi_is_loongson ()) +- { +- grub_efi_uintn_t mmap_size; +- grub_efi_uintn_t desc_size; +- grub_efi_memory_descriptor_t *mmap_buf; +- grub_err_t err; +- struct bootparamsinterface * boot_params; +- void * tmp_boot_params = NULL; +- grub_efi_uint8_t new_interface_flag = 0; +- mem_map * new_interface_mem = NULL; +- char *p = NULL; +- +- struct memmap reserve_mem[GRUB_EFI_LOONGSON_MMAP_MAX]; +- struct memmap free_mem[GRUB_EFI_LOONGSON_MMAP_MAX]; +- struct memmap acpi_table_mem[GRUB_EFI_LOONGSON_MMAP_MAX]; +- struct memmap acpi_nvs_mem[GRUB_EFI_LOONGSON_MMAP_MAX]; +- +- grub_memset(reserve_mem, 0, sizeof(struct memmap) * GRUB_EFI_LOONGSON_MMAP_MAX); +- grub_memset(free_mem, 0, sizeof(struct memmap) * GRUB_EFI_LOONGSON_MMAP_MAX); +- grub_memset(acpi_table_mem, 0, sizeof(struct memmap) * GRUB_EFI_LOONGSON_MMAP_MAX); +- grub_memset(acpi_nvs_mem, 0, sizeof(struct memmap) * GRUB_EFI_LOONGSON_MMAP_MAX); +- +- tmp_boot_params = grub_efi_loongson_get_boot_params(); +- if(tmp_boot_params == NULL) +- { +- grub_printf("not find param\n"); +- return -1; +- } +- +- boot_params = (struct bootparamsinterface *)tmp_boot_params; +- p = (char *)&(boot_params->signature); +- if(grub_strncmp(p, "BPI", 3) == 0) ++ grub_err_t err; ++ struct boot_params_interface * boot_params; ++ mem_map_v1 * mem_map_v1_table = NULL; ++ unsigned long bpi_version = 0; ++ grub_int8_t checksum = 0; ++ grub_uint32_t tmp_index = 0; ++ grub_uint32_t free_index = 0; ++ grub_uint32_t reserve_index = 0; ++ grub_uint32_t acpi_table_index = 0; ++ grub_uint32_t acpi_nvs_index = 0; ++ ++ struct memmap_v1 reserve_mem_v1[GRUB_EFI_LOONGSON_MMAP_MAX]; ++ struct memmap_v1 free_mem_v1[GRUB_EFI_LOONGSON_MMAP_MAX]; ++ struct memmap_v1 acpi_table_mem_v1[GRUB_EFI_LOONGSON_MMAP_MAX]; ++ struct memmap_v1 acpi_nvs_mem_v1[GRUB_EFI_LOONGSON_MMAP_MAX]; ++ ++ grub_memset(reserve_mem_v1, 0, sizeof(struct memmap_v1) * GRUB_EFI_LOONGSON_MMAP_MAX); ++ grub_memset(free_mem_v1, 0, sizeof(struct memmap_v1) * GRUB_EFI_LOONGSON_MMAP_MAX); ++ grub_memset(acpi_table_mem_v1, 0, sizeof(struct memmap_v1) * GRUB_EFI_LOONGSON_MMAP_MAX); ++ grub_memset(acpi_nvs_mem_v1, 0, sizeof(struct memmap_v1) * GRUB_EFI_LOONGSON_MMAP_MAX); ++ ++ boot_params = (struct boot_params_interface *)grub_efi_loongson_get_boot_params(); ++ ++ ext_list * listpointer = NULL; ++ /* Check extlist headers */ ++ listpointer = boot_params->extlist; ++ for( ;listpointer != NULL; listpointer = listpointer->next) + { +- /* Check extlist headers */ +- ext_list * listpointer = NULL; +- listpointer = boot_params->extlist; +- for( ;listpointer != NULL; listpointer = listpointer->next) ++ char *pl= (char *)&(listpointer->signature); ++ if(grub_strncmp(pl, "MEM", 3) == 0) + { +- char *pl= (char *)&(listpointer->signature); +- if(grub_strncmp(pl, "MEM", 3) == 0) +- { +- new_interface_mem = (mem_map *)listpointer; +- } ++ mem_map_v1_table = (mem_map_v1 *)listpointer; ++ break; + } +- +- new_interface_flag = 1; +- grub_dprintf("loongson", "get new parameter interface\n"); +- }else{ +- new_interface_flag = 0; +- grub_dprintf("loongson", "get old parameter interface\n"); + } +- state.gpr[6] = (grub_uint64_t)tmp_boot_params; +- grub_dprintf("loongson", "boot_params is %p\n", state.gpr[6]); + +- mmap_size = find_mmap_size (); +- if (! mmap_size) +- return grub_errno; +- mmap_buf = grub_efi_allocate_any_pages (page_align (mmap_size) >> 12); +- if (! mmap_buf) +- return grub_error (GRUB_ERR_IO, "cannot allocate memory map"); +- err = grub_efi_finish_boot_services (&mmap_size, mmap_buf, NULL, +- &desc_size, NULL); +- if (err) +- return err; ++ mmap_size = grub_efi_find_mmap_size (); ++ if (! mmap_size) ++ return grub_errno; ++ mmap_buf = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (mmap_size)); ++ if (! mmap_buf) ++ return grub_error (GRUB_ERR_IO, "cannot allocate memory map"); ++ err = grub_efi_finish_boot_services (&mmap_size, mmap_buf, NULL, ++ &desc_size, &desc_version); ++ if (err) ++ return err; + +- if(new_interface_flag) +- { +- if (!mmap_buf || !mmap_size || !desc_size) +- return -1; +- tmp_index = new_interface_mem -> mapcount; ++ if (!mmap_buf || !mmap_size || !desc_size) ++ return GRUB_ERR_BAD_ARGUMENT; ++ ++ char *p = (char *)&(boot_params->signature); ++ bpi_version = grub_efi_get_bpi_version(p); ++ grub_dprintf("loongson", "get bpi version:%ld\n", bpi_version); + ++ if (bpi_version <= GRUB_EFI_BPI_VER_V2) ++ { + /* +- According to UEFI SPEC,mmap_buf is the accurate Memory Map array \ +- now we can fill platform specific memory structure. +- */ ++ According to UEFI SPEC,mmap_buf is the accurate Memory Map array \ ++ now we can fill platform specific memory structure. ++ */ + for(lsdesc = mmap_buf; lsdesc < (grub_efi_memory_descriptor_t *)((char *)mmap_buf + mmap_size); +- lsdesc = (grub_efi_memory_descriptor_t *)((char *)lsdesc + desc_size)) ++ lsdesc = (grub_efi_memory_descriptor_t *)((char *)lsdesc + desc_size)) + { +- /* Recovery */ +- if((lsdesc->type != GRUB_EFI_ACPI_RECLAIM_MEMORY) && \ +- (lsdesc->type != GRUB_EFI_ACPI_MEMORY_NVS) && \ +- (lsdesc->type != GRUB_EFI_RUNTIME_SERVICES_DATA) && \ +- (lsdesc->type != GRUB_EFI_RUNTIME_SERVICES_CODE) && \ +- (lsdesc->type != GRUB_EFI_RESERVED_MEMORY_TYPE) && \ +- (lsdesc->type != GRUB_EFI_PAL_CODE)) ++ grub_dprintf("loongson", "type:%d, phy_start:0x%lx, phy_end:0x%lx\n", lsdesc->type, ++ lsdesc->physical_start, lsdesc->physical_start + lsdesc->num_pages * GRUB_EFI_PAGE_SIZE); ++ ++ /* System RAM */ ++ if ((lsdesc->type != GRUB_EFI_ACPI_RECLAIM_MEMORY) && \ ++ (lsdesc->type != GRUB_EFI_ACPI_MEMORY_NVS) && \ ++ (lsdesc->type != GRUB_EFI_RUNTIME_SERVICES_DATA) && \ ++ (lsdesc->type != GRUB_EFI_RUNTIME_SERVICES_CODE) && \ ++ (lsdesc->type != GRUB_EFI_RESERVED_MEMORY_TYPE) && \ ++ (lsdesc->type != GRUB_EFI_PAL_CODE)) + { +- free_mem[free_index].memtype = GRUB_EFI_LOONGSON_SYSTEM_RAM; +- free_mem[free_index].memstart = (lsdesc->physical_start) & 0xffffffffffff; +- free_mem[free_index].memsize = lsdesc->num_pages * 4096; ++ free_mem_v1[free_index].memtype = GRUB_EFI_LOONGSON_SYSTEM_RAM; ++ free_mem_v1[free_index].memstart = (lsdesc->physical_start) & GRUB_EFI_MAX_PHY_ADDRESS; ++ free_mem_v1[free_index].memsize = lsdesc->num_pages * GRUB_EFI_PAGE_SIZE; + free_index++; + + /*ACPI*/ +- }else if((lsdesc->type == GRUB_EFI_ACPI_RECLAIM_MEMORY)){ +- acpi_table_mem[acpi_table_index].memtype = GRUB_EFI_LOONGSON_ACPI_TABLE; +- acpi_table_mem[acpi_table_index].memstart = (lsdesc->physical_start) & 0xffffffffffff; +- acpi_table_mem[acpi_table_index].memsize = lsdesc->num_pages * 4096; ++ } else if ((lsdesc->type == GRUB_EFI_ACPI_RECLAIM_MEMORY)){ ++ acpi_table_mem_v1[acpi_table_index].memtype = GRUB_EFI_LOONGSON_ACPI_TABLE; ++ acpi_table_mem_v1[acpi_table_index].memstart = (lsdesc->physical_start) & GRUB_EFI_MAX_PHY_ADDRESS; ++ acpi_table_mem_v1[acpi_table_index].memsize = lsdesc->num_pages * GRUB_EFI_PAGE_SIZE; + acpi_table_index++; +- }else if((lsdesc->type == GRUB_EFI_ACPI_MEMORY_NVS)){ +- acpi_nvs_mem[acpi_nvs_index].memtype = GRUB_EFI_LOONGSON_ACPI_NVS; +- acpi_nvs_mem[acpi_nvs_index].memstart = (lsdesc->physical_start) & 0xffffffffffff; +- acpi_nvs_mem[acpi_nvs_index].memsize = lsdesc->num_pages * 4096; ++ } else if ((lsdesc->type == GRUB_EFI_ACPI_MEMORY_NVS)){ ++ acpi_nvs_mem_v1[acpi_nvs_index].memtype = GRUB_EFI_LOONGSON_ACPI_NVS; ++ acpi_nvs_mem_v1[acpi_nvs_index].memstart = (lsdesc->physical_start) & GRUB_EFI_MAX_PHY_ADDRESS; ++ acpi_nvs_mem_v1[acpi_nvs_index].memsize = lsdesc->num_pages * GRUB_EFI_PAGE_SIZE; + acpi_nvs_index++; + + /* Reserve */ +- }else{ +- reserve_mem[reserve_index].memtype = GRUB_EFI_LOONGSON_MEMORY_RESERVED; +- reserve_mem[reserve_index].memstart = (lsdesc->physical_start) & 0xffffffffffff; +- reserve_mem[reserve_index].memsize = lsdesc->num_pages * 4096; ++ } else { ++ reserve_mem_v1[reserve_index].memtype = GRUB_EFI_LOONGSON_MEMORY_RESERVED; ++ reserve_mem_v1[reserve_index].memstart = (lsdesc->physical_start) & GRUB_EFI_MAX_PHY_ADDRESS; ++ reserve_mem_v1[reserve_index].memsize = lsdesc->num_pages * GRUB_EFI_PAGE_SIZE; + reserve_index++; + } + } + +- /* Recovery sort */ +- for(j = 0; j < free_index;) +- { +- tempMemsize = free_mem[j].memsize; +- for(t = j + 1; t < free_index; t++) +- { +- if((free_mem[j].memstart + tempMemsize == free_mem[t].memstart) && (free_mem[j].memtype == free_mem[t].memtype)) +- { +- tempMemsize += free_mem[t].memsize; +- }else{ +- break; +- } +- } +- +- new_interface_mem->map[tmp_index].memtype = GRUB_EFI_LOONGSON_SYSTEM_RAM; +- new_interface_mem->map[tmp_index].memstart = free_mem[j].memstart; +- new_interface_mem->map[tmp_index].memsize = tempMemsize; +- grub_dprintf("loongson", "map[%d]:type %x, start 0x%llx, end 0x%llx\n", +- tmp_index, +- new_interface_mem->map[tmp_index].memtype, +- new_interface_mem->map[tmp_index].memstart, +- new_interface_mem->map[tmp_index].memstart+ new_interface_mem->map[tmp_index].memsize +- ); +- j = t; +- tmp_index++; +- } ++ tmp_index = mem_map_v1_table->mapcount; ++ /*System RAM Sort*/ ++ tmp_index = grub_efi_loongson_memmap_v1_sort(free_mem_v1, free_index, mem_map_v1_table, ++ tmp_index, GRUB_EFI_LOONGSON_SYSTEM_RAM); + /*ACPI Sort*/ +- tmp_index = grub_efi_loongson_memmap_sort(acpi_table_mem, acpi_table_index, new_interface_mem, tmp_index, GRUB_EFI_LOONGSON_ACPI_TABLE); +- tmp_index = grub_efi_loongson_memmap_sort(acpi_nvs_mem, acpi_nvs_index, new_interface_mem, tmp_index, GRUB_EFI_LOONGSON_ACPI_NVS); ++ tmp_index = grub_efi_loongson_memmap_v1_sort(acpi_table_mem_v1, acpi_table_index, ++ mem_map_v1_table, tmp_index, GRUB_EFI_LOONGSON_ACPI_TABLE); ++ tmp_index = grub_efi_loongson_memmap_v1_sort(acpi_nvs_mem_v1, acpi_nvs_index, ++ mem_map_v1_table, tmp_index, GRUB_EFI_LOONGSON_ACPI_NVS); + /*Reserve Sort*/ +- grub_uint64_t loongarch_addr; +- asm volatile ("csrrd %0, 0x181" : "=r" (loongarch_addr)); +- if((loongarch_addr & 0xff00000000000000) == 0x9000000000000000){ +- tmp_index = grub_efi_loongson_memmap_sort(reserve_mem, reserve_index, new_interface_mem, tmp_index, GRUB_EFI_LOONGSON_MEMORY_RESERVED); +- }else{ +- tmp_index = grub_efi_loongson_memmap_sort(reserve_mem, reserve_index, new_interface_mem, tmp_index, GRUB_EFI_LOONGSON_MEMORY_RESERVED + 1); +- } +- +- new_interface_mem->mapcount = tmp_index; +- new_interface_mem->header.checksum = 0; +- +- checksum = grub_efi_loongson_grub_calculatechecksum8(new_interface_mem, new_interface_mem->header.length); +- new_interface_mem->header.checksum = checksum; ++ { ++ grub_uint64_t loongarch_addr; ++ asm volatile ("csrrd %0, 0x181" : "=r" (loongarch_addr)); ++ if ((loongarch_addr & 0xff00000000000000) == 0x9000000000000000) ++ tmp_index = grub_efi_loongson_memmap_v1_sort(reserve_mem_v1, reserve_index, ++ mem_map_v1_table, tmp_index, ++ GRUB_EFI_LOONGSON_MEMORY_RESERVED); ++ else ++ tmp_index = grub_efi_loongson_memmap_v1_sort(reserve_mem_v1, reserve_index, ++ mem_map_v1_table, tmp_index, ++ GRUB_EFI_LOONGSON_MEMORY_RESERVED + 1); ++ } ++ mem_map_v1_table->mapcount = tmp_index; ++ mem_map_v1_table->header.checksum = 0; ++ ++ checksum = grub_efi_loongson_grub_calculatechecksum8((grub_uint8_t *)mem_map_v1_table, ++ mem_map_v1_table->header.length); ++ mem_map_v1_table->header.checksum = checksum; + } ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_linux_boot (void) ++{ ++ struct grub_relocator64_state state; ++ ++ grub_memset (&state, 0, sizeof (state)); ++ ++ /* Boot the kernel. */ ++ state.gpr[1] = entry_addr; ++ grub_dprintf("loongson", "entry_addr is 0x%lx\n", state.gpr[1]); ++ ++ if (is_fdt_boot == 1) ++ { ++ if (allocate_fdt_and_exit_boot () != GRUB_ERR_NONE) ++ return grub_errno; ++ ++ state.gpr[4] = 1 << FLAGS_EFI_SUPPORT_BIT; ++ state.gpr[5] = (grub_uint64_t)fdt; ++ state.gpr[6] = 0; ++ } else { ++ state.gpr[4] = linux_argc; ++ state.gpr[5] = (grub_addr_t) linux_args_addr; ++ state.gpr[6] = (grub_uint64_t)grub_efi_loongson_get_boot_params(); ++ ++ if (allocate_boot_params_and_exit_boot () != GRUB_ERR_NONE) ++ return grub_errno; + } ++ grub_dprintf("loongson", "gpr[4]:%ld, gpr[5]:0x%lx, gpr[6]:0x%lx\n", ++ state.gpr[4], state.gpr[5], state.gpr[6]); + + state.jumpreg = 1; + grub_relocator64_boot (relocator, state); +@@ -299,67 +350,42 @@ grub_linux_unload (void) + { + grub_relocator_unload (relocator); + grub_dl_unref (my_mod); +- + loaded = 0; + + return GRUB_ERR_NONE; + } + + static grub_err_t +-grub_linux_load32 (grub_elf_t elf, const char *filename) +-{ +- Elf32_Addr base; +- grub_err_t err; +- grub_uint8_t *playground; +- +- /* Linux's entry point incorrectly contains a virtual address. */ +- entry_addr = elf->ehdr.ehdr32.e_entry; +- +- linux_size = grub_elf32_size (elf, &base, 0); +- if (linux_size == 0) +- return grub_errno; +- target_addr = base; +- linux_size = ALIGN_UP (base + linux_size - base, 8); +- +- relocator = grub_relocator_new (); +- if (!relocator) +- return grub_errno; +- +- { +- grub_relocator_chunk_t ch; +- err = grub_relocator_alloc_chunk_addr (relocator, &ch, +- grub_vtop ((void *) target_addr), +- linux_size); +- if (err) +- return err; +- playground = get_virtual_current_address (ch); +- } +- +- /* Now load the segments into the area we claimed. */ +- return grub_elf32_load (elf, filename, playground - base, GRUB_ELF_LOAD_FLAGS_NONE, 0, 0); +-} +- +-static grub_err_t + grub_linux_load64 (grub_elf_t elf, const char *filename) + { + Elf64_Addr base; + grub_err_t err; + grub_uint8_t *playground; ++ grub_uint64_t addr; ++ int flag; + + /* Linux's entry point incorrectly contains a virtual address. */ + entry_addr = elf->ehdr.ehdr64.e_entry; +- grub_dprintf("loongson", "entry address = %p\n", entry_addr); ++ grub_dprintf("loongson", "entry address = 0x%lx\n", entry_addr); + + linux_size = grub_elf64_size (elf, &base, 0); +- grub_dprintf("loongson", "base = %p\n", base); ++ grub_dprintf("loongson", "base = 0x%lx\n", base); + + if (linux_size == 0) + return grub_errno; + target_addr = base; + linux_size = ALIGN_UP (base + linux_size - base, 8); + ++ asm volatile ("csrrd %0, 0x181" : "=r" (addr)); ++ if (addr & 0x1) { ++ flag = GRUB_ELF_LOAD_FLAGS_NONE; ++ } else { ++ flag = GRUB_ELF_LOAD_FLAGS_30BITS; ++ base &= ~ELF64_LOADMASK; ++ entry_addr &= ~ELF64_LOADMASK; ++ } ++ + relocator = grub_relocator_new (); +- // linux_size=0x322fa80; + if (!relocator) + return grub_errno; + +@@ -374,7 +400,7 @@ grub_linux_load64 (grub_elf_t elf, const char *filename) + } + + /* Now load the segments into the area we claimed. */ +- return grub_elf64_load (elf, filename, playground - base, GRUB_ELF_LOAD_FLAGS_NONE, 0, 0); ++ return grub_elf64_load (elf, filename, playground - base, flag, 0, 0); + } + + static grub_err_t +@@ -382,20 +408,21 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) + { + grub_elf_t elf = 0; +- int size; +- int i; +- grub_uint64_t *linux_argv; +- char *linux_args; + grub_err_t err; ++ int args_size = 0; ++ ++ grub_dl_ref (my_mod); + + if (argc == 0) ++ { + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); ++ } + +- elf = grub_elf_open (argv[0],GRUB_FILE_TYPE_LINUX_KERNEL); ++ elf = grub_elf_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL); + if (! elf) + return grub_errno; + +- if (elf->ehdr.ehdr32.e_type != ET_EXEC) ++ if (elf->ehdr.ehdr64.e_type != ET_EXEC) + { + grub_elf_close (elf); + return grub_error (GRUB_ERR_UNKNOWN_OS, +@@ -406,30 +433,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + grub_loader_unset (); + loaded = 0; + +- /* For arguments. */ +- linux_argc = argc; +- /* Main arguments. */ +- size = (linux_argc) * sizeof (grub_uint64_t); +- /* Initrd address and size. */ +- size += 3 * sizeof (grub_uint64_t); +- /* NULL terminator. */ +- size += sizeof (grub_uint64_t); +- /* First argument is always "a0". */ +- size += ALIGN_UP (sizeof ("a0"), 4); +- /* Normal arguments. */ +- for (i = 1; i < argc; i++) +- size += ALIGN_UP (grub_strlen (argv[i]) + 1, 4); +- +- /* rd arguments. */ +- size += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4); +- size += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4); +- size += ALIGN_UP (sizeof ("initrd=0xXXXXXXXXXXXXXXXX,0xXXXXXXXXXXXXXXXX"), 4); +- +- size = ALIGN_UP (size, 8); +- +- if (grub_elf_is_elf32 (elf)) +- err = grub_linux_load32 (elf, argv[0]); +- else + if (grub_elf_is_elf64 (elf)) + err = grub_linux_load64 (elf, argv[0]); + else +@@ -440,26 +443,71 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + if (err) + return err; + +- { +- grub_relocator_chunk_t ch; +- err = grub_relocator_alloc_chunk_align (relocator, &ch, +- 0, (0xffffffff - size) + 1, +- size, 8, +- GRUB_RELOCATOR_PREFERENCE_HIGH, 0); +- if (err) +- return err; +- linux_args_addr = get_virtual_current_address (ch); +- } ++ if (grub_efi_loongson_get_boot_params() == NULL) { ++ grub_size_t cmdline_size; + +- linux_argv = (grub_uint64_t *) linux_args_addr; +- linux_args = (char *) (linux_argv + (linux_argc + 1 + 3)); ++ is_fdt_boot = 1; ++ cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE); ++ fdt_linux_args = grub_malloc (cmdline_size); ++ if (!fdt_linux_args) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); ++ goto fail; ++ } ++ grub_memcpy (fdt_linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE)); ++ err = grub_create_loader_cmdline (argc, argv, ++ fdt_linux_args + sizeof (LINUX_IMAGE) - 1, ++ cmdline_size, ++ GRUB_VERIFY_KERNEL_CMDLINE); ++ if (err) ++ goto fail; ++ grub_dprintf("loongson", "fdt linux args:%s\n", ++ fdt_linux_args + sizeof (LINUX_IMAGE) - 1); ++ ++ } else { ++ int i; ++ grub_uint64_t *linux_argv; ++ char *linux_args; ++ ++ is_fdt_boot = 0; ++ /* For arguments. */ ++ linux_argc = argc; ++ /* Main arguments. */ ++ args_size = (linux_argc) * sizeof (grub_uint64_t); ++ /* Initrd address/size and initrd */ ++ args_size += 3 * sizeof (grub_uint64_t); ++ /* NULL terminator. */ ++ args_size += sizeof (grub_uint64_t); ++ /* First argument is always "a0". */ ++ args_size += ALIGN_UP (sizeof ("a0"), 4); ++ /* Normal arguments. */ ++ for (i = 1; i < argc; i++) ++ args_size += ALIGN_UP (grub_strlen (argv[i]) + 1, 4); ++ ++ /* rd arguments. */ ++ args_size += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4); ++ args_size += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4); ++ args_size += ALIGN_UP (sizeof ("initrd=0xXXXXXXXXXXXXXXXX,0xXXXXXXXXXXXXXXXX"), 4); ++ ++ args_size = ALIGN_UP (args_size, 8); ++ ++ linux_args_addr = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (args_size)); ++ grub_dprintf ("linux", "linux args numpages: %lld\n", ++ (long long) GRUB_EFI_BYTES_TO_PAGES (args_size)); ++ if (!linux_args_addr) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); ++ goto fail; ++ } ++ linux_argv = (grub_uint64_t *) linux_args_addr; ++ linux_args = (char *) (linux_argv + (linux_argc + 1 + 3)); + +- grub_memcpy (linux_args, "a0", sizeof ("a0")); +- *linux_argv = (grub_uint64_t) (grub_addr_t) linux_args; +- linux_argv++; +- linux_args += ALIGN_UP (sizeof ("a0"), 4); ++ grub_memcpy (linux_args, "a0", sizeof ("a0")); ++ *linux_argv = (grub_uint64_t) (grub_addr_t) linux_args; ++ linux_argv++; ++ linux_args += ALIGN_UP (sizeof ("a0"), 4); + +- for (i = 1; i < argc; i++) ++ for (i = 1; i < argc; i++) + { + grub_memcpy (linux_args, argv[i], grub_strlen (argv[i]) + 1); + *linux_argv = (grub_uint64_t) (grub_addr_t) linux_args; +@@ -467,40 +515,80 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + linux_args += ALIGN_UP (grub_strlen (argv[i]) + 1, 4); + } + +- /* Reserve space for rd arguments. */ +- rd_addr_arg_off = (grub_uint8_t *) linux_args - linux_args_addr; +- linux_args += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4); +- *linux_argv = 0; +- linux_argv++; ++ /* Reserve space for rd arguments. */ ++ rd_addr_arg_off = (grub_uint8_t *) linux_args - linux_args_addr; ++ linux_args += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4); ++ *linux_argv = 0; ++ linux_argv++; ++ ++ rd_size_arg_off = (grub_uint8_t *) linux_args - linux_args_addr; ++ linux_args += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4); ++ *linux_argv = 0; ++ linux_argv++; + +- rd_size_arg_off = (grub_uint8_t *) linux_args - linux_args_addr; +- linux_args += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4); +- *linux_argv = 0; +- linux_argv++; ++ /* Reserve space for initrd arguments. */ ++ initrd_addr_arg_off = (grub_uint8_t *) linux_args - linux_args_addr; ++ linux_args += ALIGN_UP (sizeof ("initrd=0xXXXXXXXXXXXXXXXX,0xXXXXXXXXXXXXXXXX"), 4); ++ *linux_argv = 0; ++ linux_argv++; + +- /* Reserve space for initrd arguments. */ +- initrd_addr_arg_off = (grub_uint8_t *) linux_args - linux_args_addr; +- linux_args += ALIGN_UP (sizeof ("initrd=0xXXXXXXXXXXXXXXXX,0xXXXXXXXXXXXXXXXX"), 4); +- *linux_argv = 0; +- linux_argv++; ++ *linux_argv = 0; ++ } + +- *linux_argv = 0; ++ if (grub_errno == GRUB_ERR_NONE) ++ { ++ grub_loader_set (grub_linux_boot, grub_linux_unload, 0); ++ loaded = 1; ++ } + +- grub_loader_set (grub_linux_boot, grub_linux_unload, 0); + initrd_loaded = 0; +- loaded = 1; +- grub_dl_ref (my_mod); + +- return GRUB_ERR_NONE; ++fail: ++ if (grub_errno != GRUB_ERR_NONE) ++ { ++ grub_dl_unref (my_mod); ++ loaded = 0; ++ } ++ ++ if (fdt_linux_args && !loaded) ++ grub_free (fdt_linux_args); ++ ++ if (linux_args_addr && !loaded) ++ grub_efi_free_pages ((grub_addr_t) linux_args_addr, ++ GRUB_EFI_BYTES_TO_PAGES (args_size)); ++ ++ return grub_errno; ++} ++ ++#define INITRD_MAX_ADDRESS_OFFSET (32ULL * 1024 * 1024 * 1024) ++ ++/* ++ * This function returns a pointer to a legally allocated initrd buffer, ++ * or NULL if unsuccessful ++ */ ++static void * ++allocate_initrd_mem (int initrd_pages) ++{ ++ grub_addr_t max_addr; ++ ++ if (grub_efi_get_ram_base (&max_addr) != GRUB_ERR_NONE) ++ return NULL; ++ ++ max_addr += INITRD_MAX_ADDRESS_OFFSET - 1; ++ ++ return grub_efi_allocate_pages_real (max_addr, initrd_pages, ++ GRUB_EFI_ALLOCATE_MAX_ADDRESS, ++ GRUB_EFI_LOADER_DATA); + } + ++ + static grub_err_t + grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) + { +- grub_size_t size = 0; +- void *initrd_dest; ++ grub_size_t initrd_size, initrd_pages; + grub_err_t err; ++ void *initrd_mem = NULL; + struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 }; + + if (argc == 0) +@@ -515,49 +603,71 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + if (grub_initrd_init (argc, argv, &initrd_ctx)) + goto fail; + +- size = grub_get_initrd_size (&initrd_ctx); ++ initrd_size = grub_get_initrd_size (&initrd_ctx); + ++ if (is_fdt_boot == 1) //fdt + { ++ initrd_pages = (GRUB_EFI_BYTES_TO_PAGES (initrd_size)); ++ initrd_mem = allocate_initrd_mem (initrd_pages); ++ if (!initrd_mem) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); ++ goto fail; ++ } ++ } else { + grub_relocator_chunk_t ch; + err = grub_relocator_alloc_chunk_align (relocator, &ch, +- 0, (0xffffffff - size) + 1, +- size, 0x10000, +- GRUB_RELOCATOR_PREFERENCE_HIGH, 0); ++ 0, (0xffffffff - initrd_size) + 1, ++ initrd_size, 0x10000, ++ GRUB_RELOCATOR_PREFERENCE_HIGH, 0); + + if (err) +- goto fail; +- initrd_dest = get_virtual_current_address (ch); ++ return err; ++ initrd_mem = get_virtual_current_address (ch); + } + +- if (grub_initrd_load (&initrd_ctx, argv, initrd_dest)) ++ if (grub_initrd_load (&initrd_ctx, argv, initrd_mem)) + goto fail; + +- grub_snprintf ((char *) linux_args_addr + rd_addr_arg_off, +- sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), "rd_start=0x%lx", +- (grub_uint64_t) initrd_dest); +- ((grub_uint64_t *) linux_args_addr)[linux_argc] +- = (grub_uint64_t) ((grub_addr_t) linux_args_addr + rd_addr_arg_off); +- linux_argc++; +- +- grub_snprintf ((char *) linux_args_addr + rd_size_arg_off, +- sizeof ("rd_size=0xXXXXXXXXXXXXXXXXX"), "rd_size=0x%lx", +- (grub_uint64_t) size); +- ((grub_uint64_t *) linux_args_addr)[linux_argc] +- = (grub_uint64_t) ((grub_addr_t) linux_args_addr + rd_size_arg_off); +- linux_argc++; +- ++ initrd_start = (grub_addr_t) initrd_mem; ++ initrd_end = initrd_start + initrd_size; ++ grub_dprintf ("linux", "[addr=%p, size=0x%lx]\n", ++ (void *) initrd_start, initrd_size); + +- grub_snprintf ((char *) linux_args_addr + initrd_addr_arg_off, +- sizeof ("initrd=0xXXXXXXXXXXXXXXXX,0xXXXXXXXXXXXXXXXX"), "initrd=0x%lx,0x%lx", +- ((grub_uint64_t) initrd_dest & 0xffffffff), (grub_uint64_t) size); +- ((grub_uint64_t *) linux_args_addr)[linux_argc] +- = (grub_uint64_t) ((grub_addr_t) linux_args_addr + initrd_addr_arg_off); +- linux_argc++; ++ if (is_fdt_boot == 0) //bpi ++ { ++ grub_snprintf ((char *) linux_args_addr + rd_addr_arg_off, ++ sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), ++ "rd_start=0x%lx", ++ (grub_uint64_t) initrd_mem); ++ ((grub_uint64_t *) linux_args_addr)[linux_argc] ++ = (grub_uint64_t) ((grub_addr_t) linux_args_addr + rd_addr_arg_off); ++ linux_argc++; ++ ++ grub_snprintf ((char *) linux_args_addr + rd_size_arg_off, ++ sizeof ("rd_size=0xXXXXXXXXXXXXXXXXX"), "rd_size=0x%lx", ++ (grub_uint64_t) initrd_size); ++ ((grub_uint64_t *) linux_args_addr)[linux_argc] ++ = (grub_uint64_t) ((grub_addr_t) linux_args_addr + rd_size_arg_off); ++ linux_argc++; ++ ++ grub_snprintf ((char *) linux_args_addr + initrd_addr_arg_off, ++ sizeof ("initrd=0xXXXXXXXXXXXXXXXX,0xXXXXXXXXXXXXXXXX"), ++ "initrd=0x%lx,0x%lx", ++ ((grub_uint64_t) initrd_mem & GRUB_EFI_MAX_PHY_ADDRESS), ++ (grub_uint64_t) initrd_size); ++ ((grub_uint64_t *) linux_args_addr)[linux_argc] ++ = (grub_uint64_t) ((grub_addr_t) linux_args_addr + initrd_addr_arg_off); ++ linux_argc++; ++ } + + initrd_loaded = 1; + + fail: + grub_initrd_close (&initrd_ctx); ++ if (is_fdt_boot == 1) ++ if (initrd_mem && !initrd_start) ++ grub_efi_free_pages ((grub_addr_t) initrd_mem, initrd_pages); + + return grub_errno; + } +diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h +index 4411ffa..defdd01 100644 +--- a/include/grub/efi/efi.h ++++ b/include/grub/efi/efi.h +@@ -129,7 +129,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 (__loongarch__) + void *EXPORT_FUNC(grub_efi_get_firmware_fdt)(void); + grub_err_t EXPORT_FUNC(grub_efi_get_ram_base)(grub_addr_t *); + #include +diff --git a/include/grub/fdt.h b/include/grub/fdt.h +index 6ee57e1..a0710ab 100644 +--- a/include/grub/fdt.h ++++ b/include/grub/fdt.h +@@ -19,11 +19,14 @@ + #ifndef GRUB_FDT_HEADER + #define GRUB_FDT_HEADER 1 + +-#if defined(__arm__) || defined(__aarch64__) ++#if defined(__arm__) || defined(__aarch64__) || defined (__loongarch__) + + #include + #include + ++/* Space required when preparing the /chosen node after boot has been called. */ ++#define GRUB_EFI_LINUX_FDT_EXTRA_SPACE 0x400 ++ + #define FDT_MAGIC 0xD00DFEED + + typedef struct { +diff --git a/include/grub/loongarch64/efi/boot.h b/include/grub/loongarch64/efi/boot.h +deleted file mode 100644 +index e69de29..0000000 +diff --git a/include/grub/loongarch64/efi/loader.h b/include/grub/loongarch64/efi/loader.h +deleted file mode 100644 +index 71a0159..0000000 +--- a/include/grub/loongarch64/efi/loader.h ++++ /dev/null +@@ -1,25 +0,0 @@ +-/* +- * GRUB -- GRand Unified Bootloader +- * Copyright (C) 2002,2003,2004,2006,2007,2017 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 . +- */ +- +-#ifndef GRUB_LOADER_MACHINE_HEADER +-#define GRUB_LOADER_MACHINE_HEADER 1 +- +-#include +-#include +- +-#endif /* ! GRUB_LOADER_MACHINE_HEADER */ +diff --git a/include/grub/loongarch64/efi/loongson.h b/include/grub/loongarch64/efi/loongson.h +index fa32ef5..7a9ccb4 100644 +--- a/include/grub/loongarch64/efi/loongson.h ++++ b/include/grub/loongarch64/efi/loongson.h +@@ -23,12 +23,17 @@ + + #include + +-#define GRUB_EFI_LOONGSON_SMBIOS_TABLE_GUID \ ++#define GRUB_EFI_LOONGSON_BPI_TABLE_GUID \ + { 0x4660f721, 0x2ec5, 0x416a, \ + { 0x89, 0x9a, 0x43, 0x18, 0x02, 0x50, 0xa0, 0xc9 } \ + } + ++#define GRUB_EFI_MAX_PHY_ADDRESS 0xffffffffffffULL ++#define ELF32_LOADMASK (0xf0000000UL) ++#define ELF64_LOADMASK (0xf000000000000000ULL) ++#define FLAGS_EFI_SUPPORT_BIT 0 + #define GRUB_EFI_LOONGSON_MMAP_MAX 128 ++ + typedef enum + { + GRUB_EFI_LOONGSON_SYSTEM_RAM = 1, +@@ -39,252 +44,70 @@ typedef enum + } + grub_efi_loongson_memory_type; + +-typedef struct +-{ +- grub_uint16_t vers; /* version */ +- grub_uint32_t nr_map; /* number of memory_maps */ +- grub_uint32_t mem_freq; /* memory frequence */ +- struct mem_map { +- grub_uint32_t node_id; /* node_id which memory attached to */ +- grub_uint32_t mem_type; /* system memory, pci memory, pci io, etc. */ +- grub_uint64_t mem_start; /* memory map start address */ +- grub_uint32_t mem_size; /* each memory_map size, not the total size */ +- } map[GRUB_EFI_LOONGSON_MMAP_MAX]; +-} GRUB_PACKED +-grub_efi_loongson_memory_map; +- +-/* +- * Capability and feature descriptor structure for LOONGARCH CPU +- */ +-typedef struct +-{ +- grub_uint16_t vers; /* version */ +- grub_uint32_t processor_id; /* PRID, e.g. 6305, 6306 */ +- grub_uint32_t cputype; /* Loongson_3A/3B, etc. */ +- grub_uint32_t total_node; /* num of total numa nodes */ +- grub_uint16_t cpu_startup_core_id; /* Boot core id */ +- grub_uint16_t reserved_cores_mask; +- grub_uint32_t cpu_clock_freq; /* cpu_clock */ +- grub_uint32_t nr_cpus; +-} GRUB_PACKED +-grub_efi_loongson_cpu_info; +- +-#define GRUB_EFI_LOONGSON_MAX_UARTS 64 +- +-typedef struct +-{ +- grub_uint32_t iotype; /* see include/linux/serial_core.h */ +- grub_uint32_t uartclk; +- grub_uint32_t int_offset; +- grub_uint64_t uart_base; +-} GRUB_PACKED +-grub_efi_loongson_uart_device; +- +-#define GRUB_EFI_LOONGSON_MAX_SENSORS 64 +- +-typedef struct +-{ +- char name[32]; /* a formal name */ +- char label[64]; /* a flexible description */ +- grub_uint32_t type; /* SENSOR_* */ +- grub_uint32_t id; /* instance id of a sensor-class */ +- grub_uint32_t fan_policy; +- grub_uint32_t fan_percent; /* only for constant speed policy */ +- grub_uint64_t base_addr; /* base address of device registers */ +-} GRUB_PACKED +-grub_efi_loongson_sensor_device; +- +-typedef struct +-{ +- grub_uint16_t vers; /* version */ +- grub_uint32_t ccnuma_smp; /* 0: no numa; 1: has numa */ +- grub_uint32_t sing_double_channel; /* 1:single; 2:double */ +- grub_uint32_t nr_uarts; +- grub_efi_loongson_uart_device uarts[GRUB_EFI_LOONGSON_MAX_UARTS]; +- grub_uint32_t nr_sensors; +- grub_efi_loongson_sensor_device sensors[GRUB_EFI_LOONGSON_MAX_SENSORS]; +- char has_ec; +- char ec_name[32]; +- grub_uint64_t ec_base_addr; +- char has_tcm; +- char tcm_name[32]; +- grub_uint64_t tcm_base_addr; +- grub_uint64_t workarounds; /* see workarounds.h */ +-} GRUB_PACKED +-grub_efi_loongson_system_info; +- +-typedef struct +-{ +- grub_uint16_t vers; +- grub_uint16_t size; +- grub_uint16_t rtr_bus; +- grub_uint16_t rtr_devfn; +- grub_uint32_t vendor; +- grub_uint32_t device; +- grub_uint32_t PIC_type; /* conform use HT or PCI to route to CPU-PIC */ +- grub_uint64_t ht_int_bit; /* 3A: 1<<24; 3B: 1<<16 */ +- grub_uint64_t ht_enable; /* irqs used in this PIC */ +- grub_uint32_t node_id; /* node id: 0x0-0; 0x1-1; 0x10-2; 0x11-3 */ +- grub_uint64_t pci_mem_start_addr; +- grub_uint64_t pci_mem_end_addr; +- grub_uint64_t pci_io_start_addr; +- grub_uint64_t pci_io_end_addr; +- grub_uint64_t pci_config_addr; +- grub_uint32_t dma_mask_bits; +-} GRUB_PACKED +-grub_efi_loongson_irq_src_routing_table; +- +-typedef struct +-{ +- grub_uint16_t vers; /* version */ +- grub_uint16_t size; +- grub_uint8_t flag; +- char description[64]; +-} GRUB_PACKED +-grub_efi_loongson_interface_info; +- +-#define GRUB_EFI_LOONGSON_MAX_RESOURCE_NUMBER 128 +- +-typedef struct +-{ +- grub_uint64_t start; /* resource start address */ +- grub_uint64_t end; /* resource end address */ +- char name[64]; +- grub_uint32_t flags; +-} +-grub_efi_loongson_resource; +- +-/* arch specific additions */ +-typedef struct +-{ +-} +-grub_efi_loongson_archdev_data; +- +-typedef struct +-{ +- char name[64]; /* hold the device name */ +- grub_uint32_t num_resources; /* number of device_resource */ +- /* for each device's resource */ +- grub_efi_loongson_resource resource[GRUB_EFI_LOONGSON_MAX_RESOURCE_NUMBER]; +- /* arch specific additions */ +- grub_efi_loongson_archdev_data archdata; +-} +-grub_efi_loongson_board_devices; +- +-typedef struct +-{ +- grub_uint16_t vers; /* version */ +- char special_name[64]; /* special_atribute_name */ +- grub_uint32_t loongson_special_type; /* type of special device */ +- /* for each device's resource */ +- grub_efi_loongson_resource resource[GRUB_EFI_LOONGSON_MAX_RESOURCE_NUMBER]; +-} +-grub_efi_loongson_special_attribute; +- +-typedef struct +-{ +- grub_uint64_t memory_offset; /* efi_loongson_memory_map struct offset */ +- grub_uint64_t cpu_offset; /* efi_loongson_cpuinfo struct offset */ +- grub_uint64_t system_offset; /* efi_loongson_system_info struct offset */ +- grub_uint64_t irq_offset; /* efi_loongson_irq_src_routing_table struct offset */ +- grub_uint64_t interface_offset; /* interface_info struct offset */ +- grub_uint64_t special_offset; /* efi_loongson_special_attribute struct offset */ +- grub_uint64_t boarddev_table_offset; /* efi_loongson_board_devices offset */ +-} +-grub_efi_loongson_params; +- +-typedef struct +-{ +- grub_uint16_t vers; /* version */ +- grub_uint64_t vga_bios; /* vga_bios address */ +- grub_efi_loongson_params lp; +-} +-grub_efi_loongson_smbios_table; +- +-typedef struct +-{ +- grub_uint64_t reset_cold; +- grub_uint64_t reset_warm; +- grub_uint64_t reset_type; +- grub_uint64_t shutdown; +- grub_uint64_t do_suspend; /* NULL if not support */ +-} +-grub_efi_loongson_reset_system; +- +-typedef struct +-{ +- grub_uint64_t mps; /* MPS table */ +- grub_uint64_t acpi; /* ACPI table (IA64 ext 0.71) */ +- grub_uint64_t acpi20; /* ACPI table (ACPI 2.0) */ +- grub_efi_loongson_smbios_table smbios; /* SM BIOS table */ +- grub_uint64_t sal_systab; /* SAL system table */ +- grub_uint64_t boot_info; /* boot info table */ +-} +-grub_efi_loongson; +- +-typedef struct +-{ +- grub_efi_loongson efi; +- grub_efi_loongson_reset_system reset_system; +-} +-grub_efi_loongson_boot_params; +- +-extern grub_uint64_t grub_efi_loongson_reset_system_addr; +- +-extern void grub_efi_loongson_reset_cold (void); +-extern void grub_efi_loongson_reset_warm (void); +-extern void grub_efi_loongson_reset_shutdown (void); +-extern void grub_efi_loongson_reset_suspend (void); +- +-void grub_efi_loongson_alloc_boot_params (void); +-void grub_efi_loongson_free_boot_params (void); +-void * grub_efi_loongson_get_smbios_table (void); +- +-int EXPORT_FUNC(grub_efi_is_loongson) (void); ++typedef enum ++ { ++ GRUB_EFI_BPI_VER_NONE = 0, ++ GRUB_EFI_BPI_VER_V1 = 1000, ++ GRUB_EFI_BPI_VER_V2 = 1001, ++ } ++ grub_efi_loongson_bpi_version; + + grub_uint8_t +-EXPORT_FUNC(grub_efi_loongson_calculatesum8) (const grub_uint8_t *Buffer, grub_efi_uintn_t Length); ++EXPORT_FUNC(grub_efi_loongson_calculatesum8) (const grub_uint8_t *Buffer, ++ grub_efi_uintn_t Length); + + grub_uint8_t +-EXPORT_FUNC(grub_efi_loongson_grub_calculatechecksum8) (const grub_uint8_t *Buffer, grub_efi_uintn_t Length); ++EXPORT_FUNC(grub_efi_loongson_grub_calculatechecksum8) (const grub_uint8_t *Buffer, ++ grub_efi_uintn_t Length); + ++unsigned long ++EXPORT_FUNC(grub_efi_get_bpi_version) (const char *str); + + void * + EXPORT_FUNC(grub_efi_loongson_get_boot_params) (void); + +-typedef struct _extention_list_hdr{ ++typedef struct _extention_list_hdr { + grub_uint64_t signature; + grub_uint32_t length; + grub_uint8_t revision; + grub_uint8_t checksum; +- struct _extention_list_hdr *next; ++ union { ++ struct _extention_list_hdr *next; ++ grub_uint64_t next_offset; ++ }; + }GRUB_PACKED + ext_list; + +-typedef struct bootparamsinterface { +- grub_uint64_t signature; //{'B', 'P', 'I', '_', '0', '_', '1'} ++typedef struct boot_params_interface { ++ grub_uint64_t signature; //{'B', 'P', 'I', 'x', 'x', 'x', 'x', 'x'} + grub_efi_system_table_t *systemtable; +- ext_list *extlist; ++ union { ++ ext_list *extlist; ++ grub_uint64_t extlist_offset; ++ }; ++ grub_uint64_t flags; + }GRUB_PACKED +-bootparamsinterface; ++boot_params_interface; + + typedef struct { +- ext_list header; // {'M', 'E', 'M'} ++ ext_list header; //{MEM} + grub_uint8_t mapcount; +- struct GRUB_PACKED memmap { ++ struct GRUB_PACKED memmap_v1 { + grub_uint32_t memtype; + grub_uint64_t memstart; + grub_uint64_t memsize; + } map[GRUB_EFI_LOONGSON_MMAP_MAX]; + }GRUB_PACKED +-mem_map; ++mem_map_v1; + + typedef struct { +- ext_list header; // {VBIOS} ++ ext_list header; //{VBIOS} + grub_uint64_t vbiosaddr; + }GRUB_PACKED + vbios; + +-grub_uint32_t +-EXPORT_FUNC (grub_efi_loongson_memmap_sort) (struct memmap array[], grub_uint32_t length, mem_map * bpmem, grub_uint32_t index, grub_uint32_t memtype); ++grub_uint32_t ++EXPORT_FUNC (grub_efi_loongson_memmap_v1_sort) (struct memmap_v1 array[], ++ grub_uint32_t length, mem_map_v1 * mem, ++ grub_uint32_t index, grub_uint32_t memtype); + #endif /* ! GRUB_EFI_LOONGSON_HEADER */ +diff --git a/include/grub/loongarch64/efi/memory.h b/include/grub/loongarch64/efi/memory.h +index b8556c7..73641a1 100644 +--- a/include/grub/loongarch64/efi/memory.h ++++ b/include/grub/loongarch64/efi/memory.h +@@ -1,14 +1,12 @@ + #ifndef GRUB_MEMORY_CPU_HEADER + #include + +-#define GRUB_EFI_MAX_USABLE_ADDRESS 0x9800000fffffffffUL +-#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS +- +-static inline grub_uint64_t grub_efi_max_usable_address(void) ++static inline grub_uint64_t ++grub_efi_max_usable_address(void) + { +- grub_uint64_t addr; +- asm volatile ("csrrd %0, 0x181" : "=r" (addr)); +- return addr |= 0xffffffffffUL; ++ grub_uint64_t addr; ++ asm volatile ("csrrd %0, 0x181" : "=r" (addr)); ++ return addr |= 0xffffffffffUL; + } + + #endif /* ! GRUB_MEMORY_CPU_HEADER */ +diff --git a/include/grub/loongarch64/kernel.h b/include/grub/loongarch64/kernel.h +deleted file mode 100644 +index 909d539..0000000 +--- a/include/grub/loongarch64/kernel.h ++++ /dev/null +@@ -1,24 +0,0 @@ +-/* +- * GRUB -- GRand Unified Bootloader +- * Copyright (C) 2005,2006,2007,2008,2009,2017 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 . +- */ +- +-#ifndef GRUB_KERNEL_CPU_HEADER +-#define GRUB_KERNEL_CPU_HEADER 1 +- +-#include +- +-#endif /* ! GRUB_KERNEL_MACHINE_HEADER */ +diff --git a/include/grub/loongarch64/linux.h b/include/grub/loongarch64/linux.h +index cbf8775..3c6cf65 100644 +--- a/include/grub/loongarch64/linux.h ++++ b/include/grub/loongarch64/linux.h +@@ -1,6 +1,6 @@ + /* + * GRUB -- GRand Unified Bootloader +- * Copyright (C) 2013 Free Software Foundation, Inc. ++ * Copyright (C) 2021 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 +@@ -19,4 +19,56 @@ + #ifndef GRUB_LOONGARCH64_LINUX_HEADER + #define GRUB_LOONGARCH64_LINUX_HEADER 1 + ++#include ++ ++/* LoongArch linux kernel type */ ++#define GRUB_LOONGARCH_LINUX_BAD 0 ++#define GRUB_LOONGARCH_LINUX_ELF 1 ++#define GRUB_LOONGARCH_LINUX_EFI 2 ++ ++#define GRUB_LOONGSON3_BOOT_MEM_MAP_MAX 128 ++ ++#define GRUB_LINUX_LOONGARCH_MAGIC_SIGNATURE 0x4C6F6F6E67417263 /* 'LoongArc' */ ++#define GRUB_LINUX_LOONGARCH_MAGIC_SIGNATURE2 0x68 /* 'h' */ ++#define linux_arch_kernel_header linux_loongarch64_kernel_header ++ ++/* From linux/Documentation/loongarch/booting.txt ++ * ++ * 0-1: MZ ++ * 0x28: LoongArch\0 ++ * 0x3c: PE/COFF头偏移 ++ * 0x20e:内核版本号偏移-512 ++ * riscv的version字段在0x20偏移处,现在LoongArch没有使用,是0 ++ */ ++struct linux_loongarch64_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 magic; /* Magic number, little endian, "LoongArc" */ ++ grub_uint32_t magic1; /* Magic number, little endian, "h" */ ++ grub_uint64_t res3; /* reserved */ ++ grub_uint32_t hdr_offset; /* Offset of PE/COFF header */ ++}; ++ ++struct linux_loongarch64_kernel_params ++{ ++ grub_addr_t kernel_addr; /* kernel entry address */ ++ grub_size_t kernel_size; /* kernel size */ ++ grub_addr_t ramdisk_addr; /* initrd load address */ ++ grub_size_t ramdisk_size; /* initrd size */ ++ int linux_argc; ++ grub_addr_t linux_argv; ++ void* linux_args; ++}; ++ ++#include ++#include ++ ++#define ELF32_LOADMASK (0xf0000000UL) ++#define ELF64_LOADMASK (0xf000000000000000ULL) ++ + #endif /* ! GRUB_LOONGARCH64_LINUX_HEADER */ +diff --git a/include/grub/loongarch64/memory.h b/include/grub/loongarch64/memory.h +index 03398b3..8281dab 100644 +--- a/include/grub/loongarch64/memory.h ++++ b/include/grub/loongarch64/memory.h +@@ -38,12 +38,15 @@ grub_vtop (void *a) + } + + static inline void * +-grub_map_memory (grub_phys_addr_t a, grub_size_t size) ++grub_map_memory (grub_phys_addr_t a, ++ grub_size_t size __attribute__ ((unused))) + { + grub_uint64_t addr; +- + asm volatile ("csrrd %0, 0x181" : "=r" (addr)); +- return (void *) (a | (addr & 0xffffffffffffff00UL)); ++ if (addr & 0x1) ++ return (void *) (a | (addr & 0xffffffffffffff00UL)); ++ else ++ return (void *) a; + } + + static inline void +-- +2.1.0 + diff --git a/grub.patches b/grub.patches index 0387df7..a6b6df7 100644 --- a/grub.patches +++ b/grub.patches @@ -499,5 +499,6 @@ Patch0498: 0498-x86-efi-Make-our-own-allocator-for-kernel-stuff.patch Patch0499: 0499-x86-efi-Allow-initrd-params-cmdline-allocations-abov.patch Patch0500: 0500-x86-efi-Reduce-maximum-bounce-buffer-size-to-16-MiB.patch # Support loongarch64 -#Patch1000: 1000-loongarch64-add-support.patch +Patch1000: 1000-loongarch64-add-support.patch Patch1001: 1001-bls-make-list.patch +Patch1002: 1002-loongarch64-support-fdt-and-phy-addr-BIOS.patch diff --git a/grub2.spec b/grub2.spec index 32ef860..0634a2a 100644 --- a/grub2.spec +++ b/grub2.spec @@ -1,4 +1,4 @@ -%define anolis_release .0.1 +%define anolis_release .0.2 %undefine _hardened_build %global tarversion 2.02 @@ -523,6 +523,9 @@ fi %endif %changelog +* Thu Jun 23 2022 QiMing Yang - 2.02-123.0.2 +- LoongArch64 support fdt and phy-addr BIOS + * Wed May 17 2022 Bo Ren - 2.02-123.0.1 - Build pc-modules package on x86_64 (geliwei@openanolis.org) - Add loongarch64 base support (zhangwenlong@loongson.cn)(chenguoqi@loongson.cn) -- Gitee