Re: Altix I/O code reorganization - 16 of 21
From: Pat Gefre
Date: Wed Aug 11 2004 - 19:17:55 EST
# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
# 2004/08/11 16:54:23-05:00 pfg@xxxxxxx
# code clean up
# ran thru Lindent
# changes needed for new I/O structure
# update copyright
#
# arch/ia64/sn/kernel/setup.c
# 2004/08/11 16:53:27-05:00 pfg@xxxxxxx +174 -159
#
#
# arch/ia64/sn/kernel/irq.c
# 2004/08/11 16:53:26-05:00 pfg@xxxxxxx +210 -226
#
#
diff -Nru a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c
--- a/arch/ia64/sn/kernel/irq.c 2004-08-11 16:55:17 -05:00
+++ b/arch/ia64/sn/kernel/irq.c 2004-08-11 16:55:17 -05:00
@@ -5,97 +5,55 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
*/
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/vmalloc.h>
#include <linux/irq.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/bootmem.h>
-#include <linux/cpumask.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/types.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pciio_private.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/io.h>
#include <asm/sn/intr.h>
#include <asm/sn/addrs.h>
-#include <asm/sn/driver.h>
#include <asm/sn/arch.h>
-#include <asm/sn/pda.h>
-#include <asm/processor.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
+#include <asm/sn/xtalk/xtalk_provider.h>
+#include <asm/sn/xtalk/xwidgetdev.h>
+#include <asm/sn/xtalk/xtalk_sal.h>
+#include <asm/sn/pci/pcibus_provider_defs.h>
+#include <asm/sn/pci/pcidev.h>
+#include <asm/sn/pci/pcibus.h>
+#include <asm/sn/pci/pcibr_provider.h>
#include <asm/sn/sn2/shub_mmr.h>
static void force_interrupt(int irq);
-extern void pcibr_force_interrupt(pcibr_intr_t intr);
-extern int sn_force_interrupt_flag;
-struct irq_desc * sn_irq_desc(unsigned int irq);
-extern cpumask_t __cacheline_aligned pending_irq_cpumask[NR_IRQS];
-
-struct sn_intr_list_t {
- struct sn_intr_list_t *next;
- pcibr_intr_t intr;
-};
+static void register_intr_pda(struct sn_irq_info *sn_irq_info);
+static void unregister_intr_pda(struct sn_irq_info *sn_irq_info);
-static struct sn_intr_list_t *sn_intr_list[NR_IRQS];
-
-
-static unsigned int
-sn_startup_irq(unsigned int irq)
-{
- return(0);
-}
+extern int sn_force_interrupt_flag;
+struct sn_irq_info **sn_irq;
-static void
-sn_shutdown_irq(unsigned int irq)
+static unsigned int sn_startup_irq(unsigned int irq)
{
+ return 0;
}
-static void
-sn_disable_irq(unsigned int irq)
+static void sn_shutdown_irq(unsigned int irq)
{
}
-static void
-sn_enable_irq(unsigned int irq)
+static void sn_disable_irq(unsigned int irq)
{
}
-static inline void sn_move_irq(int irq)
+static void sn_enable_irq(unsigned int irq)
{
- /* note - we hold desc->lock */
- cpumask_t tmp;
- irq_desc_t *desc = irq_descp(irq);
-
- if (!cpus_empty(pending_irq_cpumask[irq])) {
- cpus_and(tmp, pending_irq_cpumask[irq], cpu_online_map);
- if (unlikely(!cpus_empty(tmp))) {
- desc->handler->set_affinity(irq, pending_irq_cpumask[irq]);
- }
- cpus_clear(pending_irq_cpumask[irq]);
- }
}
-static void
-sn_ack_irq(unsigned int irq)
+static void sn_ack_irq(unsigned int irq)
{
- unsigned long event_occurred, mask = 0;
+ uint64_t event_occurred, mask = 0;
int nasid;
irq = irq & 0xff;
nasid = smp_physical_node_id();
- event_occurred = HUB_L( (unsigned long *)GLOBAL_MMR_ADDR(nasid,SH_EVENT_OCCURRED) );
+ event_occurred =
+ HUB_L((uint64_t *) GLOBAL_MMR_ADDR(nasid, SH_EVENT_OCCURRED));
if (event_occurred & SH_EVENT_OCCURRED_UART_INT_MASK) {
mask |= (1 << SH_EVENT_OCCURRED_UART_INT_SHFT);
}
@@ -108,63 +66,91 @@
if (event_occurred & SH_EVENT_OCCURRED_II_INT1_MASK) {
mask |= (1 << SH_EVENT_OCCURRED_II_INT1_SHFT);
}
- HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_EVENT_OCCURRED_ALIAS), mask );
+ HUB_S((uint64_t *) GLOBAL_MMR_ADDR(nasid, SH_EVENT_OCCURRED_ALIAS),
+ mask);
__set_bit(irq, (volatile void *)pda->sn_in_service_ivecs);
- sn_move_irq(irq);
}
-static void
-sn_end_irq(unsigned int irq)
+static void sn_end_irq(unsigned int irq)
{
int nasid;
int ivec;
- unsigned long event_occurred;
- irq_desc_t *desc = sn_irq_desc(irq);
- unsigned int status = desc->status;
+ uint64_t event_occurred;
ivec = irq & 0xff;
if (ivec == SGI_UART_VECTOR) {
nasid = smp_physical_node_id();
- event_occurred = HUB_L( (unsigned long *)GLOBAL_MMR_ADDR(nasid,SH_EVENT_OCCURRED) );
- // If the UART bit is set here, we may have received an interrupt from the
- // UART that the driver missed. To make sure, we IPI ourselves to force us
- // to look again.
+ event_occurred = HUB_L((uint64_t *) GLOBAL_MMR_ADDR
+ (nasid, SH_EVENT_OCCURRED));
+ /* If the UART bit is set here, we may have received an
+ * interrupt from the UART that the driver missed. To
+ * make sure, we IPI ourselves to force us to look again.
+ */
if (event_occurred & SH_EVENT_OCCURRED_UART_INT_MASK) {
- platform_send_ipi(smp_processor_id(), SGI_UART_VECTOR, IA64_IPI_DM_INT, 0);
+ platform_send_ipi(smp_processor_id(), SGI_UART_VECTOR,
+ IA64_IPI_DM_INT, 0);
}
}
__clear_bit(ivec, (volatile void *)pda->sn_in_service_ivecs);
if (sn_force_interrupt_flag)
- if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS)))
- force_interrupt(irq);
+ force_interrupt(irq);
}
-static void
-sn_set_affinity_irq(unsigned int irq, cpumask_t mask)
+static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask)
{
-#ifdef CONFIG_SMP
- int redir = 0;
- int cpu;
- struct sn_intr_list_t *p = sn_intr_list[irq];
- pcibr_intr_t intr;
- extern void sn_shub_redirect_intr(pcibr_intr_t intr, unsigned long cpu);
- extern void sn_tio_redirect_intr(pcibr_intr_t intr, unsigned long cpu);
-
- if (p == NULL)
- return;
-
- intr = p->intr;
-
- if (intr == NULL)
- return;
-
- cpu = first_cpu(mask);
- sn_shub_redirect_intr(intr, cpu);
- irq = irq & 0xff; /* strip off redirect bit, if someone stuck it on. */
- (void) set_irq_affinity_info(irq, cpu_physical_id(intr->bi_cpu), redir);
-#endif /* CONFIG_SMP */
-}
+ struct sn_irq_info *sn_irq_info = sn_irq[irq];
+ int cpuid, cpuphys;
+ nasid_t t_nasid; /* nasid to target */
+ int t_slice; /* slice to target */
+
+ cpuid = first_cpu(mask);
+ cpuphys = cpu_physical_id(cpuid);
+ t_nasid = cpu_physical_id_to_nasid(cpuphys);
+ t_slice = cpu_physical_id_to_slice(cpuphys);
+
+ while (sn_irq_info) {
+ struct xwidget_info *xwidget_info =
+ sn_irq_info->irq_xwidgetinfo;
+ struct sn_irq_info *new_sn_irq_info, *next_sn_irq_info;
+
+ new_sn_irq_info = (xwidget_info->xwi_khub_provider->intr_alloc)
+ (xwidget_info, irq, t_nasid, t_slice);
+ if (new_sn_irq_info) {
+ int bridge_type = sn_irq_info->irq_bridge_type;
+ uint64_t xtalk_addr = new_sn_irq_info->irq_xtalkaddr;
+ struct sn_irq_info *next_info =
+ new_sn_irq_info->irq_next;
+
+ *new_sn_irq_info = *sn_irq_info; /* struct copy */
+ new_sn_irq_info->irq_next = next_info;
+ new_sn_irq_info->irq_xtalkaddr = xtalk_addr;
+ new_sn_irq_info->irq_nasid = t_nasid;
+ new_sn_irq_info->irq_slice = t_slice;
+ new_sn_irq_info->irq_cpuid = cpuid;
+
+ if (IS_PCI_BRIDGE_ASIC(bridge_type) &&
+ (new_sn_irq_info->irq_bridge != NULL)) {
+ pcibr_change_devices_irq(new_sn_irq_info);
+ }
+
+ /* unregister the old irq, register the new one */
+ unregister_intr_pda(sn_irq_info);
+ register_intr_pda(new_sn_irq_info);
+
+ next_sn_irq_info = sn_irq_info->irq_next;
+ /* Free the old sn_irq_info */
+ (xwidget_info->xwi_khub_provider->intr_free)
+ (xwidget_info, sn_irq_info);
+
+ sn_irq_info = next_sn_irq_info;
+
+ set_irq_affinity_info((irq & 0xff), cpuphys, 0);
+ } else {
+ break; /* snp_affiity failed the intr_alloc */
+ }
+ }
+}
struct hw_interrupt_type irq_type_sn = {
"SN hub",
@@ -172,208 +158,206 @@
sn_shutdown_irq,
sn_enable_irq,
sn_disable_irq,
- sn_ack_irq,
+ sn_ack_irq,
sn_end_irq,
sn_set_affinity_irq
};
-
-struct irq_desc *
-sn_irq_desc(unsigned int irq)
+struct irq_desc *sn_irq_desc(unsigned int irq)
{
irq = SN_IVEC_FROM_IRQ(irq);
- return(_irq_desc + irq);
+ return (_irq_desc + irq);
}
-u8
-sn_irq_to_vector(unsigned int irq)
+u8 sn_irq_to_vector(u8 irq)
{
- return(irq);
+ return irq;
}
-unsigned int
-sn_local_vector_to_irq(u8 vector)
+unsigned int sn_local_vector_to_irq(u8 vector)
{
return (CPU_VECTOR_TO_IRQ(smp_processor_id(), vector));
}
-void
-sn_irq_init (void)
+void sn_irq_init(void)
{
int i;
irq_desc_t *base_desc = _irq_desc;
- for (i=0; i<NR_IRQS; i++) {
+ for (i = 0; i < NR_IRQS; i++) {
if (base_desc[i].handler == &no_irq_type) {
base_desc[i].handler = &irq_type_sn;
}
}
}
-void
-register_pcibr_intr(int irq, pcibr_intr_t intr)
+static void register_intr_pda(struct sn_irq_info *sn_irq_info)
{
- struct sn_intr_list_t *p = kmalloc(sizeof(struct sn_intr_list_t), GFP_KERNEL);
- struct sn_intr_list_t *list;
- int cpu = intr->bi_cpu;
+ int irq = sn_irq_info->irq_irq;
+ int cpu = sn_irq_info->irq_cpuid;
if (pdacpu(cpu)->sn_last_irq < irq) {
pdacpu(cpu)->sn_last_irq = irq;
}
- if (pdacpu(cpu)->sn_first_irq == 0 || pdacpu(cpu)->sn_first_irq > irq) pdacpu(cpu)->sn_first_irq = irq;
- if (!p) panic("Could not allocate memory for sn_intr_list_t\n");
- if ((list = sn_intr_list[irq])) {
- while (list->next) list = list->next;
- list->next = p;
- p->next = NULL;
- p->intr = intr;
- } else {
- sn_intr_list[irq] = p;
- p->next = NULL;
- p->intr = intr;
+
+ if (pdacpu(cpu)->sn_first_irq == 0 || pdacpu(cpu)->sn_first_irq > irq) {
+ pdacpu(cpu)->sn_first_irq = irq;
}
}
-void
-unregister_pcibr_intr(int irq, pcibr_intr_t intr)
+static void unregister_intr_pda(struct sn_irq_info *sn_irq_info)
{
+ int irq = sn_irq_info->irq_irq;
+ int cpu = sn_irq_info->irq_cpuid;
+ struct sn_irq_info *tmp_irq_info;
+ int i, foundmatch;
- struct sn_intr_list_t **prev, *curr;
- int cpu = intr->bi_cpu;
- int i;
-
- if (sn_intr_list[irq] == NULL)
- return;
-
- prev = &sn_intr_list[irq];
- curr = sn_intr_list[irq];
- while (curr) {
- if (curr->intr == intr) {
- *prev = curr->next;
- break;
+ if (pdacpu(cpu)->sn_last_irq == irq) {
+ foundmatch = 0;
+ for (i = pdacpu(cpu)->sn_last_irq - 1; i; i--) {
+ tmp_irq_info = sn_irq[i];
+ while (tmp_irq_info) {
+ if (tmp_irq_info->irq_cpuid == cpu) {
+ foundmatch++;
+ break;
+ }
+ tmp_irq_info = tmp_irq_info->irq_next;
+ }
+ if (foundmatch) {
+ break;
+ }
}
- prev = &curr->next;
- curr = curr->next;
+ pdacpu(cpu)->sn_last_irq = i;
}
- if (curr)
- kfree(curr);
-
- if (!sn_intr_list[irq]) {
- if (pdacpu(cpu)->sn_last_irq == irq) {
- for (i = pdacpu(cpu)->sn_last_irq - 1; i; i--)
- if (sn_intr_list[i])
+ if (pdacpu(cpu)->sn_first_irq == irq) {
+ foundmatch = 0;
+ for (i = pdacpu(cpu)->sn_first_irq + 1; i < NR_IRQS; i++) {
+ tmp_irq_info = sn_irq[i];
+ while (tmp_irq_info) {
+ if (tmp_irq_info->irq_cpuid == cpu) {
+ foundmatch++;
break;
- pdacpu(cpu)->sn_last_irq = i;
- }
-
- if (pdacpu(cpu)->sn_first_irq == irq) {
- pdacpu(cpu)->sn_first_irq = 0;
- for (i = pdacpu(cpu)->sn_first_irq + 1; i < NR_IRQS; i++)
- if (sn_intr_list[i])
- pdacpu(cpu)->sn_first_irq = i;
+ }
+ tmp_irq_info = tmp_irq_info->irq_next;
+ }
+ if (foundmatch) {
+ break;
+ }
}
+ pdacpu(cpu)->sn_first_irq = ((i == NR_IRQS) ? 0 : i);
}
-
}
-void
-force_polled_int(void)
+void sn_irq_setup(void)
{
+ struct sn_irq_info *sn_irq_info;
int i;
- struct sn_intr_list_t *p;
- for (i=0; i<NR_IRQS;i++) {
- p = sn_intr_list[i];
- while (p) {
- if (p->intr){
- pcibr_force_interrupt(p->intr);
- }
- p = p->next;
+ for (i = 0; i < NR_IRQS; i++) {
+ /* set the cpuid in all the sn_irq_info_s structures
+ * and update sn_first_irq & sn_last_irq in the PDA
+ */
+ sn_irq_info = sn_irq[i];
+ while (sn_irq_info) {
+ nasid_t nasid = sn_irq_info->irq_nasid;
+ int slice = sn_irq_info->irq_slice;
+ int cpu = nasid_slice_to_cpuid(nasid, slice);
+ sn_irq_info->irq_cpuid = cpu;
+ (void)register_intr_pda(sn_irq_info);
+ sn_irq_info = sn_irq_info->irq_next;
}
}
}
-static void
-force_interrupt(int irq)
+static void force_interrupt(int irq)
{
- struct sn_intr_list_t *p = sn_intr_list[irq];
+ struct sn_irq_info *sn_irq_info = sn_irq[irq];
- while (p) {
- if (p->intr) {
- pcibr_force_interrupt(p->intr);
+ while (sn_irq_info) {
+ if (IS_PCI_BRIDGE_ASIC(sn_irq_info->irq_bridge_type) &&
+ (sn_irq_info->irq_bridge != NULL)) {
+ pcibr_force_interrupt(sn_irq_info);
}
- p = p->next;
+ sn_irq_info = sn_irq_info->irq_next;
}
}
/*
-Check for lost interrupts. If the PIC int_status reg. says that
-an interrupt has been sent, but not handled, and the interrupt
-is not pending in either the cpu irr regs or in the soft irr regs,
-and the interrupt is not in service, then the interrupt may have
-been lost. Force an interrupt on that pin. It is possible that
-the interrupt is in flight, so we may generate a spurious interrupt,
-but we should never miss a real lost interrupt.
-*/
-
-static void
-sn_check_intr(int irq, pcibr_intr_t intr)
+ * Check for lost interrupts. If the PIC int_status reg. says that
+ * an interrupt has been sent, but not handled, and the interrupt
+ * is not pending in either the cpu irr regs or in the soft irr regs,
+ * and the interrupt is not in service, then the interrupt may have
+ * been lost. Force an interrupt on that pin. It is possible that
+ * the interrupt is in flight, so we may generate a spurious interrupt,
+ * but we should never miss a real lost interrupt.
+ */
+static void sn_check_intr(int irq, struct sn_irq_info *sn_irq_info)
{
- unsigned long regval;
+ uint64_t regval;
int irr_reg_num;
int irr_bit;
- unsigned long irr_reg;
+ uint64_t irr_reg;
+ struct pcidev_info *pcidev_info;
+ struct pcibus_info *pcibus_info;
+ pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo;
+ if (!pcidev_info)
+ return;
+
+ pcibus_info = (struct pcibus_info *) pcidev_info->pdi_pcibus_info;
+ regval = pcireg_intr_status_get(pcibus_info);
- regval = pcireg_intr_status_get(intr->bi_soft);
irr_reg_num = irq_to_vector(irq) / 64;
irr_bit = irq_to_vector(irq) % 64;
switch (irr_reg_num) {
- case 0:
- irr_reg = ia64_getreg(_IA64_REG_CR_IRR0);
- break;
- case 1:
- irr_reg = ia64_getreg(_IA64_REG_CR_IRR1);
- break;
- case 2:
- irr_reg = ia64_getreg(_IA64_REG_CR_IRR2);
- break;
- case 3:
- irr_reg = ia64_getreg(_IA64_REG_CR_IRR3);
- break;
- }
- if (!test_bit(irr_bit, &irr_reg) ) {
- if (!test_bit(irq, pda->sn_soft_irr) ) {
- if (!test_bit(irq, pda->sn_in_service_ivecs) ) {
+ case 0:
+ irr_reg = ia64_getreg(_IA64_REG_CR_IRR0);
+ break;
+ case 1:
+ irr_reg = ia64_getreg(_IA64_REG_CR_IRR1);
+ break;
+ case 2:
+ irr_reg = ia64_getreg(_IA64_REG_CR_IRR2);
+ break;
+ case 3:
+ irr_reg = ia64_getreg(_IA64_REG_CR_IRR3);
+ break;
+ }
+ if (!test_bit(irr_bit, &irr_reg)) {
+ if (!test_bit(irq, pda->sn_soft_irr)) {
+ if (!test_bit(irq, pda->sn_in_service_ivecs)) {
regval &= 0xff;
- if (intr->bi_ibits & regval & intr->bi_last_intr) {
- regval &= ~(intr->bi_ibits & regval);
- pcibr_force_interrupt(intr);
+ if (sn_irq_info->irq_int_bit & regval &
+ sn_irq_info->irq_last_intr) {
+ regval &=
+ ~(sn_irq_info->
+ irq_int_bit & regval);
+ pcibr_force_interrupt(sn_irq_info);
}
}
}
}
- intr->bi_last_intr = regval;
+ sn_irq_info->irq_last_intr = regval;
}
-void
-sn_lb_int_war_check(void)
+void sn_lb_int_war_check(void)
{
int i;
- if (pda->sn_first_irq == 0) return;
- for (i=pda->sn_first_irq;
- i <= pda->sn_last_irq; i++) {
- struct sn_intr_list_t *p = sn_intr_list[i];
- if (p == NULL) {
- continue;
- }
- while (p) {
- sn_check_intr(i, p->intr);
- p = p->next;
+ if (pda->sn_first_irq == 0)
+ return;
+ for (i = pda->sn_first_irq; i <= pda->sn_last_irq; i++) {
+ struct sn_irq_info *sn_irq_info = sn_irq[i];
+ while (sn_irq_info) {
+ /* Only call for PCI bridges that are fully initialized. */
+ if (IS_PCI_BRIDGE_ASIC(sn_irq_info->irq_bridge_type) &&
+ (sn_irq_info->irq_bridge != NULL)) {
+ sn_check_intr(i, sn_irq_info);
}
+ sn_irq_info = sn_irq_info->irq_next;
+ }
}
}
diff -Nru a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
--- a/arch/ia64/sn/kernel/setup.c 2004-08-11 16:55:17 -05:00
+++ b/arch/ia64/sn/kernel/setup.c 2004-08-11 16:55:17 -05:00
@@ -3,7 +3,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 1999,2001-2003 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1999,2001-2004 Silicon Graphics, Inc. All rights reserved.
*/
#include <linux/config.h>
@@ -35,44 +35,50 @@
#include <asm/system.h>
#include <asm/processor.h>
#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
#include <asm/sn/arch.h>
#include <asm/sn/addrs.h>
#include <asm/sn/pda.h>
#include <asm/sn/nodepda.h>
#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/sn_private.h>
#include <asm/sn/simulator.h>
#include <asm/sn/leds.h>
#include <asm/sn/bte.h>
#include <asm/sn/clksupport.h>
#include <asm/sn/sn_sal.h>
#include <asm/sn/sn2/shub.h>
+#include <asm/sn/klconfig.h>
DEFINE_PER_CPU(struct pda_s, pda_percpu);
-#define MAX_PHYS_MEMORY (1UL << 49) /* 1 TB */
+#define MAX_PHYS_MEMORY (1UL << 49) /* 1 TB */
-extern void bte_init_node (nodepda_t *, cnodeid_t);
+lboard_t *root_lboard[MAX_COMPACT_NODES];
+
+extern hubdev_init_node(nodepda_t *, cnodeid_t);
+extern void bte_init_node(nodepda_t *, cnodeid_t);
+extern void bte_init_cpu(void);
extern void sn_timer_init(void);
extern unsigned long last_time_offset;
-extern void init_platform_hubinfo(nodepda_t **nodepdaindr);
-extern void (*ia64_mark_idle)(int);
+extern void (*ia64_mark_idle) (int);
extern void snidle(int);
extern unsigned char acpi_kbd_controller_present;
+unsigned long sn_rtc_cycles_per_second;
-unsigned long sn_rtc_cycles_per_second;
+EXPORT_SYMBOL(sn_rtc_cycles_per_second);
partid_t sn_partid = -1;
+EXPORT_SYMBOL(sn_partid);
char sn_system_serial_number_string[128];
+EXPORT_SYMBOL(sn_system_serial_number_string);
u64 sn_partition_serial_number;
+EXPORT_SYMBOL(sn_partition_serial_number);
short physical_node_map[MAX_PHYSNODE_ID];
EXPORT_SYMBOL(physical_node_map);
-int numionodes;
+int numionodes;
/*
* 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],
@@ -86,11 +92,7 @@
static void sn_init_pdas(char **);
static void scan_for_ionodes(void);
-
-static nodepda_t *nodepdaindr[MAX_COMPACT_NODES];
-
-irqpda_t *irqpdaindr;
-
+static nodepda_t *nodepdaindr[MAX_COMPACT_NODES];
/*
* The format of "screen_info" is strange, and due to early i386-setup
@@ -98,14 +100,14 @@
* VGA color display.
*/
struct screen_info sn_screen_info = {
- .orig_x = 0,
- .orig_y = 0,
- .orig_video_mode = 3,
- .orig_video_cols = 80,
- .orig_video_ega_bx = 3,
- .orig_video_lines = 25,
- .orig_video_isVGA = 1,
- .orig_video_points = 16
+ .orig_x = 0,
+ .orig_y = 0,
+ .orig_video_mode = 3,
+ .orig_video_cols = 80,
+ .orig_video_ega_bx = 3,
+ .orig_video_lines = 25,
+ .orig_video_isVGA = 1,
+ .orig_video_points = 16
};
/*
@@ -117,9 +119,9 @@
* is sufficient (the IDE driver will autodetect the drive geometry).
*/
#ifdef CONFIG_IA64_GENERIC
-extern char drive_info[4*16];
+extern char drive_info[4 * 16];
#else
-char drive_info[4*16];
+char drive_info[4 * 16];
#endif
/*
@@ -131,8 +133,7 @@
* may not be initialized yet.
*/
-static int __init
-pxm_to_nasid(int pxm)
+static int __init pxm_to_nasid(int pxm)
{
int i;
int nid;
@@ -145,6 +146,7 @@
}
return -1;
}
+
/**
* early_sn_setup - early setup routine for SN platforms
*
@@ -152,16 +154,15 @@
* for bringup. See start_kernel() in init/main.c.
*/
-void __init
-early_sn_setup(void)
+void __init early_sn_setup(void)
{
- void ia64_sal_handler_init (void *entry_point, void *gpval);
- efi_system_table_t *efi_systab;
- efi_config_table_t *config_tables;
- struct ia64_sal_systab *sal_systab;
- struct ia64_sal_desc_entry_point *ep;
- char *p;
- int i;
+ void ia64_sal_handler_init(void *entry_point, void *gpval);
+ efi_system_table_t *efi_systab;
+ efi_config_table_t *config_tables;
+ struct ia64_sal_systab *sal_systab;
+ struct ia64_sal_desc_entry_point *ep;
+ char *p;
+ int i;
/*
* Parse enough of the SAL tables to locate the SAL entry point. Since, console
@@ -170,16 +171,20 @@
* This code duplicates some of the ACPI table parsing that is in efi.c & sal.c.
* Any changes to those file may have to be made hereas well.
*/
- efi_systab = (efi_system_table_t*)__va(ia64_boot_param->efi_systab);
+ efi_systab = (efi_system_table_t *) __va(ia64_boot_param->efi_systab);
config_tables = __va(efi_systab->tables);
for (i = 0; i < efi_systab->nr_tables; i++) {
- if (efi_guidcmp(config_tables[i].guid, SAL_SYSTEM_TABLE_GUID) == 0) {
+ if (efi_guidcmp(config_tables[i].guid, SAL_SYSTEM_TABLE_GUID) ==
+ 0) {
sal_systab = __va(config_tables[i].table);
- p = (char*)(sal_systab+1);
+ p = (char *)(sal_systab + 1);
for (i = 0; i < sal_systab->entry_count; i++) {
if (*p == SAL_DESC_ENTRY_POINT) {
- ep = (struct ia64_sal_desc_entry_point *) p;
- ia64_sal_handler_init(__va(ep->sal_proc), __va(ep->gp));
+ ep = (struct ia64_sal_desc_entry_point
+ *)p;
+ ia64_sal_handler_init(__va
+ (ep->sal_proc),
+ __va(ep->gp));
break;
}
p += SAL_DESC_SIZE(*p);
@@ -187,9 +192,12 @@
}
}
- if ( IS_RUNNING_ON_SIMULATOR() ) {
- master_node_bedrock_address = (u64)REMOTE_HUB(get_nasid(), SH_JUNK_BUS_UART0);
- printk(KERN_DEBUG "early_sn_setup: setting master_node_bedrock_address to 0x%lx\n", master_node_bedrock_address);
+ if (IS_RUNNING_ON_SIMULATOR()) {
+ master_node_bedrock_address =
+ (u64) REMOTE_HUB(get_nasid(), SH_JUNK_BUS_UART0);
+ printk(KERN_DEBUG
+ "early_sn_setup: setting master_node_bedrock_address to 0x%lx\n",
+ master_node_bedrock_address);
}
}
@@ -197,55 +205,32 @@
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)
+static inline int __init is_shub_1_1(int nasid)
{
unsigned long id;
- int rev;
+ int rev;
id = REMOTE_HUB_L(nasid, SH_SHUB_ID);
- rev = (id & SH_SHUB_ID_REVISION_MASK) >> SH_SHUB_ID_REVISION_SHFT;
+ rev = (id & SH_SHUB_ID_REVISION_MASK) >> SH_SHUB_ID_REVISION_SHFT;
return rev <= 2;
}
-static void __init
-sn_check_for_wars(void)
+static void __init sn_check_for_wars(void)
{
- int cnode;
+ int cnode;
- for (cnode=0; cnode< numnodes; cnode++)
+ for (cnode = 0; cnode < numnodes; cnode++)
if (is_shub_1_1(cnodeid_to_nasid(cnode)))
shub_1_1_found = 1;
}
/**
- * sn_set_error_handling_features - Tell the SN prom how to handle certain
- * error types.
- */
-static void __init
-sn_set_error_handling_features(void)
-{
- u64 ret;
- u64 sn_ehf_bits[7]; /* see ia64_sn_set_error_handling_features */
- memset(sn_ehf_bits, 0, sizeof(sn_ehf_bits));
-#define EHF(x) __set_bit(SN_SAL_EHF_ ## x, sn_ehf_bits)
- EHF(MCA_SLV_TO_OS_INIT_SLV);
- EHF(NO_RZ_TLBC);
- // Uncomment once Jesse's code goes in - EHF(NO_RZ_IO_READ);
-#undef EHF
- ret = ia64_sn_set_error_handling_features(sn_ehf_bits);
- if (ret)
- printk(KERN_ERR "%s: failed, return code %ld\n", __FUNCTION__, ret);
-}
-
-/**
* sn_setup - SN platform setup routine
* @cmdline_p: kernel command line
*
@@ -253,15 +238,12 @@
* the RTC frequency (via a SAL call), initializing secondary CPUs, and
* setting up per-node data areas. The console is also initialized here.
*/
-void __init
-sn_setup(char **cmdline_p)
+void __init sn_setup(char **cmdline_p)
{
long status, ticks_per_sec, drift;
int pxm;
int major = sn_sal_rev_major(), minor = sn_sal_rev_minor();
- extern nasid_t snia_get_master_baseio_nasid(void);
extern void sn_cpu_init(void);
- extern nasid_t snia_get_console_nasid(void);
/*
* If the generic code has enabled vga console support - lets
@@ -283,10 +265,10 @@
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++)
+ 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];
-
+ physical_node_map[pxm_to_nasid(pxm)] =
+ pxm_to_nid_map[pxm];
/*
* Old PROMs do not provide an ACPI FADT. Disable legacy keyboard
@@ -313,31 +295,28 @@
}
master_nasid = get_nasid();
- (void)snia_get_console_nasid();
- (void)snia_get_master_baseio_nasid();
- status = ia64_sal_freq_base(SAL_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec, &drift);
+ 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");
+ printk(KERN_WARNING
+ "unable to determine platform RTC clock frequency, guessing.\n");
/* PROM gives wrong value for clock freq. so guess */
- sn_rtc_cycles_per_second = 1000000000000UL/30000UL;
- }
- else
+ sn_rtc_cycles_per_second = 1000000000000UL / 30000UL;
+ } else
sn_rtc_cycles_per_second = ticks_per_sec;
platform_intr_list[ACPI_INTERRUPT_CPEI] = IA64_CPE_VECTOR;
-
- if ( IS_RUNNING_ON_SIMULATOR() )
- {
- master_node_bedrock_address = (u64)REMOTE_HUB(get_nasid(), SH_JUNK_BUS_UART0);
- printk(KERN_DEBUG "sn_setup: setting master_node_bedrock_address to 0x%lx\n",
+ if (IS_RUNNING_ON_SIMULATOR()) {
+ master_node_bedrock_address =
+ (u64) REMOTE_HUB(get_nasid(), SH_JUNK_BUS_UART0);
+ printk(KERN_DEBUG
+ "sn_setup: setting master_node_bedrock_address to 0x%lx\n",
master_node_bedrock_address);
}
- /* Tell the prom how to handle certain error types */
- sn_set_error_handling_features();
-
/*
* we set the default root device to /dev/hda
* to make simulation easy
@@ -357,12 +336,6 @@
*/
sn_cpu_init();
- /*
- * Setup hubinfo stuff. Has to happen AFTER sn_cpu_init(),
- * because it uses the cnode to nasid tables.
- */
- init_platform_hubinfo(nodepdaindr);
-
#ifdef CONFIG_SMP
init_smp_config();
#endif
@@ -376,32 +349,42 @@
*
* One time setup for Node Data Area. Called by sn_setup().
*/
-void __init
-sn_init_pdas(char **cmdline_p)
+void __init sn_init_pdas(char **cmdline_p)
{
- cnodeid_t cnode;
+ cnodeid_t cnode;
- 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]);
+ 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]);
numionodes = numnodes;
scan_for_ionodes();
- /*
- * Allocate & initalize the nodepda for each node.
- */
- for (cnode=0; cnode < numnodes; cnode++) {
- nodepdaindr[cnode] = alloc_bootmem_node(NODE_DATA(cnode), sizeof(nodepda_t));
+ /*
+ * 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));
- }
+ }
/*
- * Now copy the array of nodepda pointers to each nodepda.
+ * Allocate & initialize nodepda for TIOs. For now, put them on node 0.
*/
- for (cnode=0; cnode < numionodes; cnode++)
- memcpy(nodepdaindr[cnode]->pernode_pdaindr, nodepdaindr, sizeof(nodepdaindr));
+ for (cnode = numnodes; cnode < numionodes; 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++)
+ memcpy(nodepdaindr[cnode]->pernode_pdaindr, nodepdaindr,
+ sizeof(nodepdaindr));
/*
* Set up IO related platform-dependent nodepda fields.
@@ -409,8 +392,15 @@
* in nodepda.
*/
for (cnode = 0; cnode < numnodes; cnode++) {
- init_platform_nodepda(nodepdaindr[cnode], cnode);
- bte_init_node (nodepdaindr[cnode], cnode);
+ bte_init_node(nodepdaindr[cnode], cnode);
+ }
+
+ /*
+ * Initialize the per node hubdev. This includes IO Nodes and
+ * headless/memless nodes.
+ */
+ for (cnode = 0; cnode < numionodes; cnode++) {
+ hubdev_init_node(nodepdaindr[cnode], cnode);
}
}
@@ -423,15 +413,14 @@
* Also sets up a few fields in the nodepda. Also known as
* platform_cpu_init() by the ia64 machvec code.
*/
-void __init
-sn_cpu_init(void)
+void __init sn_cpu_init(void)
{
- int cpuid;
- int cpuphyid;
- int nasid;
- int slice;
- int cnode;
- static int wars_have_been_checked;
+ int cpuid;
+ int cpuphyid;
+ int nasid;
+ int slice;
+ int cnode;
+ static int wars_have_been_checked;
/*
* The boot cpu makes this call again after platform initialization is
@@ -448,15 +437,17 @@
memset(pda, 0, sizeof(pda));
pda->p_nodepda = nodepdaindr[cnode];
- pda->led_address = (typeof(pda->led_address)) (LED0 + (slice<<LED_CPU_SHIFT));
+ 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_count = HZ / 2;
pda->hb_state = 0;
pda->idle_flag = 0;
- if (cpuid != 0){
- memcpy(pda->cnodeid_to_nasid_table, pdacpu(0)->cnodeid_to_nasid_table,
- sizeof(pda->cnodeid_to_nasid_table));
+ if (cpuid != 0) {
+ memcpy(pda->cnodeid_to_nasid_table,
+ pdacpu(0)->cnodeid_to_nasid_table,
+ sizeof(pda->cnodeid_to_nasid_table));
}
/*
@@ -470,31 +461,30 @@
wars_have_been_checked = 1;
}
pda->shub_1_1_found = shub_1_1_found;
-
/*
* 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 ) );
+ LOCAL_MMR_ADDR((slice <
+ 2 ? SH_PIO_WRITE_STATUS_0 : SH_PIO_WRITE_STATUS_1));
pda->mem_write_status_addr = (volatile u64 *)
- LOCAL_MMR_ADDR((slice < 2 ? SH_MEMORY_WRITE_STATUS_0 : SH_MEMORY_WRITE_STATUS_1 ) );
+ LOCAL_MMR_ADDR((slice <
+ 2 ? SH_MEMORY_WRITE_STATUS_0 :
+ SH_MEMORY_WRITE_STATUS_1));
if (local_node_data->active_cpu_count++ == 0) {
- int buddy_nasid;
- 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);
+ int buddy_nasid;
+ 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();
}
/*
@@ -502,48 +492,54 @@
* physical_node_map and the pda and increment numionodes.
*/
-static void __init
-scan_for_ionodes(void)
+static void __init scan_for_ionodes(void)
{
int nasid = 0;
lboard_t *brd;
/* Setup ionodes with memory */
- for (nasid = 0; nasid < MAX_PHYSNODE_ID; nasid +=2) {
+ for (nasid = 0; nasid < MAX_PHYSNODE_ID; nasid += 2) {
u64 klgraph_header;
cnodeid_t cnodeid;
- if (physical_node_map[nasid] == -1)
+ if (physical_node_map[nasid] == -1)
continue;
klgraph_header = cnodeid = -1;
klgraph_header = ia64_sn_get_klconfig_addr(nasid);
if (klgraph_header <= 0) {
- if ( IS_RUNNING_ON_SIMULATOR() )
+ if (IS_RUNNING_ON_SIMULATOR())
continue;
- BUG(); /* All nodes must have klconfig tables! */
+ 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);
+ NODE_OFFSET_TO_LBOARD((nasid),
+ ((kl_config_hdr_t
+ *) (klgraph_header))->
+ ch_board_info);
}
/* Scan headless/memless IO Nodes. */
- for (nasid = 0; nasid < MAX_PHYSNODE_ID; nasid +=2) {
+ 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 (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 */
+ brd = KLCF_NEXT_ANY(brd); /* Skip this node's lboard */
if (!brd)
continue;
}
brd = find_lboard_any(brd, KLTYPE_SNIA);
+
while (brd) {
- pda->cnodeid_to_nasid_table[numionodes] = brd->brd_nasid;
+ pda->cnodeid_to_nasid_table[numionodes] =
+ brd->brd_nasid;
physical_node_map[brd->brd_nasid] = numionodes;
root_lboard[numionodes] = brd;
numionodes++;
@@ -554,4 +550,23 @@
brd = find_lboard_any(brd, KLTYPE_SNIA);
}
}
+
+ /* 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);
+ while (brd) {
+ pda->cnodeid_to_nasid_table[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);
+ }
+ }
+
}
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/