예제 #1
0
static void
ieee_value_to_sym(cell_t *cif)
{
	u_int	nargs, nresults;
	u_long	value;
	u_int	offset;
	char	*name = symbol;
	extern u_long value_to_name(uintptr_t value, char *symbol);

	nargs = p1275_cell2uint(cif[1]);
	nresults = p1275_cell2uint(cif[2]);

	if (nresults == 0)
		return;		/* No room for results. Just return. */

	/*
	 * If there are no arguments, fall through and return "not found".
	 * Otherwise, try to translate the value to a symbol-name/offset.
	 */
	*name = (char)0;
	offset = (u_int)-1;
	if (nargs != 0) {
		value = p1275_cell2uintptr(cif[3]); /* argument 0 */
		offset = value_to_name(value, name);
	}

	/*
	 * Stuff the results in the argument array and set the
	 * nresults element to the number of results actually returned
	 * in the argument array. (It's a maximum of 2).
	 *
	 * cif[0]:	service name	( Pointer to service name )
	 * cif[1]:	nargs		( number of argument cells)
	 * cif[2]:	nresults	( number of result cells)
	 * cif[3]:	argument{0}	( First argument cell )
	 * ...
	 * cif[3 + nargs]: result{0}	( First result cell )
	 * ...
	 */

	/*
	 * Treat this as an integer, so we sign-extend -1, offsets
	 * are always postive, -1 indicates not found.
	 */
	cif[3 + nargs] = p1275_int2cell((int)offset);

	if (nresults > 1) {
		cif[3 + nargs + 1] = p1275_ptr2cell(name);
		cif[2] = p1275_int2cell(2);	/* there are 2 results */
	} else {
		cif[2] = p1275_int2cell(1);	/* there is 1 result */
	}
}
예제 #2
0
static void
ieee_sym_to_value(cell_t *cif)
{
	int	error = -1;
	uintptr_t symvalue = 0;
	unsigned int nargs, nresults;
	char	*symname;
	extern	int name_to_value(char *name, uintptr_t *value);

	nargs = p1275_cell2uint(cif[1]);
	nresults = p1275_cell2uint(cif[2]);

	if (nresults == 0)
		return;		/* No room for results. Just return. */

	/*
	 * If there are no arguments, fall through and return an error.
	 * Otherwise, try to translate the symbol name arg to a value.
	 */
	if (nargs != 0) {
		symname = p1275_cell2ptr(cif[3]);	/* argument 0 */
		error = name_to_value(symname, &symvalue);
	}

	/*
	 * Stuff the results in the argument array and set the
	 * nresults element to the number of results actually returned
	 * in the argument array. (It's a maximum of 2).
	 *
	 * cif[0]:	service name	( Pointer to service name )
	 * cif[1]:	nargs		( number of argument cells)
	 * cif[2]:	nresults	( number of result cells)
	 * cif[3]:	argument{0}	( First argument cell )
	 * ...
	 * cif[3 + nargs]: result{0}	( First result cell )
	 * ...
	 */

	cif[3 + nargs] = p1275_int2cell(error);
	if (nresults > 1) {
		cif[3 + nargs + 1] = p1275_uintptr2cell(symvalue);
		cif[2] = p1275_int2cell(2);	/* there are 2 results */
	} else {
		cif[2] = p1275_int2cell(1);	/* there is 1 result */
	}
}
예제 #3
0
int
promif_asr_list_keys_len(void *p)
{
	cell_t	*ci = (cell_t *)p;

	ci[3] = p1275_int2cell(-1);

	return (-1);
}
예제 #4
0
int
prom_asr_disable(char *keystr, int keystr_len,
    char *reason, int reason_len)
{
	int rv;
	cell_t ci[5];

	ci[0] = p1275_ptr2cell("SUNW,asr-disable");	/* Service name */
	ci[1] = (cell_t)4;			/* #argument cells */
	ci[2] = (cell_t)0;			/* #return cells */
	ci[3] = p1275_ptr2cell(keystr);		/* Arg1: key address */
	ci[3] = p1275_int2cell(keystr_len);	/* Arg2: key len */
	ci[3] = p1275_ptr2cell(reason);		/* Arg1: reason address */
	ci[3] = p1275_int2cell(reason_len);	/* Arg2: reason len */

	promif_preprom();
	rv = p1275_cif_handler(&ci);
	promif_postprom();

	return (rv);
}
예제 #5
0
/*
 * Read the date using "set-time" method in rtc node
 * For values 00 - 68, write 2000-2068, and for 69-99,
 * write 1969-1999
 */
