Skip to content

Commit c461731

Browse files
chenhuacairalfbaechle
authored andcommitted
MIPS: Add NUMA support for Loongson-3
Multiple Loongson-3A chips can be interconnected with HT0-bus. This is a CC-NUMA system that every chip (node) has its own local memory and cache coherency is maintained by hardware. The 64-bit physical memory address format is as follows: 0x-0000-YZZZ-ZZZZ-ZZZZ The high 16 bits should be 0, which means the real physical address supported by Loongson-3 is 48-bit. The "Y" bits is the base address of each node, which can be also considered as the node-id. The "Z" bits is the address offset within a node, which means every node has a 44 bits address space. Macros XPHYSADDR and MAX_PHYSMEM_BITS are modified unconditionally, because many other MIPS CPUs have also extended their address spaces. Signed-off-by: Huacai Chen <[email protected]> Cc: John Crispin <[email protected]> Cc: Steven J. Hill <[email protected]> Cc: Aurelien Jarno <[email protected]> Cc: [email protected] Cc: Fuxin Zhang <[email protected]> Cc: Zhangjin Wu <[email protected]> Patchwork: https://patchwork.linux-mips.org/patch/7187/ Signed-off-by: Ralf Baechle <[email protected]>
1 parent 140e39c commit c461731

File tree

13 files changed

+445
-5
lines changed

13 files changed

+445
-5
lines changed

arch/mips/include/asm/addrspace.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
*/
5353
#define CPHYSADDR(a) ((_ACAST32_(a)) & 0x1fffffff)
5454
#define XPHYSADDR(a) ((_ACAST64_(a)) & \
55-
_CONST64_(0x000000ffffffffff))
55+
_CONST64_(0x0000ffffffffffff))
5656

5757
#ifdef CONFIG_64BIT
5858

