Ejemplo n.º 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);
}
Ejemplo n.º 2
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 */
}
Ejemplo n.º 3
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);
}
Ejemplo n.º 4
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);
}
Ejemplo n.º 5
0
int
p1275_ppc_cif_handler(void *p)
{
	cell_t rv;

	if (cif_handler == NULL)
		return (-1);

	rv = (*cif_handler)(p);
	return (p1275_cell2int(rv));
}
Ejemplo n.º 6
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);
	}
}
Ejemplo n.º 7
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);
}
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);
}
Ejemplo n.º 9
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 */
}
Ejemplo n.º 10
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]));
}
Ejemplo n.º 11
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 */
}
Ejemplo n.º 12
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);
	}
}
Ejemplo n.º 13
0
int
prom_seek(ihandle_t fd, u_longlong_t 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_ihandle2cell(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 */

	(void) p1275_cif_handler(&ci);

	return (p1275_cell2int(ci[6]));		/* Res1: actual */
}
Ejemplo n.º 14
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 */
}
Ejemplo n.º 15
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 */
}
Ejemplo n.º 16
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 */
}
Ejemplo n.º 17
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]));
}
Ejemplo n.º 18
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 */
}
Ejemplo n.º 19
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 */
}
Ejemplo n.º 20
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 */
}
Ejemplo n.º 21
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);
}
Ejemplo n.º 22
0
/*
 *  Returns 0 on error. Otherwise returns a handle.
 */
int
prom_open(char *path)
{
	cell_t ci[5];
	promif_owrap_t *ow;
#ifdef PROM_32BIT_ADDRS
	char *opath = NULL;
	size_t len;

	if ((uintptr_t)path > (uint32_t)-1) {
		opath = path;
		len = prom_strlen(opath) + 1; /* include terminating NUL */
		path = promplat_alloc(len);
		if (path == NULL)
			return (0);
		(void) prom_strcpy(path, opath);
	}
#endif

	ow = promif_preout();
	promif_preprom();
	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);

	promif_postprom();
	promif_postout(ow);

#ifdef PROM_32BIT_ADDRS
	if (opath != NULL)
		promplat_free(path, len);
#endif

	return (p1275_cell2int(ci[4]));		/* Res1: ihandle */
}
Ejemplo n.º 23
0
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);
}
Ejemplo n.º 24
0
int
prom_serengeti_detach_board(uint_t node, uint_t board)
{
	cell_t ci[6];
	int rv;

	ci[0] = p1275_ptr2cell("SUNW,Serengeti,remove-board");	/* name */
	ci[1] = (cell_t)2;				/* #argument cells */
	ci[2] = (cell_t)1;				/* #result cells */
	ci[3] = p1275_uint2cell(board);
	ci[4] = p1275_uint2cell(node);

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

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

	return (0);
}
Ejemplo n.º 25
0
/*
 * Get Fcode size, test if OBP supports this interface.
 */
int
prom_get_fcode_size(char *str)
{
	cell_t ci[5];
	int rv;

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

	ci[0] = p1275_ptr2cell("SUNW,get-fcode-size");
	ci[1] = (cell_t)1;	/* 1 input arg: str */
	ci[2] = (cell_t)1;	/* 1 output result: len or zero */
	ci[3] = p1275_ptr2cell(str);
	ci[4] = (cell_t)0;

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

	if (rv == 0)
		return (p1275_cell2int(ci[4]));
	return (0);
}