ihandle_t kmdb_prom_get_handle(char *name) { if (strcmp(name, "stdin") == 0) return (prom_stdin_ihandle()); else if (strcmp(name, "stdout") == 0 || strcmp(name, "stderr") == 0) return (prom_stdout_ihandle()); else return (-1); }
/* * Write string to PROM's notion of stdout. */ void prom_writestr(const char *buf, size_t len) { size_t written = 0; ihandle_t istdin; ssize_t i; istdin = prom_stdout_ihandle(); while (written < len) { if ((i = prom_write(istdin, (char *)buf, len - written, 0, BYTE)) == -1) continue; written += i; } }
ssize_t kmdb_prom_obp_writer(caddr_t buf, size_t len) { return (prom_write(prom_stdout_ihandle(), buf, len, 0, 0)); }
/*ARGSUSED3*/ ssize_t prom_write(ihandle_t fd, caddr_t buf, size_t len, uint_t startblk, char devtype) { cell_t ci[7]; promif_owrap_t *ow; ssize_t rlen; #ifdef PROM_32BIT_ADDRS caddr_t obuf = NULL; static char smallbuf[256]; ASSERT(buf); #endif /* * If the callback address is set, attempt to redirect * console output back into kernel terminal emulator. */ if (promif_redirect != NULL && fd == prom_stdout_ihandle()) { ow = promif_preout(); rlen = promif_redirect(promif_redirect_arg, (uchar_t *)buf, len); promif_postout(ow); return (rlen); } #ifdef PROM_32BIT_ADDRS if ((uintptr_t)buf > (uint32_t)-1) { /* * This is a hack for kernel message output. * By avoiding calls to promplat_alloc (and * using smallbuf instead) when memory is low * we can print shortish kernel messages without * deadlocking. smallbuf should be at least as * large as the automatic buffer in * prom_printf.c:_doprint()'s stack frame. * promplat_alloc() can block on a mutex and so * is called here before calling promif_preprom(). */ if (len > sizeof (smallbuf)) { obuf = buf; buf = promplat_alloc(len); if (buf == NULL) { return (-1); } promplat_bcopy(obuf, buf, len); } } #endif /* * Normally we'd call promif_preprom() just before * calling into the prom (to enforce single-threaded * access) but here we need to call it before accessing * smallbuf, since smallbuf is statically allocated and * hence can only be accessed by one thread at a time. */ ow = promif_preout(); promif_preprom(); #ifdef PROM_32BIT_ADDRS if ((uintptr_t)buf > (uint32_t)-1) { /* * If buf is small enough, use smallbuf * instead of promplat_alloc() (see above) * smallbuf is static, so single thread * access to it by using it only after * promif_preprom() */ if (len <= sizeof (smallbuf)) { promplat_bcopy(buf, smallbuf, len); buf = smallbuf; } } #endif ci[0] = p1275_ptr2cell("write"); /* 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_ptr2cell(buf); /* Arg2: buffer addr */ ci[5] = p1275_size2cell(len); /* Arg3: buffer len */ ci[6] = (cell_t)-1; /* Res1: Prime result */ (void) p1275_cif_handler(&ci); rlen = p1275_cell2size(ci[6]); /* Res1: actual len */ promif_postprom(); promif_postout(ow); #ifdef PROM_32BIT_ADDRS if (obuf != NULL) promplat_free(buf, len); #endif return (rlen); }