MIPS: SGI-IP27: Install the cache error vector on every CPU
PATCH v2 1/1 MIPS: SGI-IP27: Install the cache error vector on every CPU
The R10000 drives an uncached attribute on the bus, decoded by the hub. CKSEG1 uses attribute 0, UALIAS, whose low 128K is flipped by CPU slice (UALIAS_FLIP_BIT), so slice 1 reads CKSEG1 0x100 from node memory 0x10100. trap_init() writes the vector only through TO_UNCAC(), attribute 3, unflipped. Copy it on each secondary.
---
Changes in v2:
- Rewrote the message to explain the per-slice UALIAS flip that makes CKSEG1 0x100 differ from TO_UNCAC(0x100) on a secondary CPU.
- Stated in the message and in ip27_init_secondary() that the R10000 drives an uncached attribute on the bus that the hub decodes, attribute 0 for CKSEG1 and attribute 3 for TO_UNCAC().
- No code change.
arch/mips/sgi-ip27/ip27-smp.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-)
arch/mips/sgi-ip27/ip27-smp.c +17 -1
@@ -7,11 +7,13 @@* Copyright (C) 2000 - 2001 by Silicon Graphics, Inc. */ #include <linux/init.h> +#include <linux/string.h> #include <linux/sched.h> #include <linux/sched/task_stack.h> #include <linux/topology.h> #include <linux/nodemask.h> +#include <asm/addrspace.h> #include <asm/page.h> #include <asm/processor.h> #include <asm/ptrace.h>
@@ -133,6 +135,20 @@ static void ip27_init_cpu(void)per_cpu_init (); } +static void ip27_init_secondary (void ) +{ +/* +* The R10000 drives an uncached attribute on the bus and the hub +* decodes it. The cache error vector is fetched through CKSEG1, +* attribute 0, whose low 128K the hub flips per CPU slice. +* trap_init() wrote it through TO_UNCAC(), attribute 3, which is +* not flipped, so that copy only serves slice 0. +*/ +memcpy ((void *)CKSEG1ADDR (0x100 ), (void *)TO_UNCAC (0x100 ),0x80 ); + +ip27_init_cpu (); +} +static void ip27_smp_finish (void ) {hub_rt_clock_event_init ();
@@ -182,7 +198,7 @@ static void __init ip27_prepare_cpus(unsigned int max_cpus)const struct plat_smp_ops ip27_smp_ops = { .send_ipi_single = ip27_send_ipi_single, .send_ipi_mask = ip27_send_ipi_mask, - .init_secondary = ip27_init_cpu, + .init_secondary = ip27_init_secondary, .smp_finish = ip27_smp_finish, .boot_secondary = ip27_boot_secondary, .smp_setup = ip27_smp_setup,
base-commit: 24a19b953e2a3d0ea5a8c4951a0ab8f32720c907
Signature · 1 line
2.47.3
Quoted 5 lines · Imre Kaloz
The R10000 drives an uncached attribute on the bus, decoded by the hub. CKSEG1 uses attribute 0, UALIAS, whose low 128K is flipped by CPU slice (
UALIAS_FLIP_BIT), so slice 1 reads CKSEG10x100from node memory0x10100.trap_init()writes the vector only throughTO_UNCAC(), attribute 3, unflipped. Copy it on each secondary.
OK, slice 1 gets 0xffffffffa0000100 virtual mapped to 0x10100 physical.
So does slice 0 get 0xffffffffa0000100 virtual mapped to 0x100 physical?
How about other slices? "Each secondary" suggests there are more than 2.
Not questioning the validity of the change, but trying to understand the
system topology.
Maciej
Quoted 11 lines · Maciej W. Rozycki
Quoted 5 lines · Imre Kaloz
The R10000 drives an uncached attribute on the bus, decoded by the hub. CKSEG1 uses attribute 0, UALIAS, whose low 128K is flipped by CPU slice (
UALIAS_FLIP_BIT), so slice 1 reads CKSEG10x100from node memory0x10100.trap_init()writes the vector only throughTO_UNCAC(), attribute 3, unflipped. Copy it on each secondary.OK, slice 1 gets
0xffffffffa0000100virtual mapped to0x10100physical.So does slice 0 get
0xffffffffa0000100virtual mapped to0x100physical?
Yes, only slice 1 is flipped. UALIAS is node-local, tho: slice 0 on node N reads node N's 0x100 and slice 1 node N's 0x10100.
Quoted 1 line
How about other slices? "Each secondary" suggests there are more than 2.
A hub has two slices, so the flip is the only difference within a node; "each secondary" means every non-boot CPU across all nodes. trap_init() writes node 0's 0x100, and per_hub_init() already copies node 0's low 0x200 bytes into every other node, so slice 0 is covered everywhere and slice 1 on every node was not. Doing the copy on every secondary keeps it simple; on a slice 0 CPU it rewrites what per_hub_init() put there.
Imre