Пример #1
0
/*
 * Allocate physical memory, unmapped and possibly aligned.
 * Returns 0: Success; Non-zero: failure.
 * Returns *physaddr only if successful.
 *
 * This routine is suitable for platforms with 2-cell physical addresses
 * and a single size cell in the "memory" node.
 */
int
prom_allocate_phys(size_t size, uint32_t align, u_longlong_t *physaddr)
{
	cell_t ci[10];
	int32_t rv;
	ihandle_t imemory = prom_memory_ihandle();

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

	if (align == 0)
		align = (uint32_t)1;

	ci[0] = p1275_ptr2cell("call-method");	/* Service name */
	ci[1] = (cell_t)4;			/* #argument cells */
	ci[2] = (cell_t)3;			/* #result cells */
	ci[3] = p1275_ptr2cell("claim");	/* Arg1: Method name */
	ci[4] = p1275_ihandle2cell(imemory);	/* Arg2: memory ihandle */
	ci[5] = p1275_uint2cell(align);		/* Arg3: SA1: align */
	ci[6] = p1275_size2cell(size);		/* Arg4: SA2: size */

	rv = p1275_cif_handler(&ci);

	if (rv != 0)
		return (rv);
	if (p1275_cell2int(ci[7]) != 0)		/* Res1: Catch result */
		return (-1);

	*physaddr = p1275_cells2ull(ci[8], ci[9]);
				/* Res2: SR1: phys.hi ... Res3: SR2: phys.lo */
	return (0);
}
Пример #2
0
/*
 * unmap virt, then map virt to new phys;
 * see remap definition below
 */
int
prom_remap(size_t size, caddr_t virt, physaddr_t phys)
{
	ihandle_t immu;
	cell_t ci[8];
	int rv;

	immu = prom_mmu_ihandle();
	if (immu == (ihandle_t)-1)
		return (ERR);

	ci[0] = p1275_ptr2cell("call-method");	/* Service name */
	ci[1] = (cell_t)5;			/* #argument cells */
	ci[2] = (cell_t)0;			/* #result cells */
	ci[3] = p1275_ptr2cell("remap");	/* Arg1: Method name */
	ci[4] = p1275_ihandle2cell(immu);	/* Arg2: memory ihandle */
	ci[5] = p1275_size2cell(size);		/* remap arg0 */
	ci[6] = p1275_ptr2cell(virt);		/* remap arg1 */
	ci[7] = p1275_ull2cell_low(phys);	/* remap arg2 */

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

	if (rv)
		return (rv);		/* Service "call-method" failed */
	return (0);
}
Пример #3
0
/*
 * Claim a region of physical memory, unmapped.
 * Returns 0: Success; Non-zero: failure.
 *
 * This routine is suitable for platforms with 2-cell physical addresses
 * and a single size cell in the "memory" node.
 */
int
prom_claim_phys(size_t size, u_longlong_t physaddr)
{
	cell_t ci[10];
	int32_t rv;
	ihandle_t imemory = prom_memory_ihandle();

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

	ci[0] = p1275_ptr2cell("call-method");	/* Service name */
	ci[1] = (cell_t)6;			/* #argument cells */
	ci[2] = (cell_t)1;			/* #result cells */
	ci[3] = p1275_ptr2cell("claim");	/* Arg1: Method name */
	ci[4] = p1275_ihandle2cell(imemory);	/* Arg2: mmu ihandle */
	ci[5] = 0;				/* Arg3: SA1: align */
	ci[6] = p1275_size2cell(size);		/* Arg4: SA2: len */
	ci[7] = p1275_ull2cell_high(physaddr);	/* Arg5: SA3: phys.hi */
	ci[8] = p1275_ull2cell_low(physaddr);	/* Arg6: SA4: phys.lo */

	rv = p1275_cif_handler(&ci);

	if (rv != 0)
		return (rv);
	if (p1275_cell2int(ci[9]) != 0)		/* Res1: Catch result */
		return (-1);

	return (0);
}
Пример #4
0
/*
 * Read the date using "get-time" method in rtc node
 * PROM returns 1969-1999 when reading 69-99 and
 * 2000-2068 when reading 00-68
 */
