Skip to content

Instantly share code, notes, and snippets.

@shankerwangmiao
Last active July 26, 2024 18:52
Show Gist options
  • Save shankerwangmiao/a15e17fc5c1c1dfb883490862107fcbb to your computer and use it in GitHub Desktop.
Save shankerwangmiao/a15e17fc5c1c1dfb883490862107fcbb to your computer and use it in GitHub Desktop.
From 55e98fc2b96c9dbf810ef4839cc2d5f07cdfd456 Mon Sep 17 00:00:00 2001
From: Miao Wang <shankerwangmiao@gmail.com>
Date: Wed, 17 Jul 2024 09:03:32 +0800
Subject: [PATCH 1/9] loongarch: able to boot on legacy fw
---
arch/loongarch/kernel/efi.c | 18 ++++++++++++++++++
arch/loongarch/kernel/mem.c | 1 +
drivers/firmware/efi/libstub/loongarch.c | 20 ++++++++++++++++++++
3 files changed, 39 insertions(+)
diff --git a/arch/loongarch/kernel/efi.c b/arch/loongarch/kernel/efi.c
index 000825406c1f..304afd6c2fd9 100644
--- a/arch/loongarch/kernel/efi.c
+++ b/arch/loongarch/kernel/efi.c
@@ -92,6 +92,23 @@ static void __init init_screen_info(void)
memblock_reserve(screen_info.lfb_base, screen_info.lfb_size);
}
+static void __init fix_initrd_table(const efi_config_table_t *config_tables,
+ int count)
+{
+ for(int i = 0; i < count; i++) {
+ if (efi_guidcmp(config_tables[i].guid,
+ LINUX_EFI_INITRD_MEDIA_GUID) == 0) {
+ struct linux_efi_initrd *tbl =
+ early_memremap((u64)config_tables[i].table, sizeof(*tbl));
+ if (tbl) {
+ tbl->base = TO_PHYS(tbl->base);
+ early_memunmap(tbl, sizeof(*tbl));
+ }
+ break;
+ }
+ }
+}
+
void __init efi_init(void)
{
int size;
@@ -115,6 +132,7 @@ void __init efi_init(void)
size = sizeof(efi_config_table_t);
config_tables = early_memremap(efi_config_table, efi_nr_tables * size);
+ fix_initrd_table(config_tables, efi_systab->nr_tables);
efi_config_parse_tables(config_tables, efi_systab->nr_tables, arch_tables);
early_memunmap(config_tables, efi_nr_tables * size);
diff --git a/arch/loongarch/kernel/mem.c b/arch/loongarch/kernel/mem.c
index aed901c57fb4..86d37a447eec 100644
--- a/arch/loongarch/kernel/mem.c
+++ b/arch/loongarch/kernel/mem.c
@@ -19,6 +19,7 @@ void __init memblock_init(void)
/* Parse memory information */
for_each_efi_memory_desc(md) {
mem_type = md->type;
+ md->phys_addr = TO_PHYS(md->phys_addr);
mem_start = md->phys_addr;
mem_size = md->num_pages << EFI_PAGE_SHIFT;
mem_end = mem_start + mem_size;
diff --git a/drivers/firmware/efi/libstub/loongarch.c b/drivers/firmware/efi/libstub/loongarch.c
index d0ef93551c44..e76d08f09255 100644
--- a/drivers/firmware/efi/libstub/loongarch.c
+++ b/drivers/firmware/efi/libstub/loongarch.c
@@ -23,6 +23,8 @@ struct exit_boot_struct {
int runtime_entry_count;
};
+static int is_oldworld = 0;
+
static efi_status_t exit_boot_func(struct efi_boot_memmap *map, void *priv)
{
struct exit_boot_struct *p = priv;
@@ -35,9 +37,25 @@ static efi_status_t exit_boot_func(struct efi_boot_memmap *map, void *priv)
efi_get_virtmap(map->map, map->map_size, map->desc_size,
p->runtime_map, &p->runtime_entry_count);
+ if (is_oldworld) {
+ for(int l = 0; l < p->runtime_entry_count * map->desc_size; l += map->desc_size) {
+ efi_memory_desc_t *entry = (void *)(p->runtime_map) + l;
+ entry->virt_addr = TO_UNCACHE(entry->virt_addr);
+ }
+ }
+
return EFI_SUCCESS;
}
+static void detect_oldworld(void)
+{
+ is_oldworld = !!(csr_read64(LOONGARCH_CSR_DMWIN1) & CSR_DMW1_PLV0);
+ efi_debug("is_oldworld: %d\n", is_oldworld);
+ if(is_oldworld) {
+ efi_info("Booting on OldWorld firmware\n");
+ }
+}
+
unsigned long __weak kernel_entry_address(unsigned long kernel_addr,
efi_loaded_image_t *image)
{
@@ -53,6 +71,8 @@ efi_status_t efi_boot_kernel(void *handle, efi_loaded_image_t *image,
efi_status_t status;
u32 desc_ver;
+ detect_oldworld();
+
status = efi_alloc_virtmap(&priv.runtime_map, &desc_size, &desc_ver);
if (status != EFI_SUCCESS) {
efi_err("Unable to retrieve UEFI memory map.\n");
--
2.39.2
From c9bbfdae245f475f408f1eb79f3b5d1aa4f806b4 Mon Sep 17 00:00:00 2001
From: Miao Wang <shankerwangmiao@gmail.com>
Date: Wed, 17 Jul 2024 09:16:26 +0800
Subject: [PATCH] loongarch64: able to start on oldworld
---
include/grub/loongarch64/efi/memory.h | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/include/grub/loongarch64/efi/memory.h b/include/grub/loongarch64/efi/memory.h
index d460267be..534ba4b32 100644
--- a/include/grub/loongarch64/efi/memory.h
+++ b/include/grub/loongarch64/efi/memory.h
@@ -19,6 +19,25 @@
#ifndef GRUB_MEMORY_CPU_HEADER
#include <grub/efi/memory.h>
-#define GRUB_EFI_MAX_USABLE_ADDRESS 0xfffffffffffULL
+static inline grub_uint64_t
+grub_efi_max_usable_address(void)
+{
+ static grub_uint64_t addr;
+ static int addr_valid = 0;
+
+ if (!addr_valid)
+ {
+ asm volatile ("csrrd %0, 0x181" : "=r" (addr));
+ if (addr & 0x1)
+ addr |= 0xfffffffffffUL;
+ else
+ addr = 0xfffffffffffUL;
+ addr_valid = 1;
+ }
+
+ return addr;
+}
+
+#define GRUB_EFI_MAX_USABLE_ADDRESS (grub_efi_max_usable_address())
#endif /* ! GRUB_MEMORY_CPU_HEADER */
--
2.42.0
From fd89ce704666b7a1e5c8dd0b60479b89c4bbad3d Mon Sep 17 00:00:00 2001
From: Miao Wang <shankerwangmiao@gmail.com>
Date: Thu, 18 Jul 2024 18:55:59 +0800
Subject: [PATCH 2/9] add bpi init
---
arch/loongarch/kernel/Makefile | 2 +
arch/loongarch/kernel/efi.c | 3 +
arch/loongarch/kernel/legacy_boot.c | 297 ++++++++++++++++++++++++++++
arch/loongarch/kernel/legacy_boot.h | 18 ++
arch/loongarch/kernel/mem.c | 4 +
arch/loongarch/kernel/numa.c | 3 +
arch/loongarch/kernel/setup.c | 3 +
arch/loongarch/kernel/smp.c | 4 +
8 files changed, 334 insertions(+)
create mode 100644 arch/loongarch/kernel/legacy_boot.c
create mode 100644 arch/loongarch/kernel/legacy_boot.h
diff --git a/arch/loongarch/kernel/Makefile b/arch/loongarch/kernel/Makefile
index 3a7620b66bc6..84d2e2d896ab 100644
--- a/arch/loongarch/kernel/Makefile
+++ b/arch/loongarch/kernel/Makefile
@@ -78,3 +78,5 @@ obj-$(CONFIG_UPROBES) += uprobes.o
obj-$(CONFIG_JUMP_LABEL) += jump_label.o
CPPFLAGS_vmlinux.lds := $(KBUILD_CFLAGS)
+
+obj-y += legacy_boot.o
diff --git a/arch/loongarch/kernel/efi.c b/arch/loongarch/kernel/efi.c
index 304afd6c2fd9..307f35d1e71f 100644
--- a/arch/loongarch/kernel/efi.c
+++ b/arch/loongarch/kernel/efi.c
@@ -25,6 +25,8 @@
#include <asm/efi.h>
#include <asm/loongson.h>
+#include "legacy_boot.h"
+
static unsigned long efi_nr_tables;
static unsigned long efi_config_table;
@@ -35,6 +37,7 @@ static efi_system_table_t *efi_systab;
static efi_config_table_type_t arch_tables[] __initdata = {
{LINUX_EFI_BOOT_MEMMAP_GUID, &boot_memmap, "MEMMAP" },
{DEVICE_TREE_GUID, &fdt_pointer, "FDTPTR" },
+ {LOONGARCH_BPI_GUID, &loongarch_bpi_info.bpi, "BPI" },
{},
};
diff --git a/arch/loongarch/kernel/legacy_boot.c b/arch/loongarch/kernel/legacy_boot.c
new file mode 100644
index 000000000000..30c01c8b22a0
--- /dev/null
+++ b/arch/loongarch/kernel/legacy_boot.c
@@ -0,0 +1,297 @@
+#include <linux/efi.h>
+#include <linux/memblock.h>
+
+#include <asm/early_ioremap.h>
+
+#include "legacy_boot.h"
+
+#define LOONGARCH_BOOT_MEM_MAP_MAX 128
+
+enum bpi_vers {
+ BPI_VERSION_NONE = 0,
+ BPI_VERSION_V1 = 1000,
+ BPI_VERSION_V2 = 1001,
+};
+
+struct loongarch_bpi_ext_hdr {
+ u64 signature;
+ u32 length;
+ u8 revision;
+ u8 checksum;
+ u64 next;
+} __packed;
+
+struct loongarch_bpi_hdr {
+ u64 signature;
+ u64 systemtable;
+ u64 extlist;
+ u64 flags;
+} __packed;
+
+enum bpi_mem_type {
+ ADDRESS_TYPE_SYSRAM = 1,
+ ADDRESS_TYPE_RESERVED = 2,
+ ADDRESS_TYPE_ACPI = 3,
+ ADDRESS_TYPE_NVS = 4,
+ ADDRESS_TYPE_PMEM = 5,
+ ADDRESS_TYPE_MAX,
+};
+
+struct loongarch_bpi_mem_map {
+ struct loongarch_bpi_ext_hdr header; /*{"M", "E", "M"}*/
+ u8 map_count;
+ struct loongarch_bpi_mem_map_entry {
+ u32 mem_type;
+ u64 mem_start;
+ u64 mem_size;
+ } __packed map[];
+} __packed;
+
+struct loongarch_bpi_info __initdata loongarch_bpi_info = {
+ .bpi = EFI_INVALID_TABLE_ADDR,
+};
+
+static enum bpi_vers __initdata bpi_version = BPI_VERSION_NONE;
+static u64 __initdata bpi_flags = 0;
+
+static int have_bpi = 0;
+
+static __initdata struct {
+ size_t map_count;
+ struct loongarch_bpi_memmap{
+ enum bpi_mem_type type;
+ unsigned long mem_start;
+ size_t mem_size;
+ } map[LOONGARCH_BOOT_MEM_MAP_MAX];
+} bpi_meminfo = {0};
+
+static __initdata struct {
+ unsigned long addr;
+ size_t size;
+} bpi_memmap = {
+ .addr = EFI_INVALID_TABLE_ADDR,
+ .size = 0,
+};
+
+static const __initconst struct bpi_extlist_desc {
+ union {
+ u64 signature;
+ char chars[8];
+ };
+ unsigned long *ptr;
+ size_t *length;
+} bpi_extlist[] = {
+ { .chars = "MEM", &bpi_memmap.addr, &bpi_memmap.size },
+ { .signature = 0, NULL, NULL },
+};
+
+
+static void __init parse_bpi_ext_list(unsigned long exthdr)
+{
+ unsigned long cur_hdr = exthdr;
+ while(cur_hdr){
+ struct loongarch_bpi_ext_hdr *hdr = early_memremap_ro(cur_hdr, sizeof(*hdr));
+ if(!hdr) {
+ break;
+ }
+ u64 sig = hdr->signature;
+ u32 len = hdr->length;
+ u8 rev = hdr->revision;
+ unsigned long next = hdr->next;
+ early_memunmap(hdr, sizeof(*hdr));
+
+ pr_info("BPI: ext hdr: %.8s, rev %u\n", (const char *)&sig, rev);
+
+ for(const struct bpi_extlist_desc *desc = bpi_extlist; desc->signature; desc++) {
+ if(sig == desc->signature) {
+ *(desc->ptr) = cur_hdr;
+ *(desc->length) = len;
+ }
+ }
+ cur_hdr = next;
+ }
+}
+
+
+static u8 __init ext_listhdr_checksum(void *buffer, size_t length)
+{
+ u8 sum = 0;
+ u8 *end = buffer + length;
+ u8 *buf = buffer;
+
+ while (buf < end)
+ sum = (u8)(sum + *(buf++));
+
+ return sum;
+}
+
+static void __init parse_bpi_mem_map(void)
+{
+ if(bpi_memmap.addr == EFI_INVALID_TABLE_ADDR) {
+ return;
+ }
+ if(bpi_memmap.size < sizeof(struct loongarch_bpi_mem_map)) {
+ pr_err("BPI: invalid memmap size %ld\n", bpi_memmap.size);
+ return;
+ }
+ struct loongarch_bpi_mem_map *memmap = early_memremap_ro(bpi_memmap.addr, bpi_memmap.size);
+ if(!memmap) {
+ return;
+ }
+
+ u8 checksum = ext_listhdr_checksum(memmap, bpi_memmap.size);
+ if (checksum != 0) {
+ pr_err("BPI: memmap checksum mismatch\n");
+ goto err_out;
+ }
+
+ size_t map_count = memmap->map_count;
+ if (map_count > LOONGARCH_BOOT_MEM_MAP_MAX) {
+ pr_err("BPI: too many memmap entries\n");
+ goto err_out;
+ }
+ if (map_count * sizeof(memmap->map[0]) + sizeof(*memmap) > bpi_memmap.size) {
+ pr_err("BPI: invalid memmap size %ld, not enough to hold %ld entries\n", bpi_memmap.size, map_count);
+ goto err_out;
+ }
+ for(int i = 0; i < map_count; i++) {
+ bpi_meminfo.map[i].type = memmap->map[i].mem_type;
+ bpi_meminfo.map[i].mem_start = memmap->map[i].mem_start;
+ bpi_meminfo.map[i].mem_size = memmap->map[i].mem_size;
+
+ static const char * const __initconst mem_type_str[] = {
+ NULL,
+ [ADDRESS_TYPE_SYSRAM] = "SYSRAM",
+ [ADDRESS_TYPE_RESERVED] = "RESERVED",
+ [ADDRESS_TYPE_ACPI] = "ACPI",
+ [ADDRESS_TYPE_NVS] = "NVS",
+ [ADDRESS_TYPE_PMEM] = "PMEM",
+ };
+ if(bpi_meminfo.map[i].type >= ADDRESS_TYPE_MAX || bpi_meminfo.map[i].type == 0) {
+ pr_info("BPI: memmap type unknown(%d), start 0x%lx, size 0x%lx\n", bpi_meminfo.map[i].type, bpi_meminfo.map[i].mem_start, bpi_meminfo.map[i].mem_size);
+ }else{
+ pr_info("BPI: memmap type %s, start 0x%lx, size 0x%lx\n", mem_type_str[bpi_meminfo.map[i].type], bpi_meminfo.map[i].mem_start, bpi_meminfo.map[i].mem_size);
+ }
+ }
+ bpi_meminfo.map_count = map_count;
+
+err_out:
+ early_memunmap(memmap, bpi_memmap.size);
+}
+
+static int __init bpi_parse_signature (u64 signature)
+{
+ union {
+ u64 signature;
+ char chars[9];
+ } sig;
+ sig.signature = signature;
+ sig.chars[8] = '\0';
+
+ if (!(sig.chars[0] == 'B' && sig.chars[1] == 'P' && sig.chars[2] == 'I')) {
+ pr_err("BPI: invalid signature\n");
+ return -EINVAL;
+ }
+ int version;
+ int rc = kstrtoint(&sig.chars[3], 10, &version);
+ if(rc != 0 || version == BPI_VERSION_NONE) {
+ pr_err("BPI: invalid version\n");
+ return -EINVAL;
+ }
+ bpi_version = version;
+ pr_info("BPI: version %d\n", bpi_version);
+ return 0;
+}
+
+void __init bpi_init(void)
+{
+ if (loongarch_bpi_info.bpi == EFI_INVALID_TABLE_ADDR) {
+ return;
+ }
+ struct loongarch_bpi_hdr *tbl;
+
+ tbl = early_memremap_ro(loongarch_bpi_info.bpi, sizeof(*tbl));
+ if (tbl) {
+ int rc = bpi_parse_signature(tbl->signature);
+ if (rc != 0) {
+ goto err_out;
+ }
+ have_bpi = 1;
+ if (bpi_version >= BPI_VERSION_V2) {
+ bpi_flags = tbl->flags;
+ pr_info("BPI: flags 0x%llx\n", bpi_flags);
+ }
+ unsigned long bpi_extlist = tbl->extlist;
+ parse_bpi_ext_list(bpi_extlist);
+ parse_bpi_mem_map();
+err_out:
+ early_memunmap(tbl, sizeof(*tbl));
+ }
+}
+
+void __init bpi_memblock_init(unsigned long *p_max_low_pfn)
+{
+ for(int i = 0; i < bpi_meminfo.map_count; i++) {
+ unsigned long start = bpi_meminfo.map[i].mem_start;
+ size_t size = bpi_meminfo.map[i].mem_size;
+ unsigned long end = start + size;
+
+ switch(bpi_meminfo.map[i].type) {
+ case ADDRESS_TYPE_SYSRAM:
+ // EFI_CONVENTIONAL_MEMORY
+ case ADDRESS_TYPE_PMEM:
+ // EFI_PERSISTENT_MEMORY
+ memblock_add(start, size);
+ if (*p_max_low_pfn < (end >> PAGE_SHIFT))
+ *p_max_low_pfn = end >> PAGE_SHIFT;
+ break;
+ case ADDRESS_TYPE_ACPI:
+ // EFI_ACPI_RECLAIM_MEMORY
+ memblock_add(start, size);
+ fallthrough;
+ case ADDRESS_TYPE_RESERVED:
+ // EFI_RUNTIME_SERVICES_DATA or
+ // EFI_RUNTIME_SERVICES_CODE or
+ // EFI_RESERVED_MEMORY_TYPE
+ memblock_reserve(start, size);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void __init bpi_init_node_memblock(void (*p_add_numamem_region)(u64 start, u64 end, u32 type))
+{
+ for(int i = 0; i < bpi_meminfo.map_count; i++) {
+ u64 mem_start = bpi_meminfo.map[i].mem_start;
+ u64 mem_size = bpi_meminfo.map[i].mem_size;
+ u64 mem_end = mem_start + mem_size;
+ u32 mem_type;
+
+ switch(bpi_meminfo.map[i].type) {
+ case ADDRESS_TYPE_SYSRAM:
+ mem_type = EFI_CONVENTIONAL_MEMORY;
+ p_add_numamem_region(mem_start, mem_end, mem_type);
+ break;
+ case ADDRESS_TYPE_PMEM:
+ mem_type = EFI_PERSISTENT_MEMORY;
+ p_add_numamem_region(mem_start, mem_end, mem_type);
+ break;
+ case ADDRESS_TYPE_ACPI:
+ mem_type = EFI_ACPI_RECLAIM_MEMORY;
+ p_add_numamem_region(mem_start, mem_end, mem_type);
+ fallthrough;
+ case ADDRESS_TYPE_RESERVED:
+ pr_info("Resvd: mem_type:BPI_%d, mem_start:0x%llx, mem_size:0x%llx Bytes\n",
+ bpi_meminfo.map[i].type, mem_start, mem_size);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+int loongarch_have_legacy_bpi (void){
+ return have_bpi;
+}
diff --git a/arch/loongarch/kernel/legacy_boot.h b/arch/loongarch/kernel/legacy_boot.h
new file mode 100644
index 000000000000..6d3a36ebaab7
--- /dev/null
+++ b/arch/loongarch/kernel/legacy_boot.h
@@ -0,0 +1,18 @@
+#ifndef __LEGACY_BOOT_H_
+#define __LEGACY_BOOT_H_
+
+#include <linux/efi.h>
+
+#define LOONGARCH_BPI_GUID EFI_GUID(0x4660f721, 0x2ec5, 0x416a, 0x89, 0x9a, 0x43, 0x18, 0x02, 0x50, 0xa0, 0xc9)
+
+struct loongarch_bpi_info {
+ unsigned long bpi;
+};
+
+extern struct loongarch_bpi_info loongarch_bpi_info;
+extern void bpi_init(void);
+extern void bpi_memblock_init(unsigned long *p_max_low_pfn);
+extern void bpi_init_node_memblock(void (*p_add_numamem_region)(u64 start, u64 end, u32 type));
+extern int loongarch_have_legacy_bpi(void);
+
+#endif /* __LEGACY_BOOT_H_ */
diff --git a/arch/loongarch/kernel/mem.c b/arch/loongarch/kernel/mem.c
index 86d37a447eec..b24b3db96018 100644
--- a/arch/loongarch/kernel/mem.c
+++ b/arch/loongarch/kernel/mem.c
@@ -10,6 +10,8 @@
#include <asm/loongson.h>
#include <asm/sections.h>
+#include "legacy_boot.h"
+
void __init memblock_init(void)
{
u32 mem_type;
@@ -50,6 +52,8 @@ void __init memblock_init(void)
}
}
+ bpi_memblock_init(&max_low_pfn);
+
memblock_set_current_limit(PFN_PHYS(max_low_pfn));
/* Reserve the first 2MB */
diff --git a/arch/loongarch/kernel/numa.c b/arch/loongarch/kernel/numa.c
index 8fe21f868f72..5d45c389e961 100644
--- a/arch/loongarch/kernel/numa.c
+++ b/arch/loongarch/kernel/numa.c
@@ -26,6 +26,8 @@
#include <asm/sections.h>
#include <asm/time.h>
+#include "legacy_boot.h"
+
int numa_off;
struct pglist_data *node_data[MAX_NUMNODES];
unsigned char node_distances[MAX_NUMNODES][MAX_NUMNODES];
@@ -370,6 +372,7 @@ int __init init_numa_memory(void)
return -EINVAL;
init_node_memblock();
+ bpi_init_node_memblock(add_numamem_region);
if (!memblock_validate_numa_coverage(SZ_1M))
return -EINVAL;
diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/setup.c
index e8f7a54ff67c..7c8ba5f4834e 100644
--- a/arch/loongarch/kernel/setup.c
+++ b/arch/loongarch/kernel/setup.c
@@ -49,6 +49,8 @@
#include <asm/time.h>
#include <asm/unwind.h>
+#include "legacy_boot.h"
+
#define SMBIOS_BIOSSIZE_OFFSET 0x09
#define SMBIOS_BIOSEXTERN_OFFSET 0x13
#define SMBIOS_FREQLOW_OFFSET 0x16
@@ -593,6 +595,7 @@ void __init setup_arch(char **cmdline_p)
init_environ();
efi_init();
fdt_setup();
+ bpi_init();
memblock_init();
pagetable_init();
bootcmdline_init(cmdline_p);
diff --git a/arch/loongarch/kernel/smp.c b/arch/loongarch/kernel/smp.c
index fd22a32755a5..16f5f9969bec 100644
--- a/arch/loongarch/kernel/smp.c
+++ b/arch/loongarch/kernel/smp.c
@@ -33,6 +33,8 @@
#include <asm/setup.h>
#include <asm/time.h>
+#include "legacy_boot.h"
+
int __cpu_number_map[NR_CPUS]; /* Map physical to logical */
EXPORT_SYMBOL(__cpu_number_map);
@@ -320,6 +322,8 @@ void loongson_boot_secondary(int cpu, struct task_struct *idle)
pr_info("Booting CPU#%d...\n", cpu);
entry = __pa_symbol((unsigned long)&smpboot_entry);
+ if (loongarch_have_legacy_bpi())
+ entry = (unsigned long)&smpboot_entry;
cpuboot_data.stack = (unsigned long)__KSTK_TOS(idle);
cpuboot_data.thread_info = (unsigned long)task_thread_info(idle);
--
2.39.2
From d82ce006084011c6bdf86980ea8ec592532edb61 Mon Sep 17 00:00:00 2001
From: Miao Wang <shankerwangmiao@gmail.com>
Date: Sat, 20 Jul 2024 06:32:15 +0800
Subject: [PATCH 3/9] bpi acpi
---
arch/loongarch/include/asm/acpi.h | 5 +
arch/loongarch/kernel/legacy_boot.c | 301 ++++++++++++++++++++++++++++
drivers/acpi/tables.c | 2 +
include/linux/acpi.h | 10 +
4 files changed, 318 insertions(+)
diff --git a/arch/loongarch/include/asm/acpi.h b/arch/loongarch/include/asm/acpi.h
index 49e29b29996f..473d86523b03 100644
--- a/arch/loongarch/include/asm/acpi.h
+++ b/arch/loongarch/include/asm/acpi.h
@@ -44,6 +44,11 @@ static inline u32 get_acpi_id_for_cpu(unsigned int cpu)
return acpi_core_pic[cpu_logical_map(cpu)].processor_id;
}
+#define ACPI_HAVE_ARCH_TABLE_OVERRIDE
+extern void acpi_arch_os_table_override (struct acpi_table_header *existing_table, struct acpi_table_header **new_table);
+#define ACPI_HAVE_ARCH_TABLE_INIT_COMPLETE
+extern void acpi_arch_table_init_complete(void);
+
#endif /* !CONFIG_ACPI */
#define ACPI_TABLE_UPGRADE_MAX_PHYS ARCH_LOW_ADDRESS_LIMIT
diff --git a/arch/loongarch/kernel/legacy_boot.c b/arch/loongarch/kernel/legacy_boot.c
index 30c01c8b22a0..367f9ee7e315 100644
--- a/arch/loongarch/kernel/legacy_boot.c
+++ b/arch/loongarch/kernel/legacy_boot.c
@@ -1,7 +1,13 @@
#include <linux/efi.h>
#include <linux/memblock.h>
+#include <linux/acpi.h>
+#include <linux/kmemleak.h>
+#include <linux/kernel.h>
#include <asm/early_ioremap.h>
+#include <asm/loongson.h>
+#include <asm/irq.h>
+#include <asm/numa.h>
#include "legacy_boot.h"
@@ -37,6 +43,9 @@ enum bpi_mem_type {
ADDRESS_TYPE_MAX,
};
+#define MSI_MSG_ADDRESS 0x2FF00000
+#define MSI_MSG_DEFAULT_COUNT 0xC0
+
struct loongarch_bpi_mem_map {
struct loongarch_bpi_ext_hdr header; /*{"M", "E", "M"}*/
u8 map_count;
@@ -203,6 +212,9 @@ static int __init bpi_parse_signature (u64 signature)
return 0;
}
+static void (*p_init_acpi_arch_os_table_override)(struct acpi_table_header *, struct acpi_table_header **) = NULL;
+static void init_acpi_arch_os_table_override (struct acpi_table_header *existing_table, struct acpi_table_header **new_table);
+
void __init bpi_init(void)
{
if (loongarch_bpi_info.bpi == EFI_INVALID_TABLE_ADDR) {
@@ -220,6 +232,8 @@ void __init bpi_init(void)
if (bpi_version >= BPI_VERSION_V2) {
bpi_flags = tbl->flags;
pr_info("BPI: flags 0x%llx\n", bpi_flags);
+ } else {
+ p_init_acpi_arch_os_table_override = init_acpi_arch_os_table_override;
}
unsigned long bpi_extlist = tbl->extlist;
parse_bpi_ext_list(bpi_extlist);
@@ -292,6 +306,293 @@ void __init bpi_init_node_memblock(void (*p_add_numamem_region)(u64 start, u64 e
}
}
+static u8 new_mcfg_buf [ 0
+ + sizeof(struct acpi_table_mcfg)
+ + MAX_IO_PICS * sizeof(struct acpi_mcfg_allocation)
+];
+static int __initdata new_mcfg_available = 0;
+
+void __init acpi_arch_table_init_complete(void){
+ if (!new_mcfg_available){
+ return;
+ }
+ pr_info("BPI: installing new MCFG table\n");
+ acpi_install_table((struct acpi_table_header *) new_mcfg_buf);
+}
+
+static void __init init_acpi_arch_os_table_override (struct acpi_table_header *existing_table, struct acpi_table_header **new_table){
+ static int __initdata madt_table_installed = 0;
+ static u8 new_madt_buf[ 0
+ + sizeof(struct acpi_table_madt)
+ + sizeof(struct acpi_madt_lio_pic)
+ + sizeof(struct acpi_madt_core_pic) * MAX_CORE_PIC
+ + MAX_IO_PICS * ( 0
+ + sizeof(struct acpi_madt_eio_pic)
+ + sizeof(struct acpi_madt_msi_pic)
+ + sizeof(struct acpi_madt_bio_pic)
+ )
+ ];
+ if (madt_table_installed){
+ return;
+ }
+ if (bpi_version == BPI_VERSION_NONE) {
+ return;
+ }
+ if (bpi_version > BPI_VERSION_V1) {
+ return;
+ }
+ if (strncmp(existing_table->signature, ACPI_SIG_MADT, 4) != 0) {
+ return;
+ }
+ pr_info("BPI: replacing MADT table\n");
+ struct acpi_table_madt *madt = (struct acpi_table_madt *)existing_table;
+ if (madt->header.length < sizeof(struct acpi_table_madt)) {
+ pr_warn("BPI: MADT table length %u is too small\n", madt->header.length);
+ return;
+ }
+ void *madt_end = (void *)madt + madt->header.length;
+ struct acpi_subtable_header *entry = (struct acpi_subtable_header *)(madt + 1);
+ int entry_count = 0;
+ int local_apic_count = 0;
+ int io_apic_count = 0;
+ while((void *)entry < madt_end) {
+ unsigned int ent_len = entry->length;
+ if (ent_len < sizeof(struct acpi_subtable_header)) {
+ pr_warn("BPI: MADT entry %d length %u is too small\n", entry_count, ent_len);
+ return;
+ }
+ if((void *)entry + ent_len > madt_end) {
+ pr_warn("BPI: MADT entry %d length overflow\n", entry_count);
+ return;
+ }
+ switch(entry->type) {
+ case ACPI_MADT_TYPE_LOCAL_APIC:
+ local_apic_count++;
+ break;
+ case ACPI_MADT_TYPE_IO_APIC:
+ io_apic_count++;
+ break;
+ }
+ acpi_table_print_madt_entry(entry);
+
+ entry = (struct acpi_subtable_header *)((void *)entry + ent_len);
+ }
+
+ if (local_apic_count == 0) {
+ pr_warn("BPI: MADT has no local APIC entries\n");
+ return;
+ }
+ if (local_apic_count > MAX_CORE_PIC) {
+ pr_warn("BPI: MADT has too many local APIC entries\n");
+ return;
+ }
+ if (io_apic_count == 0) {
+ pr_warn("BPI: MADT has no IO APIC entries\n");
+ return;
+ }
+ if (io_apic_count > MAX_IO_PICS) {
+ pr_warn("BPI: MADT has too many IO APIC entries\n");
+ return;
+ }
+ size_t new_madt_size = sizeof(struct acpi_table_madt);
+ size_t new_mcfg_size = sizeof(struct acpi_table_mcfg);
+ new_madt_size += sizeof(struct acpi_madt_lio_pic);
+ new_madt_size += sizeof(struct acpi_madt_core_pic) * local_apic_count;
+ if (cpu_has_extioi) {
+ pr_info("BPI: Using EIOINTC interrupt mode\n");
+ new_madt_size += io_apic_count * ( 0
+ + sizeof(struct acpi_madt_eio_pic)
+ + sizeof(struct acpi_madt_msi_pic)
+ + sizeof(struct acpi_madt_bio_pic)
+ );
+ new_madt_size += sizeof(struct acpi_madt_lpc_pic);
+ new_mcfg_size += io_apic_count * sizeof(struct acpi_mcfg_allocation);
+ } else {
+ pr_info("BPI: Using HTVECINTC interrupt mode\n");
+ new_madt_size += 0;
+ new_mcfg_size += sizeof(struct acpi_mcfg_allocation);
+ }
+
+ if (new_madt_size > sizeof(new_madt_buf)) {
+ pr_warn("BPI: new madt will be too large");
+ return;
+ }
+ if (new_mcfg_size > sizeof(new_mcfg_buf)) {
+ pr_warn("BPI: new mcfg will be too large");
+ return;
+ }
+ madt_table_installed = 1;
+ new_mcfg_available = 1;
+
+ struct acpi_table_madt *new_madt = (struct acpi_table_madt *)new_madt_buf;
+
+ new_madt->header = madt->header;
+ new_madt->header.length = new_madt_size;
+ new_madt->header.checksum = 0;
+ new_madt->header.asl_compiler_id[0] = 'B';
+ new_madt->header.asl_compiler_id[1] = 'P';
+ new_madt->header.asl_compiler_id[2] = 'I';
+ new_madt->address = madt->address;
+ new_madt->flags = madt->flags;
+
+ struct acpi_table_mcfg *new_mcfg = (struct acpi_table_mcfg *)new_mcfg_buf;
+
+ memcpy(new_mcfg->header.signature, ACPI_SIG_MCFG, sizeof(new_mcfg->header.signature));
+ new_mcfg->header.length = new_mcfg_size;
+ new_mcfg->header.revision = 1;
+ new_mcfg->header.checksum = 0;
+ memcpy(new_mcfg->header.oem_id, madt->header.oem_id, sizeof(new_mcfg->header.oem_id));
+ memcpy(new_mcfg->header.oem_table_id, madt->header.oem_table_id, sizeof(new_mcfg->header.oem_table_id));
+ new_mcfg->header.oem_revision = madt->header.oem_revision;
+ memcpy(new_mcfg->header.asl_compiler_id, "BPI", sizeof(new_mcfg->header.asl_compiler_id));
+ new_mcfg->header.asl_compiler_revision = 1;
+ memset(new_mcfg->reserved, 0, sizeof(new_mcfg->reserved));
+
+ struct acpi_mcfg_allocation *mcfg_entry = (struct acpi_mcfg_allocation *)(new_mcfg + 1);
+
+ static struct acpi_madt_core_pic __initdata core_pics[MAX_CORE_PIC];
+ static struct acpi_madt_eio_pic __initdata eio_pics[MAX_IO_PICS];
+ static struct acpi_madt_msi_pic __initdata msi_pics[MAX_IO_PICS];
+ static struct acpi_madt_bio_pic __initdata bio_pics[MAX_IO_PICS];
+
+ entry = (struct acpi_subtable_header *)(madt + 1);
+ int core_idx = 0;
+ int eio_idx = 0;
+ while((void *)entry < madt_end) {
+ unsigned int ent_len = entry->length;
+ if(entry->type == ACPI_MADT_TYPE_LOCAL_APIC) {
+ struct acpi_madt_local_apic *lapic = (struct acpi_madt_local_apic *)entry;
+
+ if(core_idx >= local_apic_count){
+ panic("BPI: MADT local APIC entries are more than expected\n");
+ }
+
+ core_pics[core_idx].header.type = ACPI_MADT_TYPE_CORE_PIC;
+ core_pics[core_idx].header.length = sizeof(core_pics[0]);
+ core_pics[core_idx].version = ACPI_MADT_CORE_PIC_VERSION_V1;
+ core_pics[core_idx].processor_id = lapic->processor_id;
+ core_pics[core_idx].core_id = lapic->id;
+ core_pics[core_idx].flags = lapic->lapic_flags;
+
+ core_idx++;
+ }else if(entry->type == ACPI_MADT_TYPE_IO_APIC) {
+ struct acpi_madt_io_apic *ioapic = (struct acpi_madt_io_apic *)entry;
+
+ if(eio_idx >= io_apic_count){
+ panic("BPI: MADT IO APIC entries are more than expected\n");
+ }
+
+ eio_pics[eio_idx].header.type = ACPI_MADT_TYPE_EIO_PIC;
+ eio_pics[eio_idx].header.length = sizeof(eio_pics[0]);
+ eio_pics[eio_idx].version = ACPI_MADT_EIO_PIC_VERSION_V1;
+ eio_pics[eio_idx].cascade = 3 + eio_idx;
+ eio_pics[eio_idx].node = ioapic->id;
+ if(eio_idx == 0){
+ eio_pics[eio_idx].node_map = 1;
+ }else{
+ eio_pics[0].node_map = 0x1DF;
+ eio_pics[eio_idx].node_map = 0xFE20;
+ }
+
+ unsigned long addr = ioapic->address;
+ if(eio_idx > 0){
+ addr |= nid_to_addrbase(ioapic->id) | HT1LO_OFFSET;
+ }
+
+ msi_pics[eio_idx].header.type = ACPI_MADT_TYPE_MSI_PIC;
+ msi_pics[eio_idx].header.length = sizeof(msi_pics[0]);
+ msi_pics[eio_idx].version = ACPI_MADT_MSI_PIC_VERSION_V1;
+ msi_pics[eio_idx].msg_address = MSI_MSG_ADDRESS;
+ pr_info("BPI: will read MSI start addr for node %d from 0x%lx\n", ioapic->id, addr);
+ msi_pics[eio_idx].start = (((unsigned long)ls7a_readq(addr) >> 48) & 0xff) + 1;
+ pr_info("BPI: done read MSI start addr for node %d from 0x%lx\n", ioapic->id, addr);
+ msi_pics[eio_idx].count = MSI_MSG_DEFAULT_COUNT;
+
+ bio_pics[eio_idx].header.type = ACPI_MADT_TYPE_BIO_PIC;
+ bio_pics[eio_idx].header.length = sizeof(bio_pics[0]);
+ bio_pics[eio_idx].version = ACPI_MADT_BIO_PIC_VERSION_V1;
+ bio_pics[eio_idx].address = addr;
+ bio_pics[eio_idx].size = 0x1000;
+ bio_pics[eio_idx].id = ioapic->id;
+ bio_pics[eio_idx].gsi_base = ioapic->global_irq_base;
+
+ mcfg_entry->address = mcfg_addr_init(eio_idx);
+ mcfg_entry->pci_segment = eio_idx;
+ mcfg_entry->start_bus_number = 0;
+ mcfg_entry->end_bus_number = 0xFF; // Who knows?
+ mcfg_entry->reserved = 0;
+ mcfg_entry++;
+
+ eio_idx++;
+ }
+ entry = (struct acpi_subtable_header *)((void *)entry + ent_len);
+ }
+ if(eio_idx != io_apic_count || core_idx != local_apic_count) {
+ panic("BPI: MADT entries are less than expected\n");
+ }
+
+ // 1. Core APIC 0x11
+ struct acpi_subtable_header *new_entry = (struct acpi_subtable_header *)(new_madt + 1);
+
+ memcpy(new_entry, core_pics, local_apic_count * sizeof(core_pics[0]));
+ new_entry = (struct acpi_subtable_header *)((void *)new_entry + local_apic_count * sizeof(core_pics[0]));
+
+ // 2. LIO PIC 0x12
+ {
+ struct acpi_madt_lio_pic *lio_pic = (struct acpi_madt_lio_pic *)new_entry;
+ lio_pic->header.type = ACPI_MADT_TYPE_LIO_PIC;
+ lio_pic->header.length = sizeof(*lio_pic);
+ lio_pic->version = ACPI_MADT_LIO_PIC_VERSION_V1;
+ lio_pic->address = LOONGSON_REG_BASE + 0x1400;
+ lio_pic->size = 256;
+ lio_pic->cascade[0] = 2;
+ lio_pic->cascade[1] = 3;
+ lio_pic->cascade_map[0] = 0x00FFFFFF;
+ lio_pic->cascade_map[1] = 0xFF000000;
+ new_entry = (struct acpi_subtable_header *)((void *)new_entry + sizeof(*lio_pic));
+ }
+ // 3. HT PIC 0x13
+ if (!cpu_has_extioi) {
+ // FIX ME: Unsupported
+ } else {
+ // 4. EIO PIC 0x14
+ memcpy(new_entry, eio_pics, io_apic_count * sizeof(eio_pics[0]));
+ new_entry = (struct acpi_subtable_header *)((void *)new_entry + io_apic_count * sizeof(eio_pics[0]));
+ // 5. MSI PIC 0x15
+ memcpy(new_entry, msi_pics, io_apic_count * sizeof(msi_pics[0]));
+ new_entry = (struct acpi_subtable_header *)((void *)new_entry + io_apic_count * sizeof(msi_pics[0]));
+ // 6. BIO PIC 0x16
+ memcpy(new_entry, bio_pics, io_apic_count * sizeof(bio_pics[0]));
+ new_entry = (struct acpi_subtable_header *)((void *)new_entry + io_apic_count * sizeof(bio_pics[0]));
+ // 7. LPC PIC 0x17
+ {
+ struct acpi_madt_lpc_pic *lpc_pic = (struct acpi_madt_lpc_pic *)new_entry;
+ lpc_pic->header.type = ACPI_MADT_TYPE_LPC_PIC;
+ lpc_pic->header.length = sizeof(*lpc_pic);
+ lpc_pic->version = ACPI_MADT_LPC_PIC_VERSION_V1;
+ lpc_pic->address = LS7A_LPC_REG_BASE;
+ lpc_pic->size = SZ_4K;
+ lpc_pic->cascade = 19;
+ new_entry = (struct acpi_subtable_header *)((void *)new_entry + sizeof(*lpc_pic));
+ }
+ }
+ if((void *)new_entry != (void *)new_madt + new_madt_size) {
+ panic("BPI: missing bytes while constructing new MADT\n");
+ }
+ if((void *)mcfg_entry != (void *)new_mcfg + new_mcfg_size) {
+ panic("BPI: missing bytes while constructing new MCFG\n");
+ }
+ new_madt->header.checksum = 0 - ext_listhdr_checksum((u8 *)new_madt, new_madt_size);
+ new_mcfg->header.checksum = 0 - ext_listhdr_checksum((u8 *)new_mcfg, new_mcfg_size);
+ *new_table = (struct acpi_table_header *)new_madt;
+}
+
+void acpi_arch_os_table_override (struct acpi_table_header *existing_table, struct acpi_table_header **new_table){
+ if(p_init_acpi_arch_os_table_override && system_state == SYSTEM_BOOTING) {
+ p_init_acpi_arch_os_table_override(existing_table, new_table);
+ }
+}
+
int loongarch_have_legacy_bpi (void){
return have_bpi;
}
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index b976e5fc3fbc..6cd17bb24426 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -679,6 +679,7 @@ acpi_status acpi_os_table_override(struct acpi_table_header *existing_table,
*new_table = (struct acpi_table_header *)&dsdt_amlcode;
}
#endif
+ acpi_arch_os_table_override(existing_table, new_table);
if (*new_table != NULL)
acpi_table_taint(existing_table);
return AE_OK;
@@ -734,6 +735,7 @@ void __init acpi_table_init_complete(void)
{
acpi_table_initrd_scan();
check_multiple_madt();
+ acpi_arch_table_init_complete();
}
int __init acpi_table_init(void)
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 168201e4c782..6e1a550c675e 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -769,6 +769,16 @@ static inline u64 acpi_arch_get_root_pointer(void)
int acpi_get_local_address(acpi_handle handle, u32 *addr);
const char *acpi_get_subsystem_id(acpi_handle handle);
+#ifndef ACPI_HAVE_ARCH_TABLE_OVERRIDE
+static inline void acpi_arch_os_table_override (struct acpi_table_header *existing_table, struct acpi_table_header **new_table){
+}
+#endif
+#ifndef ACPI_HAVE_ARCH_TABLE_INIT_COMPLETE
+static inline void acpi_arch_table_init_complete(void)
+{
+}
+#endif
+
#else /* !CONFIG_ACPI */
#define acpi_disabled 1
--
2.39.2
From 10a3a8e811229588f913b8d5e47c4820cdcbc1f4 Mon Sep 17 00:00:00 2001
From: Miao Wang <shankerwangmiao@gmail.com>
Date: Wed, 24 Jul 2024 09:06:27 +0800
Subject: [PATCH 4/9] bpi: acpi root offset
---
arch/loongarch/include/asm/acpi.h | 2 ++
arch/loongarch/kernel/legacy_boot.c | 23 ++++++++++++++++++++++-
drivers/acpi/pci_root.c | 1 +
include/linux/pci-acpi.h | 4 ++++
4 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/arch/loongarch/include/asm/acpi.h b/arch/loongarch/include/asm/acpi.h
index 473d86523b03..ecf05448fe9d 100644
--- a/arch/loongarch/include/asm/acpi.h
+++ b/arch/loongarch/include/asm/acpi.h
@@ -48,6 +48,8 @@ static inline u32 get_acpi_id_for_cpu(unsigned int cpu)
extern void acpi_arch_os_table_override (struct acpi_table_header *existing_table, struct acpi_table_header **new_table);
#define ACPI_HAVE_ARCH_TABLE_INIT_COMPLETE
extern void acpi_arch_table_init_complete(void);
+#define ACPI_HAVE_ARCH_PCI_ROOT_RES_FILTER
+extern void acpi_arch_pci_probe_root_dev_filter(struct resource_entry *entry);
#endif /* !CONFIG_ACPI */
diff --git a/arch/loongarch/kernel/legacy_boot.c b/arch/loongarch/kernel/legacy_boot.c
index 367f9ee7e315..f1e50ef4c429 100644
--- a/arch/loongarch/kernel/legacy_boot.c
+++ b/arch/loongarch/kernel/legacy_boot.c
@@ -60,7 +60,7 @@ struct loongarch_bpi_info __initdata loongarch_bpi_info = {
.bpi = EFI_INVALID_TABLE_ADDR,
};
-static enum bpi_vers __initdata bpi_version = BPI_VERSION_NONE;
+static enum bpi_vers bpi_version = BPI_VERSION_NONE;
static u64 __initdata bpi_flags = 0;
static int have_bpi = 0;
@@ -593,6 +593,27 @@ void acpi_arch_os_table_override (struct acpi_table_header *existing_table, stru
}
}
+void acpi_arch_pci_probe_root_dev_filter(struct resource_entry *entry)
+{
+ if (bpi_version == BPI_VERSION_NONE) {
+ return;
+ }
+ if (bpi_version > BPI_VERSION_V1) {
+ return;
+ }
+
+ if (entry->res->flags & IORESOURCE_IO) {
+ if (entry->offset == 0) {
+ if (entry->res->start > 0) {
+ entry->res->start = 0;
+ }
+ entry->offset = LOONGSON_LIO_BASE;
+ entry->res->start += LOONGSON_LIO_BASE;
+ entry->res->end += LOONGSON_LIO_BASE;
+ }
+ }
+}
+
int loongarch_have_legacy_bpi (void){
return have_bpi;
}
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 58b89b8d950e..93936225dc37 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -914,6 +914,7 @@ int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info)
"no IO and memory resources present in _CRS\n");
else {
resource_list_for_each_entry_safe(entry, tmp, list) {
+ acpi_arch_pci_probe_root_dev_filter(entry);
if (entry->res->flags & IORESOURCE_IO)
acpi_pci_root_remap_iospace(&device->fwnode,
entry);
diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
index 078225b514d4..1c22ca4ec794 100644
--- a/include/linux/pci-acpi.h
+++ b/include/linux/pci-acpi.h
@@ -133,6 +133,10 @@ static inline void pci_acpi_remove_edr_notifier(struct pci_dev *pdev) { }
int pci_acpi_set_companion_lookup_hook(struct acpi_device *(*func)(struct pci_dev *));
void pci_acpi_clear_companion_lookup_hook(void);
+#ifndef ACPI_HAVE_ARCH_PCI_ROOT_RES_FILTER
+static inline void acpi_arch_pci_probe_root_dev_filter(struct resource_entry *entry) { }
+#endif
+
#else /* CONFIG_ACPI */
static inline void acpi_pci_add_bus(struct pci_bus *bus) { }
static inline void acpi_pci_remove_bus(struct pci_bus *bus) { }
--
2.39.2
From d6da2847720065c0360fc3f6358011c2e61729d0 Mon Sep 17 00:00:00 2001
From: Miao Wang <shankerwangmiao@gmail.com>
Date: Thu, 25 Jul 2024 16:09:19 +0800
Subject: [PATCH 5/9] bpi: acpi dsdt patch
---
arch/loongarch/include/asm/acpi.h | 2 ++
arch/loongarch/kernel/legacy_boot.c | 47 +++++++++++++++++++++++++++++
drivers/acpi/bus.c | 1 +
include/linux/acpi.h | 4 +++
4 files changed, 54 insertions(+)
diff --git a/arch/loongarch/include/asm/acpi.h b/arch/loongarch/include/asm/acpi.h
index ecf05448fe9d..915cb0a2c239 100644
--- a/arch/loongarch/include/asm/acpi.h
+++ b/arch/loongarch/include/asm/acpi.h
@@ -50,6 +50,8 @@ extern void acpi_arch_os_table_override (struct acpi_table_header *existing_tabl
extern void acpi_arch_table_init_complete(void);
#define ACPI_HAVE_ARCH_PCI_ROOT_RES_FILTER
extern void acpi_arch_pci_probe_root_dev_filter(struct resource_entry *entry);
+#define ACPI_HAVE_ARCH_INIT
+extern void acpi_arch_init(void);
#endif /* !CONFIG_ACPI */
diff --git a/arch/loongarch/kernel/legacy_boot.c b/arch/loongarch/kernel/legacy_boot.c
index f1e50ef4c429..434bab8f98cd 100644
--- a/arch/loongarch/kernel/legacy_boot.c
+++ b/arch/loongarch/kernel/legacy_boot.c
@@ -614,6 +614,53 @@ void acpi_arch_pci_probe_root_dev_filter(struct resource_entry *entry)
}
}
+static __initconst const struct {
+ struct acpi_table_header header;
+ unsigned char code [];
+} __packed dsdt_add_aml_code = {
+ .header = {
+ .signature = ACPI_SIG_DSDT
+ },
+ .code = {
+ 0x14,0x21,0x5C,0x2F, /* 00000020 " .!\/" */
+ 0x05,0x5F,0x53,0x42,0x5F,0x50,0x43,0x49, /* 00000028 "._SB_PCI" */
+ 0x30,0x4C,0x50,0x43,0x5F,0x45,0x43,0x5F, /* 00000030 "0LPC_EC_" */
+ 0x5F,0x5F,0x44,0x45,0x50,0x08,0xA4,0x12, /* 00000038 "__DEP..." */
+ 0x06,0x01,0x50,0x43,0x49,0x30 /* 00000040 "..PCI0" */
+ },
+};
+
+void __init acpi_arch_init (){
+ if (bpi_version == BPI_VERSION_NONE) {
+ return;
+ }
+ if (bpi_version > BPI_VERSION_V1) {
+ return;
+ }
+ pr_info("BPI: Trying to patch DSDT\n");
+
+ acpi_status status;
+ acpi_handle handle;
+
+ status = acpi_get_handle(NULL, "\\_SB.PCI0.LPC.EC", &handle);
+ if (ACPI_FAILURE(status)) {
+ if (status != AE_NOT_FOUND) {
+ pr_info("BPI: Unable to find EC device: %s\n", acpi_format_exception(status));
+ }
+ return;
+ }
+ if (acpi_has_method(handle, "_DEP")) {
+ return;
+ }
+
+ status = acpi_install_method((u8 *)&dsdt_add_aml_code);
+ if (ACPI_FAILURE(status)) {
+ pr_info("BPI: Unable to patch DSDT(0x%x)\n", status);
+ return;
+ }
+ acpi_handle_info(handle, "BPI: Patched DSDT\n");
+}
+
int loongarch_have_legacy_bpi (void){
return have_bpi;
}
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index a87b10eef77d..44920caedf8f 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -1445,6 +1445,7 @@ static int __init acpi_init(void)
acpi_hest_init();
acpi_ghes_init();
acpi_arm_init();
+ acpi_arch_init();
acpi_scan_init();
acpi_ec_init();
acpi_debugfs_init();
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 6e1a550c675e..0917301171e7 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -1533,6 +1533,10 @@ void acpi_arm_init(void);
static inline void acpi_arm_init(void) { }
#endif
+#ifndef ACPI_HAVE_ARCH_INIT
+static inline void acpi_arch_init(void) {}
+#endif
+
#ifdef CONFIG_ACPI_PCC
void acpi_init_pcc(void);
#else
--
2.39.2
From 195a2abe312e82fcd1a0fdbaab0ba9cb73f33bd1 Mon Sep 17 00:00:00 2001
From: Miao Wang <shankerwangmiao@gmail.com>
Date: Wed, 17 Jul 2024 08:44:09 +0800
Subject: [PATCH 6/9] loongarch: add earlyprintk for debugging
---
arch/loongarch/kernel/Makefile | 1 +
arch/loongarch/kernel/early_printk.c | 54 ++++++++++++++++++++++++++++
2 files changed, 55 insertions(+)
create mode 100644 arch/loongarch/kernel/early_printk.c
diff --git a/arch/loongarch/kernel/Makefile b/arch/loongarch/kernel/Makefile
index 84d2e2d896ab..796466f366c4 100644
--- a/arch/loongarch/kernel/Makefile
+++ b/arch/loongarch/kernel/Makefile
@@ -80,3 +80,4 @@ obj-$(CONFIG_JUMP_LABEL) += jump_label.o
CPPFLAGS_vmlinux.lds := $(KBUILD_CFLAGS)
obj-y += legacy_boot.o
+obj-y += early_printk.o
diff --git a/arch/loongarch/kernel/early_printk.c b/arch/loongarch/kernel/early_printk.c
new file mode 100644
index 000000000000..764650a46264
--- /dev/null
+++ b/arch/loongarch/kernel/early_printk.c
@@ -0,0 +1,54 @@
+#include <linux/console.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/serial_reg.h>
+#include <linux/serial.h>
+#include <asm/addrspace.h>
+#include <asm/io.h>
+
+#define LOONGUART1 0x1fe001e0
+
+static void loong_uart_putc(unsigned char c){
+ *(volatile unsigned char *)TO_UNCACHE(LOONGUART1 + UART_TX) = c;
+ int status;
+ for(int count = 0; count < 25000000; count++){
+ status = *(volatile unsigned char *)TO_UNCACHE(LOONGUART1 + UART_LSR);
+ if (uart_lsr_tx_empty(status))
+ break;
+ cpu_relax();
+ }
+}
+
+static void early_serial_write(struct console *con, const char *s, unsigned n){
+ while(*s && n-- > 0){
+ if ( *s == '\n' ){
+ loong_uart_putc('\r');
+ }
+ loong_uart_putc(*s);
+ s++;
+ }
+}
+
+static struct console early_serial_console = {
+ .name = "earlyser",
+ .write = early_serial_write,
+ .flags = CON_PRINTBUFFER | CON_BOOT,
+ .index = -1,
+};
+
+static int __init setup_early_printk(char *buf)
+{
+ static int registered = 0;
+ if (registered) {
+ return 0;
+ }
+ if (early_serial_console.index != -1) {
+ return 0;
+ }
+ register_console(&early_serial_console);
+ return 0;
+}
+
+early_param("earlyprintk", setup_early_printk);
--
2.39.2
From f3d725a903583f0b7c7fd19fc7c6e637de9d4806 Mon Sep 17 00:00:00 2001
From: Miao Wang <shankerwangmiao@gmail.com>
Date: Wed, 17 Jul 2024 09:03:32 +0800
Subject: [PATCH 7/9] loongarch: add debug outputs
---
arch/loongarch/include/uartout.h | 24 ++++++++++++
arch/loongarch/kernel/efi.c | 1 +
arch/loongarch/kernel/legacy_boot.c | 9 +++++
arch/loongarch/kernel/numa.c | 17 +++++++++
arch/loongarch/kernel/setup.c | 37 +++++++++++++++++++
arch/loongarch/kernel/smp.c | 13 +++++++
drivers/firmware/efi/libstub/efi-stub-entry.c | 2 +
drivers/firmware/efi/libstub/loongarch.c | 15 ++++++++
drivers/firmware/efi/libstub/zboot.c | 5 +++
init/main.c | 15 ++++++++
10 files changed, 138 insertions(+)
create mode 100644 arch/loongarch/include/uartout.h
diff --git a/arch/loongarch/include/uartout.h b/arch/loongarch/include/uartout.h
new file mode 100644
index 000000000000..06023fa03deb
--- /dev/null
+++ b/arch/loongarch/include/uartout.h
@@ -0,0 +1,24 @@
+#include <linux/serial_reg.h>
+#include <linux/serial.h>
+#include <asm/addrspace.h>
+#include <asm/io.h>
+
+#define LOONGUART1 0x1fe001e0
+
+static inline void loong_uart_putc(unsigned char c){
+ *(volatile unsigned char *)TO_UNCACHE(LOONGUART1 + UART_TX) = c;
+ int status;
+ for(int count = 0; count < 25000000; count++){
+ status = *(volatile unsigned char *)TO_UNCACHE(LOONGUART1 + UART_LSR);
+ if (uart_lsr_tx_empty(status))
+ break;
+ cpu_relax();
+ }
+}
+
+static inline void loong_uart_puts(const char *str){
+ while(*str){
+ loong_uart_putc(*str);
+ str++;
+ }
+}
diff --git a/arch/loongarch/kernel/efi.c b/arch/loongarch/kernel/efi.c
index 307f35d1e71f..3db8e859592b 100644
--- a/arch/loongarch/kernel/efi.c
+++ b/arch/loongarch/kernel/efi.c
@@ -63,6 +63,7 @@ void __init efi_runtime_init(void)
}
efi.runtime = (efi_runtime_services_t *)efi_systab->runtime;
+ pr_info("efi_systab->runtime=0x%lx\n", (unsigned long) efi_systab->runtime);
efi.runtime_version = (unsigned int)efi.runtime->hdr.revision;
efi_native_runtime_setup();
diff --git a/arch/loongarch/kernel/legacy_boot.c b/arch/loongarch/kernel/legacy_boot.c
index 434bab8f98cd..7a22f70d71f1 100644
--- a/arch/loongarch/kernel/legacy_boot.c
+++ b/arch/loongarch/kernel/legacy_boot.c
@@ -533,9 +533,11 @@ static void __init init_acpi_arch_os_table_override (struct acpi_table_header *e
// 1. Core APIC 0x11
struct acpi_subtable_header *new_entry = (struct acpi_subtable_header *)(new_madt + 1);
+ pr_info("new_entry = %lx\n", (unsigned long)new_entry);
memcpy(new_entry, core_pics, local_apic_count * sizeof(core_pics[0]));
new_entry = (struct acpi_subtable_header *)((void *)new_entry + local_apic_count * sizeof(core_pics[0]));
+ pr_info("new_entry = %lx\n", (unsigned long)new_entry);
// 2. LIO PIC 0x12
{
@@ -550,6 +552,7 @@ static void __init init_acpi_arch_os_table_override (struct acpi_table_header *e
lio_pic->cascade_map[0] = 0x00FFFFFF;
lio_pic->cascade_map[1] = 0xFF000000;
new_entry = (struct acpi_subtable_header *)((void *)new_entry + sizeof(*lio_pic));
+ pr_info("new_entry = %lx\n", (unsigned long)new_entry);
}
// 3. HT PIC 0x13
if (!cpu_has_extioi) {
@@ -558,12 +561,15 @@ static void __init init_acpi_arch_os_table_override (struct acpi_table_header *e
// 4. EIO PIC 0x14
memcpy(new_entry, eio_pics, io_apic_count * sizeof(eio_pics[0]));
new_entry = (struct acpi_subtable_header *)((void *)new_entry + io_apic_count * sizeof(eio_pics[0]));
+ pr_info("new_entry = %lx\n", (unsigned long)new_entry);
// 5. MSI PIC 0x15
memcpy(new_entry, msi_pics, io_apic_count * sizeof(msi_pics[0]));
new_entry = (struct acpi_subtable_header *)((void *)new_entry + io_apic_count * sizeof(msi_pics[0]));
+ pr_info("new_entry = %lx\n", (unsigned long)new_entry);
// 6. BIO PIC 0x16
memcpy(new_entry, bio_pics, io_apic_count * sizeof(bio_pics[0]));
new_entry = (struct acpi_subtable_header *)((void *)new_entry + io_apic_count * sizeof(bio_pics[0]));
+ pr_info("new_entry = %lx\n", (unsigned long)new_entry);
// 7. LPC PIC 0x17
{
struct acpi_madt_lpc_pic *lpc_pic = (struct acpi_madt_lpc_pic *)new_entry;
@@ -574,12 +580,15 @@ static void __init init_acpi_arch_os_table_override (struct acpi_table_header *e
lpc_pic->size = SZ_4K;
lpc_pic->cascade = 19;
new_entry = (struct acpi_subtable_header *)((void *)new_entry + sizeof(*lpc_pic));
+ pr_info("new_entry = %lx\n", (unsigned long)new_entry);
}
}
if((void *)new_entry != (void *)new_madt + new_madt_size) {
+ pr_err("BPI: new_madt=%lx new_entry=%lx new_madt_size=%ld\n", (unsigned long)new_madt, (unsigned long)new_entry, new_madt_size);
panic("BPI: missing bytes while constructing new MADT\n");
}
if((void *)mcfg_entry != (void *)new_mcfg + new_mcfg_size) {
+ pr_err("BPI: new_mcfg=%lx mcfg_entry=%lx new_mcfg_size=%ld\n", (unsigned long)new_mcfg, (unsigned long)mcfg_entry, new_mcfg_size);
panic("BPI: missing bytes while constructing new MCFG\n");
}
new_madt->header.checksum = 0 - ext_listhdr_checksum((u8 *)new_madt, new_madt_size);
diff --git a/arch/loongarch/kernel/numa.c b/arch/loongarch/kernel/numa.c
index 5d45c389e961..11a7fbc7d52a 100644
--- a/arch/loongarch/kernel/numa.c
+++ b/arch/loongarch/kernel/numa.c
@@ -26,6 +26,8 @@
#include <asm/sections.h>
#include <asm/time.h>
+#include <uartout.h>
+
#include "legacy_boot.h"
int numa_off;
@@ -288,6 +290,9 @@ static void __init init_node_memblock(void)
mem_size = md->num_pages << EFI_PAGE_SHIFT;
mem_end = mem_start + mem_size;
+ pr_info("memDesc: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx Bytes\n",
+ mem_type, mem_start, mem_size);
+
switch (mem_type) {
case EFI_LOADER_CODE:
case EFI_LOADER_DATA:
@@ -371,21 +376,33 @@ int __init init_numa_memory(void)
if (WARN_ON(nodes_empty(node_possible_map)))
return -EINVAL;
+ loong_uart_puts("will_init_node_memblock\n");
init_node_memblock();
+ loong_uart_puts("done_init_node_memblock\n");
+ loong_uart_puts("will_bpi_init_node_memblock\n");
bpi_init_node_memblock(add_numamem_region);
+ loong_uart_puts("done_bpi_init_node_memblock\n");
+ loong_uart_puts("will_memblock_validate_numa_coverage\n");
if (!memblock_validate_numa_coverage(SZ_1M))
return -EINVAL;
+ loong_uart_puts("done_memblock_validate_numa_coverage\n");
for_each_node_mask(node, node_possible_map) {
+ loong_uart_puts("will_node_mem_init\n");
node_mem_init(node);
+ loong_uart_puts("will_node_set_online\n");
node_set_online(node);
+ loong_uart_puts("done_node_set_online\n");
}
+ loong_uart_puts("will_memblock_end_of_DRAM\n");
max_low_pfn = PHYS_PFN(memblock_end_of_DRAM());
+ loong_uart_puts("will_setup_nr_node_ids\n");
setup_nr_node_ids();
loongson_sysconf.nr_nodes = nr_node_ids;
loongson_sysconf.cores_per_node = cpumask_weight(&phys_cpus_on_node[0]);
+ loong_uart_puts("done_init_numa_memory\n");
return 0;
}
diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/setup.c
index 7c8ba5f4834e..7ef540ca91bb 100644
--- a/arch/loongarch/kernel/setup.c
+++ b/arch/loongarch/kernel/setup.c
@@ -49,6 +49,8 @@
#include <asm/time.h>
#include <asm/unwind.h>
+#include <uartout.h>
+
#include "legacy_boot.h"
#define SMBIOS_BIOSSIZE_OFFSET 0x09
@@ -350,28 +352,45 @@ static void __init bootcmdline_init(char **cmdline_p)
void __init platform_init(void)
{
+ loong_uart_puts("will_reserve_vmcore!!\n");
arch_reserve_vmcore();
+ loong_uart_puts("will_reserve_carshker!!\n");
arch_reserve_crashkernel();
#ifdef CONFIG_ACPI_TABLE_UPGRADE
+ loong_uart_puts("will_acpi_table_upgrade!!\n");
acpi_table_upgrade();
#endif
+ loong_uart_puts("done_acpi_table_upgrade!!\n");
#ifdef CONFIG_ACPI
acpi_gbl_use_default_register_widths = false;
+ loong_uart_puts("will_acpi_boot_table_init!!\n");
acpi_boot_table_init();
+ loong_uart_puts("done_acpi_boot_table_init!!\n");
#endif
+ loong_uart_puts("will_fdt_scan_rsv_mem!!\n");
early_init_fdt_scan_reserved_mem();
+ loong_uart_puts("will_cpdt!!\n");
unflatten_and_copy_device_tree();
#ifdef CONFIG_NUMA
+ loong_uart_puts("will_init_numa_mem!!\n");
init_numa_memory();
#endif
+ loong_uart_puts("done_init_numa_mem!!\n");
+ loong_uart_puts("will_dmi_setup!!\n");
dmi_setup();
+ loong_uart_puts("will_smbios_parse!!\n");
smbios_parse();
+ loong_uart_puts("bios ver:");
+ loong_uart_puts(b_info.bios_version);
+ loong_uart_puts("\n");
pr_info("The BIOS Version: %s\n", b_info.bios_version);
+ loong_uart_puts("will_efi_runtime_init!!\n");
efi_runtime_init();
+ loong_uart_puts("done_platform_init!!\n");
}
static void __init check_kernel_sections_mem(void)
@@ -589,31 +608,49 @@ static void __init prefill_possible_map(void)
void __init setup_arch(char **cmdline_p)
{
+ loong_uart_puts("will_cpu_probe!!\n");
cpu_probe();
unwind_init();
+ loong_uart_puts("will_init_environ!!\n");
init_environ();
+ loong_uart_puts("will_efi_init!!\n");
efi_init();
+ loong_uart_puts("will_fdt_setup!!\n");
fdt_setup();
+ loong_uart_puts("will_bpi_init!!\n");
bpi_init();
+ loong_uart_puts("will_memblock_init!!\n");
memblock_init();
+ loong_uart_puts("will_pagetable_init!!\n");
pagetable_init();
+ loong_uart_puts("will_bootcmdline_init!!\n");
bootcmdline_init(cmdline_p);
+ loong_uart_puts("will_parse_early_param!!\n");
parse_early_param();
+ loong_uart_puts("will_reserve_initrd_mem!!\n");
reserve_initrd_mem();
+ loong_uart_puts("will_platform_init!!\n");
platform_init();
+ loong_uart_puts("will_arch_mem_init!!\n");
arch_mem_init(cmdline_p);
+ loong_uart_puts("will_resource_init!!\n");
resource_init();
+ loong_uart_puts("will_plat_smp_setup!!\n");
#ifdef CONFIG_SMP
plat_smp_setup();
+ loong_uart_puts("will_prefill_possible_map!!\n");
prefill_possible_map();
#endif
+ loong_uart_puts("will_paging_init!!\n");
paging_init();
+ loong_uart_puts("will_ksasn_init!!\n");
#ifdef CONFIG_KASAN
kasan_init();
#endif
+ loong_uart_puts("done_setup_arch!!\n");
}
diff --git a/arch/loongarch/kernel/smp.c b/arch/loongarch/kernel/smp.c
index 16f5f9969bec..8a1cf8afd513 100644
--- a/arch/loongarch/kernel/smp.c
+++ b/arch/loongarch/kernel/smp.c
@@ -33,6 +33,8 @@
#include <asm/setup.h>
#include <asm/time.h>
+#include <uartout.h>
+
#include "legacy_boot.h"
int __cpu_number_map[NR_CPUS]; /* Map physical to logical */
@@ -285,15 +287,26 @@ static void __init fdt_smp_setup(void)
void __init loongson_smp_setup(void)
{
+ loong_uart_puts("will_fdt_smp_setup\n");
fdt_smp_setup();
+ loong_uart_puts("done_fdt_smp_setup\n");
+ static char __initdata buf[128] = {};
+ snprintf(buf, sizeof(buf), "loongson_sysconf.cores_per_package = %d\n", loongson_sysconf.cores_per_package);
+ loong_uart_puts(buf);
+ snprintf(buf, sizeof(buf), "loongson_sysconf.nr_cpus = %d\n", loongson_sysconf.nr_cpus);
+ loong_uart_puts(buf);
if (loongson_sysconf.cores_per_package == 0)
loongson_sysconf.cores_per_package = num_processors;
+ snprintf(buf, sizeof(buf), "cpu_logical_map(0)=%x\n", cpu_logical_map(0));
+ loong_uart_puts(buf);
cpu_data[0].core = cpu_logical_map(0) % loongson_sysconf.cores_per_package;
cpu_data[0].package = cpu_logical_map(0) / loongson_sysconf.cores_per_package;
+ loong_uart_puts("will_iocsr_write IPI_EN\n");
iocsr_write32(0xffffffff, LOONGARCH_IOCSR_IPI_EN);
+ loong_uart_puts("done_iocsr_write IPI_EN\n");
pr_info("Detected %i available CPU(s)\n", loongson_sysconf.nr_cpus);
}
diff --git a/drivers/firmware/efi/libstub/efi-stub-entry.c b/drivers/firmware/efi/libstub/efi-stub-entry.c
index a6c049835190..cadc8f8935e6 100644
--- a/drivers/firmware/efi/libstub/efi-stub-entry.c
+++ b/drivers/firmware/efi/libstub/efi-stub-entry.c
@@ -64,6 +64,7 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
efi_info("Booting Linux Kernel...\n");
+ efi_debug("image_addr=%p\n", (void *)image_addr);
status = handle_kernel_image(&image_addr, &image_size,
&reserve_addr,
&reserve_size,
@@ -72,6 +73,7 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
efi_err("Failed to relocate kernel\n");
return status;
}
+ efi_debug("after: image_addr=%p\n", (void *)image_addr);
screen_info_offset = image_addr - (unsigned long)image->image_base;
diff --git a/drivers/firmware/efi/libstub/loongarch.c b/drivers/firmware/efi/libstub/loongarch.c
index e76d08f09255..3e4615920ed2 100644
--- a/drivers/firmware/efi/libstub/loongarch.c
+++ b/drivers/firmware/efi/libstub/loongarch.c
@@ -10,6 +10,8 @@
#include "efistub.h"
#include "loongarch-stub.h"
+#include <uartout.h>
+
typedef void __noreturn (*kernel_entry_t)(bool efi, unsigned long cmdline,
unsigned long systab);
@@ -40,7 +42,12 @@ static efi_status_t exit_boot_func(struct efi_boot_memmap *map, void *priv)
if (is_oldworld) {
for(int l = 0; l < p->runtime_entry_count * map->desc_size; l += map->desc_size) {
efi_memory_desc_t *entry = (void *)(p->runtime_map) + l;
+ char buf[256];
+ snprintf(buf, sizeof(buf), "virt_map_bfr: phys=%llx, virt=%llx\n", entry->phys_addr, entry->virt_addr);
+ loong_uart_puts(buf);
entry->virt_addr = TO_UNCACHE(entry->virt_addr);
+ snprintf(buf, sizeof(buf), "virt_map_aft: phys=%llx, virt=%llx\n", entry->phys_addr, entry->virt_addr);
+ loong_uart_puts(buf);
}
}
@@ -51,6 +58,10 @@ static void detect_oldworld(void)
{
is_oldworld = !!(csr_read64(LOONGARCH_CSR_DMWIN1) & CSR_DMW1_PLV0);
efi_debug("is_oldworld: %d\n", is_oldworld);
+ efi_debug("dmwin0: %lx\n", csr_read64(LOONGARCH_CSR_DMWIN0));
+ efi_debug("dmwin1: %lx\n", csr_read64(LOONGARCH_CSR_DMWIN1));
+ efi_debug("dmwin2: %lx\n", csr_read64(LOONGARCH_CSR_DMWIN2));
+ efi_debug("dmwin3: %lx\n", csr_read64(LOONGARCH_CSR_DMWIN3));
if(is_oldworld) {
efi_info("Booting on OldWorld firmware\n");
}
@@ -79,6 +90,10 @@ efi_status_t efi_boot_kernel(void *handle, efi_loaded_image_t *image,
return status;
}
+ efi_debug("kernel_addr=%p\n", (void *)kernel_addr);
+ efi_debug("image=%p\n", image);
+ efi_debug("real_kernel_entry=%p\n", (void *)kernel_entry_address(kernel_addr, image));
+ efi_debug("*(kernel_addr + 8)=%p\n", *(void **)(kernel_addr + 8));
efi_info("Exiting boot services\n");
efi_novamap = false;
diff --git a/drivers/firmware/efi/libstub/zboot.c b/drivers/firmware/efi/libstub/zboot.c
index 1ceace956758..af1fb2f74149 100644
--- a/drivers/firmware/efi/libstub/zboot.c
+++ b/drivers/firmware/efi/libstub/zboot.c
@@ -72,6 +72,7 @@ efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab)
int ret;
WRITE_ONCE(efi_system_table, systab);
+ efi_debug("efi_system_table=%p\n", efi_system_table);
free_mem_ptr = (unsigned long)&zboot_heap;
free_mem_end_ptr = free_mem_ptr + sizeof(zboot_heap);
@@ -82,6 +83,7 @@ efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab)
error("Failed to locate parent's loaded image protocol");
return status;
}
+ efi_debug("image=%p\n", image);
status = efi_handle_cmdline(image, &cmdline_ptr);
if (status != EFI_SUCCESS)
@@ -96,6 +98,7 @@ efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab)
// If the architecture has a preferred address for the image,
// try that first.
image_base = alloc_preferred_address(alloc_size);
+ efi_debug("image_base=%p\n", (void *)image_base);
if (image_base == ULONG_MAX) {
unsigned long min_kimg_align = efi_get_kimg_min_align();
u32 seed = U32_MAX;
@@ -124,9 +127,11 @@ efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab)
efi_err("Failed to allocate memory\n");
goto free_cmdline;
}
+ efi_debug("2:image_base=%p\n", (void *)image_base);
}
// Decompress the payload into the newly allocated buffer.
+ efi_debug("_gzdata_start=%p\n", _gzdata_start);
ret = __decompress(_gzdata_start, compressed_size, NULL, NULL,
(void *)image_base, alloc_size, NULL, error);
if (ret < 0) {
diff --git a/init/main.c b/init/main.c
index 5dcf5274c09c..768537a5efcf 100644
--- a/init/main.c
+++ b/init/main.c
@@ -109,6 +109,8 @@
#include <asm/sections.h>
#include <asm/cacheflush.h>
+#include <uartout.h>
+
#define CREATE_TRACE_POINTS
#include <trace/events/initcall.h>
@@ -750,6 +752,9 @@ static int __init do_early_param(char *param, char *val,
(strcmp(param, "console") == 0 &&
strcmp(p->str, "earlycon") == 0)
) {
+ loong_uart_puts("will_do_early_param: ");
+ loong_uart_puts(param);
+ loong_uart_puts("\n");
if (p->setup_func(val) != 0)
pr_warn("Malformed early option '%s'\n", param);
}
@@ -884,6 +889,8 @@ void start_kernel(void)
char *command_line;
char *after_dashes;
+ loong_uart_puts("start_kernel!!\n");
+
set_task_stack_end_magic(&init_task);
smp_setup_processor_id();
debug_objects_early_init();
@@ -902,14 +909,22 @@ void start_kernel(void)
page_address_init();
pr_notice("%s", linux_banner);
early_security_init();
+ loong_uart_puts("will_setup_arch!!\n");
setup_arch(&command_line);
+ loong_uart_puts("will_setup_boot_config!!\n");
setup_boot_config();
+ loong_uart_puts("will_setup_command_line!!\n");
setup_command_line(command_line);
+ loong_uart_puts("will_setup_nr_cpu_ids!!\n");
setup_nr_cpu_ids();
+ loong_uart_puts("will_setup_per_cpu_areas!!\n");
setup_per_cpu_areas();
+ loong_uart_puts("will_prepare_boot_cpu!!\n");
smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */
+ loong_uart_puts("will_boot_cpu_hp_init!!\n");
boot_cpu_hotplug_init();
+ loong_uart_puts("will_print_cmdline!!\n");
pr_notice("Kernel command line: %s\n", saved_command_line);
/* parameters may set static keys */
jump_label_init();
--
2.39.2
From a180fda61f5034b9b938fb8559c2c50337511cac Mon Sep 17 00:00:00 2001
From: Huacai Chen <chenhuacai@loongson.cn>
Date: Tue, 23 Jul 2024 14:45:08 +0800
Subject: [PATCH 8/9] irqchip/loongarch-cpu: Fix return value of
lpic_gsi_to_irq()
lpic_gsi_to_irq() should return a valid irq if acpi_register_gsi()
succeed, and return 0 otherwise. But now lpic_gsi_to_irq() converts
a negative return value of acpi_register_gsi() to a positive value
silently, so fix it.
Reported-by: Miao Wang <shankerwangmiao@gmail.com>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
---
drivers/irqchip/irq-loongarch-cpu.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/irqchip/irq-loongarch-cpu.c b/drivers/irqchip/irq-loongarch-cpu.c
index 9d8f2c406043..b35903a06902 100644
--- a/drivers/irqchip/irq-loongarch-cpu.c
+++ b/drivers/irqchip/irq-loongarch-cpu.c
@@ -18,11 +18,13 @@ struct fwnode_handle *cpuintc_handle;
static u32 lpic_gsi_to_irq(u32 gsi)
{
+ int irq = 0;
+
/* Only pch irqdomain transferring is required for LoongArch. */
if (gsi >= GSI_MIN_PCH_IRQ && gsi <= GSI_MAX_PCH_IRQ)
- return acpi_register_gsi(NULL, gsi, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_HIGH);
+ irq = acpi_register_gsi(NULL, gsi, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_HIGH);
- return 0;
+ return (irq > 0) ? irq : 0;
}
static struct fwnode_handle *lpic_get_gsi_domain_id(u32 gsi)
--
2.39.2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment