aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/sn/kernel/setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64/sn/kernel/setup.c')
-rw-r--r--arch/ia64/sn/kernel/setup.c268
1 files changed, 118 insertions, 150 deletions
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
index 363a87497284e3..8831bd886e36ed 100644
--- a/arch/ia64/sn/kernel/setup.c
+++ b/arch/ia64/sn/kernel/setup.c
@@ -69,18 +69,17 @@
#include <asm/sn/bte.h>
#include <asm/sn/clksupport.h>
#include <asm/sn/sn_sal.h>
-
-#ifdef CONFIG_IA64_SGI_SN2
#include <asm/sn/sn2/shub.h>
-#endif
DEFINE_PER_CPU(struct pda_s, pda_percpu);
+#define pxm_to_nasid(pxm) ((pxm)<<1)
+
extern void bte_init_node (nodepda_t *, cnodeid_t);
extern void bte_init_cpu (void);
extern void sn_timer_init (void);
extern void (*ia64_mark_idle)(int);
-extern void snidle(int);
+void snidle(int);
unsigned long sn_rtc_cycles_per_second;
@@ -88,6 +87,8 @@ partid_t sn_partid = -1;
char sn_system_serial_number_string[128];
u64 sn_partition_serial_number;
+short physical_node_map[MAX_PHYSNODE_ID];
+
/*
* This is the address of the RRegs in the HSpace of the global
* master. It is used by a hack in serial.c (serial_[in|out],
@@ -96,21 +97,14 @@ u64 sn_partition_serial_number;
* early_printk won't try to access the UART before
* master_node_bedrock_address is properly calculated.
*/
-u64 master_node_bedrock_address = 0UL;
+u64 master_node_bedrock_address;
static void sn_init_pdas(char **);
-extern struct irq_desc *_sn_irq_desc[];
-
-#if defined(CONFIG_IA64_SGI_SN1)
-extern synergy_da_t *Synergy_da_indr[];
-#endif
static nodepda_t *nodepdaindr[MAX_COMPACT_NODES];
-#ifdef CONFIG_IA64_SGI_SN2
-irqpda_t *irqpdaindr[NR_CPUS];
-#endif /* CONFIG_IA64_SGI_SN2 */
+irqpda_t *irqpdaindr;
/*
@@ -137,29 +131,19 @@ struct screen_info sn_screen_info = {
* running in the simulator. Note that passing zeroes in DRIVE_INFO
* is sufficient (the IDE driver will autodetect the drive geometry).
*/
+#ifdef CONFIG_IA64_GENERIC
+extern char drive_info[4*16];
+#else
char drive_info[4*16];
-
-/**
- * sn_map_nr - return the mem_map entry for a given kernel address
- * @addr: kernel address to query
- *
- * Finds the mem_map entry for the kernel address given. Used by
- * virt_to_page() (asm-ia64/page.h), among other things.
- */
-unsigned long
-sn_map_nr (unsigned long addr)
-{
- return BANK_MAP_NR(addr);
-}
+#endif
/**
* early_sn_setup - early setup routine for SN platforms
*
* Sets up an initial console to aid debugging. Intended primarily
- * for bringup, it's only called if %BRINGUP and %CONFIG_IA64_EARLY_PRINTK
- * are turned on. See start_kernel() in init/main.c.
+ * for bringup. See start_kernel() in init/main.c.
*/
-#if defined(CONFIG_IA64_EARLY_PRINTK)
+#if defined(CONFIG_IA64_EARLY_PRINTK) || defined(CONFIG_IA64_SGI_SN_SIM)
void __init
early_sn_setup(void)
@@ -197,21 +181,48 @@ early_sn_setup(void)
}
if ( IS_RUNNING_ON_SIMULATOR() ) {
-#if defined(CONFIG_IA64_SGI_SN1)
- master_node_bedrock_address = (u64)REMOTE_HSPEC_ADDR(get_nasid(), 0);
-#else
master_node_bedrock_address = (u64)REMOTE_HUB(get_nasid(), SH_JUNK_BUS_UART0);
-#endif
printk(KERN_DEBUG "early_sn_setup: setting master_node_bedrock_address to 0x%lx\n", master_node_bedrock_address);
}
}
-#endif /* CONFIG_IA64_SGI_SN1 */
+#endif /* CONFIG_IA64_EARLY_PRINTK */
#ifdef CONFIG_IA64_MCA
extern int platform_intr_list[];
#endif
extern nasid_t master_nasid;
+static int shub_1_1_found __initdata;
+
+
+/*
+ * sn_check_for_wars
+ *
+ * Set flag for enabling shub specific wars
+ */
+
+static inline int __init
+is_shub_1_1(int nasid)
+{
+ unsigned long id;
+ int rev;
+
+ id = REMOTE_HUB_L(nasid, SH_SHUB_ID);
+ rev = (id & SH_SHUB_ID_REVISION_MASK) >> SH_SHUB_ID_REVISION_SHFT;
+ return rev <= 2;
+}
+
+static void __init
+sn_check_for_wars(void)
+{
+ int cnode;
+
+ for (cnode=0; cnode< numnodes; cnode++)
+ if (is_shub_1_1(cnodeid_to_nasid(cnode)))
+ shub_1_1_found = 1;
+}
+
+
/**
* sn_setup - SN platform setup routine
@@ -225,8 +236,18 @@ void __init
sn_setup(char **cmdline_p)
{
long status, ticks_per_sec, drift;
- int i;
+ int pxm;
int major = sn_sal_rev_major(), minor = sn_sal_rev_minor();
+ extern void io_sh_swapper(int, int);
+ extern nasid_t get_master_baseio_nasid(void);
+ 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];
printk("SGI SAL version %x.%02x\n", major, minor);
@@ -239,23 +260,13 @@ sn_setup(char **cmdline_p)
"%x.%02x\n", SN_SAL_MIN_MAJOR, SN_SAL_MIN_MINOR);
panic("PROM version too old\n");
}
-#ifdef CONFIG_PCI
-#ifdef CONFIG_IA64_SGI_SN2
- {
- extern void io_sh_swapper(int, int);
- io_sh_swapper(get_nasid(), 0);
- }
-#endif
+
+ io_sh_swapper(get_nasid(), 0);
master_nasid = get_nasid();
(void)get_console_nasid();
-#ifndef CONFIG_IA64_SGI_SN1
- {
- extern nasid_t get_master_baseio_nasid(void);
- (void)get_master_baseio_nasid();
- }
-#endif
-#endif /* CONFIG_PCI */
+ (void)get_master_baseio_nasid();
+
status = ia64_sal_freq_base(SAL_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec, &drift);
if (status != 0 || ticks_per_sec < 100000) {
printk(KERN_WARNING "unable to determine platform RTC clock frequency, guessing.\n");
@@ -265,19 +276,12 @@ sn_setup(char **cmdline_p)
else
sn_rtc_cycles_per_second = ticks_per_sec;
- for (i=0;i<NR_CPUS;i++)
- _sn_irq_desc[i] = _irq_desc;
-
platform_intr_list[ACPI_INTERRUPT_CPEI] = IA64_PCE_VECTOR;
if ( IS_RUNNING_ON_SIMULATOR() )
{
-#ifdef CONFIG_IA64_SGI_SN2
master_node_bedrock_address = (u64)REMOTE_HUB(get_nasid(), SH_JUNK_BUS_UART0);
-#else
- master_node_bedrock_address = (u64)REMOTE_HSPEC_ADDR(get_nasid(), 0);
-#endif
printk(KERN_DEBUG "sn_setup: setting master_node_bedrock_address to 0x%lx\n",
master_node_bedrock_address);
}
@@ -287,6 +291,10 @@ sn_setup(char **cmdline_p)
*/
sn_init_pdas(cmdline_p);
+ /*
+ * Check for WARs.
+ */
+ sn_check_for_wars();
/*
* For the bootcpu, we do this here. All other cpus will make the
@@ -300,11 +308,6 @@ sn_setup(char **cmdline_p)
#endif
screen_info = sn_screen_info;
- /*
- * Turn off "floating-point assist fault" warnings by default.
- */
- current->thread.flags |= IA64_THREAD_FPEMU_NOPRINT;
-
sn_timer_init();
ia64_mark_idle = &snidle;
@@ -324,22 +327,19 @@ sn_init_pdas(char **cmdline_p)
* Make sure that the PDA fits entirely in the same page as the
* cpu_data area.
*/
- if ( (((unsigned long)pda & ~PAGE_MASK) + sizeof(pda_t)) > PAGE_SIZE)
+ if ((((unsigned long)pda & (~PAGE_MASK)) + sizeof(pda_t)) > PAGE_SIZE)
panic("overflow of cpu_data page");
+ memset(pda->cnodeid_to_nasid_table, -1, sizeof(pda->cnodeid_to_nasid_table));
+ for (cnode=0; cnode<numnodes; cnode++)
+ pda->cnodeid_to_nasid_table[cnode] = pxm_to_nasid(nid_to_pxm_map[cnode]);
+
/*
* Allocate & initalize the nodepda for each node.
*/
for (cnode=0; cnode < numnodes; cnode++) {
nodepdaindr[cnode] = alloc_bootmem_node(NODE_DATA(cnode), sizeof(nodepda_t));
memset(nodepdaindr[cnode], 0, sizeof(nodepda_t));
-
-#if defined(CONFIG_IA64_SGI_SN1)
- Synergy_da_indr[cnode * 2] = (synergy_da_t *) alloc_bootmem_node(NODE_DATA(cnode), sizeof(synergy_da_t));
- Synergy_da_indr[cnode * 2 + 1] = (synergy_da_t *) alloc_bootmem_node(NODE_DATA(cnode), sizeof(synergy_da_t));
- memset(Synergy_da_indr[cnode * 2], 0, sizeof(synergy_da_t));
- memset(Synergy_da_indr[cnode * 2 + 1], 0, sizeof(synergy_da_t));
-#endif
}
/*
@@ -348,7 +348,7 @@ sn_init_pdas(char **cmdline_p)
for (cnode=0; cnode < numnodes; cnode++)
memcpy(nodepdaindr[cnode]->pernode_pdaindr, nodepdaindr, sizeof(nodepdaindr));
-#ifdef CONFIG_PCI
+
/*
* Set up IO related platform-dependent nodepda fields.
* The following routine actually sets up the hubinfo struct
@@ -358,7 +358,6 @@ sn_init_pdas(char **cmdline_p)
init_platform_nodepda(nodepdaindr[cnode], cnode);
bte_init_node (nodepdaindr[cnode], cnode);
}
-#endif
}
/**
@@ -373,7 +372,11 @@ sn_init_pdas(char **cmdline_p)
void __init
sn_cpu_init(void)
{
- int cpuid, cpuphyid, nasid, nodeid, slice;
+ int cpuid;
+ int cpuphyid;
+ int nasid;
+ int slice;
+ int cnode, i;
/*
* The boot cpu makes this call again after platform initialization is
@@ -385,14 +388,43 @@ sn_cpu_init(void)
cpuid = smp_processor_id();
cpuphyid = ((ia64_get_lid() >> 16) & 0xffff);
nasid = cpu_physical_id_to_nasid(cpuphyid);
- nodeid = cpu_to_node_map[cpuphyid];
+ cnode = nasid_to_cnodeid(nasid);
slice = cpu_physical_id_to_slice(cpuphyid);
- memset(pda, 0, sizeof(pda_t));
- pda->p_nodepda = nodepdaindr[nodeid];
+ printk("CPU %d: nasid %d, slice %d, cnode %d\n",
+ smp_processor_id(), nasid, slice, cnode);
+
+ memset(pda, 0, sizeof(pda));
+ pda->p_nodepda = nodepdaindr[cnode];
+ pda->led_address = (typeof(pda->led_address)) (LED0 + (slice<<LED_CPU_SHIFT));
+ pda->led_state = LED_ALWAYS_SET;
pda->hb_count = HZ/2;
pda->hb_state = 0;
pda->idle_flag = 0;
+ pda->shub_1_1_found = shub_1_1_found;
+
+ memset(pda->cnodeid_to_nasid_table, -1, sizeof(pda->cnodeid_to_nasid_table));
+ for (i=0; i<numnodes; i++)
+ pda->cnodeid_to_nasid_table[i] = pxm_to_nasid(nid_to_pxm_map[i]);
+
+ if (local_node_data->active_cpu_count == 1)
+ nodepda->node_first_cpu = cpuid;
+
+
+
+ /*
+ * We must use different memory allocators for first cpu (bootmem
+ * allocator) than for the other cpus (regular allocator).
+ */
+ if (cpuid == 0)
+ irqpdaindr = alloc_bootmem_node(NODE_DATA(cpuid_to_cnodeid(cpuid)),sizeof(irqpda_t));
+
+ memset(irqpdaindr, 0, sizeof(irqpda_t));
+ irqpdaindr->irq_flags[SGI_PCIBR_ERROR] = SN2_IRQ_SHARED;
+ irqpdaindr->irq_flags[SGI_PCIBR_ERROR] |= SN2_IRQ_RESERVED;
+ irqpdaindr->irq_flags[SGI_II_ERROR] = SN2_IRQ_SHARED;
+ irqpdaindr->irq_flags[SGI_II_ERROR] |= SN2_IRQ_RESERVED;
+
pda->pio_write_status_addr = (volatile unsigned long *)
LOCAL_MMR_ADDR((slice < 2 ? SH_PIO_WRITE_STATUS_0 : SH_PIO_WRITE_STATUS_1 ) );
pda->mem_write_status_addr = (volatile u64 *)
@@ -400,89 +432,25 @@ sn_cpu_init(void)
if (nodepda->node_first_cpu == cpuid) {
int buddy_nasid;
- buddy_nasid = cnodeid_to_nasid(local_nodeid == numnodes - 1 ? 0 : local_nodeid + 1);
+ buddy_nasid = cnodeid_to_nasid(numa_node_id() == numnodes-1 ? 0 : numa_node_id()+ 1);
pda->pio_shub_war_cam_addr = (volatile unsigned long*)GLOBAL_MMR_ADDR(nasid, SH_PI_CAM_CONTROL);
}
bte_init_cpu();
}
-#ifdef II_PRTE_TLB_WAR
-long iiprt_lock[16*64] __cacheline_aligned; /* allow for NASIDs up to 64 */
-#endif
-
-#ifdef BUS_INT_WAR
-
-#include <asm/hw_irq.h>
-#include <asm/sn/pda.h>
-
-void ia64_handle_irq (ia64_vector vector, struct pt_regs *regs);
-
-static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED;
-
-#define IRQCPU(irq) ((irq)>>8)
-
-void
-sn_add_polled_interrupt(int irq, int interval)
-{
- unsigned long flags, irq_cnt;
- sn_poll_entry_t *irq_list;
-
- irq_list = pdacpu(IRQCPU(irq)).pda_poll_entries;;
-
- spin_lock_irqsave(&irq_lock, flags);
- irq_cnt = pdacpu(IRQCPU(irq)).pda_poll_entry_count;
- irq_list[irq_cnt].irq = irq;
- irq_list[irq_cnt].interval = interval;
- irq_list[irq_cnt].tick = interval;
- pdacpu(IRQCPU(irq)).pda_poll_entry_count++;
- spin_unlock_irqrestore(&irq_lock, flags);
-
-
-}
-
-void
-sn_delete_polled_interrupt(int irq)
+void snidle(int idleness)
{
- unsigned long flags, i, irq_cnt;
- sn_poll_entry_t *irq_list;
-
- irq_list = pdacpu(IRQCPU(irq)).pda_poll_entries;
-
- spin_lock_irqsave(&irq_lock, flags);
- irq_cnt = pdacpu(IRQCPU(irq)).pda_poll_entry_count;
- for (i=0; i<irq_cnt; i++) {
- if (irq_list[i].irq == irq) {
- irq_list[i] = irq_list[irq_cnt-1];
- pdacpu(IRQCPU(irq)).pda_poll_entry_count--;
- break;
+ if (!idleness) {
+ if (pda->idle_flag == 0) {
+ set_led_bits(0, LED_CPU_ACTIVITY);
}
- }
- spin_unlock_irqrestore(&irq_lock, flags);
-}
-void
-sn_irq_poll(int cpu, int reason)
-{
- unsigned long flags, i;
- sn_poll_entry_t *irq_list;
-
-
- ia64_handle_irq(IA64_IPI_VECTOR, 0);
-
- if (reason == 0)
- return;
-
- irq_list = pda->pda_poll_entries;
-
- for (i=0; i<pda->pda_poll_entry_count; i++, irq_list++) {
- if (--irq_list->tick <= 0) {
- irq_list->tick = irq_list->interval;
- local_irq_save(flags);
- ia64_handle_irq(irq_to_vector(irq_list->irq), 0);
- local_irq_restore(flags);
- }
+ pda->idle_flag = 1;
}
-}
+ else {
+ set_led_bits(LED_CPU_ACTIVITY, LED_CPU_ACTIVITY);
-#endif
+ pda->idle_flag = 0;
+ }
+}