static int
todds1307_prom_getdate(struct rtc_t *rtc)
{
    int year;
    cell_t ci[12];

    ci[0] = p1275_ptr2cell("call-method");  /* Service name */
    ci[1] = 2; /* # of arguments */
    ci[2] = 7; /* # of result cells */
    ci[3] = p1275_ptr2cell("get-time");
    ci[4] = p1275_ihandle2cell(todds1307_ihandle);

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

    year 		= p1275_cell2int(ci[6]);
    rtc->rtc_mon	= p1275_cell2int(ci[7]);
    rtc->rtc_dom	= p1275_cell2int(ci[8]);
    rtc->rtc_dow	= 0;
    rtc->rtc_hrs	= p1275_cell2int(ci[9]);
    rtc->rtc_min	= p1275_cell2int(ci[10]);
    rtc->rtc_sec	= p1275_cell2int(ci[11]);
    if (year >= 2000)
        year -= 2000;
    else
        year -= 1900;
    rtc->rtc_year	= year;

    return (DDI_SUCCESS);
}
Пример #5
0
int
prom_pathname(char *pathname)
{
	char *from = buffer;
	char *to = pathname;
	cell_t ci[7];

	if ((to == (char *)0) || (*to == (char)0))
		return;

	(void) prom_strcpy(from, to);
	*to = (char)0;

	ci[0] = p1275_ptr2cell("canon");	/* Service name */
	ci[1] = (cell_t)3;			/* #argument cells */
	ci[2] = (cell_t)1;			/* #result cells */
	ci[3] = p1275_ptr2cell(from);		/* Arg1: device specifier */
	ci[4] = p1275_ptr2cell(to);		/* Arg2: buffer address */
	ci[5] = p1275_uint2cell(OBP_MAXPATHLEN); /* Arg3: buffer length */
	ci[6] = (cell_t)-1;

	(void) p1275_cif_handler(&ci);

	return (p1275_cell2int(ci[6]));		/* Res1: length */
}
Пример #6
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);
}
Пример #7
0
int
prom_getprop(pnode_t nodeid, caddr_t name, caddr_t value)
{
	int len, rv;
	cell_t ci[8];

	/*
	 * This function assumes the buffer is large enough to
	 * hold the result, so in 1275 mode, we pass in the length
	 * of the property as the length of the buffer, since we
	 * have no way of knowing the size of the buffer. Pre-1275
	 * OpenBoot(tm) PROMs did not have a bounded getprop.
	 *
	 * Note that we ignore the "length" result of the service.
	 */

	if ((len = prom_getproplen(nodeid, name)) <= 0)
		return (len);

	ci[0] = p1275_ptr2cell("getprop");	/* Service name */
	ci[1] = (cell_t)4;			/* #argument cells */
	ci[2] = (cell_t)0;			/* #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] = len;				/* Arg4: buf len (assumed) */

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

	if (rv != 0)
		return (-1);
	return (len);				/* Return known length */
}
Пример #8
0
/*
 * Get Fcode into supplied buffer.
 */
int
prom_get_fcode(char *str, char *buf)
{
	cell_t ci[6];
	int rv;

	if (prom_test("SUNW,get-fcode") != 0) {
		return (0);
	}

	ci[0] = p1275_ptr2cell("SUNW,get-fcode");
	ci[1] = (cell_t)2;	/* 2 input args: str + buf */
	ci[2] = (cell_t)1;	/* 1 output result: true or false */
	ci[3] = p1275_ptr2cell(buf);	/* Arg#1: buffer to put fcode */
	ci[4] = p1275_ptr2cell(str);	/* Arg#2: name of drop-in */
	ci[5] = (cell_t)0;

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

	if (rv == 0)
		return (p1275_cell2int(ci[5]));
	return (0);
}
Пример #9
0
/*
 * This interface allows the client to safely take over the %tba by
 * the prom's service. The prom will take care of the quiescence of
 * interrupts and handle any pending soft interrupts.
 */
void
prom_set_traptable(void *tba_addr)
{
	cell_t ci[4];

	ci[0] = p1275_ptr2cell("SUNW,set-trap-table");	/* Service name */
	ci[1] = (cell_t)1;			/* #argument cells */
	ci[2] = (cell_t)0;			/* #result cells */
	ci[3] = p1275_ptr2cell(tba_addr);	/* Arg1: tba address */

	(void) p1275_cif_handler(&ci);
}
Пример #10
0
/*
 * Request that OBP write 'len' bytes from the memory indicated by 'buf' into
 * the IOSRAM chunk associated with 'key', starting at 'offset'.  Although there
 * is a driver that provides this functionality, there are certain cases where
 * the OS requires access to IOSRAM before the driver is loaded.  Return 0 on
 * success, non-zero on failure.
 */
