Beispiel #1
0
module_t *module_add_node(moduleid_t id, cnodeid_t n)
{
    module_t	       *m;
    int			i;

    DPRINTF("module_add_node: id=%x node=%d\n", id, n);

    if ((m = module_lookup(id)) == 0) {
#ifndef CONFIG_IA64_SGI_IO
	m = kmem_zalloc_node(sizeof (module_t), KM_NOSLEEP, n);
#else
	m = kmalloc(sizeof (module_t), GFP_KERNEL);
	memset(m, 0 , sizeof(module_t));
	printk("Module nodecnt = %d\n", m->nodecnt); 
#endif
	ASSERT_ALWAYS(m);

	DPRINTF("module_add_node: m=0x%p\n", m);

	m->id = id;
	spin_lock_init(&m->lock);

	init_MUTEX_LOCKED(&m->thdcnt);

printk("Set elsc to 0x%p on node %d\n", &m->elsc, get_nasid());

set_elsc(&m->elsc);
	elsc_init(&m->elsc, COMPACT_TO_NASID_NODEID(n));
	spin_lock_init(&m->elsclock);

	/* Insert in sorted order by module number */

	for (i = nummodules; i > 0 && modules[i - 1]->id > id; i--)
	    modules[i] = modules[i - 1];

	modules[i] = m;
	nummodules++;
    }

    m->nodes[m->nodecnt++] = n;

printk("module_add_node: module %x now has %d nodes\n", id, m->nodecnt);
    DPRINTF("module_add_node: module %x now has %d nodes\n", id, m->nodecnt);

    return m;
}
Beispiel #2
0
module_t *module_add_node(moduleid_t id, cnodeid_t n)
{
    module_t	       *m;
    int			i;
    char		buffer[16];

#ifdef __ia64
    memset(buffer, 0, 16);
    format_module_id(buffer, id, MODULE_FORMAT_BRIEF);
    DPRINTF("module_add_node: id=%s node=%d\n", buffer, n);
#endif

    if ((m = module_lookup(id)) == 0) {
#ifdef LATER
	m = kmem_zalloc_node(sizeof (module_t), KM_NOSLEEP, n);
#else
	m = kmalloc(sizeof (module_t), GFP_KERNEL);
	memset(m, 0 , sizeof(module_t));
#endif
	ASSERT_ALWAYS(m);

	m->id = id;
	spin_lock_init(&m->lock);

	mutex_init_locked(&m->thdcnt);

// set_elsc(&m->elsc);
	elsc_init(&m->elsc, COMPACT_TO_NASID_NODEID(n));
	spin_lock_init(&m->elsclock);

	/* Insert in sorted order by module number */

	for (i = nummodules; i > 0 && modules[i - 1]->id > id; i--)
	    modules[i] = modules[i - 1];

	modules[i] = m;
	nummodules++;
    }

    m->nodes[m->nodecnt++] = n;

    DPRINTF("module_add_node: module %s now has %d nodes\n", buffer, m->nodecnt);

    return m;
}
Beispiel #3
0
void
hub_error_init(cnodeid_t cnode)
{
	nasid_t nasid;

    nasid = cnodeid_to_nasid(cnode);
    hub_error_clear(nasid);

#ifdef ajm
    if (cnode == 0) {
	/*
	 * Allocate log for storing the node specific error info
	 */
	for (i = 0; i < numnodes; i++) {
	    kl_error_log[i]  = kmem_zalloc_node(sizeof(sn0_error_log_t), 
						KM_NOSLEEP, i);
	    hub_err_count[i] = kmem_zalloc_node(sizeof(hub_errcnt_t),
						VM_DIRECT | KM_NOSLEEP, i);
	    ASSERT_ALWAYS(kl_error_log[i] && hub_err_count[i]);
	}
    }

    /*
     * Assumption: There will be only one cpu who will initialize
     * a hub. we need to setup the ii and each pi error interrupts.
     * The SN1 hub (bedrock) has two PI, one for up to two processors.
     */

    if (cpuid_to_cnodeid(smp_processor_id()) == cnode) { 
	int generic_intr_mask = PI_ERR_GENERIC; /* These interrupts are sent to only 1 CPU per NODE */

	ASSERT_ALWAYS(kl_error_log[cnode]);
	ASSERT_ALWAYS(hub_err_count[cnode]);
	MD_ERR_LOG_INIT(kl_error_log[cnode]);

	/* One for each CPU */
	recover_error_init(RECOVER_ERROR_TABLE(cnode, 0));
	recover_error_init(RECOVER_ERROR_TABLE(cnode, 1));
	recover_error_init(RECOVER_ERROR_TABLE(cnode, 2));
	recover_error_init(RECOVER_ERROR_TABLE(cnode, 3));

	/*
	 * Setup error intr masks.
	 */
	for(sn=0; sn<NUM_SUBNODES; sn++) {
		int cpuA_present = REMOTE_HUB_PI_L(nasid, sn, PI_CPU_ENABLE_A);
		int cpuB_present = REMOTE_HUB_PI_L(nasid, sn, PI_CPU_ENABLE_B);

		if (cpuA_present) {
			if (cpuB_present) {		/* A && B */
	    			REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_MASK_A,
					(PI_FATAL_ERR_CPU_B | PI_MISC_ERR_CPU_A|generic_intr_mask));
	    			REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_MASK_B,
					(PI_FATAL_ERR_CPU_A | PI_MISC_ERR_CPU_B));

			} else {			/* A && !B */
	    			REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_MASK_A,
					(PI_FATAL_ERR_CPU_A | PI_MISC_ERR_CPU_A|generic_intr_mask));
			}
			generic_intr_mask = 0;
		} else {
			if (cpuB_present) {		/* !A && B */
	    			REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_MASK_B,
					(PI_FATAL_ERR_CPU_B | PI_MISC_ERR_CPU_B|generic_intr_mask));
				generic_intr_mask = 0;

			} else {			/* !A && !B */
				/* nothing to set up */
			}
		}
	}

	/*
	 * Turn off UNCAC_UNCORR interrupt in the masks. Anyone interested
	 * in these errors will peek at the int pend register to see if its
	 * set.
	 */ 
	for(sn=0; sn<NUM_SUBNODES; sn++) {
		misc = REMOTE_HUB_PI_L(nasid, sn, PI_ERR_INT_MASK_A);
		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_MASK_A, (misc & ~PI_ERR_UNCAC_UNCORR_A));
		misc = REMOTE_HUB_PI_L(nasid, sn, PI_ERR_INT_MASK_B);
		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_MASK_B, (misc & ~PI_ERR_UNCAC_UNCORR_B));
	}

	/*
	 * enable all error indicators to turn on, in case of errors.
	 *
	 * This is not good on single cpu node boards.
	 **** LOCAL_HUB_S(PI_SYSAD_ERRCHK_EN, PI_SYSAD_CHECK_ALL);
	 */
	for(sn=0; sn<NUM_SUBNODES; sn++) {
		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_STATUS1_A_CLR, 0);
		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_STATUS1_B_CLR, 0);
	}

	/* Set up stack for each present processor */
	for(sn=0; sn<NUM_SUBNODES; sn++) {
		if (REMOTE_HUB_PI_L(nasid, sn, PI_CPU_PRESENT_A)) {
	    	SN0_ERROR_LOG(cnode)->el_spool_cur_addr[0] =
			SN0_ERROR_LOG(cnode)->el_spool_last_addr[0] =
		    	REMOTE_HUB_PI_L(nasid, sn, PI_ERR_STACK_ADDR_A);
		}
	    
		if (REMOTE_HUB_PI_L(nasid, sn, PI_CPU_PRESENT_B)) {
	    	SN0_ERROR_LOG(cnode)->el_spool_cur_addr[1] =
			SN0_ERROR_LOG(cnode)->el_spool_last_addr[1] =
		    	REMOTE_HUB_PI_L(nasid, sn, PI_ERR_STACK_ADDR_B);
		}
	}


	PI_SPOOL_SIZE_BYTES = 
	    ERR_STACK_SIZE_BYTES(REMOTE_HUB_L(nasid, PI_ERR_STACK_SIZE));

