Пример #1
0
/* Call an RTAS method by token */
int
rtas_call_method(cell_t token, int nargs, int nreturns, ...)
{
	vm_offset_t argsptr;
	faultbuf env, *oldfaultbuf;
	va_list ap;
	struct {
		cell_t token;
		cell_t nargs;
		cell_t nreturns;
		cell_t args_n_results[12];
	} args;
	int n, result;

	if (!rtas_exists() || nargs + nreturns > 12)
		return (-1);

	args.token = token;
	va_start(ap, nreturns);

	mtx_lock_spin(&rtas_mtx);
	rtas_bounce_offset = 0;

	args.nargs = nargs;
	args.nreturns = nreturns;

	for (n = 0; n < nargs; n++)
		args.args_n_results[n] = va_arg(ap, cell_t);

	argsptr = rtas_real_map(&args, sizeof(args));

	/* Get rid of any stale machine checks that have been waiting.  */
	__asm __volatile ("sync; isync");
	oldfaultbuf = curthread->td_pcb->pcb_onfault;
        if (!setfault(env)) {
		__asm __volatile ("sync");
		result = rtascall(argsptr, rtas_private_data);
		__asm __volatile ("sync; isync");
	} else {
		result = RTAS_HW_ERROR;
	}
	curthread->td_pcb->pcb_onfault = oldfaultbuf;
	__asm __volatile ("sync");

	rtas_real_unmap(argsptr, &args, sizeof(args));
	mtx_unlock_spin(&rtas_mtx);

	if (result < 0)
		return (result);

	for (n = nargs; n < nargs + nreturns; n++)
		*va_arg(ap, cell_t *) = args.args_n_results[n];
	return (result);
}
Пример #2
0
static int
rtasdev_probe(device_t dev)
{
    const char *name = ofw_bus_get_name(dev);

    if (strcmp(name, "rtas") != 0)
        return (ENXIO);
    if (!rtas_exists())
        return (ENXIO);

    device_set_desc(dev, "Run-Time Abstraction Services");
    return (0);
}
Пример #3
0
/* Look up an RTAS token */
cell_t
rtas_token_lookup(const char *method)
{
	cell_t token;
	
	if (!rtas_exists())
		return (-1);

	if (OF_getprop(rtas, method, &token, sizeof(token)) == -1)
		return (-1);

	return (token);
}
Пример #4
0
static int
rtaspci_probe(device_t dev)
{
	const char	*type;

	if (!rtas_exists())
		return (ENXIO);

	type = ofw_bus_get_type(dev);

	if (OF_getproplen(ofw_bus_get_node(dev), "used-by-rtas") < 0)
		return (ENXIO);
	if (type == NULL || strcmp(type, "pci") != 0)
		return (ENXIO);

	device_set_desc(dev, "RTAS Host-PCI bridge");
	return (BUS_PROBE_GENERIC);
}
Пример #5
0
static int
chrp_smp_start_cpu(platform_t plat, struct pcpu *pc)
{
	cell_t start_cpu;
	int result, err, timeout;

	if (!rtas_exists()) {
		printf("RTAS uninitialized: unable to start AP %d\n",
		    pc->pc_cpuid);
		return (ENXIO);
	}

	start_cpu = rtas_token_lookup("start-cpu");
	if (start_cpu == -1) {
		printf("RTAS unknown method: unable to start AP %d\n",
		    pc->pc_cpuid);
		return (ENXIO);
	}

	ap_pcpu = pc;
	powerpc_sync();

	result = rtas_call_method(start_cpu, 3, 1, pc->pc_cpuid, EXC_RST, pc,
	    &err);
	if (result < 0 || err != 0) {
		printf("RTAS error (%d/%d): unable to start AP %d\n",
		    result, err, pc->pc_cpuid);
		return (ENXIO);
	}

	timeout = 10000;
	while (!pc->pc_awake && timeout--)
		DELAY(100);

	return ((pc->pc_awake) ? 0 : EBUSY);
}