int
prom_starcat_iosram_write(uint32_t key, uint32_t offset, uint32_t len,
    caddr_t buf)
{
	static uint8_t	warned = 0;
	cell_t 		ci[8];
	int 		rv;

	/*
	 * Make sure we have the necessary support in OBP.
	 */
	if (prom_test(iosram_write_cmd) == 0) {
		ci[0] = p1275_ptr2cell(iosram_write_cmd); /* name */
	} else {
		if (!warned) {
			warned = 1;
			prom_printf(
			    "Warning: No prom support for iosram-write!\n");
		}
		return (-1);
	}

	/*
	 * Set up the arguments and call into OBP.  Note that the argument order
	 * needs to be reversed to accomodate OBP.  The order must remain as it
	 * is in the function prototype to maintain intercompatibility with the
	 * IOSRAM driver's equivalent routine.
	 */
	ci[1] = (cell_t)4;				/* #argument cells */
	ci[2] = (cell_t)1;				/* #result cells */
	ci[3] = p1275_ptr2cell(buf);
	ci[4] = p1275_uint2cell(len);
	ci[5] = p1275_uint2cell(offset);
	ci[6] = p1275_uint2cell(key);

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

	/*
	 * p1275_cif_handler will return 0 on success, non-zero on failure.  If
	 * it fails, the return cell from OBP is meaningless, because the OBP
	 * client interface probably wasn't even invoked.  OBP will return 0 on
	 * success and non-zero on failure for this interface.
	 */
	if (rv != 0) {
		return (rv);
	} else if (p1275_cell2int(ci[7]) == 0)	{
		return (0);
	} else {
		return (-1);
	}
}
Пример #11
0
/*
 *  Returns 0 on error. Otherwise returns a handle.
 */
ihandle_t
prom_open(char *path)
{
	cell_t ci[5];

	ci[0] = p1275_ptr2cell("open");		/* Service name */
	ci[1] = (cell_t)1;			/* #argument cells */
	ci[2] = (cell_t)1;			/* #result cells */
	ci[3] = p1275_ptr2cell(path);		/* Arg1: Pathname */
	ci[4] = (cell_t)0;			/* Res1: Prime result */

	(void) p1275_cif_handler(&ci);

	return (p1275_cell2ihandle(ci[4]));	/* Res1: ihandle */
}
Пример #12
0
/*
 * Test for existance of a specific P1275 client interface service
 */
