/* * 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); }
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 */ }
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 */ }
/* * 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); }
/* * 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); }