Skip to content

Commit 88d4d95

Browse files
AaronDotchenhuacai
authored andcommitted
LoongArch: Add FDT booting support from efi system table
Since commit 40cd01a("efi/loongarch: libstub: remove dependency on flattened DT"), we can parse the FDT from efi system table. And now, LoongArch is coming to support booting with FDT, so we add the relevant booting support as well as parameter parsing. Signed-off-by: Binbin Zhou <[email protected]> Signed-off-by: Huacai Chen <[email protected]>
1 parent a275a82 commit 88d4d95

File tree

10 files changed

+145
-7
lines changed

10 files changed

+145
-7
lines changed

arch/loongarch/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ config LOONGARCH
111111
select MODULES_USE_ELF_RELA if MODULES
112112
select NEED_PER_CPU_EMBED_FIRST_CHUNK
113113
select NEED_PER_CPU_PAGE_FIRST_CHUNK
114+
select OF
115+
select OF_EARLY_FLATTREE
114116
select PCI
115117
select PCI_DOMAINS_GENERIC
116118
select PCI_ECAM if ACPI

arch/loongarch/include/asm/efi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
void __init efi_init(void);
1111
void __init efi_runtime_init(void);
12+
void __init *efi_fdt_pointer(void);
1213
void efifb_setup_from_dmi(struct screen_info *si, const char *opt);
1314

1415
#define ARCH_EFI_IRQ_FLAGS_MASK 0x00000004 /* Bit 2: CSR.CRMD.IE */

arch/loongarch/include/asm/setup.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
extern unsigned long eentry;
1515
extern unsigned long tlbrentry;
16+
extern char init_command_line[COMMAND_LINE_SIZE];
1617
extern void tlb_init(int cpu);
1718
extern void cpu_cache_init(void);
1819
extern void cache_error_setup(void);

arch/loongarch/kernel/acpi.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <linux/irq.h>
1313
#include <linux/irqdomain.h>
1414
#include <linux/memblock.h>
15+
#include <linux/of_fdt.h>
1516
#include <linux/serial_core.h>
1617
#include <asm/io.h>
1718
#include <asm/numa.h>
@@ -145,14 +146,14 @@ void __init acpi_boot_table_init(void)
145146
* If acpi_disabled, bail out
146147
*/
147148
if (acpi_disabled)
148-
return;
149+
goto fdt_earlycon;
149150

150151
/*
151152
* Initialize the ACPI boot-time table parser.
152153
*/
153154
if (acpi_table_init()) {
154155
disable_acpi();
155-
return;
156+
goto fdt_earlycon;
156157
}
157158

158159
loongson_sysconf.boot_cpu_id = read_csr_cpuid();
@@ -164,6 +165,12 @@ void __init acpi_boot_table_init(void)
164165

165166
/* Do not enable ACPI SPCR console by default */
166167
acpi_parse_spcr(earlycon_acpi_spcr_enable, false);
168+
169+
return;
170+
171+
fdt_earlycon:
172+
if (earlycon_acpi_spcr_enable)
173+
early_init_dt_scan_chosen_stdout();
167174
}
168175

169176
#ifdef CONFIG_ACPI_NUMA

arch/loongarch/kernel/efi.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,29 @@ static unsigned long efi_nr_tables;
2828
static unsigned long efi_config_table;
2929

3030
static unsigned long __initdata boot_memmap = EFI_INVALID_TABLE_ADDR;
31+
static unsigned long __initdata fdt_pointer = EFI_INVALID_TABLE_ADDR;
3132

3233
static efi_system_table_t *efi_systab;
3334
static efi_config_table_type_t arch_tables[] __initdata = {
3435
{LINUX_EFI_BOOT_MEMMAP_GUID, &boot_memmap, "MEMMAP" },
36+
{DEVICE_TREE_GUID, &fdt_pointer, "FDTPTR" },
3537
{},
3638
};
3739

