Commit 2ce29370 authored by Jack Steiner's avatar Jack Steiner Committed by Tony Luck

[IA64-SGI] Add support for a future SGI chipset (shub2) 2of4

This patch adds the addresses of shub2 MMRS to the shub_mmr
header file. During boot, a SAL call is made to determine the
type of the shub. Platform initialization sets the appropriate
MMR addresses for the platform.

A new macro (is_shub1() & is_shub2()) can be used at runtime to
determine the type of the shub.
Signed-off-by: default avatarJack Steiner <steiner@sgi.com>
parent 8ebb4697
...@@ -42,8 +42,7 @@ void *sn_io_addr(unsigned long port) ...@@ -42,8 +42,7 @@ void *sn_io_addr(unsigned long port)
*/ */
if ((port >= 0x1f0 && port <= 0x1f7) || if ((port >= 0x1f0 && port <= 0x1f7) ||
port == 0x3f6 || port == 0x3f7) { port == 0x3f6 || port == 0x3f7) {
io_base = (0xc000000fcc000000UL | io_base = GLOBAL_MMR_ADDR(get_nasid(), 0xfcc000000UL);
((unsigned long)get_nasid() << 38));
addr = io_base | ((port >> 2) << 12) | (port & 0xfff); addr = io_base | ((port >> 2) << 12) | (port & 0xfff);
} else { } else {
addr = __ia64_get_io_port_base() | ((port >> 2) << 2); addr = __ia64_get_io_port_base() | ((port >> 2) << 2);
...@@ -66,9 +65,10 @@ EXPORT_SYMBOL(sn_io_addr); ...@@ -66,9 +65,10 @@ EXPORT_SYMBOL(sn_io_addr);
*/ */
void __sn_mmiowb(void) void __sn_mmiowb(void)
{ {
while ((((volatile unsigned long)(*pda->pio_write_status_addr)) & volatile unsigned long *adr = pda->pio_write_status_addr;
SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_MASK) != unsigned long val = pda->pio_write_status_val;
SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_MASK)
while ((*adr & SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK) != val)
cpu_relax(); cpu_relax();
} }
......
...@@ -215,8 +215,10 @@ static inline int __init is_shub_1_1(int nasid) ...@@ -215,8 +215,10 @@ static inline int __init is_shub_1_1(int nasid)
unsigned long id; unsigned long id;
int rev; int rev;
id = REMOTE_HUB_L(nasid, SH_SHUB_ID); if (is_shub2())
rev = (id & SH_SHUB_ID_REVISION_MASK) >> SH_SHUB_ID_REVISION_SHFT; return 0;
id = REMOTE_HUB_L(nasid, SH1_SHUB_ID);
rev = (id & SH1_SHUB_ID_REVISION_MASK) >> SH1_SHUB_ID_REVISION_SHFT;
return rev <= 2; return rev <= 2;
} }
...@@ -224,9 +226,13 @@ static void __init sn_check_for_wars(void) ...@@ -224,9 +226,13 @@ static void __init sn_check_for_wars(void)
{ {
int cnode; int cnode;
for (cnode = 0; cnode < numnodes; cnode++) if (is_shub2()) {
if (is_shub_1_1(cnodeid_to_nasid(cnode))) /* none yet */
shub_1_1_found = 1; } else {
for (cnode = 0; cnode < numnodes; cnode++)
if (is_shub_1_1(cnodeid_to_nasid(cnode)))
shub_1_1_found = 1;
}
} }
/** /**
...@@ -477,21 +483,29 @@ void __init sn_cpu_init(void) ...@@ -477,21 +483,29 @@ void __init sn_cpu_init(void)
pda->shub_1_1_found = shub_1_1_found; pda->shub_1_1_found = shub_1_1_found;
/* /*
* We must use different memory allocators for first cpu (bootmem * Set up addresses of PIO/MEM write status registers.
* allocator) than for the other cpus (regular allocator).
*/ */
pda->pio_write_status_addr = (volatile unsigned long *) {
LOCAL_MMR_ADDR((slice < u64 pio1[] = {SH1_PIO_WRITE_STATUS_0, 0, SH1_PIO_WRITE_STATUS_1, 0};
2 ? SH_PIO_WRITE_STATUS_0 : SH_PIO_WRITE_STATUS_1)); u64 pio2[] = {SH2_PIO_WRITE_STATUS_0, SH2_PIO_WRITE_STATUS_1,
SH2_PIO_WRITE_STATUS_2, SH2_PIO_WRITE_STATUS_3};
u64 *pio;
pio = is_shub1() ? pio1 : pio2;
pda->pio_write_status_addr = (volatile unsigned long *) LOCAL_MMR_ADDR(pio[slice]);
pda->pio_write_status_val = is_shub1() ? SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK : 0;
}
if (local_node_data->active_cpu_count++ == 0) { /*
* WAR addresses for SHUB 1.x.
*/
if (local_node_data->active_cpu_count++ == 0 && is_shub1()) {
int buddy_nasid; int buddy_nasid;
buddy_nasid = buddy_nasid =
cnodeid_to_nasid(numa_node_id() == cnodeid_to_nasid(numa_node_id() ==
numnodes - 1 ? 0 : numa_node_id() + 1); numnodes - 1 ? 0 : numa_node_id() + 1);
pda->pio_shub_war_cam_addr = pda->pio_shub_war_cam_addr =
(volatile unsigned long *)GLOBAL_MMR_ADDR(nasid, (volatile unsigned long *)GLOBAL_MMR_ADDR(nasid,
SH_PI_CAM_CONTROL); SH1_PI_CAM_CONTROL);
} }
} }
......
...@@ -9,9 +9,9 @@ ...@@ -9,9 +9,9 @@
#include <asm/sn/shub_mmr.h> #include <asm/sn/shub_mmr.h>
#define ZEROVAL 0x3f // "zero" value for outstanding PIO requests #define ZEROVAL 0x3f // "zero" value for outstanding PIO requests
#define DEADLOCKBIT SH_PIO_WRITE_STATUS_0_WRITE_DEADLOCK_SHFT #define DEADLOCKBIT SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_SHFT
#define WRITECOUNT SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_SHFT #define WRITECOUNT SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_SHFT
#define ALIAS_OFFSET (SH_PIO_WRITE_STATUS_0_ALIAS-SH_PIO_WRITE_STATUS_0) #define ALIAS_OFFSET (SH1_PIO_WRITE_STATUS_0_ALIAS-SH1_PIO_WRITE_STATUS_0)
.global sn2_ptc_deadlock_recovery_core .global sn2_ptc_deadlock_recovery_core
......
...@@ -46,15 +46,14 @@ static unsigned long sn2_ptc_deadlock_count; ...@@ -46,15 +46,14 @@ static unsigned long sn2_ptc_deadlock_count;
static inline unsigned long wait_piowc(void) static inline unsigned long wait_piowc(void)
{ {
volatile unsigned long *piows; volatile unsigned long *piows, piows_val;
unsigned long ws; unsigned long ws;
piows = pda->pio_write_status_addr; piows = pda->pio_write_status_addr;
piows_val = pda->pio_write_status_val;
do { do {
ia64_mfa(); cpu_relax();
} while (((ws = } while (((ws = *piows) & SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK) != piows_val);
*piows) & SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_MASK) !=
SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_MASK);
return ws; return ws;
} }
...@@ -129,20 +128,20 @@ sn2_global_tlb_purge(unsigned long start, unsigned long end, ...@@ -129,20 +128,20 @@ sn2_global_tlb_purge(unsigned long start, unsigned long end,
cnode = find_next_bit(&nodes_flushed, NR_NODES, ++cnode)) cnode = find_next_bit(&nodes_flushed, NR_NODES, ++cnode))
nasids[nix++] = cnodeid_to_nasid(cnode); nasids[nix++] = cnodeid_to_nasid(cnode);
data0 = (1UL << SH_PTC_0_A_SHFT) | data0 = (1UL << SH1_PTC_0_A_SHFT) |
(nbits << SH_PTC_0_PS_SHFT) | (nbits << SH1_PTC_0_PS_SHFT) |
((ia64_get_rr(start) >> 8) << SH_PTC_0_RID_SHFT) | ((ia64_get_rr(start) >> 8) << SH1_PTC_0_RID_SHFT) |
(1UL << SH_PTC_0_START_SHFT); (1UL << SH1_PTC_0_START_SHFT);
ptc0 = (long *)GLOBAL_MMR_PHYS_ADDR(0, SH_PTC_0); ptc0 = (long *)GLOBAL_MMR_PHYS_ADDR(0, SH1_PTC_0);
ptc1 = (long *)GLOBAL_MMR_PHYS_ADDR(0, SH_PTC_1); ptc1 = (long *)GLOBAL_MMR_PHYS_ADDR(0, SH1_PTC_1);
mynasid = get_nasid(); mynasid = get_nasid();
spin_lock_irqsave(&sn2_global_ptc_lock, flags); spin_lock_irqsave(&sn2_global_ptc_lock, flags);
do { do {
data1 = start | (1UL << SH_PTC_1_START_SHFT); data1 = start | (1UL << SH1_PTC_1_START_SHFT);
for (i = 0; i < nix; i++) { for (i = 0; i < nix; i++) {
nasid = nasids[i]; nasid = nasids[i];
if (likely(nasid == mynasid)) { if (likely(nasid == mynasid)) {
...@@ -159,7 +158,7 @@ sn2_global_tlb_purge(unsigned long start, unsigned long end, ...@@ -159,7 +158,7 @@ sn2_global_tlb_purge(unsigned long start, unsigned long end,
if (flushed if (flushed
&& (wait_piowc() & && (wait_piowc() &
SH_PIO_WRITE_STATUS_0_WRITE_DEADLOCK_MASK)) { SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_MASK)) {
sn2_ptc_deadlock_recovery(data0, data1); sn2_ptc_deadlock_recovery(data0, data1);
} }
...@@ -188,8 +187,8 @@ void sn2_ptc_deadlock_recovery(unsigned long data0, unsigned long data1) ...@@ -188,8 +187,8 @@ void sn2_ptc_deadlock_recovery(unsigned long data0, unsigned long data1)
sn2_ptc_deadlock_count++; sn2_ptc_deadlock_count++;
ptc0 = (long *)GLOBAL_MMR_PHYS_ADDR(0, SH_PTC_0); ptc0 = (long *)GLOBAL_MMR_PHYS_ADDR(0, SH1_PTC_0);
ptc1 = (long *)GLOBAL_MMR_PHYS_ADDR(0, SH_PTC_1); ptc1 = (long *)GLOBAL_MMR_PHYS_ADDR(0, SH1_PTC_1);
piows = (long *)pda->pio_write_status_addr; piows = (long *)pda->pio_write_status_addr;
mycnode = numa_node_id(); mycnode = numa_node_id();
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
#include <asm/hw_irq.h> #include <asm/hw_irq.h>
#include <asm/system.h> #include <asm/system.h>
#include "shub.h"
#include <asm/sn/leds.h> #include <asm/sn/leds.h>
#include <asm/sn/shub_mmr.h> #include <asm/sn/shub_mmr.h>
#include <asm/sn/clksupport.h> #include <asm/sn/clksupport.h>
......
...@@ -20,7 +20,8 @@ ...@@ -20,7 +20,8 @@
* Effectively, it's the maximum number of compact node ids (cnodeid_t). * Effectively, it's the maximum number of compact node ids (cnodeid_t).
* This is not necessarily the same as MAX_NASIDS. * This is not necessarily the same as MAX_NASIDS.
*/ */
#define MAX_COMPACT_NODES 2048 #define MAX_COMPACT_NODES 2048
#define CPUS_PER_NODE 4
extern void sn_flush_all_caches(long addr, long bytes); extern void sn_flush_all_caches(long addr, long bytes);
......
This diff is collapsed.
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/config.h> #include <linux/config.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <asm/sn/addrs.h>
#include <asm/sn/pda.h> #include <asm/sn/pda.h>
#include <asm/intrinsics.h> #include <asm/intrinsics.h>
...@@ -86,11 +87,9 @@ ...@@ -86,11 +87,9 @@
#endif #endif
#define get_node_number(addr) (((unsigned long)(addr)>>38) & 0x7ff) #define get_node_number(addr) NASID_GET(addr)
/* /*
* NOTE: id & eid refer to Intel's definitions of the LID register
*
* NOTE: on non-MP systems, only cpuid 0 exists * NOTE: on non-MP systems, only cpuid 0 exists
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment