Adjust boot & setup for both 32BIT and 64BIT, including: efi header
definition, MAX_IO_PICS definition, kernel entry and environment setup
routines, etc.
Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
---
arch/loongarch/include/asm/addrspace.h | 2 +-
arch/loongarch/include/asm/irq.h | 5 ++++
arch/loongarch/kernel/efi-header.S | 4 +++
arch/loongarch/kernel/efi.c | 4 ++-
arch/loongarch/kernel/env.c | 9 ++++--
arch/loongarch/kernel/head.S | 39 +++++++++++---------------
arch/loongarch/kernel/relocate.c | 9 +++++-
7 files changed, 45 insertions(+), 27 deletions(-)
diff --git a/arch/loongarch/include/asm/addrspace.h b/arch/loongarch/include/asm/addrspace.h
index e739dbc6329d..9766a100504a 100644
--- a/arch/loongarch/include/asm/addrspace.h
+++ b/arch/loongarch/include/asm/addrspace.h
@@ -42,7 +42,7 @@ extern unsigned long vm_map_base;
#endif
#define DMW_PABITS 48
-#define TO_PHYS_MASK ((1ULL << DMW_PABITS) - 1)
+#define TO_PHYS_MASK ((_ULL(1) << _ULL(DMW_PABITS)) - 1)
/*
* Memory above this physical address will be considered highmem.
diff --git a/arch/loongarch/include/asm/irq.h b/arch/loongarch/include/asm/irq.h
index 12bd15578c33..cf6c82a9117b 100644
--- a/arch/loongarch/include/asm/irq.h
+++ b/arch/loongarch/include/asm/irq.h
@@ -53,7 +53,12 @@ void spurious_interrupt(void);
#define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace
void arch_trigger_cpumask_backtrace(const struct cpumask *mask, int exclude_cpu);
+#ifdef CONFIG_32BIT
+#define MAX_IO_PICS 1
+#else
#define MAX_IO_PICS 8
+#endif
+
#define NR_IRQS (64 + NR_VECTORS * (NR_CPUS + MAX_IO_PICS))
struct acpi_vector_group {
diff --git a/arch/loongarch/kernel/efi-header.S b/arch/loongarch/kernel/efi-header.S
index ba0bdbf86aa8..6df56241cb95 100644
--- a/arch/loongarch/kernel/efi-header.S
+++ b/arch/loongarch/kernel/efi-header.S
@@ -9,7 +9,11 @@
.macro __EFI_PE_HEADER
.long IMAGE_NT_SIGNATURE
.Lcoff_header:
+#ifdef CONFIG_32BIT
+ .short IMAGE_FILE_MACHINE_LOONGARCH32 /* Machine */
+#else
.short IMAGE_FILE_MACHINE_LOONGARCH64 /* Machine */
+#endif
.short .Lsection_count /* NumberOfSections */
.long 0 /* TimeDateStamp */
.long 0 /* PointerToSymbolTable */
diff --git a/arch/loongarch/kernel/efi.c b/arch/loongarch/kernel/efi.c
index 860a3bc030e0..52c21c895318 100644
--- a/arch/loongarch/kernel/efi.c
+++ b/arch/loongarch/kernel/efi.c
@@ -115,7 +115,9 @@ void __init efi_init(void)
efi_systab_report_header(&efi_systab->hdr, efi_systab->fw_vendor);
- set_bit(EFI_64BIT, &efi.flags);
+ if (IS_ENABLED(CONFIG_64BIT))
+ set_bit(EFI_64BIT, &efi.flags);
+
efi_nr_tables = efi_systab->nr_tables;
efi_config_table = (unsigned long)efi_systab->tables;
diff --git a/arch/loongarch/kernel/env.c b/arch/loongarch/kernel/env.c
index 23bd5ae2212c..3e8a25eb901b 100644
--- a/arch/loongarch/kernel/env.c
+++ b/arch/loongarch/kernel/env.c
@@ -68,18 +68,23 @@ static int __init fdt_cpu_clk_init(void)
np = of_get_cpu_node(0, NULL);
if (!np)
- return -ENODEV;
+ goto fallback;
clk = of_clk_get(np, 0);
of_node_put(np);
if (IS_ERR(clk))
- return -ENODEV;
+ goto fallback;
cpu_clock_freq = clk_get_rate(clk);
clk_put(clk);
return 0;
+
+fallback:
+ cpu_clock_freq = 200 * 1000 * 1000;
+
+ return -ENODEV;
}
late_initcall(fdt_cpu_clk_init);
diff --git a/arch/loongarch/kernel/head.S b/arch/loongarch/kernel/head.S
index e3865e92a917..aba548db2446 100644
--- a/arch/loongarch/kernel/head.S
+++ b/arch/loongarch/kernel/head.S
@@ -43,36 +43,29 @@ SYM_DATA(kernel_fsize, .long _kernel_fsize);
SYM_CODE_START(kernel_entry) # kernel entry point
- /* Config direct window and set PG */
- SETUP_DMWINS t0
+ SETUP_TWINS
+ SETUP_MODES t0
JUMP_VIRT_ADDR t0, t1
-
- /* Enable PG */
- li.w t0, 0xb0 # PLV=0, IE=0, PG=1
- csrwr t0, LOONGARCH_CSR_CRMD
- li.w t0, 0x04 # PLV=0, PIE=1, PWE=0
- csrwr t0, LOONGARCH_CSR_PRMD
- li.w t0, 0x00 # FPE=0, SXE=0, ASXE=0, BTE=0
- csrwr t0, LOONGARCH_CSR_EUEN
+ SETUP_DMWINS t0
la.pcrel t0, __bss_start # clear .bss
- st.d zero, t0, 0
+ LONG_S zero, t0, 0
la.pcrel t1, __bss_stop - LONGSIZE
1:
- addi.d t0, t0, LONGSIZE
- st.d zero, t0, 0
+ PTR_ADDI t0, t0, LONGSIZE
+ LONG_S zero, t0, 0
bne t0, t1, 1b
la.pcrel t0, fw_arg0
- st.d a0, t0, 0 # firmware arguments
+ PTR_S a0, t0, 0 # firmware arguments
la.pcrel t0, fw_arg1
- st.d a1, t0, 0
+ PTR_S a1, t0, 0
la.pcrel t0, fw_arg2
- st.d a2, t0, 0
+ PTR_S a2, t0, 0
#ifdef CONFIG_PAGE_SIZE_4KB
- li.d t0, 0
- li.d t1, CSR_STFILL
+ LONG_LI t0, 0
+ LONG_LI t1, CSR_STFILL
csrxchg t0, t1, LOONGARCH_CSR_IMPCTL1
#endif
/* KSave3 used for percpu base, initialized as 0 */
@@ -98,7 +91,7 @@ SYM_CODE_START(kernel_entry) # kernel entry point
/* Jump to the new kernel: new_pc = current_pc + random_offset */
pcaddi t0, 0
- add.d t0, t0, a0
+ PTR_ADD t0, t0, a0
jirl zero, t0, 0xc
#endif /* CONFIG_RANDOMIZE_BASE */
@@ -121,12 +114,14 @@ SYM_CODE_END(kernel_entry)
*/
SYM_CODE_START(smpboot_entry)
- SETUP_DMWINS t0
+ SETUP_TWINS
+ SETUP_MODES t0
JUMP_VIRT_ADDR t0, t1
+ SETUP_DMWINS t0
#ifdef CONFIG_PAGE_SIZE_4KB
- li.d t0, 0
- li.d t1, CSR_STFILL
+ LONG_LI t0, 0
+ LONG_LI t1, CSR_STFILL
csrxchg t0, t1, LOONGARCH_CSR_IMPCTL1
#endif
/* Enable PG */
diff --git a/arch/loongarch/kernel/relocate.c b/arch/loongarch/kernel/relocate.c
index b5e2312a2fca..c28ba45d80d6 100644
--- a/arch/loongarch/kernel/relocate.c
+++ b/arch/loongarch/kernel/relocate.c
@@ -68,18 +68,25 @@ static inline void __init relocate_absolute(long random_offset)
for (p = begin; (void *)p < end; p++) {
long v = p->symvalue;
- uint32_t lu12iw, ori, lu32id, lu52id;
+ uint32_t lu12iw, ori;
+#ifdef CONFIG_64BIT
+ uint32_t lu32id, lu52id;
+#endif
union loongarch_instruction *insn = (void *)p->pc;
lu12iw = (v >> 12) & 0xfffff;
ori = v & 0xfff;
+#ifdef CONFIG_64BIT
lu32id = (v >> 32) & 0xfffff;
lu52id = v >> 52;
+#endif
insn[0].reg1i20_format.immediate = lu12iw;
insn[1].reg2i12_format.immediate = ori;
+#ifdef CONFIG_64BIT
insn[2].reg1i20_format.immediate = lu32id;
insn[3].reg2i12_format.immediate = lu52id;
+#endif
}
}
--
2.47.3
On Tue, Nov 18, 2025 at 07:27:18PM +0800, Huacai Chen wrote: > Adjust boot & setup for both 32BIT and 64BIT, including: efi header > definition, MAX_IO_PICS definition, kernel entry and environment setup > routines, etc. > > Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com> > Signed-off-by: Huacai Chen <chenhuacai@loongson.cn> > --- > arch/loongarch/include/asm/addrspace.h | 2 +- > arch/loongarch/include/asm/irq.h | 5 ++++ > arch/loongarch/kernel/efi-header.S | 4 +++ > arch/loongarch/kernel/efi.c | 4 ++- > arch/loongarch/kernel/env.c | 9 ++++-- > arch/loongarch/kernel/head.S | 39 +++++++++++--------------- > arch/loongarch/kernel/relocate.c | 9 +++++- > 7 files changed, 45 insertions(+), 27 deletions(-) > ... > diff --git a/arch/loongarch/kernel/env.c b/arch/loongarch/kernel/env.c > index 23bd5ae2212c..3e8a25eb901b 100644 > --- a/arch/loongarch/kernel/env.c > +++ b/arch/loongarch/kernel/env.c > @@ -68,18 +68,23 @@ static int __init fdt_cpu_clk_init(void) > > np = of_get_cpu_node(0, NULL); > if (!np) > - return -ENODEV; > + goto fallback; > > clk = of_clk_get(np, 0); > of_node_put(np); > > if (IS_ERR(clk)) > - return -ENODEV; > + goto fallback; > > cpu_clock_freq = clk_get_rate(clk); > clk_put(clk); > > return 0; > + > +fallback: > + cpu_clock_freq = 200 * 1000 * 1000; Why pick 200MHz here? And shouldn't the clock being always provided in devicetree if it's necessary for kernel to function? Per the schema for LoongArch CPUs (loongarch/cpus.yaml), "clocks" property is also described as mandantory, thus I don't think such fallback makes sense. > + > + return -ENODEV; > } > late_initcall(fdt_cpu_clk_init); Best regards, Yao Zi
On Wed, Nov 19, 2025 at 1:09 AM Yao Zi <ziyao@disroot.org> wrote: > > On Tue, Nov 18, 2025 at 07:27:18PM +0800, Huacai Chen wrote: > > Adjust boot & setup for both 32BIT and 64BIT, including: efi header > > definition, MAX_IO_PICS definition, kernel entry and environment setup > > routines, etc. > > > > Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com> > > Signed-off-by: Huacai Chen <chenhuacai@loongson.cn> > > --- > > arch/loongarch/include/asm/addrspace.h | 2 +- > > arch/loongarch/include/asm/irq.h | 5 ++++ > > arch/loongarch/kernel/efi-header.S | 4 +++ > > arch/loongarch/kernel/efi.c | 4 ++- > > arch/loongarch/kernel/env.c | 9 ++++-- > > arch/loongarch/kernel/head.S | 39 +++++++++++--------------- > > arch/loongarch/kernel/relocate.c | 9 +++++- > > 7 files changed, 45 insertions(+), 27 deletions(-) > > > > ... > > > diff --git a/arch/loongarch/kernel/env.c b/arch/loongarch/kernel/env.c > > index 23bd5ae2212c..3e8a25eb901b 100644 > > --- a/arch/loongarch/kernel/env.c > > +++ b/arch/loongarch/kernel/env.c > > @@ -68,18 +68,23 @@ static int __init fdt_cpu_clk_init(void) > > > > np = of_get_cpu_node(0, NULL); > > if (!np) > > - return -ENODEV; > > + goto fallback; > > > > clk = of_clk_get(np, 0); > > of_node_put(np); > > > > if (IS_ERR(clk)) > > - return -ENODEV; > > + goto fallback; > > > > cpu_clock_freq = clk_get_rate(clk); > > clk_put(clk); > > > > return 0; > > + > > +fallback: > > + cpu_clock_freq = 200 * 1000 * 1000; > > Why pick 200MHz here? And shouldn't the clock being always provided in > devicetree if it's necessary for kernel to function? > > Per the schema for LoongArch CPUs (loongarch/cpus.yaml), "clocks" > property is also described as mandantory, thus I don't think such > fallback makes sense. Yes, "clocks" is mandatory in theory, but sometimes is missing in practice, at least in QEMU. On the other hand, if "clocks" really always exist, then the error checking in fdt_cpu_clk_init() can also be removed. So the fallback makes sense. Why pick 200MHz? That is because we assume the constant timer is 100MHz (which is true for all real machines), 200MHz is the minimal multiple of 100MHz, it is more reasonable than 0MHz. Huacai > > > + > > + return -ENODEV; > > } > > late_initcall(fdt_cpu_clk_init); > > Best regards, > Yao Zi >
© 2016 - 2025 Red Hat, Inc.