Beispiel #1
0
/*
 * prom_walk_devs() implements a generic walker for the OBP tree; this
 * implementation uses an explicitly managed stack in order to save the
 * overhead of a recursive implementation.
 */
void
prom_walk_devs(pnode_t node, int (*cb)(pnode_t, void *, void *), void *arg,
    void *result)
{
	pnode_t stack[OBP_STACKDEPTH];
	int stackidx = 0;

	if (node == OBP_NONODE || node == OBP_BADNODE) {
		prom_panic("Invalid node specified as root of prom tree walk");
	}

	stack[0] = node;

	for (;;) {
		pnode_t curnode = stack[stackidx];
		pnode_t child;

		/*
		 * We're out of stuff to do at this level, bump back up a level
		 * in the tree, and move to the next node;  if the new level
		 * will be level -1, we're done.
		 */
		if (curnode == OBP_NONODE || curnode == OBP_BADNODE) {
			stackidx--;

			if (stackidx < 0)
				return;

			stack[stackidx] = prom_nextnode(stack[stackidx]);
			continue;
		}

		switch ((*cb)(curnode, arg, result)) {

		case PROM_WALK_TERMINATE:
			return;

		case PROM_WALK_CONTINUE:
			/*
			 * If curnode has a child, traverse to it,
			 * otherwise move to curnode's sibling.
			 */
			child = prom_childnode(curnode);
			if (child != OBP_NONODE && child != OBP_BADNODE) {
				stackidx++;
				stack[stackidx] = child;
			} else {
				stack[stackidx] =
				    prom_nextnode(stack[stackidx]);
			}
			break;

		default:
			prom_panic("unrecognized walk directive");
		}
	}
}
Beispiel #2
0
int
pxtool_dev_reg_ops_platchk(dev_info_t *dip, pcitool_reg_t *prg_p)
{
	int		devi_nodeid = ddi_get_nodeid(dip);

	/*
	 * Guard against checking a root nexus which is empty.
	 * On some systems this will result in a Fatal Reset.
	 */
	if ((int)prom_childnode((pnode_t)devi_nodeid) == OBP_NONODE) {
		DBG(DBG_TOOLS, dip,
		    "pxtool_dev_reg_ops set/get reg: nexus has no devs!\n");
		prg_p->status = PCITOOL_IO_ERROR;
		return (ENXIO);
	}

	return (SUCCESS);
}
/*
 * Platform specific lgroup initialization
 */
void
plat_lgrp_init(void)
{
	pnode_t		curnode;
	char		tmp_name[MAXSYSNAME];
	int		portid;
	int		cpucnt = 0;
	int		max_portid = -1;
	extern uint32_t lgrp_expand_proc_thresh;
	extern uint32_t lgrp_expand_proc_diff;
	extern pgcnt_t	lgrp_mem_free_thresh;
	extern uint32_t lgrp_loadavg_tolerance;
	extern uint32_t lgrp_loadavg_max_effect;
	extern uint32_t lgrp_load_thresh;
	extern lgrp_mem_policy_t  lgrp_mem_policy_root;

	/*
	 * Count the number of CPUs installed to determine if
	 * NUMA optimization should be enabled or not.
	 *
	 * All CPU nodes reside in the root node and have a
	 * device type "cpu".
	 */
	curnode = prom_rootnode();
	for (curnode = prom_childnode(curnode); curnode;
	    curnode = prom_nextnode(curnode)) {
		bzero(tmp_name, MAXSYSNAME);
		if (prom_getprop(curnode, OBP_NAME, (caddr_t)tmp_name) == -1 ||
		    prom_getprop(curnode, OBP_DEVICETYPE, tmp_name) == -1 ||
		    strcmp(tmp_name, "cpu") != 0)
			continue;

		cpucnt++;
		if (prom_getprop(curnode, "portid", (caddr_t)&portid) != -1 &&
		    portid > max_portid)
			max_portid = portid;
	}
	if (cpucnt <= 1)
		max_mem_nodes = 1;
	else if (max_portid >= 0 && max_portid < MAX_MEM_NODES)
		max_mem_nodes = max_portid + 1;

	/*
	 * Set tuneables for fiesta architecture
	 *
	 * lgrp_expand_proc_thresh is the minimum load on the lgroups
	 * this process is currently running on before considering
	 * expanding threads to another lgroup.
	 *
	 * lgrp_expand_proc_diff determines how much less the remote lgroup
	 * must be loaded before expanding to it.
	 *
	 * Optimize for memory bandwidth by spreading multi-threaded
	 * program to different lgroups.
	 */
	lgrp_expand_proc_thresh = lgrp_loadavg_max_effect - 1;
	lgrp_expand_proc_diff = lgrp_loadavg_max_effect / 2;
	lgrp_loadavg_tolerance = lgrp_loadavg_max_effect / 2;
	lgrp_mem_free_thresh = 1;	/* home lgrp must have some memory */
	lgrp_expand_proc_thresh = lgrp_loadavg_max_effect - 1;
	lgrp_mem_policy_root = LGRP_MEM_POLICY_NEXT;
	lgrp_load_thresh = 0;

	mem_node_pfn_shift = ENCHILADA_MC_SHIFT - MMU_PAGESHIFT;
}
Beispiel #4
0
/*ARGSUSED1*/
static int
get_neighbors(dev_info_t *di, int flag)
{
	register int nid, snid, cnid;
	dev_info_t *parent;
	char buf[OBP_MAXPROPNAME];

	if (di == NULL)
		return (DDI_WALK_CONTINUE);

	nid = ddi_get_nodeid(di);

	snid = cnid = 0;
	switch (flag) {
		case DDI_WALK_PRUNESIB:
			cnid = (int)prom_childnode((pnode_t)nid);
			break;
		case DDI_WALK_PRUNECHILD:
			snid = (int)prom_nextnode((pnode_t)nid);
			break;
		case 0:
			snid = (int)prom_nextnode((pnode_t)nid);
			cnid = (int)prom_childnode((pnode_t)nid);
			break;
		default:
			return (DDI_WALK_TERMINATE);
	}


	if (snid && (snid != -1) && ((parent = ddi_get_parent(di)) != NULL)) {
		/*
		 * add the first sibling that passes check_status()
		 */
		for (; snid && (snid != -1);
		    snid = (int)prom_nextnode((pnode_t)snid)) {
			if (getlongprop_buf(snid, OBP_NAME, buf,
			    sizeof (buf)) > 0) {
				if (check_status(snid, buf, parent) ==
				    DDI_SUCCESS) {
					(void) ddi_add_child(parent, buf,
					    snid, -1);
					break;
				}
			}
		}
	}

	if (cnid && (cnid != -1)) {
		/*
		 * add the first child that passes check_status()
		 */
		if (getlongprop_buf(cnid, OBP_NAME, buf, sizeof (buf)) > 0) {
			if (check_status(cnid, buf, di) == DDI_SUCCESS) {
				(void) ddi_add_child(di, buf, cnid, -1);
			} else {
				for (cnid = (int)prom_nextnode((pnode_t)cnid);
				    cnid && (cnid != -1);
				    cnid = (int)prom_nextnode((pnode_t)cnid)) {
					if (getlongprop_buf(cnid, OBP_NAME,
					    buf, sizeof (buf)) > 0) {
						if (check_status(cnid, buf, di)
						    == DDI_SUCCESS) {
							(void) ddi_add_child(
							    di, buf, cnid, -1);
							break;
						}
					}
				}
			}
		}
	}

	return (DDI_WALK_CONTINUE);
}