arch/mips/include/asm/mach-loongson/boot_param.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,9 @@ struct boot_params {
146146

147147
struct loongson_system_configuration {
148148
u32 nr_cpus;
149+
u32 nr_nodes;
150+
int cores_per_node;
151+
int cores_per_package;
149152
enum loongson_cpu_type cputype;
150153
u64 ht_control_base;
151154
u64 pci_mem_start_addr;
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* This file is subject to the terms and conditions of the GNU General Public
3+
* License. See the file "COPYING" in the main directory of this archive
4+
* for more details.
5+
*
6+
* Copyright (C) 2005 Embedded Alley Solutions, Inc
7+
* Copyright (C) 2005 Ralf Baechle ([email protected])
8+
* Copyright (C) 2009 Jiajie Chen ([email protected])
9+
* Copyright (C) 2012 Huacai Chen ([email protected])
10+
*/
11+
#ifndef __ASM_MACH_LOONGSON_KERNEL_ENTRY_H
12+
#define __ASM_MACH_LOONGSON_KERNEL_ENTRY_H
13+
14+
/*
15+
* Override macros used in arch/mips/kernel/head.S.
16+
*/
17+
.macro kernel_entry_setup
18+
#ifdef CONFIG_CPU_LOONGSON3
19+
.set push
20+
.set mips64
21+
/* Set LPA on LOONGSON3 config3 */
22+
mfc0 t0, $16, 3
23+
or t0, (0x1 << 7)
24+
mtc0 t0, $16, 3
25+
/* Set ELPA on LOONGSON3 pagegrain */
26+
li t0, (0x1 << 29)
27+
mtc0 t0, $5, 1
28+
_ehb
29+
.set pop
30+
#endif
31+
.endm
32+
33+
/*
34+
* Do SMP slave processor setup.
35+
*/
36+
.macro smp_slave_setup
37+
#ifdef CONFIG_CPU_LOONGSON3
38+
.set push
39+
.set mips64
40+
/* Set LPA on LOONGSON3 config3 */
41+
mfc0 t0, $16, 3
42+
or t0, (0x1 << 7)
43+
mtc0 t0, $16, 3
44+
/* Set ELPA on LOONGSON3 pagegrain */
45+
li t0, (0x1 << 29)
46+
mtc0 t0, $5, 1
47+
_ehb
48+
.set pop
49+
#endif
50+
.endm
51+
52+
#endif /* __ASM_MACH_LOONGSON_KERNEL_ENTRY_H */
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright (C) 2010 Loongson Inc. & Lemote Inc. &
3+
* Insititute of Computing Technology
4+
* Author: Xiang Gao, [email protected]
5+
* Huacai Chen, [email protected]
6+
* Xiaofu Meng, Shuangshuang Zhang
7+
*
8+
* This program is free software; you can redistribute it and/or modify it
9+
* under the terms of the GNU General Public License as published by the
10+
* Free Software Foundation; either version 2 of the License, or (at your
11+
* option) any later version.
12+
*/
13+
#ifndef _ASM_MACH_MMZONE_H
14+
#define _ASM_MACH_MMZONE_H
15+
16+
#include <boot_param.h>
17+
#define NODE_ADDRSPACE_SHIFT 44
18+
#define NODE0_ADDRSPACE_OFFSET 0x000000000000UL
19+
#define NODE1_ADDRSPACE_OFFSET 0x100000000000UL
20+
#define NODE2_ADDRSPACE_OFFSET 0x200000000000UL
21+
#define NODE3_ADDRSPACE_OFFSET 0x300000000000UL
22+
23+
#define pa_to_nid(addr) (((addr) & 0xf00000000000) >> NODE_ADDRSPACE_SHIFT)
24+
25+
#define LEVELS_PER_SLICE 128
26+
27+
struct slice_data {
28+
unsigned long irq_enable_mask[2];
29+
int level_to_irq[LEVELS_PER_SLICE];
30+
};
31+
32+
struct hub_data {
33+
cpumask_t h_cpus;
34+
unsigned long slice_map;
35+
unsigned long irq_alloc_mask[2];
36+
struct slice_data slice[2];
37+
};
38+
39+
struct node_data {
40+
struct pglist_data pglist;
41+
struct hub_data hub;
42+
cpumask_t cpumask;
43+
};
44+
45+
extern struct node_data *__node_data[];
46+
47+
#define NODE_DATA(n) (&__node_data[(n)]->pglist)
48+
#define hub_data(n) (&__node_data[(n)]->hub)
49+
50+
extern void setup_zero_pages(void);
51+
extern void __init prom_init_numa_memory(void);
52+
53+
#endif /* _ASM_MACH_MMZONE_H */
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#ifndef _ASM_MACH_TOPOLOGY_H
2+
#define _ASM_MACH_TOPOLOGY_H
3+
4+
#ifdef CONFIG_NUMA
5+
6+
#define cpu_to_node(cpu) ((cpu) >> 2)
7+
#define parent_node(node) (node)
8+
#define cpumask_of_node(node) (&__node_data[(node)]->cpumask)
9+
10+
struct pci_bus;
11+
extern int pcibus_to_node(struct pci_bus *);
12+
13+
#define cpumask_of_pcibus(bus) (cpu_online_mask)
14+
15+
extern unsigned char __node_distances[MAX_NUMNODES][MAX_NUMNODES];
16+
17+
#define node_distance(from, to) (__node_distances[(from)][(to)])
18+
19+
#endif
20+
21+
#include <asm-generic/topology.h>
22+
23+
#endif /* _ASM_MACH_TOPOLOGY_H */

arch/mips/include/asm/sparsemem.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#else
1212
# define SECTION_SIZE_BITS 28
1313
#endif
14-
#define MAX_PHYSMEM_BITS 35
14+
#define MAX_PHYSMEM_BITS 48
1515

1616
#endif /* CONFIG_SPARSEMEM */
1717
#endif /* _MIPS_SPARSEMEM_H */

arch/mips/kernel/setup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ static unsigned long __init init_initrd(void)
282282
* Initialize the bootmem allocator. It also setup initrd related data
283283
* if needed.
284284
*/
285-
#ifdef CONFIG_SGI_IP27
285+
#if defined(CONFIG_SGI_IP27) || (defined(CONFIG_CPU_LOONGSON3) && defined(CONFIG_NUMA))
286286

287287
static void __init bootmem_init(void)
288288
{

arch/mips/loongson/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ config LEMOTE_MACH3A
7979
select SYS_HAS_EARLY_PRINTK
8080
select SYS_SUPPORTS_SMP
8181
select SYS_SUPPORTS_HOTPLUG_CPU
82+
select SYS_SUPPORTS_NUMA
8283
select SYS_SUPPORTS_64BIT_KERNEL
8384
select SYS_SUPPORTS_HIGHMEM
8485
select SYS_SUPPORTS_LITTLE_ENDIAN

arch/mips/loongson/common/env.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,17 +80,24 @@ void __init prom_init_env(void)
8080
cpu_clock_freq = ecpu->cpu_clock_freq;
8181
loongson_sysconf.cputype = ecpu->cputype;
8282
if (ecpu->cputype == Loongson_3A) {
83+
loongson_sysconf.cores_per_node = 4;
84+
loongson_sysconf.cores_per_package = 4;
8385
loongson_chipcfg[0] = 0x900000001fe00180;
8486
loongson_chipcfg[1] = 0x900010001fe00180;
8587
loongson_chipcfg[2] = 0x900020001fe00180;
8688
loongson_chipcfg[3] = 0x900030001fe00180;
8789
} else {
90+
loongson_sysconf.cores_per_node = 1;
91+
loongson_sysconf.cores_per_package = 1;
8892
loongson_chipcfg[0] = 0x900000001fe00180;
8993
}
9094

9195
loongson_sysconf.nr_cpus = ecpu->nr_cpus;
9296
if (ecpu->nr_cpus > NR_CPUS || ecpu->nr_cpus == 0)
9397
loongson_sysconf.nr_cpus = NR_CPUS;
98+
loongson_sysconf.nr_nodes = (loongson_sysconf.nr_cpus +
99+
loongson_sysconf.cores_per_node - 1) /
100+
loongson_sysconf.cores_per_node;
94101

95102
loongson_sysconf.pci_mem_start_addr = eirq_source->pci_mem_start_addr;
96103
loongson_sysconf.pci_mem_end_addr = eirq_source->pci_mem_end_addr;

arch/mips/loongson/common/init.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,11 @@ void __init prom_init(void)
3030
set_io_port_base((unsigned long)
3131
ioremap(LOONGSON_PCIIO_BASE, LOONGSON_PCIIO_SIZE));
3232

33+
#ifdef CONFIG_NUMA
34+
prom_init_numa_memory();
35+
#else
3336
prom_init_memory();
37+
#endif
3438

3539
/*init the uart base address */
3640
prom_init_uart_base();

0 commit comments

Comments
 (0)