int
prom_test(char *service)
{
	cell_t ci[5];

	ci[0] = p1275_ptr2cell("test");		/* Service name */
	ci[1] = (cell_t)1;			/* #argument cells */
	ci[2] = (cell_t)1;			/* #result cells */
	ci[3] = p1275_ptr2cell(service);	/* Arg1: requested svc name */
	ci[4] = (cell_t)-1;			/* Res1: Prime result */

	(void) p1275_cif_handler(&ci);

	return (p1275_cell2int(ci[4]));		/* Res1: missing flag */
}
Пример #13
0
void
prom_free(caddr_t virt, size_t size)
{
	cell_t ci[5];

	ci[0] = p1275_ptr2cell("release");	/* Service name */
	ci[1] = (cell_t)2;			/* #argument cells */
	ci[2] = (cell_t)0;			/* #result cells */
	ci[3] = p1275_ptr2cell(virt);		/* Arg1: virt */
	ci[4] = p1275_uint2cell(size);		/* Arg2: size */

	promif_preprom();
	(void) p1275_cif_handler(&ci);
	promif_postprom();
}
Пример #14
0
void
prom_set_symbol_lookup(void *sym2val, void *val2sym)
{
	cell_t ci[5];

	ci[0] = p1275_ptr2cell("set-symbol-lookup");	/* Service name */
	ci[1] = (cell_t)2;			/* #argument cells */
	ci[2] = (cell_t)0;			/* #return cells */
	ci[3] = p1275_ptr2cell(sym2val);	/* Arg1: s2v handler */
	ci[4] = p1275_ptr2cell(val2sym);	/* Arg1: v2s handler */

	promif_preprom();
	(void) p1275_cif_handler(&ci);
	promif_postprom();
}
Пример #15
0
int
prom_test_method(char *method, dnode_t node)
{
	cell_t ci[6];

	ci[0] = p1275_ptr2cell("test-method");	/* service */
	ci[1] = (cell_t)2;			/* #argument cells */
	ci[2] = (cell_t)1;			/* #result cells */
	ci[3] = p1275_dnode2cell(node);
	ci[4] = p1275_ptr2cell(method);
	ci[5] = (cell_t)-1;

	(void) p1275_cif_handler(&ci);

	return (p1275_cell2int(ci[5]));
}
Пример #16
0
uint32_t
prom_read(ihandle_t fd, caddr_t buf, uint32_t len)
{
	cell_t ci[7];

	ci[0] = p1275_ptr2cell("read");		/* Service name */
	ci[1] = (cell_t)3;			/* #argument cells */
	ci[2] = (cell_t)1;			/* #result cells */
	ci[3] = p1275_ihandle2cell(fd);		/* Arg1: ihandle */
	ci[4] = p1275_ptr2cell(buf);		/* Arg2: buffer address */
	ci[5] = p1275_uint2cell(len);		/* Arg3: buffer length */
	ci[6] = (cell_t)-1;			/* Res1: Prime result */

	(void) p1275_cif_handler(&ci);

	return (p1275_cell2uint(ci[6]));	/* Res1: actual length */
}
Пример #17
0
void *
prom_set_callback(void *handler)
{
	cell_t ci[5];

	ci[0] = p1275_ptr2cell("set-callback");	/* Service name */
	ci[1] = (cell_t)1;			/* #argument cells */
	ci[2] = (cell_t)1;			/* #return cells */
	ci[3] = p1275_ptr2cell(handler);	/* Arg1: New handler */
	ci[4] = (cell_t)-1;			/* Res1: Prime result */

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

	return (p1275_cell2ptr(ci[4]));		/* Res1: Old handler */
}
Пример #18
0
int
prom_getproplen(pnode_t nodeid, caddr_t name)
{
	cell_t ci[6];

	ci[0] = p1275_ptr2cell("getproplen");	/* Service name */
	ci[1] = (cell_t)2;			/* #argument cells */
	ci[2] = (cell_t)1;			/* #return cells */
	ci[3] = p1275_phandle2cell((phandle_t)nodeid);	/* Arg1: package */
	ci[4] = p1275_ptr2cell(name);		/* Arg2: Property name */
	ci[5] = (cell_t)-1;			/* Res1: Prime result */

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

	return (p1275_cell2int(ci[5]));		/* Res1: Property length */
}
Пример #19
0
int
prom_asr_enable(char *keystr, int keystr_len)
{
	int rv;
	cell_t ci[5];

	ci[0] = p1275_ptr2cell("SUNW,asr-enable");	/* Service name */
	ci[1] = (cell_t)2;			/* #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 */

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

	return (rv);
}
Пример #20
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 */
}
Пример #21
0
int
prom_asr_export(caddr_t value)
{
	int rv;
	cell_t ci[5];

	ci[0] = p1275_ptr2cell("SUNW,asr-export");	/* Service name */
	ci[1] = (cell_t)1;			/* #argument cells */
	ci[2] = (cell_t)1;			/* #return cells */
	ci[3] = p1275_ptr2cell(value);		/* Arg1: buffer address */
	ci[4] = -1;				/* Res1: buf len */

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

	if (rv != 0)
		return (-1);
	return (p1275_cell2int(ci[4]));		/* Res1: buf length */
}
Пример #22
0
caddr_t
prom_nextprop(pnode_t nodeid, caddr_t previous, caddr_t next)
{
	cell_t ci[7];

	(void) prom_strcpy(next, "");	/* Prime result, in case call fails */

	ci[0] = p1275_ptr2cell("nextprop");	/* Service name */
	ci[1] = (cell_t)3;			/* #argument cells */
	ci[2] = (cell_t)0;			/* #result cells */
	ci[3] = p1275_phandle2cell((phandle_t)nodeid); /* Arg1: phandle */
	ci[4] = p1275_ptr2cell(previous);	/* Arg2: addr of prev name */
	ci[5] = p1275_ptr2cell(next);		/* Arg3: addr of 32 byte buf */

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

	return (next);
}
Пример #23
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 */
}
Пример #24
0
char *
prom_serengeti_set_console_input(char *new_value)
{
	cell_t ci[5];
	int rv;

	ci[0] = p1275_ptr2cell("SUNW,set-console-input");
	ci[1] = (cell_t)1;			/* #argument cells */
	ci[2] = (cell_t)1;			/* #return cells */
	ci[3] = p1275_ptr2cell(new_value);

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

	if (rv != 0)
		return (NULL);

	return (p1275_cell2ptr(ci[4]));
}
Пример #25
0
/*
 * Free physical memory (no unmapping is done).
 * This routine is suitable for platforms with 2-cell physical addresses
 * with a single size cell.
 */
