Beispiel #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, u_int align, unsigned long long *physaddr)
{
	cell_t ci[10];
	int rv;
	ihandle_t imemory = prom_memory_ihandle();

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

	if (align == 0)
		align = (u_int)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 */

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

	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);
}
Beispiel #2
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);
}
Beispiel #3
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);
}
Beispiel #4
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 */
}
Beispiel #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);
}
Beispiel #6
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);
}
Beispiel #7
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, unsigned long long physaddr)
{
	cell_t ci[10];
	int 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 */

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

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

	return (0);
}
Beispiel #8
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);
	}
}
Beispiel #9
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();
}
Beispiel #10
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();
}
Beispiel #11
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();
}
Beispiel #12
0
u_int
prom_gettime(void)
{
	cell_t ci[4];

	ci[0] = p1275_ptr2cell("milliseconds");	/* Service name */
	ci[1] = (cell_t)0;			/* #argument cells */
	ci[2] = (cell_t)1;			/* #return cells */

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

	return (p1275_cell2uint(ci[3]));	/* Res0: time in ms. */
}
Beispiel #13
0
int
prom_asr_list_keys_len()
{
	cell_t ci[4];

	ci[0] = p1275_ptr2cell("SUNW,asr-list-keys-len");
	ci[1] = (cell_t)0;			/* #argument cells */
	ci[2] = (cell_t)1;			/* #return cells */
	ci[3] = (cell_t)-1;			/* Res1: Prime result */

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

	return (p1275_cell2int(ci[3]));		/* Res1: buf length */
}
Beispiel #14
0
/*
 * Given the portid of the IOB to which the tunnel should be moved and the type
 * of move that should be performed, ask OBP to switch the IOSRAM tunnel from
 * its current host IOB to a new location.  If the move type is 0, OBP will
 * coordinate the change with SMS and will copy data from the current location
 * to the new location.  If the move type is 1, OBP will simply mark the new
 * location valid and start using it, without doing any data copying and without
 * communicating with SMS.  Return 0 on success, non-zero on failure.
 */
int
prom_starcat_switch_tunnel(uint_t portid, uint_t msgtype)
{
	static uint8_t	warned = 0;
	cell_t		ci[6];
	int		rv;

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

	/*
	 * Set up the arguments and call into OBP.
	 */
	ci[1] = (cell_t)2;				/* #argument cells */
	ci[2] = (cell_t)1;				/* #result cells */
	ci[3] = p1275_uint2cell(portid);
	ci[4] = p1275_uint2cell(msgtype);

	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
	 * failure and non-zero on success for this interface.
	 */
	if (rv != 0) {
		return (rv);
	} else if (p1275_cell2int(ci[5]) == 0)	{
		return (-1);
	} else {
		return (0);
	}
}
Beispiel #15
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 */
}
Beispiel #16
0
pnode_t
prom_childnode(pnode_t nodeid)
{
	cell_t ci[5];

	ci[0] = p1275_ptr2cell("child");	/* Service name */
	ci[1] = (cell_t)1;			/* #argument cells */
	ci[2] = (cell_t)1;			/* #result cells */
	ci[3] = p1275_dnode2cell(nodeid);	/* Arg1: input phandle */
	ci[4] = p1275_dnode2cell(OBP_NONODE);	/* Res1: Prime result */

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

	return (p1275_cell2dnode(ci[4]));	/* Res1: child phandle */
}
Beispiel #17
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 */
}
Beispiel #18
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);
}
Beispiel #19
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 */
}
Beispiel #20
0
int
prom_close(int fd)
{
	cell_t ci[4];
	promif_owrap_t *ow;

	ci[0] = p1275_ptr2cell("close");	/* Service name */
	ci[1] = (cell_t)1;			/* #argument cells */
	ci[2] = (cell_t)0;			/* #result cells */
	ci[3] = p1275_uint2cell((uint_t)fd);	/* Arg1: ihandle */

	ow = promif_preout();
	promif_preprom();
	(void) p1275_cif_handler(&ci);
	promif_postprom();
	promif_postout(ow);

	return (0);
}
Beispiel #21
0
int
prom_seek(int fd, unsigned long long offset)
{
	cell_t ci[7];

	ci[0] = p1275_ptr2cell("seek");		/* Service name */
	ci[1] = (cell_t)3;			/* #argument cells */
	ci[2] = (cell_t)1;			/* #result cells */
	ci[3] = p1275_uint2cell((uint_t)fd);	/* Arg1: ihandle */
	ci[4] = p1275_ull2cell_high(offset);	/* Arg2: pos.hi */
	ci[5] = p1275_ull2cell_low(offset);	/* Arg3: pos.lo */
	ci[6] = (cell_t)-1;			/* Res1: Prime result */

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

	return (p1275_cell2int(ci[6]));		/* Res1: actual */
}
Beispiel #22
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 */
}
Beispiel #23
0
int
prom_serengeti_cpu_off(pnode_t node)
{
	cell_t ci[5];
	int rv;

	ci[0] = p1275_ptr2cell("SUNW,Serengeti,park-cpu");
	ci[1] = (cell_t)1;			/* #argument cells */
	ci[2] = (cell_t)1;			/* #return cells */
	ci[3] = p1275_dnode2cell(node);

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

	if (rv != 0)
		return (-1);

	return (p1275_cell2int(ci[4]));
}
Beispiel #24
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);
}
Beispiel #25
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 */
}
Beispiel #26
0
int
prom_serengeti_wakeupcpu(pnode_t node)
{
	cell_t ci[5];
	int	rv;

	ci[0] = p1275_ptr2cell("SUNW,Serengeti,wakeup-cpu"); /* Service name */
	ci[1] = (cell_t)1;			/* #argument cells */
	ci[2] = (cell_t)1;			/* #result cells */
	ci[3] = p1275_dnode2cell(node);		/* Arg1: nodeid to wakeup */

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

	if (rv != 0)
		return (rv);
	else
		return (p1275_cell2int(ci[4])); /* Res1: Catch result */
}
Beispiel #27
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]));
}
Beispiel #28
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);
}
Beispiel #29
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 */
}
Beispiel #30
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);
}