Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ec0f8d3f authored by Huacai Chen's avatar Huacai Chen Committed by Ralf Baechle
Browse files

MIPS: Loongson: Allow booting from any core



By offering Logical->Physical core id mapping, so as to reserve some
physical cores via mask. This allow booting from any core when core-0
has problems. Since the maximun cores supported by Loongson-3 is 16,
32-bit cpu_startup_core_id can be split to 16-bit cpu_startup_core_id
and 16-bit reserved_cores_mask for compatibility.

Signed-off-by: default avatarHuacai Chen <chenhc@lemote.com>
Cc: John Crispin <john@phrozen.org>
Cc: Steven J. Hill <Steven.Hill@imgtec.com>
Cc: linux-mips@linux-mips.org
Cc: Fuxin Zhang <zhangfx@lemote.com>
Cc: Zhangjin Wu <wuzhangjin@gmail.com>
Patchwork: https://patchwork.linux-mips.org/patch/8323/


Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent f490682a
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -42,7 +42,8 @@ struct efi_cpuinfo_loongson {
	u32 processor_id; /* PRID, e.g. 6305, 6306 */
	u32 cputype;  /* Loongson_3A/3B, etc. */
	u32 total_node;   /* num of total numa nodes */
	u32 cpu_startup_core_id; /* Core id */
	u16 cpu_startup_core_id; /* Boot core id */
	u16 reserved_cores_mask;
	u32 cpu_clock_freq; /* cpu_clock */
	u32 nr_cpus;
} __packed;
@@ -149,6 +150,8 @@ struct loongson_system_configuration {
	u32 nr_nodes;
	int cores_per_node;
	int cores_per_package;
	u16 boot_cpu_id;
	u16 reserved_cpus_mask;
	enum loongson_cpu_type cputype;
	u64 ht_control_base;
	u64 pci_mem_start_addr;
+1 −2
Original line number Diff line number Diff line
@@ -32,8 +32,7 @@
#define LOONGSON_INT_ROUTER_LPC		LOONGSON_INT_ROUTER_ENTRY(0x0a)
#define LOONGSON_INT_ROUTER_HT1(n)	LOONGSON_INT_ROUTER_ENTRY(n + 0x18)

#define LOONGSON_INT_CORE0_INT0		0x11 /* route to int 0 of core 0 */
#define LOONGSON_INT_CORE0_INT1		0x21 /* route to int 1 of core 0 */
#define LOONGSON_INT_COREx_INTy(x, y)	(1<<(x) | 1<<(y+4))	/* route to int y of core x */

#endif

+1 −1
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@

#ifdef CONFIG_NUMA

#define cpu_to_node(cpu)	((cpu) >> 2)
#define cpu_to_node(cpu)	(cpu_logical_map(cpu) >> 2)
#define parent_node(node)	(node)
#define cpumask_of_node(node)	(&__node_data[(node)]->cpumask)

+2 −0
Original line number Diff line number Diff line
@@ -119,6 +119,8 @@ void __init prom_init_env(void)
	}

	loongson_sysconf.nr_cpus = ecpu->nr_cpus;
	loongson_sysconf.boot_cpu_id = ecpu->cpu_startup_core_id;
	loongson_sysconf.reserved_cpus_mask = ecpu->reserved_cores_mask;
	if (ecpu->nr_cpus > NR_CPUS || ecpu->nr_cpus == 0)
		loongson_sysconf.nr_cpus = NR_CPUS;
	loongson_sysconf.nr_nodes = (loongson_sysconf.nr_cpus +
+8 −6
Original line number Diff line number Diff line
@@ -55,8 +55,8 @@ static inline void mask_loongson_irq(struct irq_data *d)
	/* Workaround: UART IRQ may deliver to any core */
	if (d->irq == LOONGSON_UART_IRQ) {
		int cpu = smp_processor_id();
		int node_id = cpu / loongson_sysconf.cores_per_node;
		int core_id = cpu % loongson_sysconf.cores_per_node;
		int node_id = cpu_logical_map(cpu) / loongson_sysconf.cores_per_node;
		int core_id = cpu_logical_map(cpu) % loongson_sysconf.cores_per_node;
		u64 intenclr_addr = smp_group[node_id] |
			(u64)(&LOONGSON_INT_ROUTER_INTENCLR);
		u64 introuter_lpc_addr = smp_group[node_id] |
@@ -72,8 +72,8 @@ static inline void unmask_loongson_irq(struct irq_data *d)
	/* Workaround: UART IRQ may deliver to any core */
	if (d->irq == LOONGSON_UART_IRQ) {
		int cpu = smp_processor_id();
		int node_id = cpu / loongson_sysconf.cores_per_node;
		int core_id = cpu % loongson_sysconf.cores_per_node;
		int node_id = cpu_logical_map(cpu) / loongson_sysconf.cores_per_node;
		int core_id = cpu_logical_map(cpu) % loongson_sysconf.cores_per_node;
		u64 intenset_addr = smp_group[node_id] |
			(u64)(&LOONGSON_INT_ROUTER_INTENSET);
		u64 introuter_lpc_addr = smp_group[node_id] |
@@ -102,10 +102,12 @@ void irq_router_init(void)
	int i;

	/* route LPC int to cpu core0 int 0 */
	LOONGSON_INT_ROUTER_LPC = LOONGSON_INT_CORE0_INT0;
	LOONGSON_INT_ROUTER_LPC =
		LOONGSON_INT_COREx_INTy(loongson_sysconf.boot_cpu_id, 0);
	/* route HT1 int0 ~ int7 to cpu core0 INT1*/
	for (i = 0; i < 8; i++)
		LOONGSON_INT_ROUTER_HT1(i) = LOONGSON_INT_CORE0_INT1;
		LOONGSON_INT_ROUTER_HT1(i) =
			LOONGSON_INT_COREx_INTy(loongson_sysconf.boot_cpu_id, 1);
	/* enable HT1 interrupt */
	LOONGSON_HT1_INTN_EN(0) = 0xffffffff;
	/* enable router interrupt intenset */
Loading