void
prom_free_phys(size_t size, u_longlong_t physaddr)
{
	cell_t ci[8];
	ihandle_t imemory = prom_memory_ihandle();

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

	ci[0] = p1275_ptr2cell("call-method");	/* Service name */
	ci[1] = (cell_t)5;			/* #argument cells */
	ci[2] = (cell_t)0;			/* #return cells */
	ci[3] = p1275_ptr2cell("release");	/* Arg1: Method name */
	ci[4] = p1275_ihandle2cell(imemory);	/* Arg2: memory ihandle */
	ci[5] = p1275_size2cell(size);		/* Arg3: SA1: size */
	ci[6] = p1275_ull2cell_high(physaddr);	/* Arg4: SA2: phys.hi */
	ci[7] = p1275_ull2cell_low(physaddr);	/* Arg5: SA3: phys.lo */

	(void) p1275_cif_handler(&ci);
}
Пример #26
0
/*ARGSUSED3*/
ssize_t
prom_read(ihandle_t fd, caddr_t buf, size_t len, uint_t startblk, char devtype)
{
	cell_t ci[7];
	promif_owrap_t *ow;
#ifdef PROM_32BIT_ADDRS
	caddr_t obuf = NULL;

	if ((uintptr_t)buf > (uint32_t)-1) {
		obuf = buf;
		buf = promplat_alloc(len);
		if (buf == NULL)
			return (-1);
	}
#endif

	ow = promif_preout();
	promif_preprom();

	ci[0] = p1275_ptr2cell("read");		/* Service name */
	ci[1] = (cell_t)3;			/* #argument cells */
	ci[2] = (cell_t)1;			/* #result cells */
	ci[3] = p1275_size2cell((uint_t)fd);	/* Arg1: ihandle */
	ci[4] = p1275_ptr2cell(buf);		/* Arg2: buffer address */
	ci[5] = p1275_uint2cell(len);		/* Arg3: buffer length */
	ci[6] = (cell_t)-1;			/* Res1: Prime result */

	(void) p1275_cif_handler(&ci);

	promif_postprom();
	promif_postout(ow);

#ifdef PROM_32BIT_ADDRS
	if (obuf != NULL) {
		promplat_bcopy(buf, obuf, len);
		promplat_free(buf, len);
	}
#endif

	return (p1275_cell2size(ci[6]));	/* Res1: actual length */
}
Пример #27
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);
}
Пример #28
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 */
	}
}
Пример #29
0
/*
 * This is the generic client interface to "claim" memory.
 * These two routines belong in the common directory.
 */
caddr_t
prom_malloc(caddr_t virt, size_t size, uint_t align)
{
	cell_t ci[7];
	int rv;

	ci[0] = p1275_ptr2cell("claim");	/* Service name */
	ci[1] = (cell_t)3;			/* #argument cells */
	ci[2] = (cell_t)1;			/* #result cells */
	ci[3] = p1275_ptr2cell(virt);		/* Arg1: virt */
	ci[4] = p1275_uint2cell(size);		/* Arg2: size */
	ci[5] = p1275_uint2cell(align);		/* Arg3: align */

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

	if (rv == 0)
		return ((caddr_t)p1275_cell2ptr(ci[6])); /* Res1: base */
	return ((caddr_t)-1);
}
Пример #30
0
/*
 * This interface allows the client to power off the machine.
 * There's no return from this service.
 */
void
prom_power_off()
{
	cell_t ci[3];

	ci[0] = p1275_ptr2cell("SUNW,power-off");	/* Service name */
	ci[1] = (cell_t) 0;				/* #argument cells */
	ci[2] = (cell_t) 0;				/* #result cells */

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