40+
void __init *efi_fdt_pointer(void)
41+
{
42+
if (!efi_systab)
43+
return NULL;
44+
45+
if (fdt_pointer == EFI_INVALID_TABLE_ADDR)
46+
return NULL;
47+
48+
return early_memremap_ro(fdt_pointer, SZ_64K);
49+
}
50+
3851
void __init efi_runtime_init(void)
3952
{
40-
if (!efi_enabled(EFI_BOOT))
53+
if (!efi_enabled(EFI_BOOT) || !efi_systab->runtime)
4154
return;
4255

4356
if (efi_runtime_disabled()) {

arch/loongarch/kernel/env.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <asm/early_ioremap.h>
1212
#include <asm/bootinfo.h>
1313
#include <asm/loongson.h>
14+
#include <asm/setup.h>
1415

1516
u64 efi_system_table;
1617
struct loongson_system_configuration loongson_sysconf;
@@ -27,6 +28,7 @@ void __init init_environ(void)
2728
clear_bit(EFI_BOOT, &efi.flags);
2829

2930
strscpy(boot_command_line, cmdline, COMMAND_LINE_SIZE);
31+
strscpy(init_command_line, cmdline, COMMAND_LINE_SIZE);
3032
early_memunmap(cmdline, COMMAND_LINE_SIZE);
3133

3234
efi_system_table = fw_arg2;

arch/loongarch/kernel/numa.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,21 @@ static void __init numa_default_distance(void)
388388
}
389389
}
390390

391+
/*
392+
* fake_numa_init() - For Non-ACPI systems
393+
* Return: 0 on success, -errno on failure.
394+
*/
395+
static int __init fake_numa_init(void)
396+
{
397+
phys_addr_t start = memblock_start_of_DRAM();
398+
phys_addr_t end = memblock_end_of_DRAM() - 1;
399+
400+
node_set(0, numa_nodes_parsed);
401+
pr_info("Faking a node at [mem %pap-%pap]\n", &start, &end);
402+
403+
return numa_add_memblk(0, start, end + 1);
404+
}
405+
391406
int __init init_numa_memory(void)
392407
{
393408
int i;
@@ -404,7 +419,7 @@ int __init init_numa_memory(void)
404419
memset(&numa_meminfo, 0, sizeof(numa_meminfo));
405420

406421
/* Parse SRAT and SLIT if provided by firmware. */
407-
ret = acpi_numa_init();
422+
ret = acpi_disabled ? fake_numa_init() : acpi_numa_init();
408423
if (ret < 0)
409424
return ret;
410425

arch/loongarch/kernel/setup.c

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
#include <linux/sizes.h>
2929
#include <linux/device.h>
3030
#include <linux/dma-map-ops.h>
31+
#include <linux/libfdt.h>
32+
#include <linux/of_fdt.h>
33+
#include <linux/of_address.h>
3134
#include <linux/swiotlb.h>
3235

3336
#include <asm/addrspace.h>
@@ -69,6 +72,7 @@ static const char dmi_empty_string[] = " ";
6972
*
7073
* These are initialized so they are in the .data section
7174
*/
75+
char init_command_line[COMMAND_LINE_SIZE] __initdata;
7276

7377
static int num_standard_resources;
7478
static struct resource *standard_resources;
@@ -253,6 +257,58 @@ static void __init arch_parse_crashkernel(void)
253257
#endif
254258
}
255259

