Exemple #1
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);
}
Exemple #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);
}
Exemple #3
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);
}
Exemple #4
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);
}
Exemple #5
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);
}
Exemple #6
0
int
prom_close(ihandle_t fd)
{
	cell_t ci[4];

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

	(void) p1275_cif_handler(&ci);

	return (0);
}
Exemple #7
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 */
}
Exemple #8
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 */
}
Exemple #9
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);
}
Exemple #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);
}