1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * CDDL HEADER START
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo *
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * The contents of this file are subject to the terms of the
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Common Development and Distribution License (the "License").
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * You may not use this file except in compliance with the License.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo *
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * or http://www.opensolaris.org/os/licensing.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * See the License for the specific language governing permissions
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * and limitations under the License.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo *
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * When distributing Covered Code, include this CDDL HEADER in each
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * If applicable, add the following below this CDDL HEADER, with the
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * fields enclosed by brackets "[]" replaced with your own identifying
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * information: Portions Copyright [yyyy] [name of copyright owner]
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo *
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * CDDL HEADER END
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/*
de81a4f48d467f6d0263221cbf4a199b6a925948jm * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Use is subject to license terms.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#pragma ident "%Z%%M% %I% %E% SMI"
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/promif_impl.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/systm.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/hypervisor_api.h>
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm#include <sys/consdev.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#ifndef _KMDB
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/kmem.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#endif
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm/*
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm * Definitions for using Polled I/O.
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm *
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm * The usage of Polled I/O is different when we are in kmdb. In that case,
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm * we can not directly invoke the polled I/O functions and we have to use
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm * the kmdb DPI interface. Also we don't need to enter/exit the polled I/O
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm * mode because this is already managed by kmdb when entering/exiting the
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm * debugger.
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm *
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm * When we are not in kmdb then we can directly call the polled I/O functions
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm * but we have to enter the polled I/O mode first. After using polled I/O
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm * functions we have to exit the polled I/O mode. Note that entering/exiting
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm * the polled I/O mode is time consuming so this should be avoided when
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm * possible.
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm */
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm#ifdef _KMDB
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajmextern struct cons_polledio *kmdb_kdi_get_polled_io(void);
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajmextern uintptr_t kmdb_dpi_call(uintptr_t, uint_t, const uintptr_t *);
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm#define PROMIF_PIO (kmdb_kdi_get_polled_io())
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm#define PROMIF_PIO_CALL1(fn, arg) \
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm (kmdb_dpi_call((uintptr_t)fn, 1, (uintptr_t *)&arg))
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm#define PROMIF_PIO_CALL2(fn, arg1, arg2) \
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm { \
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm uintptr_t args[2]; \
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm args[0] = (uintptr_t)arg1; \
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm args[1] = (uintptr_t)arg2; \
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm (void) (kmdb_dpi_call((uintptr_t)fn, 2, (uintptr_t *)args)); \
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm }
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm#define PROMIF_PIO_ENTER(pio)
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm#define PROMIF_PIO_EXIT(pio)
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm#else /* _KMDB */
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm#define PROMIF_PIO (cons_polledio)
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm#define PROMIF_PIO_CALL1(fn, arg) (fn(arg))
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm#define PROMIF_PIO_CALL2(fn, arg1, arg2) (fn(arg1, arg2))
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm#define PROMIF_PIO_ENTER(pio) \
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm if (pio->cons_polledio_enter != NULL) { \
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm pio->cons_polledio_enter(pio->cons_polledio_argument); \
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm }
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm#define PROMIF_PIO_EXIT(pio) \
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm if (pio->cons_polledio_exit != NULL) { \
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm pio->cons_polledio_exit(pio->cons_polledio_argument); \
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm }
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm#endif /* _KMDB */
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#define PROM_REG_TO_UNIT_ADDR(r) ((r) & ~(0xful << 28))
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic pnode_t instance_to_package(ihandle_t ih);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* cached copies of IO params */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic phandle_t pstdin;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic phandle_t pstdout;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic ihandle_t istdin;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic ihandle_t istdout;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajmstatic struct cons_polledio *promif_polledio = NULL;
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoint
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppopromif_instance_to_package(void *p)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cell_t *ci = (cell_t *)p;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ihandle_t ih;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo phandle_t ph;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ih = p1275_cell2ihandle(ci[3]);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ph = instance_to_package(ih);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ci[4] = p1275_phandle2cell(ph);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm/* This function is not used but it is convenient for debugging I/O problems */
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajmstatic void
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm/* LINTED */
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajmpromif_hv_print(char *str)
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm{
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm size_t i, len = strlen(str);
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm for (i = 0; i < len; i++) {
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm while (hv_cnputchar((uint8_t)str[i]) == H_EWOULDBLOCK)
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm /* try forever */;
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm }
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm}
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajmstatic void
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajmpromif_pio_enter(void)
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm{
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm ASSERT(promif_polledio == NULL);
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm promif_polledio = PROMIF_PIO;
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm ASSERT(promif_polledio != NULL);
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm PROMIF_PIO_ENTER(promif_polledio);
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm}
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajmstatic void
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajmpromif_pio_exit(void)
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm{
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm ASSERT(promif_polledio != NULL);
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm PROMIF_PIO_EXIT(promif_polledio);
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm promif_polledio = NULL;
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm}
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajmstatic int
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajmpromif_do_read(char *buf, size_t len, boolean_t wait)
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm{
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm int rlen;
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm int (*getchar)(cons_polledio_arg_t);
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm boolean_t (*ischar)(cons_polledio_arg_t);
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm cons_polledio_arg_t arg;
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm promif_pio_enter();
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm if ((ischar = promif_polledio->cons_polledio_ischar) == NULL)
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm return (0);
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm if ((getchar = promif_polledio->cons_polledio_getchar) == NULL)
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm return (0);
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm arg = promif_polledio->cons_polledio_argument;
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm for (rlen = 0; rlen < len; ) {
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm if (PROMIF_PIO_CALL1(ischar, arg)) {
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm buf[rlen] = PROMIF_PIO_CALL1(getchar, arg);
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm rlen++;
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm continue;
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm }
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm if (!wait)
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm break;
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm }
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm promif_pio_exit();
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm return (rlen);
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm}
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajmstatic int
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajmpromif_do_write(char *buf, size_t len)
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm{
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm int rlen;
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm void (*putchar)(cons_polledio_arg_t, uchar_t);
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm cons_polledio_arg_t arg;
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm promif_pio_enter();
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm if ((putchar = promif_polledio->cons_polledio_putchar) == NULL)
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm return (0);
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm arg = promif_polledio->cons_polledio_argument;
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm for (rlen = 0; rlen < len; rlen++)
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm PROMIF_PIO_CALL2(putchar, arg, buf[rlen]);
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm promif_pio_exit();
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm return (rlen);
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm}
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajmchar
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajmpromif_getchar(void)
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm{
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm char c;
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm (void) promif_do_read(&c, 1, B_TRUE);
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm return (c);
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm}
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoint
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppopromif_write(void *p)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cell_t *ci = (cell_t *)p;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo uint_t fd;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo char *buf;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo size_t len;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo size_t rlen;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ASSERT(ci[1] == 3);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo fd = p1275_cell2uint(ci[3]);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo buf = p1275_cell2ptr(ci[4]);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo len = p1275_cell2size(ci[5]);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* only support stdout (console) */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ASSERT(fd == istdout);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm rlen = promif_do_write(buf, len);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* return the length written */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ci[6] = p1275_size2cell(rlen);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoint
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppopromif_read(void *p)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cell_t *ci = (cell_t *)p;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo uint_t fd;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo char *buf;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo size_t len;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo size_t rlen;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ASSERT(ci[1] == 3);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* unpack arguments */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo fd = p1275_cell2uint(ci[3]);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo buf = p1275_cell2ptr(ci[4]);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo len = p1275_cell2size(ci[5]);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* only support stdin (console) */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ASSERT(fd == istdin);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1b83305cfc332b1e19ad6a194b73b2975e6bf79ajm rlen = promif_do_read(buf, len, B_FALSE);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* return the length read */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ci[6] = p1275_size2cell(rlen);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic pnode_t
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoinstance_to_package(ihandle_t ih)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* only support stdin and stdout */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ASSERT((ih == istdin) || (ih == istdout));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (ih == istdin)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (pstdin);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (ih == istdout)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (pstdout);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (OBP_BADNODE);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#ifdef _KMDB
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppovoid
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppopromif_io_init(ihandle_t in, ihandle_t out, phandle_t pin, phandle_t pout)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo istdin = in;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo istdout = out;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo pstdin = pin;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo pstdout = pout;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#else
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppovoid
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppopromif_io_init(void)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Cache the mapping between the stdin and stdout
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * ihandles and their respective phandles.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo pstdin = prom_stdin_node();
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo pstdout = prom_stdout_node();
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo istdin = prom_stdin_ihandle();
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo istdout = prom_stdout_ihandle();
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoint
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppopromif_instance_to_path(void *p)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cell_t *ci = (cell_t *)p;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo pnode_t node;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ihandle_t ih;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo char *buf;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int rlen;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo char *regval;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo uint_t *csaddr;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo char name[OBP_MAXPROPNAME];
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo char scratch[OBP_MAXPATHLEN];
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int rvlen;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ih = p1275_cell2ihandle(ci[3]);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo buf = p1275_cell2ptr(ci[4]);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ci[6] = p1275_uint2cell(0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo node = instance_to_package(ih);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo *buf = '\0';
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo while (node != prom_rootnode()) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (prom_getprop(node, OBP_NAME, name) == -1) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo prom_printf("instance_to_path: no name property "
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo "node=0x%x\n", node);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (-1);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* construct the unit address from the 'reg' property */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((rlen = prom_getproplen(node, OBP_REG)) == -1)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (-1);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
a47315d76ac34b1416ba8bd333c4d3b7ee54a56bjm /*
a47315d76ac34b1416ba8bd333c4d3b7ee54a56bjm * Make sure we don't get dispatched onto a different
a47315d76ac34b1416ba8bd333c4d3b7ee54a56bjm * cpu if we happen to sleep. See kern_postprom().
a47315d76ac34b1416ba8bd333c4d3b7ee54a56bjm */
de81a4f48d467f6d0263221cbf4a199b6a925948jm thread_affinity_set(curthread, CPU->cpu_id);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo regval = kmem_zalloc(rlen, KM_SLEEP);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) prom_getprop(node, OBP_REG, regval);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo csaddr = (uint_t *)regval;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) prom_sprintf(scratch, "/%s@%lx%s", name,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo PROM_REG_TO_UNIT_ADDR(*csaddr), buf);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo kmem_free(regval, rlen);
de81a4f48d467f6d0263221cbf4a199b6a925948jm thread_affinity_clear(curthread);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) prom_strcpy(buf, scratch);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo node = prom_parentnode(node);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo rvlen = prom_strlen(buf);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ci[6] = p1275_uint2cell(rvlen);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#endif /* _KMDB */