#define MAX_PHYS_MEMORY (1UL << IA64_MAX_PHYS_BITS) /* Max physical address supported */
-lboard_t *root_lboard[MAX_COMPACT_NODES];
-
extern void bte_init_node(nodepda_t *, cnodeid_t);
extern void sn_timer_init(void);
EXPORT_SYMBOL(sn_region_size);
int sn_prom_type; /* 0=hardware, 1=medusa/realprom, 2=medusa/fakeprom */
-short physical_node_map[MAX_PHYSNODE_ID];
+short physical_node_map[MAX_NUMALINK_NODES];
static unsigned long sn_prom_features[MAX_PROM_FEATURE_SETS];
EXPORT_SYMBOL(physical_node_map);
-int numionodes;
+int num_cnodes;
static void sn_init_pdas(char **);
-static void scan_for_ionodes(void);
+static void build_cnode_tables(void);
static nodepda_t *nodepdaindr[MAX_COMPACT_NODES];
char drive_info[4 * 16];
#endif
-/*
- * Get nasid of current cpu early in boot before nodepda is initialized
- */
-static int
-boot_get_nasid(void)
-{
- int nasid;
-
- if (ia64_sn_get_sapic_info(get_sapicid(), &nasid, NULL, NULL))
- BUG();
- return nasid;
-}
-
/*
* This routine can only be used during init, since
* smp_boot_data is an init data structure.
}
extern int platform_intr_list[];
-extern nasid_t master_nasid;
static int __initdata shub_1_1_found = 0;
/*
void __init sn_setup(char **cmdline_p)
{
long status, ticks_per_sec, drift;
- int pxm;
u32 version = sn_sal_rev();
extern void sn_cpu_init(void);
MAX_DMA_ADDRESS = PAGE_OFFSET + MAX_PHYS_MEMORY;
- memset(physical_node_map, -1, sizeof(physical_node_map));
- for (pxm = 0; pxm < MAX_PXM_DOMAINS; pxm++)
- if (pxm_to_nid_map[pxm] != -1)
- physical_node_map[pxm_to_nasid(pxm)] =
- pxm_to_nid_map[pxm];
+ /*
+ * Build the tables for managing cnodes.
+ */
+ build_cnode_tables();
/*
* Old PROMs do not provide an ACPI FADT. Disable legacy keyboard
printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF);
- master_nasid = boot_get_nasid();
-
status =
ia64_sal_freq_base(SAL_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec,
&drift);
{
cnodeid_t cnode;
- memset(sn_cnodeid_to_nasid, -1,
- sizeof(__ia64_per_cpu_var(__sn_cnodeid_to_nasid)));
- for_each_online_node(cnode)
- sn_cnodeid_to_nasid[cnode] =
- pxm_to_nasid(nid_to_pxm_map[cnode]);
-
- numionodes = num_online_nodes();
- scan_for_ionodes();
-
/*
* Allocate & initalize the nodepda for each node.
*/
/*
* Allocate & initialize nodepda for TIOs. For now, put them on node 0.
*/
- for (cnode = num_online_nodes(); cnode < numionodes; cnode++) {
+ for (cnode = num_online_nodes(); cnode < num_cnodes; cnode++) {
nodepdaindr[cnode] =
alloc_bootmem_node(NODE_DATA(0), sizeof(nodepda_t));
memset(nodepdaindr[cnode], 0, sizeof(nodepda_t));
/*
* Now copy the array of nodepda pointers to each nodepda.
*/
- for (cnode = 0; cnode < numionodes; cnode++)
+ for (cnode = 0; cnode < num_cnodes; cnode++)
memcpy(nodepdaindr[cnode]->pernode_pdaindr, nodepdaindr,
sizeof(nodepdaindr));
* Initialize the per node hubdev. This includes IO Nodes and
* headless/memless nodes.
*/
- for (cnode = 0; cnode < numionodes; cnode++) {
+ for (cnode = 0; cnode < num_cnodes; cnode++) {
hubdev_init_node(nodepdaindr[cnode], cnode);
}
}
}
/*
- * Scan klconfig for ionodes. Add the nasids to the
- * physical_node_map and the pda and increment numionodes.
+ * Build tables for converting between NASIDs and cnodes.
*/
+static inline int __init board_needs_cnode(int type)
+{
+ return (type == KLTYPE_SNIA || type == KLTYPE_TIO);
+}
-static void __init scan_for_ionodes(void)
+void __init build_cnode_tables(void)
{
- int nasid = 0;
+ int nasid;
+ int node;
lboard_t *brd;
- /* fakeprom does not support klgraph */
- if (IS_RUNNING_ON_FAKE_PROM())
- return;
-
- /* Setup ionodes with memory */
- for (nasid = 0; nasid < MAX_PHYSNODE_ID; nasid += 2) {
- char *klgraph_header;
- cnodeid_t cnodeid;
-
- if (physical_node_map[nasid] == -1)
- continue;
+ memset(physical_node_map, -1, sizeof(physical_node_map));
+ memset(sn_cnodeid_to_nasid, -1,
+ sizeof(__ia64_per_cpu_var(__sn_cnodeid_to_nasid)));
- cnodeid = -1;
- klgraph_header = __va(ia64_sn_get_klconfig_addr(nasid));
- if (!klgraph_header) {
- BUG(); /* All nodes must have klconfig tables! */
- }
- cnodeid = nasid_to_cnodeid(nasid);
- root_lboard[cnodeid] = (lboard_t *)
- NODE_OFFSET_TO_LBOARD((nasid),
- ((kl_config_hdr_t
- *) (klgraph_header))->
- ch_board_info);
+ /*
+ * First populate the tables with C/M bricks. This ensures that
+ * cnode == node for all C & M bricks.
+ */
+ for_each_online_node(node) {
+ nasid = pxm_to_nasid(nid_to_pxm_map[node]);
+ sn_cnodeid_to_nasid[node] = nasid;
+ physical_node_map[nasid] = node;
}
- /* Scan headless/memless IO Nodes. */
- for (nasid = 0; nasid < MAX_PHYSNODE_ID; nasid += 2) {
- /* if there's no nasid, don't try to read the klconfig on the node */
- if (physical_node_map[nasid] == -1)
- continue;
- brd = find_lboard_any((lboard_t *)
- root_lboard[nasid_to_cnodeid(nasid)],
- KLTYPE_SNIA);
- if (brd) {
- brd = KLCF_NEXT_ANY(brd); /* Skip this node's lboard */
- if (!brd)
- continue;
- }
-
- brd = find_lboard_any(brd, KLTYPE_SNIA);
+ /*
+ * num_cnodes is total number of C/M/TIO bricks. Because of the 256 node
+ * limit on the number of nodes, we can't use the generic node numbers
+ * for this. Note that num_cnodes is incremented below as TIOs or
+ * headless/memoryless nodes are discovered.
+ */
+ num_cnodes = num_online_nodes();
- while (brd) {
- sn_cnodeid_to_nasid[numionodes] = brd->brd_nasid;
- physical_node_map[brd->brd_nasid] = numionodes;
- root_lboard[numionodes] = brd;
- numionodes++;
- brd = KLCF_NEXT_ANY(brd);
- if (!brd)
- break;
-
- brd = find_lboard_any(brd, KLTYPE_SNIA);
- }
- }
+ /* fakeprom does not support klgraph */
+ if (IS_RUNNING_ON_FAKE_PROM())
+ return;
- /* Scan for TIO nodes. */
- for (nasid = 0; nasid < MAX_PHYSNODE_ID; nasid += 2) {
- /* if there's no nasid, don't try to read the klconfig on the node */
- if (physical_node_map[nasid] == -1)
- continue;
- brd = find_lboard_any((lboard_t *)
- root_lboard[nasid_to_cnodeid(nasid)],
- KLTYPE_TIO);
+ /* Find TIOs & headless/memoryless nodes and add them to the tables */
+ for_each_online_node(node) {
+ kl_config_hdr_t *klgraph_header;
+ nasid = cnodeid_to_nasid(node);
+ if ((klgraph_header = ia64_sn_get_klconfig_addr(nasid)) == NULL)
+ BUG();
+ brd = NODE_OFFSET_TO_LBOARD(nasid, klgraph_header->ch_board_info);
while (brd) {
- sn_cnodeid_to_nasid[numionodes] = brd->brd_nasid;
- physical_node_map[brd->brd_nasid] = numionodes;
- root_lboard[numionodes] = brd;
- numionodes++;
- brd = KLCF_NEXT_ANY(brd);
- if (!brd)
- break;
-
- brd = find_lboard_any(brd, KLTYPE_TIO);
+ if (board_needs_cnode(brd->brd_type) && physical_node_map[brd->brd_nasid] < 0) {
+ sn_cnodeid_to_nasid[num_cnodes] = brd->brd_nasid;
+ physical_node_map[brd->brd_nasid] = num_cnodes++;
+ }
+ brd = find_lboard_next(brd);
}
}
}
#include <asm/sn/types.h>
#include <asm/sn/sn_cpuid.h>
+/*
+ * This is the maximum number of NUMALINK nodes that can be part of a single
+ * SSI kernel. This number includes C-brick, M-bricks, and TIOs. Nodes in
+ * remote partitions are NOT included in this number.
+ * The number of compact nodes cannot exceed size of a coherency domain.
+ * The purpose of this define is to specify a node count that includes
+ * all C/M/TIO nodes in an SSI system.
+ *
+ * SGI system can currently support up to 256 C/M nodes plus additional TIO nodes.
+ *
+ * Note: ACPI20 has an architectural limit of 256 nodes. When we upgrade
+ * to ACPI3.0, this limit will be removed. The notion of "compact nodes"
+ * should be deleted and TIOs should be included in MAX_NUMNODES.
+ */
+#define MAX_COMPACT_NODES 512
+
+/*
+ * Maximum number of nodes in all partitions and in all coherency domains.
+ * This is the total number of nodes accessible in the numalink fabric. It
+ * includes all C & M bricks, plus all TIOs.
+ *
+ * This value is also the value of the maximum number of NASIDs in the numalink
+ * fabric.
+ */
+#define MAX_NUMALINK_NODES 2048
+
/*
* The following defines attributes of the HUB chip. These attributes are
* frequently referenced. They are kept in the per-cpu data areas of each cpu.
#define enable_shub_wars_1_1() (sn_hub_info->shub_1_1_found)
-/*
- * This is the maximum number of nodes that can be part of a kernel.
- * Effectively, it's the maximum number of compact node ids (cnodeid_t).
- * This is not necessarily the same as MAX_NASIDS.
- */
-#define MAX_COMPACT_NODES 2048
-#define CPUS_PER_NODE 4
-
-
/*
* Compact node ID to nasid mappings kept in the per-cpu data areas of each
* cpu.
#define sn_cnodeid_to_nasid (&__get_cpu_var(__sn_cnodeid_to_nasid[0]))
-
extern u8 sn_partition_id;
extern u8 sn_system_size;
extern u8 sn_sharing_domain_size;
klconf_off_t brd_next_same; /* Next BOARD with same nasid */
} lboard_t;
-#define KLCF_NUM_COMPS(_brd) ((_brd)->brd_numcompts)
-#define NODE_OFFSET_TO_KLINFO(n,off) ((klinfo_t*) TO_NODE_CAC(n,off))
-#define KLCF_NEXT(_brd) \
- ((_brd)->brd_next_same ? \
- (NODE_OFFSET_TO_LBOARD((_brd)->brd_next_same_host, (_brd)->brd_next_same)): NULL)
-#define KLCF_NEXT_ANY(_brd) \
- ((_brd)->brd_next_any ? \
- (NODE_OFFSET_TO_LBOARD(NASID_GET(_brd), (_brd)->brd_next_any)): NULL)
-#define KLCF_COMP(_brd, _ndx) \
- ((((_brd)->brd_compts[(_ndx)]) == 0) ? 0 : \
- (NODE_OFFSET_TO_KLINFO(NASID_GET(_brd), (_brd)->brd_compts[(_ndx)])))
-
-
/*
* Generic info structure. This stores common info about a
* component.
} klinfo_t ;
-static inline lboard_t *find_lboard_any(lboard_t * start, unsigned char brd_type)
+static inline lboard_t *find_lboard_next(lboard_t * brd)
{
- /* Search all boards stored on this node. */
-
- while (start) {
- if (start->brd_type == brd_type)
- return start;
- start = KLCF_NEXT_ANY(start);
- }
- /* Didn't find it. */
- return (lboard_t *) NULL;
+ if (brd && brd->brd_next_any)
+ return NODE_OFFSET_TO_LBOARD(NASID_GET(brd), brd->brd_next_any);
+ return NULL;
}
-
-/* external declarations of Linux kernel functions. */
-
-extern lboard_t *root_lboard[];
-extern klinfo_t *find_component(lboard_t *brd, klinfo_t *kli, unsigned char type);
-extern klinfo_t *find_first_component(lboard_t *brd, unsigned char type);
-
#endif /* _ASM_IA64_SN_KLCONFIG_H */