예제 #1
0
파일: dr.c 프로젝트: AlainODea/illumos-gate
/*
 * Callback to the ptree walk function during add_cpus.
 * As a part of the args receives a cpu di_node, compares
 * each picl cpu node's cpuid to the device tree node's cpuid.
 * Sets arg struct's result to 1 on a match.
 */
static int
cpu_exists(picl_nodehdl_t nodeh, void *c_args)
{
	di_node_t	di_node;
	cpu_lookup_t	*cpu_arg;
	int	err;
	int	dcpuid, pcpuid;
	int reg_prop[4];

	if (c_args == NULL)
		return (PICL_INVALIDARG);

	cpu_arg = c_args;
	di_node = cpu_arg->di_node;
	dcpuid = get_cpuid(di_node);

	err = ptree_get_propval_by_name(nodeh, OBP_REG, reg_prop,
	    sizeof (reg_prop));

	if (err != PICL_SUCCESS)
		return (PICL_WALK_CONTINUE);

	pcpuid = CFGHDL_TO_CPUID(reg_prop[0]);

	if (dcpuid == pcpuid) {
		cpu_arg->result = 1;
		return (PICL_WALK_TERMINATE);
	}

	cpu_arg->result = 0;
	return (PICL_WALK_CONTINUE);
}
예제 #2
0
파일: dr.c 프로젝트: AlainODea/illumos-gate
/*
 * Callback to the ptree walk function during remove_cpus.
 * As a part of the args receives a picl nodeh, searches
 * the device tree for a cpu whose cpuid matches the picl cpu node.
 * Sets arg struct's result to 1 if it failed to match and terminates
 * the walk.
 */
static int
remove_cpu_candidate(picl_nodehdl_t nodeh, void *c_args)
{
	di_node_t	di_node;
	cpu_lookup_t	*cpu_arg;
	int	err;
	int	pcpuid;
	int reg_prop[SUN4V_CPU_REGSIZE];

	if (c_args == NULL)
		return (PICL_INVALIDARG);

	cpu_arg = c_args;
	di_node = cpu_arg->di_node;

	err = ptree_get_propval_by_name(nodeh, OBP_REG, reg_prop,
	    sizeof (reg_prop));

	if (err != PICL_SUCCESS) {
		return (PICL_WALK_CONTINUE);
	}

	pcpuid = CFGHDL_TO_CPUID(reg_prop[0]);

	if (!find_cpu(di_node, pcpuid)) {
		cpu_arg->result = 1;
		cpu_arg->nodeh = nodeh;
		return (PICL_WALK_TERMINATE);
	}

	cpu_arg->result = 0;
	return (PICL_WALK_CONTINUE);
}
예제 #3
0
파일: dr.c 프로젝트: AlainODea/illumos-gate
/*
 * Given a devinfo cpu node find its cpuid property.
 */
int
get_cpuid(di_node_t di_node)
{
	int	len;
	int	*idata;
	int	dcpuid = -1;

	len = get_reg_prop(di_node, &idata);

	if (len != SUN4V_CPU_REGSIZE)
		return (dcpuid);
	if (len == SUN4V_CPU_REGSIZE)
		dcpuid = CFGHDL_TO_CPUID(idata[0]);

	return (dcpuid);
}
예제 #4
0
int
add_cpu_prop(picl_nodehdl_t node, void *args)
{
	mde_cookie_t *cpulistp;
	mde_cookie_t *cachelistp;
	mde_cookie_t *tlblistp;
	int x, num_nodes;
	int ncpus, ncaches, ntlbs;
	int status;
	int reg_prop[SUN4V_CPU_REGSIZE], cpuid;
	uint64_t int_value;

	status = ptree_get_propval_by_name(node, OBP_REG, reg_prop,
	    sizeof (reg_prop));
	if (status != PICL_SUCCESS) {
		return (PICL_WALK_TERMINATE);
	}

	cpuid = CFGHDL_TO_CPUID(reg_prop[0]);

	/*
	 * Allocate space for our searches.
	 */

	num_nodes = md_node_count(mdp);

	cpulistp = (mde_cookie_t *) alloca(sizeof (mde_cookie_t) *num_nodes);
	if (cpulistp == NULL) {
		return (PICL_WALK_TERMINATE);
	}

	cachelistp = (mde_cookie_t *) alloca(sizeof (mde_cookie_t) *num_nodes);
	if (cachelistp == NULL) {
		return (PICL_WALK_TERMINATE);
	}

	tlblistp = (mde_cookie_t *) alloca(sizeof (mde_cookie_t) *num_nodes);
	if (tlblistp == NULL) {
		return (PICL_WALK_TERMINATE);
	}

	/*
	 * Starting at the root node, scan the "fwd" dag for
	 * all the cpus in this description.
	 */

	ncpus = md_scan_dag(mdp, rootnode, md_find_name(mdp, "cpu"),
	    md_find_name(mdp, "fwd"), cpulistp);

	if (ncpus < 0) {
		return (PICL_WALK_TERMINATE);
	}

	/*
	 * Create PD cpus with a few select properties
	 */

	for (x = 0; x < ncpus; x++) {
		if (md_get_prop_val(mdp, cpulistp[x], "id", &int_value)) {
			continue;
		}

		if (int_value != cpuid)
			continue;

		add_md_prop(node, sizeof (int_value), "cpuid", &int_value,
			PICL_PTYPE_INT);

		add_md_prop(node, sizeof (int_value), "portid", &int_value,
		    PICL_PTYPE_INT);

		/* get caches for CPU */
		ncaches = md_scan_dag(mdp, cpulistp[x],
		    md_find_name(mdp, "cache"),
		    md_find_name(mdp, "fwd"),
		    cachelistp);

		add_cache_props(node, cachelistp, ncaches);

		/* get tlbs for CPU */
		ntlbs = md_scan_dag(mdp, cpulistp[x],
		    md_find_name(mdp, "tlb"),
		    md_find_name(mdp, "fwd"),
		    tlblistp);

		add_tlb_props(node, tlblistp, ntlbs);
	}

	return (PICL_WALK_CONTINUE);
}