static int
todds1307_prom_setdate(struct rtc_t *rtc)
{
    int year;
    cell_t ci[12];

    year = rtc->rtc_year;

    if ((year < 0) || (year > 99))
        return (DDI_FAILURE);

    if (year <= 68)
        year = rtc->rtc_year + 2000;
    else
        year = rtc->rtc_year + 1900;

    ci[0] = p1275_ptr2cell("call-method");  /* Service name */
    ci[1] = 8; /* # of arguments */
    ci[2] = 0; /* # of result cells */
    ci[3] = p1275_ptr2cell("set-time");
    ci[4] = p1275_ihandle2cell(todds1307_ihandle);
    ci[5] = p1275_int2cell(year);
    ci[6] = p1275_int2cell(rtc->rtc_mon);
    ci[7] = p1275_int2cell(rtc->rtc_dom);
    ci[8] = p1275_int2cell(rtc->rtc_hrs);
    ci[9] = p1275_int2cell(rtc->rtc_min);
    ci[10] = p1275_int2cell(rtc->rtc_sec);

    promif_preprom();
    (void) p1275_cif_handler(&ci);
    promif_postprom();

    return (DDI_SUCCESS);
}
int
promif_get_sun4v_api_version(void *p)
{
	cell_t *ci = (cell_t *)p;
	uint64_t api_group;
	uint64_t major;
	uint64_t minor;
	uint64_t status;

	ASSERT(ci[1] == 1);
	ASSERT(ci[2] == 3);

	api_group = (uint64_t)p1275_cell2int(ci[3]);

	status = hv_api_get_version(api_group, &major, &minor);

	ci[4] = p1275_int2cell(status);
	ci[5] = p1275_int2cell(major);
	ci[6] = p1275_int2cell(minor);

	return ((status == H_EOK) ? 0 : -1);
}
int
promif_set_sun4v_api_version(void *p)
{
	cell_t *ci = (cell_t *)p;
	uint64_t api_group;
	uint64_t major;
	uint64_t minor;
	uint64_t status;
	uint64_t supported_minor;

	ASSERT(ci[1] == 3);
	ASSERT(ci[2] == 2);

	api_group = (uint64_t)p1275_cell2int(ci[3]);
	major = (uint64_t)p1275_cell2int(ci[4]);
	minor = (uint64_t)p1275_cell2int(ci[5]);

	status = hv_api_set_version(api_group, major, minor, &supported_minor);

	ci[6] = p1275_int2cell(status);
	ci[7] = p1275_int2cell(supported_minor);

	return ((status == H_EOK) ? 0 : -1);
}
예제 #8
0
int
prom_setprop(pnode_t nodeid, caddr_t name, caddr_t value, int len)
{
	cell_t ci[8];
#ifdef PROM_32BIT_ADDRS
	caddr_t ovalue = NULL;

	if ((uintptr_t)value > (uint32_t)-1) {
		ovalue = value;
		value = promplat_alloc(len);
		if (value == NULL) {
			return (-1);
		}
		promplat_bcopy(ovalue, value, len);
	}
#endif

	prom_setprop_enter();

	promif_preprom();

	ci[0] = p1275_ptr2cell("setprop");	/* Service name */
	ci[1] = (cell_t)4;			/* #argument cells */
	ci[2] = (cell_t)1;			/* #result cells */
	ci[3] = p1275_phandle2cell((phandle_t)nodeid);	/* Arg1: phandle */
	ci[4] = p1275_ptr2cell(name);		/* Arg2: property name */
	ci[5] = p1275_ptr2cell(value);		/* Arg3: New value ptr */
	ci[6] = p1275_int2cell(len);		/* Arg4: New value len */
	ci[7] = (cell_t)-1;			/* Res1: Prime result */

	(void) p1275_cif_handler(&ci);

	promif_postprom();

	prom_setprop_exit();

#ifdef PROM_32BIT_ADDRS
	if (ovalue != NULL)
		promplat_free(value, len);
#endif

	return (p1275_cell2int(ci[7]));		/* Res1: Actual new size */
}
예제 #9
0
int
prom_bounded_getprop(pnode_t nodeid, caddr_t name, caddr_t value, int len)
{
	cell_t ci[8];

	ci[0] = p1275_ptr2cell("getprop");	/* Service name */
	ci[1] = (cell_t)4;			/* #argument cells */
	ci[2] = (cell_t)1;			/* #result cells */
	ci[3] = p1275_phandle2cell((phandle_t)nodeid); /* Arg1: package */
	ci[4] = p1275_ptr2cell(name);		/* Arg2: property name */
	ci[5] = p1275_ptr2cell(value);		/* Arg3: buffer address */
	ci[6] = p1275_int2cell(len);		/* Arg4: buffer length */
	ci[7] = (cell_t)-1;			/* Res1: Prime result */

	promif_preprom();
	(void) p1275_cif_handler(&ci);
	promif_postprom();

	return (p1275_cell2int(ci[7]));		/* Res1: Returned length */
}
예제 #10
0
/*
 * This service converts the given physical address into a text string,
 * representing the name of the field-replacable part for the given
 * physical address. In other words, it tells the kernel which ecache
 * module got the (un)correctable ECC error.
 */
