Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
/*
 * 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;
	}
}
Ejemplo n.º 3
0
ssize_t
kmdb_prom_obp_writer(caddr_t buf, size_t len)
{
	return (prom_write(prom_stdout_ihandle(), buf, len, 0, 0));
}
Ejemplo n.º 4
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);
}