260+
static void __init fdt_setup(void)
261+
{
262+
#ifdef CONFIG_OF_EARLY_FLATTREE
263+
void *fdt_pointer;
264+
265+
/* ACPI-based systems do not require parsing fdt */
266+
if (acpi_os_get_root_pointer())
267+
return;
268+
269+
/* Look for a device tree configuration table entry */
270+
fdt_pointer = efi_fdt_pointer();
271+
if (!fdt_pointer || fdt_check_header(fdt_pointer))
272+
return;
273+
274+
early_init_dt_scan(fdt_pointer);
275+
early_init_fdt_reserve_self();
276+
277+
max_low_pfn = PFN_PHYS(memblock_end_of_DRAM());
278+
#endif
279+
}
280+
281+
static void __init bootcmdline_init(char **cmdline_p)
282+
{
283+
/*
284+
* If CONFIG_CMDLINE_FORCE is enabled then initializing the command line
285+
* is trivial - we simply use the built-in command line unconditionally &
286+
* unmodified.
287+
*/
288+
if (IS_ENABLED(CONFIG_CMDLINE_FORCE)) {
289+
strscpy(boot_command_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
290+
goto out;
291+
}
292+
293+
#ifdef CONFIG_OF_FLATTREE
294+
/*
295+
* If CONFIG_CMDLINE_BOOTLOADER is enabled and we are in FDT-based system,
296+
* the boot_command_line will be overwritten by early_init_dt_scan_chosen().
297+
* So we need to append init_command_line (the original copy of boot_command_line)
298+
* to boot_command_line.
299+
*/
300+
if (initial_boot_params) {
301+
if (boot_command_line[0])
302+
strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
303+
304+
strlcat(boot_command_line, init_command_line, COMMAND_LINE_SIZE);
305+
}
306+
#endif
307+
308+
out:
309+
*cmdline_p = boot_command_line;
310+
}
311+
256312
void __init platform_init(void)
257313
{
258314
arch_reserve_vmcore();
@@ -265,6 +321,7 @@ void __init platform_init(void)
265321
acpi_gbl_use_default_register_widths = false;
266322
acpi_boot_table_init();
267323
#endif
324+
unflatten_and_copy_device_tree();
268325

269326
#ifdef CONFIG_NUMA
270327
init_numa_memory();
@@ -297,6 +354,8 @@ static void __init arch_mem_init(char **cmdline_p)
297354

298355
check_kernel_sections_mem();
299356

357+
early_init_fdt_scan_reserved_mem();
358+
300359
/*
301360
* In order to reduce the possibility of kernel panic when failed to
302361
* get IO TLB memory under CONFIG_SWIOTLB, it is better to allocate
@@ -422,12 +481,13 @@ static void __init prefill_possible_map(void)
422481
void __init setup_arch(char **cmdline_p)
423482
{
424483
cpu_probe();
425-
*cmdline_p = boot_command_line;
426484

427485
init_environ();
428486
efi_init();
487+
fdt_setup();
429488
memblock_init();
430489
pagetable_init();
490+
bootcmdline_init(cmdline_p);
431491
parse_early_param();
432492
reserve_initrd_mem();
433493

arch/loongarch/kernel/smp.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,42 @@ irqreturn_t loongson_ipi_interrupt(int irq, void *dev)
180180
return IRQ_HANDLED;
181181
}
182182

183+
static void __init fdt_smp_setup(void)
184+
{
185+
#ifdef CONFIG_OF
186+
unsigned int cpu, cpuid;
187+
struct device_node *node = NULL;
188+
189+
for_each_of_cpu_node(node) {
190+
if (!of_device_is_available(node))
191+
continue;
192+
193+
cpuid = of_get_cpu_hwid(node, 0);
194+
if (cpuid >= nr_cpu_ids)
195+
continue;
196+
197+
if (cpuid == loongson_sysconf.boot_cpu_id) {
198+
cpu = 0;
199+
numa_add_cpu(cpu);
200+
} else {
201+
cpu = cpumask_next_zero(-1, cpu_present_mask);
202+
}
203+
204+
num_processors++;
205+
set_cpu_possible(cpu, true);
206+
set_cpu_present(cpu, true);
207+
__cpu_number_map[cpuid] = cpu;
208+
__cpu_logical_map[cpu] = cpuid;
209+
}
210+
211+
loongson_sysconf.nr_cpus = num_processors;
212+
#endif
213+
}
214+
183215
void __init loongson_smp_setup(void)
184216
{
217+
fdt_smp_setup();
218+
185219
cpu_data[0].core = cpu_logical_map(0) % loongson_sysconf.cores_per_package;
186220
cpu_data[0].package = cpu_logical_map(0) / loongson_sysconf.cores_per_package;
187221

arch/loongarch/pci/acpi.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,12 @@ void pcibios_add_bus(struct pci_bus *bus)
2626

2727
int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
2828
{
29-
struct pci_config_window *cfg = bridge->bus->sysdata;
30-
struct acpi_device *adev = to_acpi_device(cfg->parent);
29+
struct acpi_device *adev = NULL;
3130
struct device *bus_dev = &bridge->bus->dev;
31+
struct pci_config_window *cfg = bridge->bus->sysdata;
32+
33+
if (!acpi_disabled)
34+
adev = to_acpi_device(cfg->parent);
3235

3336
ACPI_COMPANION_SET(&bridge->dev, adev);
3437
set_dev_node(bus_dev, pa_to_nid(cfg->res.start));

0 commit comments

Comments
 (0)