#ifdef BRINGUP
/* BRINGUP: The following code looks like a check to make sure
the prom set up the error spool correctly for 2 processors.  I
don't think it is needed.  */
	for(sn=0; sn<NUM_SUBNODES; sn++) {
		if (REMOTE_HUB_PI_L(nasid, sn, PI_CPU_PRESENT_B)) {
			__psunsigned_t addr_a = REMOTE_HUB_PI_L(nasid, sn, PI_ERR_STACK_ADDR_A);
			__psunsigned_t addr_b = REMOTE_HUB_PI_L(nasid, sn, PI_ERR_STACK_ADDR_B);
			if ((addr_a & ~0xff) == (addr_b & ~0xff)) {
			    REMOTE_HUB_PI_S(nasid, sn, PI_ERR_STACK_ADDR_B, 	
					addr_b + PI_SPOOL_SIZE_BYTES);
	
			    SN0_ERROR_LOG(cnode)->el_spool_cur_addr[1] =
				SN0_ERROR_LOG(cnode)->el_spool_last_addr[1] =
				    REMOTE_HUB_PI_L(nasid, sn, PI_ERR_STACK_ADDR_B);
	
		    }
		}
	}
#endif /* BRINGUP */

	/* programming our own hub. Enable error_int_pend intr.
	 * If both present, CPU A takes CPU b's error interrupts and any
	 * generic ones. CPU B takes CPU A error ints.
	 */
	if (cause_intr_connect (SRB_ERR_IDX,
				(intr_func_t)(hubpi_eint_handler),
				SR_ALL_MASK|SR_IE)) {
	    cmn_err(ERR_WARN, 
		    "hub_error_init: cause_intr_connect failed on %d", cnode);
	}
    }
    else {
	/* programming remote hub. The only valid reason that this
	 * is called will be on headless hubs. No interrupts 
	 */
	for(sn=0; sn<NUM_SUBNODES; sn++) {
		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_MASK_A, 0); /* not necessary */
		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_MASK_B, 0); /* not necessary */
	}
    }
#endif /* ajm */
    /*
     * Now setup the hub ii and ni error interrupt handler.
     */

    hubii_eint_init(cnode);
    hubni_eint_init(cnode);

#ifdef ajm
    /*** XXX FIXME XXX resolve the following***/
    /* INT_PEND1 bits set up for one hub only:
     *	SHUTDOWN_INTR
     *	MD_COR_ERR_INTR
     *  COR_ERR_INTR_A and COR_ERR_INTR_B should be sent to the
     *  appropriate CPU only.
     */

    if (cnode == 0) {
	    error_consistency_check.eps_state = 0;
	    error_consistency_check.eps_cpuid = -1;
	    spinlock_init(&error_consistency_check.eps_lock, "error_dump_lock");
    }
#endif

    nodepda->huberror_ticks = HUB_ERROR_PERIOD;
    return;
}