/* Setup timer on comparator RTC1 */ static void mmtimer_setup_int_0(int cpu, u64 expires) { u64 val; /* Disable interrupt */ HUB_S((u64 *)LOCAL_MMR_ADDR(SH_RTC1_INT_ENABLE), 0UL); /* Initialize comparator value */ HUB_S((u64 *)LOCAL_MMR_ADDR(SH_INT_CMPB), -1L); /* Clear pending bit */ mmtimer_clr_int_pending(0); val = ((u64)SGI_MMTIMER_VECTOR << SH_RTC1_INT_CONFIG_IDX_SHFT) | ((u64)cpu_physical_id(cpu) << SH_RTC1_INT_CONFIG_PID_SHFT); /* Set configuration */ HUB_S((u64 *)LOCAL_MMR_ADDR(SH_RTC1_INT_CONFIG), val); /* Enable RTC interrupts */ HUB_S((u64 *)LOCAL_MMR_ADDR(SH_RTC1_INT_ENABLE), 1UL); /* Initialize comparator value */ HUB_S((u64 *)LOCAL_MMR_ADDR(SH_INT_CMPB), expires); }
/* * Change protections to allow IPI operations (and AMO operations on * Shub 1.1 systems). */ void xpc_allow_IPI_ops(void) { int node; int nasid; // >>> Change SH_IPI_ACCESS code to use SAL call once it is available. if (is_shub2()) { xpc_sh2_IPI_access0 = (u64) HUB_L((u64 *) LOCAL_MMR_ADDR(SH2_IPI_ACCESS0)); xpc_sh2_IPI_access1 = (u64) HUB_L((u64 *) LOCAL_MMR_ADDR(SH2_IPI_ACCESS1)); xpc_sh2_IPI_access2 = (u64) HUB_L((u64 *) LOCAL_MMR_ADDR(SH2_IPI_ACCESS2)); xpc_sh2_IPI_access3 = (u64) HUB_L((u64 *) LOCAL_MMR_ADDR(SH2_IPI_ACCESS3)); for_each_online_node(node) { nasid = cnodeid_to_nasid(node); HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS0), -1UL); HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS1), -1UL); HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS2), -1UL); HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS3), -1UL); } } else {
static int mmtimer_disable_int(long nasid, int comparator) { switch (comparator) { case 0: nasid == -1 ? HUB_S((u64 *)LOCAL_MMR_ADDR(SH_RTC1_INT_ENABLE), 0UL) : REMOTE_HUB_S(nasid, SH_RTC1_INT_ENABLE, 0UL); break; case 1: nasid == -1 ? HUB_S((u64 *)LOCAL_MMR_ADDR(SH_RTC2_INT_ENABLE), 0UL) : REMOTE_HUB_S(nasid, SH_RTC2_INT_ENABLE, 0UL); break; case 2: nasid == -1 ? HUB_S((u64 *)LOCAL_MMR_ADDR(SH_RTC3_INT_ENABLE), 0UL) : REMOTE_HUB_S(nasid, SH_RTC3_INT_ENABLE, 0UL); break; default: return -EFAULT; } return 0; }
/* Setup timer on comparator RTC3 */ static void mmtimer_setup_int_2(int cpu, u64 expires) { u64 val; HUB_S((u64 *)LOCAL_MMR_ADDR(SH_RTC3_INT_ENABLE), 0UL); HUB_S((u64 *)LOCAL_MMR_ADDR(SH_INT_CMPD), -1L); mmtimer_clr_int_pending(2); val = ((u64)SGI_MMTIMER_VECTOR << SH_RTC3_INT_CONFIG_IDX_SHFT) | ((u64)cpu_physical_id(cpu) << SH_RTC3_INT_CONFIG_PID_SHFT); HUB_S((u64 *)LOCAL_MMR_ADDR(SH_RTC3_INT_CONFIG), val); HUB_S((u64 *)LOCAL_MMR_ADDR(SH_RTC3_INT_ENABLE), 1UL); HUB_S((u64 *)LOCAL_MMR_ADDR(SH_INT_CMPD), expires); }
static void sn_ack_irq(unsigned int irq) { u64 event_occurred, mask; irq = irq & 0xff; event_occurred = HUB_L((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED)); mask = event_occurred & SH_ALL_INT_MASK; HUB_S((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED_ALIAS), mask); __set_bit(irq, (volatile void *)pda->sn_in_service_ivecs); move_native_irq(irq); }
/*ARGSUSED*/ int cpuprom_map(devfs_handle_t dev, vhandl_t *vt, off_t addr, size_t len) { int errcode; caddr_t kvaddr; devfs_handle_t node; cnodeid_t cnode; node = prominfo_nodeget(dev); if (!node) return EIO; kvaddr = hubdev_prombase_get(node); cnode = hubdev_cnodeid_get(node); #ifdef HUBSPC_DEBUG printf("cpuprom_map: hubnode %d kvaddr 0x%x\n", node, kvaddr); #endif if (len > RBOOT_SIZE) len = RBOOT_SIZE; /* * Map in the prom space */ errcode = v_mapphys(vt, kvaddr, len); if (errcode == 0 ) { /* * Set the MD configuration registers suitably. */ nasid_t nasid; uint64_t value; volatile hubreg_t *regaddr; nasid = COMPACT_TO_NASID_NODEID(cnode); regaddr = REMOTE_HUB_ADDR(nasid, FPROM_CONFIG_ADDR); value = HUB_L(regaddr); value &= ~(FPROM_SETUP_MASK | FPROM_ENABLE_MASK); { value |= (((long)CONFIG_FPROM_SETUP << FPROM_SETUP_SHFT) | ((long)CONFIG_FPROM_ENABLE << FPROM_ENABLE_SHFT)); } HUB_S(regaddr, value); } return (errcode); }
static void sn_ack_irq(unsigned int irq) { uint64_t event_occurred, mask = 0; int nasid; irq = irq & 0xff; nasid = get_nasid(); event_occurred = HUB_L((uint64_t *) GLOBAL_MMR_ADDR(nasid, SH_EVENT_OCCURRED)); mask = event_occurred & SH_ALL_INT_MASK; HUB_S((uint64_t *) GLOBAL_MMR_ADDR(nasid, SH_EVENT_OCCURRED_ALIAS), mask); __set_bit(irq, (volatile void *)pda->sn_in_service_ivecs); move_irq(irq); }
static void sn_ack_irq(unsigned int irq) { unsigned long 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) ); if (event_occurred & SH_EVENT_OCCURRED_UART_INT_MASK) { mask |= (1 << SH_EVENT_OCCURRED_UART_INT_SHFT); } if (event_occurred & SH_EVENT_OCCURRED_IPI_INT_MASK) { mask |= (1 << SH_EVENT_OCCURRED_IPI_INT_SHFT); } if (event_occurred & SH_EVENT_OCCURRED_II_INT0_MASK) { mask |= (1 << SH_EVENT_OCCURRED_II_INT0_SHFT); } 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 ); __set_bit(irq, (volatile void *)pda.sn_in_service_ivecs); }
static void sn_ack_irq(unsigned int irq) { #ifdef CONFIG_IA64_SGI_SN1 int bit = -1; unsigned long long intpend_val; int subnode; #endif #ifdef CONFIG_IA64_SGI_SN2 unsigned long event_occurred, mask = 0; #endif int nasid; irq = irq & 0xff; nasid = smp_physical_node_id(); #ifdef CONFIG_IA64_SGI_SN1 subnode = cpuid_to_subnode(smp_processor_id()); if (irq == SGI_UART_IRQ) { intpend_val = REMOTE_HUB_PI_L(nasid, subnode, PI_INT_PEND0); if (intpend_val & (1L<<GFX_INTR_A) ) { bit = GFX_INTR_A; REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit); } if ( intpend_val & (1L<<GFX_INTR_B) ) { bit = GFX_INTR_B; REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit); } if (intpend_val & (1L<<PG_MIG_INTR) ) { bit = PG_MIG_INTR; REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit); } if (intpend_val & (1L<<CC_PEND_A)) { bit = CC_PEND_A; REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit); } if (intpend_val & (1L<<CC_PEND_B)) { bit = CC_PEND_B; REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit); } return; } bit = irq_to_bit_pos(irq); REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit); #endif #ifdef CONFIG_IA64_SGI_SN2 event_occurred = HUB_L( (unsigned long *)GLOBAL_MMR_ADDR(nasid,SH_EVENT_OCCURRED) ); if (event_occurred & SH_EVENT_OCCURRED_UART_INT_MASK) { mask |= (1 << SH_EVENT_OCCURRED_UART_INT_SHFT); } if (event_occurred & SH_EVENT_OCCURRED_IPI_INT_MASK) { mask |= (1 << SH_EVENT_OCCURRED_IPI_INT_SHFT); } if (event_occurred & SH_EVENT_OCCURRED_II_INT0_MASK) { mask |= (1 << SH_EVENT_OCCURRED_II_INT0_SHFT); } 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 ); #endif }
/* Clear the RTC interrupt pending bit */ static void mmtimer_clr_int_pending(int comparator) { HUB_S((u64 *)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED_ALIAS), SH_EVENT_OCCURRED_RTC1_INT_MASK << comparator); }
void intr_init_vecblk( nodepda_t *npda, cnodeid_t node, int sn) { int nasid = cnodeid_to_nasid(node); sh_ii_int0_config_u_t ii_int_config; cpuid_t cpu; cpuid_t cpu0, cpu1; nodepda_t *lnodepda; sh_ii_int0_enable_u_t ii_int_enable; sh_int_node_id_config_u_t node_id_config; sh_local_int5_config_u_t local5_config; sh_local_int5_enable_u_t local5_enable; extern void sn_init_cpei_timer(void); static int timer_added = 0; if (is_headless_node(node) ) { int cnode; struct ia64_sal_retval ret_stuff; // retarget all interrupts on this node to the master node. node_id_config.sh_int_node_id_config_regval = 0; node_id_config.sh_int_node_id_config_s.node_id = master_nasid; node_id_config.sh_int_node_id_config_s.id_sel = 1; HUB_S( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_INT_NODE_ID_CONFIG), node_id_config.sh_int_node_id_config_regval); cnode = nasid_to_cnodeid(master_nasid); lnodepda = NODEPDA(cnode); cpu = lnodepda->node_first_cpu; cpu = cpu_physical_id(cpu); SAL_CALL(ret_stuff, SN_SAL_REGISTER_CE, nasid, cpu, master_nasid,0,0,0,0); if (ret_stuff.status < 0) { printk("%s: SN_SAL_REGISTER_CE SAL_CALL failed\n",__FUNCTION__); } } else { lnodepda = NODEPDA(node); cpu = lnodepda->node_first_cpu; cpu = cpu_physical_id(cpu); } // Get the physical id's of the cpu's on this node. cpu0 = nasid_slice_to_cpu_physical_id(nasid, 0); cpu1 = nasid_slice_to_cpu_physical_id(nasid, 2); HUB_S( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_PI_ERROR_MASK), 0); HUB_S( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_PI_CRBP_ERROR_MASK), 0); // Config and enable UART interrupt, all nodes. local5_config.sh_local_int5_config_regval = 0; local5_config.sh_local_int5_config_s.idx = SGI_UART_VECTOR; local5_config.sh_local_int5_config_s.pid = cpu; HUB_S( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT5_CONFIG), local5_config.sh_local_int5_config_regval); local5_enable.sh_local_int5_enable_regval = 0; local5_enable.sh_local_int5_enable_s.uart_int = 1; HUB_S( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT5_ENABLE), local5_enable.sh_local_int5_enable_regval); // The II_INT_CONFIG register for cpu 0. ii_int_config.sh_ii_int0_config_regval = 0; ii_int_config.sh_ii_int0_config_s.type = 0; ii_int_config.sh_ii_int0_config_s.agt = 0; ii_int_config.sh_ii_int0_config_s.pid = cpu0; ii_int_config.sh_ii_int0_config_s.base = 0; HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_II_INT0_CONFIG), ii_int_config.sh_ii_int0_config_regval); // The II_INT_CONFIG register for cpu 1. ii_int_config.sh_ii_int0_config_regval = 0; ii_int_config.sh_ii_int0_config_s.type = 0; ii_int_config.sh_ii_int0_config_s.agt = 0; ii_int_config.sh_ii_int0_config_s.pid = cpu1; ii_int_config.sh_ii_int0_config_s.base = 0; HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_II_INT1_CONFIG), ii_int_config.sh_ii_int0_config_regval); // Enable interrupts for II_INT0 and 1. ii_int_enable.sh_ii_int0_enable_regval = 0; ii_int_enable.sh_ii_int0_enable_s.ii_enable = 1; HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_II_INT0_ENABLE), ii_int_enable.sh_ii_int0_enable_regval); HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_II_INT1_ENABLE), ii_int_enable.sh_ii_int0_enable_regval); if (!timer_added) { // can only init the timer once. timer_added = 1; sn_init_cpei_timer(); } }