int
prom_serengeti_get_ecacheunum(int cpuid, unsigned long long physaddr, char *buf,
		uint_t buflen, int *ustrlen)
{
	cell_t ci[12];
	int rv;
	ihandle_t imemory = prom_memory_ihandle();

	*ustrlen = -1;
	if ((imemory == (ihandle_t)-1))
		return (-1);

	if (prom_test_method("SUNW,Serengeti,get-ecache-unum",
	    prom_getphandle(imemory)) != 0)
		return (-1);

	ci[0] = p1275_ptr2cell("call-method");		/* Service name */
	ci[1] = (cell_t)7;				/* #argument cells */
	ci[2] = (cell_t)2;				/* #result cells */
	ci[3] = p1275_ptr2cell("SUNW,Serengeti,get-ecache-unum");
							/* Arg1: Method name */
	ci[4] = p1275_ihandle2cell(imemory);		/* Arg2: mem. ihandle */
	ci[5] = p1275_uint2cell(buflen);		/* Arg3: buflen */
	ci[6] = p1275_ptr2cell(buf);			/* Arg4: buf */
	ci[7] = p1275_ull2cell_high(physaddr);		/* Arg5: physhi */
	ci[8] = p1275_ull2cell_low(physaddr);		/* Arg6: physlo */
	ci[9] = p1275_int2cell(cpuid);			/* Arg7: cpuid */
	ci[10] = (cell_t)-1;				/* ret1: catch result */
	ci[11] = (cell_t)-1;				/* ret2: length */

	promif_preprom();
	rv = p1275_cif_handler(&ci);
	promif_postprom();

	if (rv != 0)
		return (rv);
	if (p1275_cell2int(ci[10]) != 0)	/* Res1: catch result */
		return (-1);	/* "SUNW,Serengeti,get-ecache-unum" failed */
	*ustrlen = p1275_cell2uint(ci[11]);	/* Res2: unum str length */
	return (0);
}