LoongArch: Adjust boot & setup for 32BIT/64BIT

Adjust boot & setup for both 32BIT and 64BIT, including: efi header
definition, MAX_IO_PICS definition, kernel entry and environment setup
routines, etc.

Add a fallback path in fdt_cpu_clk_init() to avoid 0MHz in /proc/cpuinfo
if there is no valid clock freq from firmware.

Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
This commit is contained in:
Huacai Chen 2025-12-08 18:09:17 +08:00
parent 708ed32c84
commit 7b2afeafaf
8 changed files with 43 additions and 27 deletions

View file

@ -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.

View file

@ -12,7 +12,7 @@
#define dmi_early_unmap(x, l) dmi_unmap(x)
#define dmi_alloc(l) memblock_alloc(l, PAGE_SIZE)
static inline void *dmi_remap(u64 phys_addr, unsigned long size)
static inline void *dmi_remap(phys_addr_t phys_addr, unsigned long size)
{
return ((void *)TO_CACHE(phys_addr));
}

View file

@ -60,7 +60,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 {

View file

@ -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 */

View file

@ -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;

View file

@ -72,9 +72,12 @@ static int __init fdt_cpu_clk_init(void)
clk = of_clk_get(np, 0);
of_node_put(np);
cpu_clock_freq = 200 * 1000 * 1000;
if (IS_ERR(clk))
if (IS_ERR(clk)) {
pr_warn("No valid CPU clock freq, assume 200MHz.\n");
return -ENODEV;
}
cpu_clock_freq = clk_get_rate(clk);
clk_put(clk);

View file

@ -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 */

View file

@ -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
}
}