diff options
| author | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
|---|---|---|
| committer | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
| commit | 7c478bd95313f5f23a4c958a745db2134aa03244 (patch) | |
| tree | c871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/psm/promif | |
| download | illumos-joyent-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz | |
OpenSolaris Launch
Diffstat (limited to 'usr/src/psm/promif')
63 files changed, 6506 insertions, 0 deletions
diff --git a/usr/src/psm/promif/ieee1275/README.promif b/usr/src/psm/promif/ieee1275/README.promif new file mode 100644 index 0000000000..568236674b --- /dev/null +++ b/usr/src/psm/promif/ieee1275/README.promif @@ -0,0 +1,40 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# Copyright 1991-1994, 2003 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. + +#pragma ident "%Z%%M% %I% %E% SMI" + +This directory contains the IEEE 1275-1994 implementation +of the promif interfaces. + +The "common" subdirectory contains machine and platform +independent implementation of common promif interfaces. + +ISA and platform dependent implementations of promif +interfaces (including platform and/or ISA defined interfaces) +should be placed in appropriately named subdirectories: +(e.g.: sparc/v9, sun4u, ... ). + +The "sun4" directory contains common implementations of promif +interfaces which are used by sun4u and sun4r. diff --git a/usr/src/psm/promif/ieee1275/common/Makefile.files b/usr/src/psm/promif/ieee1275/common/Makefile.files new file mode 100644 index 0000000000..fb290c39e9 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/Makefile.files @@ -0,0 +1,74 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 1995-1997, 2002-2003 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# psm/promif/ieee1275/common/Makefile.files +# +# This Makefile defines all the promif file modules for the +# directory psm/promif/ieee1275/common +# + +# +# IEEE 1275-1994 'common' PROM Routines +# + +COMMON_PROM = \ + prom_2path.o \ + prom_boot.o \ + prom_devname.o \ + prom_devtype.o \ + prom_enter.o \ + prom_env.o \ + prom_exit.o \ + prom_fb.o \ + prom_getchar.o \ + prom_gettime.o \ + prom_handler.o \ + prom_inpath.o \ + prom_interp.o \ + prom_io.o \ + prom_kbd.o \ + prom_key.o \ + prom_node.o \ + prom_outpath.o \ + prom_panic.o \ + prom_path.o \ + prom_phandle.o \ + prom_printf.o \ + prom_prop.o \ + prom_putchar.o \ + prom_reboot.o \ + prom_stdin.o \ + prom_stdout.o \ + prom_string.o \ + prom_test.o \ + prom_trap.o \ + prom_version.o \ + prom_wrtestr.o + +sparc_PROM = + +CORE_OBJS += $(COMMON_PROM) $($(MACH)_PROM) diff --git a/usr/src/psm/promif/ieee1275/common/Makefile.rules b/usr/src/psm/promif/ieee1275/common/Makefile.rules new file mode 100644 index 0000000000..298c469314 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/Makefile.rules @@ -0,0 +1,45 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 1992-2002 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# This Makefile defines all build rules for the promif version for +# IEEE 1275-1994 compliant firmware (generic portions). +# + +# +# C object build rules +# + +$(OBJS_DIR)/%.o: $(PSMBASE)/promif/ieee1275/common/%.c + $(COMPILE.c) -o $@ $< + $(CTFCONVERT_O) + +# +# Lint `object' build rules +# + +$(LINTS_DIR)/%.ln: $(PSMBASE)/promif/ieee1275/common/%.c + @($(LHEAD) $(LINT.c) $< $(LTAIL)) diff --git a/usr/src/psm/promif/ieee1275/common/README.common b/usr/src/psm/promif/ieee1275/common/README.common new file mode 100644 index 0000000000..0f99e6ca8a --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/README.common @@ -0,0 +1,35 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 1994, Sun Microsystems, Inc. +# All rights reserved. + +#ident "%Z%%M% %I% %E% SMI" + +This directory contains the "common" (machine and platform-independent) +implementations of the promif interfaces for machines compliant with +IEEE 1275-1994. + +This implementation depends on the definition of certain fundamental +types and definitions (i.e. cell size) in external ISA and platform- +dependent header files, thus, the binaries created by compiling these +files, are ISA and platform-dependent. + diff --git a/usr/src/psm/promif/ieee1275/common/prom_2path.c b/usr/src/psm/promif/ieee1275/common/prom_2path.c new file mode 100644 index 0000000000..50bdada053 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/prom_2path.c @@ -0,0 +1,85 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 1991-1994,1998,2002 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +static int token2path(char *svc, uint_t token, char *buf, uint_t len); + +int +prom_ihandle_to_path(ihandle_t instance, char *buf, uint_t len) +{ + return (token2path("instance-to-path", (uint_t)instance, buf, len)); +} + +int +prom_phandle_to_path(phandle_t package, char *buf, uint_t len) +{ + return (token2path("package-to-path", (uint_t)package, buf, len)); +} + +static int +token2path(char *service, uint_t token, char *buf, uint_t len) +{ + cell_t ci[7]; + int rv; +#ifdef PROM_32BIT_ADDRS + char *obuf = NULL; + + if ((uintptr_t)buf > (uint32_t)-1) { + obuf = buf; + buf = promplat_alloc(len); + if (buf == NULL) { + return (-1); + } + } +#endif + + promif_preprom(); + + ci[0] = p1275_ptr2cell(service); /* Service name */ + ci[1] = 3; /* #argument cells */ + ci[2] = 1; /* #return cells */ + ci[3] = p1275_uint2cell(token); /* Arg1: ihandle/phandle */ + ci[4] = p1275_ptr2cell(buf); /* Arg2: Result buffer */ + ci[5] = p1275_uint2cell(len); /* Arg3: Buffer len */ + rv = p1275_cif_handler(&ci); + + promif_postprom(); + +#ifdef PROM_32BIT_ADDRS + if (obuf != NULL) { + promplat_bcopy(buf, obuf, len); + promplat_free(buf, len); + } +#endif + + if (rv != 0) + return (-1); + return (p1275_cell2int(ci[6])); /* Res1: Actual length */ +} diff --git a/usr/src/psm/promif/ieee1275/common/prom_boot.c b/usr/src/psm/promif/ieee1275/common/prom_boot.c new file mode 100644 index 0000000000..bebe45bd00 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/prom_boot.c @@ -0,0 +1,84 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1991-1994, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +char * +prom_bootargs(void) +{ + int length; + dnode_t node; + static char *name = "bootargs"; + static char bootargs[OBP_MAXPATHLEN]; + + if (bootargs[0] != (char)0) + return (bootargs); + + node = prom_chosennode(); + if ((node == OBP_NONODE) || (node == OBP_BADNODE)) + node = prom_rootnode(); + length = prom_getproplen(node, name); + if ((length == -1) || (length == 0)) + return (NULL); + if (length > OBP_MAXPATHLEN) + length = OBP_MAXPATHLEN - 1; /* Null terminator */ + (void) prom_bounded_getprop(node, name, bootargs, length); + return (bootargs); +} + + +struct bootparam * +prom_bootparam(void) +{ + PROMIF_DPRINTF(("prom_bootparam on P1275?\n")); + return ((struct bootparam *)0); +} + +char * +prom_bootpath(void) +{ + static char bootpath[OBP_MAXPATHLEN]; + int length; + dnode_t node; + static char *name = "bootpath"; + + if (bootpath[0] != (char)0) + return (bootpath); + + node = prom_chosennode(); + if ((node == OBP_NONODE) || (node == OBP_BADNODE)) + node = prom_rootnode(); + length = prom_getproplen(node, name); + if ((length == -1) || (length == 0)) + return (NULL); + if (length > OBP_MAXPATHLEN) + length = OBP_MAXPATHLEN - 1; /* Null terminator */ + (void) prom_bounded_getprop(node, name, bootpath, length); + return (bootpath); +} diff --git a/usr/src/psm/promif/ieee1275/common/prom_devname.c b/usr/src/psm/promif/ieee1275/common/prom_devname.c new file mode 100644 index 0000000000..b8510e3d4e --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/prom_devname.c @@ -0,0 +1,109 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1991-1994, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +int +prom_devname_from_pathname(register char *pathname, register char *buffer) +{ + register char *p; + + if ((pathname == (char *)0) || (*pathname == (char)0)) + return (-1); + + p = prom_strrchr(pathname, '/'); + if (p == 0) + return (-1); + + p++; + while (*p != 0) { + *buffer++ = *p++; + if ((*p == '@') || (*p == ':')) + break; + } + *buffer = (char)0; + + return (0); +} + +/* + * Get base device name of stdin/stdout device into callers buffer. + * Return 0 if successful; -1 otherwise. + */ + +int +prom_stdin_devname(char *buffer) +{ + return (prom_devname_from_pathname(prom_stdinpath(), buffer)); +} + +int +prom_stdout_devname(char *buffer) +{ + return (prom_devname_from_pathname(prom_stdoutpath(), buffer)); +} + +/* + * Return 1 if stdin/stdout are on the same device and subdevice. + * Return 0, otherwise. + */ + +int +prom_stdin_stdout_equivalence(void) +{ + register char *s, *p; + + s = prom_stdinpath(); + p = prom_stdoutpath(); + + if ((s != (char *)0) && (p != (char *)0)) { + return (prom_strcmp(s, p) == 0 ? 1:0); + } + + return (0); +} + +/* + * This just returns a pointer to the option's part of the + * last part of the string. Useful for determining which is + * the boot partition, tape file or channel of the DUART. + */ +char * +prom_path_options(register char *path) +{ + register char *p, *s; + + s = prom_strrchr(path, '/'); + if (s == (char *)0) + return ((char *)0); + p = prom_strrchr(s, ':'); + if (p == (char *)0) + return ((char *)0); + return (p+1); +} diff --git a/usr/src/psm/promif/ieee1275/common/prom_devtype.c b/usr/src/psm/promif/ieee1275/common/prom_devtype.c new file mode 100644 index 0000000000..3310376337 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/prom_devtype.c @@ -0,0 +1,66 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1991-1994, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +int +prom_devicetype(dnode_t id, char *type) +{ + register int len; + char buf[OBP_MAXDRVNAME]; + + len = prom_getproplen(id, OBP_DEVICETYPE); + if (len <= 0 || len >= OBP_MAXDRVNAME) + return (0); + + (void) prom_getprop(id, OBP_DEVICETYPE, (caddr_t)buf); + + if (prom_strcmp(type, buf) == 0) + return (1); + + return (0); +} + +int +prom_getnode_byname(dnode_t id, char *name) +{ + int len; + char buf[OBP_MAXDRVNAME]; + + len = prom_getproplen(id, OBP_NAME); + if (len <= 0 || len >= OBP_MAXDRVNAME) + return (0); + + (void) prom_getprop(id, OBP_NAME, (caddr_t)buf); + + if (prom_strcmp(name, buf) == 0) + return (1); + + return (0); +} diff --git a/usr/src/psm/promif/ieee1275/common/prom_enter.c b/usr/src/psm/promif/ieee1275/common/prom_enter.c new file mode 100644 index 0000000000..6f6037f935 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/prom_enter.c @@ -0,0 +1,47 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1991-1994,2001 by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +void +prom_enter_mon(void) +{ + cell_t ci[3]; + promif_owrap_t *ow; + + ci[0] = p1275_ptr2cell("enter"); /* Service name */ + ci[1] = (cell_t)0; /* #argument cells */ + ci[2] = (cell_t)0; /* #return cells */ + + ow = promif_preout(); + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); + promif_postout(ow); +} diff --git a/usr/src/psm/promif/ieee1275/common/prom_env.c b/usr/src/psm/promif/ieee1275/common/prom_env.c new file mode 100644 index 0000000000..4b96de9737 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/prom_env.c @@ -0,0 +1,173 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +/* + * The functions in this file are used to control the pre- and post-processing + * functions that bracket calls to the OBP CIF handler. One set, promif_preprom + * and promif_postprom, are provided for general kernel use. The other set, + * promif_preout and promif_postout, are used by the power management subsystem + * to ensure that the framebuffer is active when PROM functions that interact + * with the console are invoked. + * + * In some cases, the operation of these functions must be suppressed. As such, + * this file provides the ability to suspend and resume use of both sets + * simultaneously. Complicating matters is the fact that both current uses of + * the pre- and post-processor suspension and resume facilities, kmdb and CPR + * may be used simultaneously. We therefore support normal operation and two + * levels of suspension. The pre- and post-processing functions are only + * called during normal operation. With each suspension request, this + * subsystem enters the first suspension level, or passes to the second + * suspension level, as appropriate. Resume calls decrement the suspension + * level. Only two nested suspensions are supported. + * + * As indicated above, the two current users are CPR and kmdb. CPR must prevent + * kernel accesses outside of the nucleus page during the late stages of system + * suspension and during the early stages of system resumption. As such, the + * PM-related processing must not occur during these times. + * + * The platform-specific portions of kmdb live in the platmods, and thus execute + * in the linker environment of the platmods. That is, any promif calls they + * may make are executed by the kernel copies of those functions, rather than + * the versions included with kmdb. The only difference between the two copies + * being the nonuse of the pre- and post-processing functions in the kmdb + * versions, we must ensure that these functions are not used when the kmdb + * platmod code executes. Accordingly, kmdb disables the pre- and post- + * processing functions via the KDI prior to passing control to the platmod + * debugger code. + */ + +static int promif_suspendlevel; + +static promif_preprom_f *promif_preprom_fn; +static promif_postprom_f *promif_postprom_fn; + +void +prom_set_preprom(promif_preprom_f *new) +{ + promif_preprom_fn = new; +} + +void +prom_set_postprom(promif_postprom_f *new) +{ + promif_postprom_fn = new; +} + +void +promif_preprom(void) +{ + if (promif_suspendlevel == 0 && promif_preprom_fn != NULL) + promif_preprom_fn(); +} + +void +promif_postprom(void) +{ + if (promif_suspendlevel == 0 && promif_postprom_fn != NULL) + promif_postprom_fn(); +} + +/* + * The reader will note that the layout and calling conventions of the + * prom_preout and prom_postout functions differ from the prom_preprom and + * prom_postprom functions, above. At the time the preout and postout + * functions are initialized, kernel startup is well underway. There exists + * a race condition whereby a PROM call may begin before preout has been + * initialized, and may end after postout has been initialized. In such + * cases, there will be a call to postout without a corresponding preout + * call. The preprom and postprom calls above are initialized early enough + * that this race condition does not occur. + * + * To avoid the race condition, the preout/postout functions are designed + * such that the initialization is atomic. Further, the preout call returns + * a data structure that includes a pointer to the postout function that + * corresponds to the invoked preout function. This ensures that the preout + * and postout functions will only be used as a matched set. + */ + +static void +null_outfunc(void) +{ +} + +static promif_owrap_t nullwrapper = +{ + null_outfunc, + null_outfunc +}; + +static promif_owrap_t *wrapper = &nullwrapper; +static promif_owrap_t pmwrapper; + +promif_owrap_t +*promif_preout(void) +{ + promif_owrap_t *ow; + + if (promif_suspendlevel > 0) + return (&nullwrapper); + + ow = wrapper; + if (ow->preout != NULL) + (ow->preout)(); + return (ow); +} + +void +promif_postout(promif_owrap_t *ow) +{ + if (ow->postout != NULL) + (ow->postout)(); +} + +void +prom_set_outfuncs(void (*pref)(void), void (*postf)(void)) +{ + pmwrapper.preout = pref; + pmwrapper.postout = postf; + wrapper = &pmwrapper; +} + +void +prom_suspend_prepost(void) +{ + ASSERT(promif_suspendlevel < 2); + + promif_suspendlevel++; +} + +void +prom_resume_prepost(void) +{ + ASSERT(promif_suspendlevel >= 0); + + promif_suspendlevel--; +} diff --git a/usr/src/psm/promif/ieee1275/common/prom_exit.c b/usr/src/psm/promif/ieee1275/common/prom_exit.c new file mode 100644 index 0000000000..f78c727013 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/prom_exit.c @@ -0,0 +1,52 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +/* + * There should be no return from this function + */ +void +prom_exit_to_mon(void) +{ + cell_t ci[3]; + + ci[0] = p1275_ptr2cell("exit"); /* Service name */ + ci[1] = (cell_t)0; /* #argument cells */ + ci[2] = (cell_t)0; /* #return cells */ + + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); + + /*CONSTCOND*/ + while (1) + ; + /*NOTREACHED*/ +} diff --git a/usr/src/psm/promif/ieee1275/common/prom_fb.c b/usr/src/psm/promif/ieee1275/common/prom_fb.c new file mode 100644 index 0000000000..bc3cb5f8bf --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/prom_fb.c @@ -0,0 +1,41 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1995, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +int +prom_stdout_is_framebuffer(void) +{ + static int remember = -1; + + if (remember == -1) + remember = prom_devicetype((dnode_t) prom_stdout_node(), + OBP_DISPLAY); + return (remember); +} diff --git a/usr/src/psm/promif/ieee1275/common/prom_getchar.c b/usr/src/psm/promif/ieee1275/common/prom_getchar.c new file mode 100644 index 0000000000..4e58c9503b --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/prom_getchar.c @@ -0,0 +1,51 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1991-1994, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +u_char +prom_getchar(void) +{ + int c; + + while ((c = prom_mayget()) == -1) + ; + + return ((u_char)c); +} + +int +prom_mayget(void) +{ + ssize_t rv; + char c; + + rv = prom_read(prom_stdin_ihandle(), &c, 1, 0, BYTE); + return (rv == 1 ? (int)c : -1); +} diff --git a/usr/src/psm/promif/ieee1275/common/prom_gettime.c b/usr/src/psm/promif/ieee1275/common/prom_gettime.c new file mode 100644 index 0000000000..ba39822947 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/prom_gettime.c @@ -0,0 +1,53 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1991-1994, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +/* + * This prom entry point cannot be used once the kernel is up + * and running (after stop_mon_clock is called) since the kernel + * takes over level 14 interrupt handling which the PROM depends + * on to update the time. + */ + +u_int +prom_gettime(void) +{ + cell_t ci[4]; + + ci[0] = p1275_ptr2cell("milliseconds"); /* Service name */ + ci[1] = (cell_t)0; /* #argument cells */ + ci[2] = (cell_t)1; /* #return cells */ + + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); + + return (p1275_cell2uint(ci[3])); /* Res0: time in ms. */ +} diff --git a/usr/src/psm/promif/ieee1275/common/prom_handler.c b/usr/src/psm/promif/ieee1275/common/prom_handler.c new file mode 100644 index 0000000000..d3150dd0bd --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/prom_handler.c @@ -0,0 +1,64 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1994 by Sun Microsystems, Inc. + * All Rights Reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +void * +prom_set_callback(void *handler) +{ + cell_t ci[5]; + + ci[0] = p1275_ptr2cell("set-callback"); /* Service name */ + ci[1] = (cell_t)1; /* #argument cells */ + ci[2] = (cell_t)1; /* #return cells */ + ci[3] = p1275_ptr2cell(handler); /* Arg1: New handler */ + ci[4] = (cell_t)-1; /* Res1: Prime result */ + + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); + + return (p1275_cell2ptr(ci[4])); /* Res1: Old handler */ +} + +void +prom_set_symbol_lookup(void *sym2val, void *val2sym) +{ + cell_t ci[5]; + + ci[0] = p1275_ptr2cell("set-symbol-lookup"); /* Service name */ + ci[1] = (cell_t)2; /* #argument cells */ + ci[2] = (cell_t)0; /* #return cells */ + ci[3] = p1275_ptr2cell(sym2val); /* Arg1: s2v handler */ + ci[4] = p1275_ptr2cell(val2sym); /* Arg1: v2s handler */ + + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); +} diff --git a/usr/src/psm/promif/ieee1275/common/prom_inpath.c b/usr/src/psm/promif/ieee1275/common/prom_inpath.c new file mode 100644 index 0000000000..7c7bd7f04f --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/prom_inpath.c @@ -0,0 +1,50 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1994, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +static char *stdinpath; +static char buffer[OBP_MAXPATHLEN]; + +char * +prom_stdinpath(void) +{ + ihandle_t istdin; + + if (stdinpath != (char *) 0) /* Got it already? */ + return (stdinpath); + + istdin = prom_stdin_ihandle(); + + if (istdin != (ihandle_t)-1) + if (prom_ihandle_to_path(istdin, buffer, + OBP_MAXPATHLEN - 1) > 0) + return (stdinpath = buffer); + return ((char *)0); +} diff --git a/usr/src/psm/promif/ieee1275/common/prom_interp.c b/usr/src/psm/promif/ieee1275/common/prom_interp.c new file mode 100644 index 0000000000..bed15c0710 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/prom_interp.c @@ -0,0 +1,73 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1991-1997,2001 by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +void +prom_interpret(char *string, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, + uintptr_t arg4, uintptr_t arg5) +{ + cell_t ci[9]; + promif_owrap_t *ow; + + /* + * NB: It is not possible to provide a compatible interface + * here, if the size of an int is different from the size of a + * cell, since we don't know how to promote the arguments. We + * simply promote arguments treating them as unsigned integers; + * thus pointers will be properly promoted and negative signed + * integer value will not be properly promoted. This isn't an + * issue for LP64 client programs since this code will simply + * pass the entire 64-bit arguments through unchanged. + * + * XXX: This is not fully capable via this interface. Use + * p1275_cif_handler directly for all features. Specifically, + * there's no catch_result and no result cells available via this + * interface. This interface provided for compatibilty with + * existing OBP code. Note that we also assume that the + * arguments are not to be sign extended. Assuming the code + * using these arguments is written correctly, this should be OK. + */ + + ci[0] = p1275_ptr2cell("interpret"); /* Service name */ + ci[1] = (cell_t)6; /* #argument cells */ + ci[2] = (cell_t)0; /* #return cells */ + ci[3] = p1275_ptr2cell(string); /* Arg1: Interpreted string */ + ci[4] = p1275_uintptr2cell(arg1); /* Arg2: stack arg 1 */ + ci[5] = p1275_uintptr2cell(arg2); /* Arg3: stack arg 2 */ + ci[6] = p1275_uintptr2cell(arg3); /* Arg4: stack arg 3 */ + ci[7] = p1275_uintptr2cell(arg4); /* Arg5: stack arg 4 */ + ci[8] = p1275_uintptr2cell(arg5); /* Arg6: stack arg 5 */ + + ow = promif_preout(); + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); + promif_postout(ow); +} diff --git a/usr/src/psm/promif/ieee1275/common/prom_io.c b/usr/src/psm/promif/ieee1275/common/prom_io.c new file mode 100644 index 0000000000..1563936cbc --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/prom_io.c @@ -0,0 +1,233 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 1994,1998,2001-2002 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +/* + * Returns 0 on error. Otherwise returns a handle. + */ +int +prom_open(char *path) +{ + cell_t ci[5]; + promif_owrap_t *ow; +#ifdef PROM_32BIT_ADDRS + char *opath = NULL; + size_t len; + + if ((uintptr_t)path > (uint32_t)-1) { + opath = path; + len = prom_strlen(opath) + 1; /* include terminating NUL */ + path = promplat_alloc(len); + if (path == NULL) + return (0); + (void) prom_strcpy(path, opath); + } +#endif + + ow = promif_preout(); + promif_preprom(); + ci[0] = p1275_ptr2cell("open"); /* Service name */ + ci[1] = (cell_t)1; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_ptr2cell(path); /* Arg1: Pathname */ + ci[4] = (cell_t)0; /* Res1: Prime result */ + + (void) p1275_cif_handler(&ci); + + promif_postprom(); + promif_postout(ow); + +#ifdef PROM_32BIT_ADDRS + if (opath != NULL) + promplat_free(path, len); +#endif + + return (p1275_cell2int(ci[4])); /* Res1: ihandle */ +} + + +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 */ +} + +/*ARGSUSED3*/ +ssize_t +prom_read(ihandle_t fd, caddr_t buf, size_t len, uint_t startblk, char devtype) +{ + cell_t ci[7]; + promif_owrap_t *ow; +#ifdef PROM_32BIT_ADDRS + caddr_t obuf = NULL; + + if ((uintptr_t)buf > (uint32_t)-1) { + obuf = buf; + buf = promplat_alloc(len); + if (buf == NULL) + return (-1); + } +#endif + + ow = promif_preout(); + promif_preprom(); + + ci[0] = p1275_ptr2cell("read"); /* Service name */ + ci[1] = (cell_t)3; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_size2cell((uint_t)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); + + promif_postprom(); + promif_postout(ow); + +#ifdef PROM_32BIT_ADDRS + if (obuf != NULL) { + promplat_bcopy(buf, obuf, len); + promplat_free(buf, len); + } +#endif + + return (p1275_cell2size(ci[6])); /* Res1: actual length */ +} + +/*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; +#ifdef PROM_32BIT_ADDRS + caddr_t obuf = NULL; + static char smallbuf[256]; + + ASSERT(buf); + + 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 + + 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 address */ + ci[5] = p1275_size2cell(len); /* Arg3: buffer length */ + ci[6] = (cell_t)-1; /* Res1: Prime result */ + + (void) p1275_cif_handler(&ci); + + promif_postprom(); + promif_postout(ow); + +#ifdef PROM_32BIT_ADDRS + if (obuf != NULL) + promplat_free(buf, len); +#endif + + return (p1275_cell2size(ci[6])); /* Res1: actual length */ +} + +int +prom_close(int fd) +{ + cell_t ci[4]; + promif_owrap_t *ow; + + ci[0] = p1275_ptr2cell("close"); /* Service name */ + ci[1] = (cell_t)1; /* #argument cells */ + ci[2] = (cell_t)0; /* #result cells */ + ci[3] = p1275_uint2cell((uint_t)fd); /* Arg1: ihandle */ + + ow = promif_preout(); + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); + promif_postout(ow); + + return (0); +} diff --git a/usr/src/psm/promif/ieee1275/common/prom_kbd.c b/usr/src/psm/promif/ieee1275/common/prom_kbd.c new file mode 100644 index 0000000000..f09dfdb2e9 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/prom_kbd.c @@ -0,0 +1,56 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1998-1999 by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +/* + * If the stdin device exports the "keyboard" property and + * the length of the property is 0, return true. Otherwise, + * check the name of the stdin device node. If the name is + * "keyboard" return true, else return false. + * XXX: The "keyboard" property is not part of the IEEE 1275 standard. + * XXX: Perhaps this belongs in platform dependent directories? + */ +int +prom_stdin_is_keyboard(void) +{ + char dev_name[OBP_MAXDRVNAME]; + + /* + * NB: A keyboard property with a value might be an alias + * or something else so we distinguish it by length. + */ + if (prom_getproplen(prom_stdin_node(), "keyboard") == 0) + return (1); + + if (prom_stdin_devname(dev_name) == -1) + return (0); + + return (prom_strcmp(dev_name, "keyboard") == 0); +} diff --git a/usr/src/psm/promif/ieee1275/common/prom_key.c b/usr/src/psm/promif/ieee1275/common/prom_key.c new file mode 100644 index 0000000000..75363ad4a0 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/prom_key.c @@ -0,0 +1,198 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2002-2003 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * This provides the interface to store a named key in stable local + * storage. These keys are retrieved and used by OBP and WAN boot + * to do decryption and HMAC verification of network-downloaded data. + */ + +#include <sys/promimpl.h> +#ifdef PROM_32BIT_ADDRS +#include <sys/sunddi.h> +#endif /* PROM_32BIT_ADDRS */ + +int +prom_set_security_key(char *keyname, caddr_t buf, int buflen, int *reslen, + int *status) +{ + int rv; + cell_t ci[7]; + int result; +#ifdef PROM_32BIT_ADDRS + char *okeyname = NULL; + char *obuf = NULL; + size_t keynamelen; + + if ((uintptr_t)keyname > (uint32_t)-1) { + okeyname = keyname; + keynamelen = prom_strlen(okeyname) + 1; /* include '\0' */ + keyname = promplat_alloc(keynamelen); + if (keyname == NULL) + return (-1); + (void) prom_strcpy(keyname, okeyname); + } + + /* + * A key length of zero is used to delete the named key. + * No need to reallocate and copy buf[] in this case. + */ + if (buflen > 0 && ((uintptr_t)buf > (uint32_t)-1)) { + obuf = buf; + buf = promplat_alloc(buflen); + if ((buf == NULL) && (okeyname != NULL)) { + promplat_free(keyname, keynamelen); + return (-1); + } + promplat_bcopy(obuf, buf, buflen); + } +#endif /* PROM_32BIT_ADDRS */ + + /* + * The arguments to the SUNW,set-security-key service + * that stores a key are + * ci[0] the service name + * ci[1] the number of ``in'' arguments + * ci[2] the number of ``out'' arguments + * ci[3] the key's name, as a string + * ci[4] the key buffer itself + * ci[5] the length of the key buffer + * + * When p1275_cif_handler() returns, the return value is + * ci[6] the length of the key stored, or (if + * negative) an error code. + */ + ci[0] = p1275_ptr2cell("SUNW,set-security-key"); + ci[1] = 3; + ci[2] = 1; + ci[3] = p1275_ptr2cell(keyname); + ci[4] = p1275_ptr2cell(buf); + ci[5] = p1275_uint2cell(buflen); + + promif_preprom(); + rv = p1275_cif_handler(ci); + promif_postprom(); + +#ifdef PROM_32BIT_ADDRS + if (okeyname != NULL) + promplat_free(keyname, keynamelen); + if (obuf != NULL) + promplat_free(buf, buflen); +#endif /* PROM_32BIT_ADDRS */ + + if (rv != 0) + return (-1); + + result = p1275_cell2int(ci[6]); + if (result >= 0) { + *reslen = result; + *status = 0; + } else { + *reslen = 0; + *status = result; + } + return (0); +} + +int +prom_get_security_key(char *keyname, caddr_t buf, int buflen, int *keylen, + int *status) +{ + int rv; + cell_t ci[7]; + int result; +#ifdef PROM_32BIT_ADDRS + char *okeyname = NULL; + char *obuf = NULL; + size_t keynamelen; + + if ((uintptr_t)keyname > (uint32_t)-1) { + okeyname = keyname; + keynamelen = prom_strlen(okeyname) + 1; /* include '\0' */ + keyname = promplat_alloc(keynamelen); + if (keyname == NULL) + return (-1); + (void) prom_strcpy(keyname, okeyname); + } + if ((uintptr_t)buf > (uint32_t)-1) { + obuf = buf; + buf = promplat_alloc(buflen); + if ((buf == NULL) && (okeyname != NULL)) { + promplat_free(keyname, keynamelen); + return (-1); + } + } +#endif /* PROM_32BIT_ADDRS */ + + /* + * The arguments to the SUNW,get-security-key service + * that stores a key are + * ci[0] the service name + * ci[1] the number of ``in'' arguments + * ci[2] the number of ``out'' arguments + * ci[3] the key's name, as a string + * ci[4] the key buffer itself + * ci[5] the length of the key buffer + * + * When p1275_cif_handler() returns, the return value is + * ci[6] the length of the key, or (if + * negative) an error code. + */ + ci[0] = p1275_ptr2cell("SUNW,get-security-key"); + ci[1] = 3; + ci[2] = 1; + ci[3] = p1275_ptr2cell(keyname); + ci[4] = p1275_ptr2cell(buf); + ci[5] = p1275_uint2cell(buflen); + + promif_preprom(); + rv = p1275_cif_handler(ci); + promif_postprom(); + +#ifdef PROM_32BIT_ADDRS + if (okeyname != NULL) + promplat_free(keyname, keynamelen); + if (obuf != NULL) { + promplat_bcopy(buf, obuf, buflen); + promplat_free(buf, buflen); + } +#endif /* PROM_32BIT_ADDRS */ + + if (rv != 0) + return (-1); + + result = p1275_cell2int(ci[6]); + if (result > 0) { + *keylen = result; + *status = 0; + } else { + *keylen = 0; + *status = result; + } + return (0); +} diff --git a/usr/src/psm/promif/ieee1275/common/prom_node.c b/usr/src/psm/promif/ieee1275/common/prom_node.c new file mode 100644 index 0000000000..95ff877149 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/prom_node.c @@ -0,0 +1,294 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 1994,1998-2000,2002 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +/* + * Routines for walking the PROMs devinfo tree + */ +dnode_t +prom_nextnode(dnode_t nodeid) +{ + cell_t ci[5]; + + ci[0] = p1275_ptr2cell("peer"); /* Service name */ + ci[1] = (cell_t)1; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_dnode2cell(nodeid); /* Arg1: input phandle */ + ci[4] = p1275_dnode2cell(OBP_NONODE); /* Res1: Prime result */ + + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); + + return (p1275_cell2dnode(ci[4])); /* Res1: peer phandle */ +} + +dnode_t +prom_childnode(dnode_t nodeid) +{ + cell_t ci[5]; + + ci[0] = p1275_ptr2cell("child"); /* Service name */ + ci[1] = (cell_t)1; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_dnode2cell(nodeid); /* Arg1: input phandle */ + ci[4] = p1275_dnode2cell(OBP_NONODE); /* Res1: Prime result */ + + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); + + return (p1275_cell2dnode(ci[4])); /* Res1: child phandle */ +} + +/* + * prom_walk_devs() implements a generic walker for the OBP tree; this + * implementation uses an explicitly managed stack in order to save the + * overhead of a recursive implementation. + */ +void +prom_walk_devs(dnode_t node, int (*cb)(dnode_t, void *, void *), void *arg, + void *result) +{ + dnode_t stack[OBP_STACKDEPTH]; + int stackidx = 0; + + if (node == OBP_NONODE || node == OBP_BADNODE) { + prom_panic("Invalid node specified as root of prom tree walk"); + } + + stack[0] = node; + + for (;;) { + dnode_t curnode = stack[stackidx]; + dnode_t child; + + /* + * We're out of stuff to do at this level, bump back up a level + * in the tree, and move to the next node; if the new level + * will be level -1, we're done. + */ + if (curnode == OBP_NONODE || curnode == OBP_BADNODE) { + stackidx--; + + if (stackidx < 0) + return; + + stack[stackidx] = prom_nextnode(stack[stackidx]); + continue; + } + + switch ((*cb)(curnode, arg, result)) { + + case PROM_WALK_TERMINATE: + return; + + case PROM_WALK_CONTINUE: + /* + * If curnode has a child, traverse to it, + * otherwise move to curnode's sibling. + */ + child = prom_childnode(curnode); + if (child != OBP_NONODE && child != OBP_BADNODE) { + stackidx++; + stack[stackidx] = child; + } else { + stack[stackidx] = + prom_nextnode(stack[stackidx]); + } + break; + + default: + prom_panic("unrecognized walk directive"); + } + } +} + +/* + * prom_findnode_bydevtype() searches the prom device subtree rooted at 'node' + * and returns the first node whose device type property matches the type + * supplied in 'devtype'. + */ +static int +bytype_cb(dnode_t node, void *arg, void *result) +{ + if (prom_devicetype(node, (char *)arg)) { + *((dnode_t *)result) = node; + return (PROM_WALK_TERMINATE); + } + return (PROM_WALK_CONTINUE); +} + +dnode_t +prom_findnode_bydevtype(dnode_t node, char *devtype) +{ + dnode_t result = OBP_NONODE; + prom_walk_devs(node, bytype_cb, devtype, &result); + return (result); +} + + +/* + * prom_findnode_byname() searches the prom device subtree rooted at 'node' and + * returns the first node whose name matches the name supplied in 'name'. + */ +static int +byname_cb(dnode_t node, void *arg, void *result) +{ + if (prom_getnode_byname(node, (char *)arg)) { + *((dnode_t *)result) = node; + return (PROM_WALK_TERMINATE); + } + return (PROM_WALK_CONTINUE); +} + +dnode_t +prom_findnode_byname(dnode_t node, char *name) +{ + dnode_t result = OBP_NONODE; + prom_walk_devs(node, byname_cb, name, &result); + return (result); +} + +/* + * Return the root nodeid. + * Calling prom_nextnode(0) returns the root nodeid. + */ +dnode_t +prom_rootnode(void) +{ + static dnode_t rootnode; + + return (rootnode ? rootnode : (rootnode = prom_nextnode(OBP_NONODE))); +} + +dnode_t +prom_parentnode(dnode_t nodeid) +{ + cell_t ci[5]; + + ci[0] = p1275_ptr2cell("parent"); /* Service name */ + ci[1] = (cell_t)1; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_dnode2cell(nodeid); /* Arg1: input phandle */ + ci[4] = p1275_dnode2cell(OBP_NONODE); /* Res1: Prime result */ + + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); + + return (p1275_cell2dnode(ci[4])); /* Res1: parent phandle */ +} + +dnode_t +prom_finddevice(char *path) +{ + cell_t ci[5]; +#ifdef PROM_32BIT_ADDRS + char *opath = NULL; + size_t len; + + if ((uintptr_t)path > (uint32_t)-1) { + opath = path; + len = prom_strlen(opath) + 1; /* include terminating NUL */ + path = promplat_alloc(len); + if (path == NULL) { + return (OBP_BADNODE); + } + (void) prom_strcpy(path, opath); + } +#endif + + promif_preprom(); + + ci[0] = p1275_ptr2cell("finddevice"); /* Service name */ + ci[1] = (cell_t)1; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_ptr2cell(path); /* Arg1: pathname */ + ci[4] = p1275_dnode2cell(OBP_BADNODE); /* Res1: Prime result */ + + (void) p1275_cif_handler(&ci); + + promif_postprom(); + +#ifdef PROM_32BIT_ADDRS + if (opath != NULL) + promplat_free(path, len); +#endif + + return ((dnode_t)p1275_cell2dnode(ci[4])); /* Res1: phandle */ +} + +dnode_t +prom_chosennode(void) +{ + static dnode_t chosen; + dnode_t node; + + if (chosen) + return (chosen); + + node = prom_finddevice("/chosen"); + + if (node != OBP_BADNODE) + return (chosen = node); + + prom_fatal_error("prom_chosennode: Can't find </chosen>\n"); + /*NOTREACHED*/ +} + +/* + * Returns the nodeid of /aliases. + * /aliases exists in OBP >= 2.4 and in Open Firmware. + * Returns OBP_BADNODE if it doesn't exist. + */ +dnode_t +prom_alias_node(void) +{ + static dnode_t node; + + if (node == 0) + node = prom_finddevice("/aliases"); + return (node); +} + +/* + * Returns the nodeid of /options. + * Returns OBP_BADNODE if it doesn't exist. + */ +dnode_t +prom_optionsnode(void) +{ + static dnode_t node; + + if (node == 0) + node = prom_finddevice("/options"); + return (node); +} diff --git a/usr/src/psm/promif/ieee1275/common/prom_outpath.c b/usr/src/psm/promif/ieee1275/common/prom_outpath.c new file mode 100644 index 0000000000..a78bc82bdb --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/prom_outpath.c @@ -0,0 +1,50 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1991-1994, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +static char *stdoutpath; +static char buffer[OBP_MAXPATHLEN]; + +char * +prom_stdoutpath(void) +{ + ihandle_t istdout; + + if (stdoutpath != (char *)0) + return (stdoutpath); + + istdout = prom_stdout_ihandle(); + + if (istdout != (ihandle_t)-1) + if (prom_ihandle_to_path(istdout, buffer, + OBP_MAXPATHLEN - 1) > 0) + return (stdoutpath = buffer); + return ((char *)0); +} diff --git a/usr/src/psm/promif/ieee1275/common/prom_panic.c b/usr/src/psm/promif/ieee1275/common/prom_panic.c new file mode 100644 index 0000000000..3ee5ca361d --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/prom_panic.c @@ -0,0 +1,40 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1991-1995, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +void +prom_panic(char *s) +{ + if (!s) + s = "unknown panic"; + prom_printf("panic - %s: %s\n", promif_clntname, s); + prom_exit_to_mon(); + /*NOTREACHED*/ +} diff --git a/usr/src/psm/promif/ieee1275/common/prom_path.c b/usr/src/psm/promif/ieee1275/common/prom_path.c new file mode 100644 index 0000000000..1f963351f2 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/prom_path.c @@ -0,0 +1,165 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 1991-1994,1998,2002 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +char * +prom_path_gettoken(register char *from, register char *to) +{ + while (*from) { + switch (*from) { + case '/': + case '@': + case ':': + case ',': + *to = '\0'; + return (from); + default: + *to++ = *from++; + } + } + *to = '\0'; + return (from); +} + +/* + * Given an OBP pathname, do the best we can to fully expand + * the OBP pathname, in place in the callers buffer. + * + * If we have to complete the addrspec of any component, we can + * only handle devices that have a maximum of NREGSPECS "reg" specs. + * We cannot allocate memory inside this function. + * + * XXX: Assumes a single threaded model, as static buffers are used + * for temporary storage. This is not to be used an an external + * interface. The external interface should have temporary + * buffers passed in, or they should be allocated on the stack, + * (which may not be desirable in the kernel). + */ + +static char buffer[OBP_MAXPATHLEN]; + +void +prom_pathname(char *pathname) +{ + char *from = buffer; + char *to = pathname; + char *p; + cell_t ci[7]; +#ifdef PROM_32BIT_ADDRS + char *opathname = NULL; +#endif + + if ((to == (char *)0) || (*to == (char)0)) + return; + +#ifdef PROM_32BIT_ADDRS + if ((uintptr_t)pathname > (uint32_t)-1) { + opathname = pathname; + pathname = promplat_alloc(OBP_MAXPATHLEN); + if (pathname == NULL) { + return; + } + (void) prom_strcpy(pathname, opathname); + to = pathname; + } +#endif + + promif_preprom(); + + (void) prom_strcpy(from, to); + *to = (char)0; + + ci[0] = p1275_ptr2cell("canon"); /* Service name */ + ci[1] = (cell_t)3; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_ptr2cell(from); /* Arg1: token */ + ci[4] = p1275_ptr2cell(to); /* Arg2: buffer address */ + ci[5] = p1275_uint2cell(OBP_MAXPATHLEN); /* Arg3: buffer length */ + + (void) p1275_cif_handler(&ci); + + promif_postprom(); + +#ifdef PROM_32BIT_ADDRS + if (opathname != NULL) { + (void) prom_strcpy(opathname, pathname); + promplat_free(pathname, OBP_MAXPATHLEN); + to = pathname = opathname; + } +#endif + + /* + * workaround for bugid 1218110, the prom strips the + * options from the input string ... save options at + * at the end of the string if the prom didn't. + * NB: The workaround only preserves options in the last + * component of the string. + */ + + /* + * If there are any options in the last component of the + * output, the prom has copied them; No workaround required. + */ + if ((p = prom_strrchr(to, '/')) == 0) + return; + if ((p = prom_strchr(p, ':')) != 0) + return; + + /* + * If there are no options in the input ... there's + * nothing to preserve; return. + */ + if ((p = prom_strrchr(from, '/')) == 0) + p = from; + if ((p = prom_strchr(p, ':')) == 0) + return; + + /* + * Concatenate the options we found to the end of the output string. + */ + (void) prom_strcat(to, p); +} + +/* + * Strip any options strings from an OBP pathname. + * Output buffer (to) expected to be as large as input buffer (from). + */ +void +prom_strip_options(char *from, char *to) +{ + while (*from != (char)0) { + if (*from == ':') { + while ((*from != (char)0) && (*from != '/')) + ++from; + } else + *to++ = *from++; + } + *to = (char)0; +} diff --git a/usr/src/psm/promif/ieee1275/common/prom_phandle.c b/usr/src/psm/promif/ieee1275/common/prom_phandle.c new file mode 100644 index 0000000000..c82d5e0cd4 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/prom_phandle.c @@ -0,0 +1,48 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1991-1994, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +phandle_t +prom_getphandle(ihandle_t i) +{ + cell_t ci[5]; + + ci[0] = p1275_ptr2cell("instance-to-package"); /* Service name */ + ci[1] = (cell_t)1; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_ihandle2cell(i); /* Arg1: instance */ + ci[4] = p1275_dnode2cell(OBP_BADNODE); /* Res1: Prime result */ + + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); + + return (p1275_cell2phandle(ci[4])); /* Res1: package */ +} diff --git a/usr/src/psm/promif/ieee1275/common/prom_printf.c b/usr/src/psm/promif/ieee1275/common/prom_printf.c new file mode 100644 index 0000000000..e510540310 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/prom_printf.c @@ -0,0 +1,242 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1995-1996, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> +#include <sys/varargs.h> + +static void _doprint(const char *, va_list, char **); +static void _printn(uint64_t, int, int, int, char **); + +/* + * Emit character functions... + */ + +static void +_pput_flush(char *start, char *end) +{ + while (prom_write(prom_stdout_ihandle(), + start, end - start, 0, BYTE) == -1) + ; +} + +static void +_sput(char c, char **p) +{ + **p = c; + *p += 1; +} + +/*VARARGS1*/ +void +prom_printf(const char *fmt, ...) +{ + va_list adx; + + va_start(adx, fmt); + _doprint(fmt, adx, (char **)0); + va_end(adx); +} + +void +prom_vprintf(const char *fmt, va_list adx) +{ + _doprint(fmt, adx, (char **)0); +} + +/*VARARGS2*/ +char * +prom_sprintf(char *s, const char *fmt, ...) +{ + char *bp = s; + va_list adx; + + va_start(adx, fmt); + _doprint(fmt, adx, &bp); + *bp++ = (char)0; + va_end(adx); + return (s); +} + +char * +prom_vsprintf(char *s, const char *fmt, va_list adx) +{ + char *bp = s; + + _doprint(fmt, adx, &bp); + *bp++ = (char)0; + return (s); +} + +static void +_doprint(const char *fmt, va_list adx, char **bp) +{ + int b, c, i, pad, width, ells; + char *s, *start; + char localbuf[100], *lbp; + int64_t l; + uint64_t ul; + + if (bp == 0) { + bp = &lbp; + lbp = &localbuf[0]; + } + start = *bp; +loop: + width = 0; + while ((c = *fmt++) != '%') { + if (c == '\0') + goto out; + if (c == '\n') { + _sput('\r', bp); + _sput('\n', bp); + if (start == localbuf) { + _pput_flush(start, *bp); + lbp = &localbuf[0]; + } + } else + _sput((char)c, bp); + if (start == localbuf && (*bp - start > 80)) { + _pput_flush(start, *bp); + lbp = &localbuf[0]; + } + } + + c = *fmt++; + for (pad = ' '; c == '0'; c = *fmt++) + pad = '0'; + + for (width = 0; c >= '0' && c <= '9'; c = *fmt++) + width = width * 10 + c - '0'; + + for (ells = 0; c == 'l'; c = *fmt++) + ells++; + + switch (c) { + case 'd': + case 'D': + b = 10; + if (ells == 0) + l = (int64_t)va_arg(adx, int); + else if (ells == 1) + l = (int64_t)va_arg(adx, long); + else + l = (int64_t)va_arg(adx, int64_t); + if (l < 0) { + _sput('-', bp); + width--; + ul = -l; + } else + ul = l; + goto number; + + case 'p': + ells = 1; + /*FALLTHROUGH*/ + case 'x': + case 'X': + b = 16; + goto u_number; + + case 'u': + b = 10; + goto u_number; + + case 'o': + case 'O': + b = 8; +u_number: + if (ells == 0) + ul = (uint64_t)va_arg(adx, u_int); + else if (ells == 1) + ul = (uint64_t)va_arg(adx, u_long); + else + ul = (uint64_t)va_arg(adx, uint64_t); +number: + _printn(ul, b, width, pad, bp); + break; + + case 'c': + b = va_arg(adx, int); + for (i = 24; i >= 0; i -= 8) + if ((c = ((b >> i) & 0x7f)) != 0) { + if (c == '\n') + _sput('\r', bp); + _sput((char)c, bp); + } + break; + + case 's': + s = va_arg(adx, char *); + while ((c = *s++) != 0) { + if (c == '\n') + _sput('\r', bp); + _sput((char)c, bp); + if (start == localbuf && (*bp - start > 80)) { + _pput_flush(start, *bp); + lbp = &localbuf[0]; + } + } + break; + + case '%': + _sput('%', bp); + break; + } + if (start == localbuf && (*bp - start > 80)) { + _pput_flush(start, *bp); + lbp = &localbuf[0]; + } + goto loop; +out: + if (start == localbuf && (*bp - start > 0)) + _pput_flush(start, *bp); +} + +/* + * Printn prints a number n in base b. + * We don't use recursion to avoid deep kernel stacks. + */ +static void +_printn(uint64_t n, int b, int width, int pad, char **bp) +{ + char prbuf[40]; + char *cp; + + cp = prbuf; + do { + *cp++ = "0123456789abcdef"[n%b]; + n /= b; + width--; + } while (n); + while (width-- > 0) + *cp++ = (char)pad; + do { + _sput(*--cp, bp); + } while (cp > prbuf); +} diff --git a/usr/src/psm/promif/ieee1275/common/prom_prop.c b/usr/src/psm/promif/ieee1275/common/prom_prop.c new file mode 100644 index 0000000000..5440be79e0 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/prom_prop.c @@ -0,0 +1,348 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * Stuff for mucking about with properties + * + * XXX: There is no distinction between intefer and non-integer properties + * XXX: and no functions included for decoding properties. As is, this + * XXX: file is suitable for a big-endian machine, since properties are + * XXX: encoded using an XDR-like property encoding mechanism, which is + * XXX: big-endian native ordering. To fix this, you need to add type- + * XXX: sensitive decoding mechanisms and have the consumer of the data + * XXX: decode the data, since only the consumer can claim to know the + * XXX: the type of the data. (It can't be done automatically.) + */ + +#include <sys/promif.h> +#include <sys/promimpl.h> +#include <sys/platform_module.h> + +static void prom_setprop_null(void); + + +/* + * prom_setprop_{enter,exit} are set to plat_setprop_{enter,exit} on + * platforms which require access to the seeproms to be serialized. + * Otherwise these default to null functions. These functions must be + * called before promif_preprom, since it can sleep and change CPU's, + * thereby failing the assert in promif_postprom(). + */ +void (*prom_setprop_enter)(void) = prom_setprop_null; +void (*prom_setprop_exit)(void) = prom_setprop_null; + +int +prom_asr_export_len() +{ + cell_t ci[4]; + + ci[0] = p1275_ptr2cell("SUNW,asr-export-len"); /* Service name */ + ci[1] = (cell_t)0; /* #argument cells */ + ci[2] = (cell_t)1; /* #return cells */ + ci[3] = (cell_t)-1; /* Res1: Prime result */ + + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); + + return (p1275_cell2int(ci[3])); /* Res1: buf length */ +} + +int +prom_asr_list_keys_len() +{ + cell_t ci[4]; + + ci[0] = p1275_ptr2cell("SUNW,asr-list-keys-len"); + ci[1] = (cell_t)0; /* #argument cells */ + ci[2] = (cell_t)1; /* #return cells */ + ci[3] = (cell_t)-1; /* Res1: Prime result */ + + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); + + return (p1275_cell2int(ci[3])); /* Res1: buf length */ +} + +int +prom_asr_export(caddr_t value) +{ + int rv; + cell_t ci[5]; + + ci[0] = p1275_ptr2cell("SUNW,asr-export"); /* Service name */ + ci[1] = (cell_t)1; /* #argument cells */ + ci[2] = (cell_t)1; /* #return cells */ + ci[3] = p1275_ptr2cell(value); /* Arg1: buffer address */ + ci[4] = -1; /* Res1: buf len */ + + promif_preprom(); + rv = p1275_cif_handler(&ci); + promif_postprom(); + + if (rv != 0) + return (-1); + return (p1275_cell2int(ci[4])); /* Res1: buf length */ +} + +int +prom_asr_list_keys(caddr_t value) +{ + int rv; + cell_t ci[5]; + + ci[0] = p1275_ptr2cell("SUNW,asr-list-keys"); /* Service name */ + ci[1] = (cell_t)1; /* #argument cells */ + ci[2] = (cell_t)1; /* #return cells */ + ci[3] = p1275_ptr2cell(value); /* Arg1: buffer address */ + ci[4] = -1; /* Res1: buf len */ + + promif_preprom(); + rv = p1275_cif_handler(&ci); + promif_postprom(); + + if (rv != 0) + return (-1); + return (p1275_cell2int(ci[4])); /* Res1: buf length */ +} + +int +prom_asr_disable(char *keystr, int keystr_len, + char *reason, int reason_len) +{ + int rv; + cell_t ci[5]; + + ci[0] = p1275_ptr2cell("SUNW,asr-disable"); /* Service name */ + ci[1] = (cell_t)4; /* #argument cells */ + ci[2] = (cell_t)0; /* #return cells */ + ci[3] = p1275_ptr2cell(keystr); /* Arg1: key address */ + ci[3] = p1275_int2cell(keystr_len); /* Arg2: key len */ + ci[3] = p1275_ptr2cell(reason); /* Arg1: reason address */ + ci[3] = p1275_int2cell(reason_len); /* Arg2: reason len */ + + promif_preprom(); + rv = p1275_cif_handler(&ci); + promif_postprom(); + + return (rv); +} + +int +prom_asr_enable(char *keystr, int keystr_len) +{ + int rv; + cell_t ci[5]; + + ci[0] = p1275_ptr2cell("SUNW,asr-enable"); /* Service name */ + ci[1] = (cell_t)2; /* #argument cells */ + ci[2] = (cell_t)0; /* #return cells */ + ci[3] = p1275_ptr2cell(keystr); /* Arg1: key address */ + ci[3] = p1275_int2cell(keystr_len); /* Arg2: key len */ + + promif_preprom(); + rv = p1275_cif_handler(&ci); + promif_postprom(); + + return (rv); +} + +static void +prom_setprop_null(void) +{ +} + +int +prom_getproplen(dnode_t nodeid, caddr_t name) +{ + cell_t ci[6]; + + ci[0] = p1275_ptr2cell("getproplen"); /* Service name */ + ci[1] = (cell_t)2; /* #argument cells */ + ci[2] = (cell_t)1; /* #return cells */ + ci[3] = p1275_phandle2cell((phandle_t)nodeid); /* Arg1: package */ + ci[4] = p1275_ptr2cell(name); /* Arg2: Property name */ + ci[5] = (cell_t)-1; /* Res1: Prime result */ + + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); + + return (p1275_cell2int(ci[5])); /* Res1: Property length */ +} + + +int +prom_getprop(dnode_t nodeid, caddr_t name, caddr_t value) +{ + int len, rv; + cell_t ci[8]; + + /* + * This function assumes the buffer is large enough to + * hold the result, so in 1275 mode, we pass in the length + * of the property as the length of the buffer, since we + * have no way of knowing the size of the buffer. Pre-1275 + * OpenBoot(tm) PROMs did not have a bounded getprop. + * + * Note that we ignore the "length" result of the service. + */ + + if ((len = prom_getproplen(nodeid, name)) <= 0) + return (len); + + ci[0] = p1275_ptr2cell("getprop"); /* Service name */ + ci[1] = (cell_t)4; /* #argument cells */ + ci[2] = (cell_t)0; /* #result cells */ + ci[3] = p1275_phandle2cell((phandle_t)nodeid); /* Arg1: package */ + ci[4] = p1275_ptr2cell(name); /* Arg2: property name */ + ci[5] = p1275_ptr2cell(value); /* Arg3: buffer address */ + ci[6] = len; /* Arg4: buf len (assumed) */ + + promif_preprom(); + rv = p1275_cif_handler(&ci); + promif_postprom(); + + if (rv != 0) + return (-1); + return (len); /* Return known length */ +} + +int +prom_bounded_getprop(dnode_t nodeid, caddr_t name, caddr_t value, int len) +{ + cell_t ci[8]; + + ci[0] = p1275_ptr2cell("getprop"); /* Service name */ + ci[1] = (cell_t)4; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_phandle2cell((phandle_t)nodeid); /* Arg1: package */ + ci[4] = p1275_ptr2cell(name); /* Arg2: property name */ + ci[5] = p1275_ptr2cell(value); /* Arg3: buffer address */ + ci[6] = p1275_int2cell(len); /* Arg4: buffer length */ + ci[7] = (cell_t)-1; /* Res1: Prime result */ + + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); + + return (p1275_cell2int(ci[7])); /* Res1: Returned length */ +} + +caddr_t +prom_nextprop(dnode_t nodeid, caddr_t previous, caddr_t next) +{ + cell_t ci[7]; + + (void) prom_strcpy(next, ""); /* Prime result, in case call fails */ + + ci[0] = p1275_ptr2cell("nextprop"); /* Service name */ + ci[1] = (cell_t)3; /* #argument cells */ + ci[2] = (cell_t)0; /* #result cells */ + ci[3] = p1275_phandle2cell((phandle_t)nodeid); /* Arg1: phandle */ + ci[4] = p1275_ptr2cell(previous); /* Arg2: addr of prev name */ + ci[5] = p1275_ptr2cell(next); /* Arg3: addr of 32 byte buf */ + + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); + + return (next); +} + +int +prom_setprop(dnode_t nodeid, caddr_t name, caddr_t value, int len) +{ + cell_t ci[8]; +#ifdef PROM_32BIT_ADDRS + caddr_t ovalue = NULL; + + if ((uintptr_t)value > (uint32_t)-1) { + ovalue = value; + value = promplat_alloc(len); + if (value == NULL) { + return (-1); + } + promplat_bcopy(ovalue, value, len); + } +#endif + + prom_setprop_enter(); + + promif_preprom(); + + ci[0] = p1275_ptr2cell("setprop"); /* Service name */ + ci[1] = (cell_t)4; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_phandle2cell((phandle_t)nodeid); /* Arg1: phandle */ + ci[4] = p1275_ptr2cell(name); /* Arg2: property name */ + ci[5] = p1275_ptr2cell(value); /* Arg3: New value ptr */ + ci[6] = p1275_int2cell(len); /* Arg4: New value len */ + ci[7] = (cell_t)-1; /* Res1: Prime result */ + + (void) p1275_cif_handler(&ci); + + promif_postprom(); + + prom_setprop_exit(); + +#ifdef PROM_32BIT_ADDRS + if (ovalue != NULL) + promplat_free(value, len); +#endif + + return (p1275_cell2int(ci[7])); /* Res1: Actual new size */ +} + +/* + * prom_decode_composite_string: + * + * Returns successive strings in a composite string property. + * A composite string property is a buffer containing one or more + * NULL terminated strings contained within the length of the buffer. + * + * Always call with the base address and length of the property buffer. + * On the first call, call with prev == 0, call successively + * with prev == to the last value returned from this function + * until the routine returns zero which means no more string values. + */ +char * +prom_decode_composite_string(void *buf, size_t buflen, char *prev) +{ + if ((buf == 0) || (buflen == 0) || ((int)buflen == -1)) + return ((char *)0); + + if (prev == 0) + return ((char *)buf); + + prev += prom_strlen(prev) + 1; + if (prev >= ((char *)buf + buflen)) + return ((char *)0); + return (prev); +} diff --git a/usr/src/psm/promif/ieee1275/common/prom_putchar.c b/usr/src/psm/promif/ieee1275/common/prom_putchar.c new file mode 100644 index 0000000000..b53a87463d --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/prom_putchar.c @@ -0,0 +1,49 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1991-1994, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +void +prom_putchar(char c) +{ + while (prom_mayput(c) == -1) + ; +} + +int +prom_mayput(char c) +{ + /* + * prom_write returns the number of bytes that were written + */ + if (prom_write(prom_stdout_ihandle(), &c, 1, 0, BYTE) > 0) + return (0); + else + return (-1); +} diff --git a/usr/src/psm/promif/ieee1275/common/prom_reboot.c b/usr/src/psm/promif/ieee1275/common/prom_reboot.c new file mode 100644 index 0000000000..0793d8278e --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/prom_reboot.c @@ -0,0 +1,46 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1991-1994, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +/* + * There should be no return from this function + */ +void +prom_reboot(char *bootstr) +{ + cell_t ci[4]; + + ci[0] = p1275_ptr2cell("boot"); /* Service name */ + ci[1] = (cell_t)1; /* #argument cells */ + ci[2] = (cell_t)0; /* #result cells */ + ci[3] = p1275_ptr2cell(bootstr); /* Arg1: bootspec */ + (void) p1275_cif_handler(&ci); + prom_panic("prom_reboot: reboot call returned!"); +} diff --git a/usr/src/psm/promif/ieee1275/common/prom_stdin.c b/usr/src/psm/promif/ieee1275/common/prom_stdin.c new file mode 100644 index 0000000000..f371d5e4ad --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/prom_stdin.c @@ -0,0 +1,73 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1994, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +/* + * Return ihandle of stdin + */ +ihandle_t +prom_stdin_ihandle(void) +{ + static ihandle_t istdin; + static char *name = "stdin"; + + if (istdin) + return (istdin); + + if (prom_getproplen(prom_chosennode(), name) != + sizeof (ihandle_t)) { +#if defined(PROMIF_DEBUG) || defined(lint) + prom_fatal_error("No stdout ihandle?"); +#endif + return (istdin = (ihandle_t)-1); + } + (void) prom_getprop(prom_chosennode(), name, + (caddr_t)(&istdin)); + istdin = prom_decode_int(istdin); + return (istdin); +} + +/* + * Return phandle of stdin + */ +dnode_t +prom_stdin_node(void) +{ + static phandle_t pstdin; + ihandle_t istdin; + + if (pstdin) + return (pstdin); + + if ((istdin = prom_stdin_ihandle()) == (ihandle_t)-1) + return (pstdin = (dnode_t)OBP_BADNODE); + + return (pstdin = prom_getphandle(istdin)); +} diff --git a/usr/src/psm/promif/ieee1275/common/prom_stdout.c b/usr/src/psm/promif/ieee1275/common/prom_stdout.c new file mode 100644 index 0000000000..f30bc03119 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/prom_stdout.c @@ -0,0 +1,71 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1991-1994, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +/* + * Return ihandle of stdout + */ +ihandle_t +prom_stdout_ihandle(void) +{ + static ihandle_t istdout; + static char *name = "stdout"; + + if (istdout) + return (istdout); + + if (prom_getproplen(prom_chosennode(), name) != + sizeof (ihandle_t)) { + return (istdout = (ihandle_t)-1); + } + (void) prom_getprop(prom_chosennode(), name, + (caddr_t)(&istdout)); + istdout = prom_decode_int(istdout); + return (istdout); + +} + +/* + * Return phandle of stdout + */ +dnode_t +prom_stdout_node(void) +{ + static phandle_t pstdout; + ihandle_t istdout; + + if (pstdout) + return (pstdout); + + if ((istdout = prom_stdout_ihandle()) == (ihandle_t)-1) + return (pstdout = (dnode_t)OBP_BADNODE); + + return (pstdout = prom_getphandle(istdout)); +} diff --git a/usr/src/psm/promif/ieee1275/common/prom_string.c b/usr/src/psm/promif/ieee1275/common/prom_string.c new file mode 100644 index 0000000000..014ea1a40a --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/prom_string.c @@ -0,0 +1,153 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1991-1995, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * The routines are NOT part of the interface, merely internal + * utilities which assist in making the interface standalone. + */ + +#include <sys/promif.h> +#include <sys/promimpl.h> + +/* + * a version of string copy that is bounded + */ +char * +prom_strncpy(register char *s1, register char *s2, size_t n) +{ + register char *os1 = s1; + + n++; + while (--n != 0 && (*s1++ = *s2++) != '\0') + ; + if (n != 0) + while (--n != 0) + *s1++ = '\0'; + return (os1); +} + +/* + * and one that knows no bounds + */ +char * +prom_strcpy(register char *s1, register char *s2) +{ + register char *os1; + + os1 = s1; + while (*s1++ = *s2++) + ; + return (os1); +} + +/* + * a copy of string compare that is bounded + */ +int +prom_strncmp(register char *s1, register char *s2, register size_t n) +{ + n++; + if (s1 == s2) + return (0); + while (--n != 0 && *s1 == *s2++) + if (*s1++ == '\0') + return (0); + return ((n == 0) ? 0: (*s1 - s2[-1])); +} + +/* + * and one that knows no bounds + */ +int +prom_strcmp(register char *s1, register char *s2) +{ + while (*s1 == *s2++) + if (*s1++ == '\0') + return (0); + return (*s1 - *--s2); +} + +/* + * finds the length of a succession of non-NULL chars + */ +int +prom_strlen(register char *s) +{ + register int n = 0; + + while (*s++) + n++; + + return (n); +} + +/* + * return the ptr in sp at which the character c last + * appears; 0 if not found + */ +char * +prom_strrchr(register char *sp, register char c) +{ + register char *r; + + for (r = (char *)0; *sp != (char)0; ++sp) + if (*sp == c) + r = sp; + return (r); +} + +/* + * Concatenate string s2 to string s1 + */ +char * +prom_strcat(register char *s1, register char *s2) +{ + char *os1 = s1; + + while ((*s1) != ((char)0)) + s1++; /* find the end of string s1 */ + + while (*s1++ = *s2++) /* Concatenate s2 */ + ; + return (os1); +} + +/* + * Return the ptr in sp at which the character c first + * appears; NULL if not found + */ +char * +prom_strchr(register const char *sp, register int c) +{ + + do { + if (*sp == (char)c) + return ((char *)sp); + } while (*sp++); + return (NULL); +} diff --git a/usr/src/psm/promif/ieee1275/common/prom_test.c b/usr/src/psm/promif/ieee1275/common/prom_test.c new file mode 100644 index 0000000000..23b1a9e6b6 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/prom_test.c @@ -0,0 +1,79 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1991-1994, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +/* + * Test for existance of a specific P1275 client interface service + */ +int +prom_test(char *service) +{ + cell_t ci[5]; + + ci[0] = p1275_ptr2cell("test"); /* Service name */ + ci[1] = (cell_t)1; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_ptr2cell(service); /* Arg1: requested svc name */ + ci[4] = (cell_t)-1; /* Res1: Prime result */ + + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); + + return (p1275_cell2int(ci[4])); /* Res1: missing flag */ +} + +int +prom_test_method(char *method, dnode_t node) +{ + cell_t ci[6]; + int rv; + char buf[80]; + + if (prom_test("test-method") == 0) { + ci[0] = p1275_ptr2cell("test-method"); /* service */ + ci[1] = (cell_t)2; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_dnode2cell(node); + ci[4] = p1275_ptr2cell(method); + ci[5] = (cell_t)-1; + + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); + rv = p1275_cell2int(ci[5]); + } else { + (void) prom_sprintf(buf, + "\" %s\" h# %x find-method invert h# %x l!", + method, node, &rv); + prom_interpret(buf, 0, 0, 0, 0, 0); + } + return (rv); +} diff --git a/usr/src/psm/promif/ieee1275/common/prom_trap.c b/usr/src/psm/promif/ieee1275/common/prom_trap.c new file mode 100644 index 0000000000..42142d3b37 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/prom_trap.c @@ -0,0 +1,35 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1991, by Sun Microsystems, Inc. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +void +prom_montrap(void (*funcptr)()) +{ + ((*funcptr)()); +} diff --git a/usr/src/psm/promif/ieee1275/common/prom_version.c b/usr/src/psm/promif/ieee1275/common/prom_version.c new file mode 100644 index 0000000000..e2209dec65 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/prom_version.c @@ -0,0 +1,74 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1991-1994, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +int +prom_getversion(void) +{ + + /* + * For compatibility with older client programs, if there is no + * ROMVEC, we simply return a very large number here. + */ + return (obp_romvec_version); +} + +int +prom_is_openprom(void) +{ + /* + * Returns true, if openboot or open firmware interface exists. + */ + return (1); +} + +int +prom_is_p1275(void) +{ + /* + * Returns true, if IEEE 1275 interface exists. + */ + return (1); +} + +/* + * Certain standalones need to get the revision of a certain + * version of the firmware to be able to figure out how to + * correct for certain errors in certain versions of the PROM. + * + * The caller has to know what to do with the cookie returned + * from prom_mon_id(). c.f. uts/sun4c/io/autoconf.c:impl_fix_props(). + */ + +void * +prom_mon_id(void) +{ + return (NULL); /* For compatibilty, none exists in 1275 */ +} diff --git a/usr/src/psm/promif/ieee1275/common/prom_wrtestr.c b/usr/src/psm/promif/ieee1275/common/prom_wrtestr.c new file mode 100644 index 0000000000..92165ecec0 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/common/prom_wrtestr.c @@ -0,0 +1,49 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1991-1994, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +/* + * 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; + } +} diff --git a/usr/src/psm/promif/ieee1275/sun4/prom_alloc.c b/usr/src/psm/promif/ieee1275/sun4/prom_alloc.c new file mode 100644 index 0000000000..d38e199fe5 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/sun4/prom_alloc.c @@ -0,0 +1,145 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1991-1994, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +/* + * This allocator has SMCC-OBP-like semantics associated with it. + * Specifically, the alignment value specifies both a physical + * and virtual alignment. If virthint is zero, a suitable virt + * is chosen. In either case, align is not ignored. + * + * This routine returns NULL on failure. + * This routine is suitable for (the given semantics) machines with + * a 2-cell physical address. + * + * Memory allocated with prom_alloc can be freed with prom_free. + * + * The generic allocator is prom_malloc. + * + */ + +caddr_t +prom_alloc(caddr_t virthint, size_t size, u_int align) +{ + + caddr_t virt = virthint; + unsigned long long physaddr; + + if (align == 0) + align = (u_int)1; + + /* + * First, allocate or claim the virtual address space. + * In either case, after this code, "virt" is the chosen address. + */ + if (virthint == 0) { + virt = prom_allocate_virt(align, size); + if (virt == (caddr_t)-1) + return ((caddr_t)0); + } else { + if (prom_claim_virt(size, virthint) == (caddr_t)-1) + return ((caddr_t)0); + } + + /* + * Next, allocate the physical address space, at the specified + * physical alignment (or 1 byte alignment, if none specified) + */ + + if (prom_allocate_phys(size, align, &physaddr) == -1) { + + /* + * Request failed, free virtual address space and return. + */ + prom_free_virt(size, virt); + return ((caddr_t)0); + } + + /* + * Next, create a mapping from the physical to virtual address, + * using a default "mode". + */ + + if (prom_map_phys(-1, size, virt, physaddr) == -1) { + + /* + * The call failed; release the physical and virtual + * addresses allocated or claimed, and return. + */ + + prom_free_virt(size, virt); + prom_free_phys(size, physaddr); + return ((caddr_t)0); + } + return (virt); +} + +/* + * This is the generic client interface to "claim" memory. + * These two routines belong in the common directory. + */ +caddr_t +prom_malloc(caddr_t virt, size_t size, u_int align) +{ + cell_t ci[7]; + int rv; + + ci[0] = p1275_ptr2cell("claim"); /* Service name */ + ci[1] = (cell_t)3; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_ptr2cell(virt); /* Arg1: virt */ + ci[4] = p1275_size2cell(size); /* Arg2: size */ + ci[5] = p1275_uint2cell(align); /* Arg3: align */ + + promif_preprom(); + rv = p1275_cif_handler(&ci); + promif_postprom(); + + if (rv == 0) + return ((caddr_t)p1275_cell2ptr(ci[6])); /* Res1: base */ + return ((caddr_t)-1); +} + + +void +prom_free(caddr_t virt, size_t size) +{ + cell_t ci[5]; + + ci[0] = p1275_ptr2cell("release"); /* Service name */ + ci[1] = (cell_t)2; /* #argument cells */ + ci[2] = (cell_t)0; /* #result cells */ + ci[3] = p1275_ptr2cell(virt); /* Arg1: virt */ + ci[4] = p1275_size2cell(size); /* Arg2: size */ + + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); +} diff --git a/usr/src/psm/promif/ieee1275/sun4/prom_cpuctl.c b/usr/src/psm/promif/ieee1275/sun4/prom_cpuctl.c new file mode 100644 index 0000000000..515c88bffb --- /dev/null +++ b/usr/src/psm/promif/ieee1275/sun4/prom_cpuctl.c @@ -0,0 +1,162 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 1994-2000, 2002 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +int +prom_stopcpu_bycpuid(int cpuid) +{ + cell_t ci[5]; + + ci[0] = p1275_ptr2cell("SUNW,stop-cpu-by-cpuid"); /* Service name */ + ci[1] = (cell_t)1; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_int2cell(cpuid); /* Arg1: cpuid to stop */ + + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); + + return (p1275_cell2int(ci[4])); +} + + +int +prom_startcpu(dnode_t node, caddr_t pc, int arg) +{ + cell_t ci[6]; + + ci[0] = p1275_ptr2cell("SUNW,start-cpu"); /* Service name */ + ci[1] = (cell_t)3; /* #argument cells */ + ci[2] = (cell_t)0; /* #result cells */ + ci[3] = p1275_dnode2cell(node); /* Arg1: nodeid to start */ + ci[4] = p1275_ptr2cell(pc); /* Arg2: pc */ + ci[5] = p1275_int2cell(arg); /* Arg3: cpuid */ + + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); + + return (0); +} + +int +prom_startcpu_bycpuid(int cpuid, caddr_t pc, int arg) +{ + cell_t ci[7]; + + ci[0] = p1275_ptr2cell("SUNW,start-cpu-by-cpuid"); /* Service name */ + ci[1] = (cell_t)3; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_int2cell(cpuid); /* Arg1: cpuid to start */ + ci[4] = p1275_ptr2cell(pc); /* Arg2: pc */ + ci[5] = p1275_int2cell(arg); /* Arg3: cpuid */ + + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); + + return (p1275_cell2int(ci[6])); +} + +int +prom_wakeupcpu(dnode_t node) +{ + cell_t ci[5]; + int rv; + + ci[0] = p1275_ptr2cell("SUNW,wakeup-cpu"); /* Service name */ + ci[1] = (cell_t)1; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_dnode2cell(node); /* Arg1: nodeid to wakeup */ + + promif_preprom(); + rv = p1275_cif_handler(&ci); + promif_postprom(); + + if (rv != 0) + return (rv); + else + return (p1275_cell2int(ci[4])); /* Res1: Catch result */ +} + +int +prom_cpuoff(dnode_t node) +{ + cell_t ci[5]; + int rv; + + ci[0] = p1275_ptr2cell("SUNW,park-cpu"); + ci[1] = (cell_t)1; /* #argument cells */ + ci[2] = (cell_t)1; /* #return cells */ + ci[3] = p1275_dnode2cell(node); + + promif_preprom(); + rv = p1275_cif_handler(&ci); + promif_postprom(); + + if (rv != 0) + return (-1); + + return (p1275_cell2int(ci[4])); +} + +int +prom_hotaddcpu(int cpuid) +{ + cell_t ci[5]; + + ci[0] = p1275_ptr2cell("SUNW,hotadd-cpu-by-cpuid"); /* Service name */ + ci[1] = (cell_t)1; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_int2cell(cpuid); /* Arg1: cpuid to start */ + + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); + + return (p1275_cell2int(ci[4])); +} + +int +prom_hotremovecpu(int cpuid) +{ + cell_t ci[5]; + + ci[0] = p1275_ptr2cell("SUNW,hotremove-cpu-by-cpuid"); /* Service */ + ci[1] = (cell_t)1; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_int2cell(cpuid); /* Arg1: cpuid to start */ + + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); + + return (p1275_cell2int(ci[4])); +} diff --git a/usr/src/psm/promif/ieee1275/sun4/prom_efcode.c b/usr/src/psm/promif/ieee1275/sun4/prom_efcode.c new file mode 100644 index 0000000000..8c3e716f97 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/sun4/prom_efcode.c @@ -0,0 +1,91 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2000 by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * Embedded Fcode Interpreter "get-fcode" client interfaces. + */ + +#include <sys/promif.h> +#include <sys/promimpl.h> + +/* + * Get Fcode size, test if OBP supports this interface. + */ +int +prom_get_fcode_size(char *str) +{ + cell_t ci[5]; + int rv; + + if (prom_test("SUNW,get-fcode-size") != 0) { + return (0); + } + + ci[0] = p1275_ptr2cell("SUNW,get-fcode-size"); + ci[1] = (cell_t)1; /* 1 input arg: str */ + ci[2] = (cell_t)1; /* 1 output result: len or zero */ + ci[3] = p1275_ptr2cell(str); + ci[4] = (cell_t)0; + + promif_preprom(); + rv = p1275_cif_handler(&ci); + promif_postprom(); + + if (rv == 0) + return (p1275_cell2int(ci[4])); + return (0); +} + +/* + * Get Fcode into supplied buffer. + */ +int +prom_get_fcode(char *str, char *buf) +{ + cell_t ci[6]; + int rv; + + if (prom_test("SUNW,get-fcode") != 0) { + return (0); + } + + ci[0] = p1275_ptr2cell("SUNW,get-fcode"); + ci[1] = (cell_t)2; /* 2 input args: str + buf */ + ci[2] = (cell_t)1; /* 1 output result: true or false */ + ci[3] = p1275_ptr2cell(buf); /* Arg#1: buffer to put fcode */ + ci[4] = p1275_ptr2cell(str); /* Arg#2: name of drop-in */ + ci[5] = (cell_t)0; + + promif_preprom(); + rv = p1275_cif_handler(&ci); + promif_postprom(); + + if (rv == 0) + return (p1275_cell2int(ci[5])); + return (0); +} diff --git a/usr/src/psm/promif/ieee1275/sun4/prom_getunum.c b/usr/src/psm/promif/ieee1275/sun4/prom_getunum.c new file mode 100644 index 0000000000..f182bad97a --- /dev/null +++ b/usr/src/psm/promif/ieee1275/sun4/prom_getunum.c @@ -0,0 +1,73 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1994-2000 by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +/* + * 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 chip got + * the (un)correctable ECC error, which info is hopefully relayed to the user! + */ +int +prom_get_unum(int syn_code, 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); + + 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,get-unumber"); /* 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(syn_code); /* Arg7: bit # */ + 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,get-unumber" failed */ + *ustrlen = p1275_cell2uint(ci[11]); /* Res2: unum str length */ + return (0); +} diff --git a/usr/src/psm/promif/ieee1275/sun4/prom_idprom.c b/usr/src/psm/promif/ieee1275/sun4/prom_idprom.c new file mode 100644 index 0000000000..41b09ab04a --- /dev/null +++ b/usr/src/psm/promif/ieee1275/sun4/prom_idprom.c @@ -0,0 +1,75 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1990,1992-1994 by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * XXX: Break this up into individual property lookups. + */ + +#include <sys/promif.h> +#include <sys/promimpl.h> +#include <sys/idprom.h> + +/* + * Get idprom property from root node, return to callers buffer. + */ + +int +prom_getidprom(caddr_t addr, int size) +{ + u_char *cp, val = 0; + /*LINTED [idprom unused]*/ + idprom_t idprom; + int i; + int length; + + length = prom_getproplen(prom_rootnode(), OBP_IDPROM); + if (length == -1) { + prom_printf("Missing OBP idprom property.\n"); + return (-1); + } + + if (length > size) { + prom_printf("Buffer size too small.\n"); + return (-1); + } + + (void) prom_getprop(prom_rootnode(), OBP_IDPROM, + (caddr_t) addr); + + /* + * Test the checksum for sanity + */ + for (cp = (u_char *)addr, i = 0; + i < (sizeof (idprom) - sizeof (idprom.id_undef)); i++) + val ^= *cp++; + + if (val != 0) + prom_printf("Warning: IDprom checksum error.\n"); + + return (0); +} diff --git a/usr/src/psm/promif/ieee1275/sun4/prom_init.c b/usr/src/psm/promif/ieee1275/sun4/prom_init.c new file mode 100644 index 0000000000..66779087c9 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/sun4/prom_init.c @@ -0,0 +1,137 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 1994, 2001-2003 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> +#include <sys/platform_module.h> + +int obp_romvec_version = -1; /* -1 rsrvd for non-obp sunromvec */ +int prom_aligned_allocator = 0; /* Not needed for 1275 */ +void *p1275cif; /* 1275 Client interface handler */ + +#ifdef PROMIF_DEBUG +int promif_debug = 0; +#endif /* PROMIF_DEBUG */ + +/* + * This is the string we use to print out "panic" level messages, + * so that it's easier to identify who's doing the complaining. + */ +#define PROMIF_CLNTNAMELEN 16 +char promif_clntname[PROMIF_CLNTNAMELEN]; + +/* + * The plat_setprop_enter() and plat_setprop_exit() routines are actually + * defined as #pragma weak symbols, which confuses lint since it does not grok + * #pragma weak and thus thinks the routines are used but not defined. Until + * lint is enhanced, we workaround this with the following stubs. + */ +#ifdef __lint +void +plat_setprop_enter(void) +{} + +void +plat_setprop_exit(void) +{} +#endif + +/* + * This 'do-nothing' function is called immediately before and immediately + * after entry to the PROM. Some standalones (e.g. the kernel) + * may replace this routine with their own. + */ +static void +default_prepost_prom(void) +{} + +/* + * Every standalone that wants to use this library must call + * prom_init() before any of the other routines can be called. + * The only state it creates is the obp_romvec_version variable, + * and the prom_aligned_allocator variable (plus the default pre- + * and post-prom handlers, and the clientname string) + * + */ +void +prom_init(char *pgmname, void *p1275cookie) +{ + /* + * Allow implementation to validate input argument. + */ + p1275cif = p1275_cif_init(p1275cookie); + + if ((p1275cif == NULL)) { + prom_fatal_error("promif: No interface!"); + /*NOTREACHED*/ + } + + /* + * Initialize the "clientname" string with the string we've + * been handed by the standalone + */ + (void) prom_strncpy(promif_clntname, pgmname, PROMIF_CLNTNAMELEN - 1); + promif_clntname[PROMIF_CLNTNAMELEN - 1] = '\0'; + + obp_romvec_version = OBP_PSEUDO_ROMVEC_VERSION; + + /* + * Add default pre- and post-prom handlers + * (We add this null handler to avoid the numerous tests + * that would otherwise have to be included around every call) + */ + (void) prom_set_preprom(default_prepost_prom); + (void) prom_set_postprom(default_prepost_prom); + + if (&plat_setprop_enter != NULL) { + prom_setprop_enter = &plat_setprop_enter; + prom_setprop_exit = &plat_setprop_exit; + ASSERT(prom_setprop_exit != NULL); + } +} + +/* + * Fatal promif internal error, not an external interface + */ + +/*ARGSUSED*/ +void +prom_fatal_error(const char *errormsg) +{ + + volatile int zero = 0; + volatile int i = 1; + + /* + * No prom interface, try to cause a trap by + * dividing by zero, leaving the message in %i0. + */ + + i = i / zero; + /*NOTREACHED*/ +} diff --git a/usr/src/psm/promif/ieee1275/sun4/prom_macaddr.c b/usr/src/psm/promif/ieee1275/sun4/prom_macaddr.c new file mode 100644 index 0000000000..492b66869d --- /dev/null +++ b/usr/src/psm/promif/ieee1275/sun4/prom_macaddr.c @@ -0,0 +1,78 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1994, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * Return our machine address in the single argument. + */ + +#include <sys/promif.h> +#include <sys/promimpl.h> +#include <sys/idprom.h> + +/*ARGSUSED*/ +int +prom_getmacaddr(ihandle_t hd, caddr_t ea) +{ + idprom_t idprom; + dnode_t macnodeid; + + /* + * Look for the 'mac-address' property in the device node + * associated with the ihandle 'hd'. This handles the + * cases when we booted from the network device, using either + * the platform mac address or a local mac address. This + * code will always return whichever mac-address was used by the + * firmware (local or platform, depending on nvram settings). + */ + macnodeid = prom_getphandle(hd); + if (macnodeid != OBP_BADNODE) { + if (prom_getproplen(macnodeid, OBP_MAC_ADDR) != -1) { + (void) prom_getprop(macnodeid, OBP_MAC_ADDR, ea); + return (0); + } + } + + /* + * The code above, should have taken care of the case + * when we booted from the device ... otherwise, as a fallback + * case, return the system mac address from the idprom. + * This code (idprom) is SMCC (and compatibles) platform-centric. + * This code always returns the platform mac address. + */ + if (prom_getidprom((caddr_t) &idprom, sizeof (idprom)) == 0) { + register char *f = (char *) idprom.id_ether; + register char *t = ea; + int i; + + for (i = 0; i < sizeof (idprom.id_ether); ++i) + *t++ = *f++; + + return (0); + } else + return (-1); /* our world must be starting to explode */ +} diff --git a/usr/src/psm/promif/ieee1275/sun4/prom_map.c b/usr/src/psm/promif/ieee1275/sun4/prom_map.c new file mode 100644 index 0000000000..d346cd68ac --- /dev/null +++ b/usr/src/psm/promif/ieee1275/sun4/prom_map.c @@ -0,0 +1,74 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1991-1994, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +/* + * Mapping routines suitable for implementations using 2-cell physical + * address formats. Use of these routines makes the caller + * platform-dependent. The implementation of these routines is + * a bit sun-hardware centric, for historical use by SunOS and standalones. + */ + +caddr_t +prom_map(caddr_t virthint, unsigned long long physaddr, u_int size) +{ + caddr_t virt; + + /* + * If no virthint, allocate it; otherwise claim it, + * the physical address is assumed to be a device or + * already claimed, or not appearing in a resource list. + */ + if (virthint == (caddr_t)0) { + if ((virt = prom_allocate_virt((u_int)1, size)) == 0) + return ((caddr_t)0); + } else { + virt = virthint; + if (prom_claim_virt(size, virt) != virt) + return ((caddr_t)0); + } + + if (prom_map_phys(-1, size, virt, physaddr) != 0) { + /* + * The map operation failed, free the virtual + * addresses we allocated or claimed. + */ + (void) prom_free_virt(size, virt); + return ((caddr_t)0); + } + return (virt); +} + +void +prom_unmap(caddr_t virt, u_int size) +{ + (void) prom_unmap_virt(size, virt); + prom_free_virt(size, virt); +} diff --git a/usr/src/psm/promif/ieee1275/sun4/prom_mem.c b/usr/src/psm/promif/ieee1275/sun4/prom_mem.c new file mode 100644 index 0000000000..6983d1e09a --- /dev/null +++ b/usr/src/psm/promif/ieee1275/sun4/prom_mem.c @@ -0,0 +1,164 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1991-1994, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * This file contains platform-dependent memory support routines, + * suitable for memory methods with 2-cell physical addresses. + * Use of these routines makes the caller platform-dependent, + * since the caller assumes knowledge of the physical layout of + * the machines address space. Generic programs should use the + * standard client interface memory allocators. + */ + +#include <sys/promif.h> +#include <sys/promimpl.h> + +ihandle_t +prom_memory_ihandle(void) +{ + static ihandle_t imemory; + + if (imemory != (ihandle_t)0) + return (imemory); + + if (prom_getproplen(prom_chosennode(), "memory") != sizeof (ihandle_t)) + return (imemory = (ihandle_t)-1); + + (void) prom_getprop(prom_chosennode(), "memory", (caddr_t)(&imemory)); + return (imemory); +} + +/* + * 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, u_int align, unsigned long long *physaddr) +{ + cell_t ci[10]; + int rv; + ihandle_t imemory = prom_memory_ihandle(); + + if ((imemory == (ihandle_t)-1)) + return (-1); + + if (align == 0) + align = (u_int)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 */ + + promif_preprom(); + rv = p1275_cif_handler(&ci); + promif_postprom(); + + 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); +} + +/* + * 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, unsigned long long physaddr) +{ + cell_t ci[10]; + int 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 */ + + promif_preprom(); + rv = p1275_cif_handler(&ci); + promif_postprom(); + + if (rv != 0) + return (rv); + if (p1275_cell2int(ci[9]) != 0) /* Res1: Catch result */ + return (-1); + + return (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, unsigned long long 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 */ + + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); +} diff --git a/usr/src/psm/promif/ieee1275/sun4/prom_power_off.c b/usr/src/psm/promif/ieee1275/sun4/prom_power_off.c new file mode 100644 index 0000000000..1c8ea21ddf --- /dev/null +++ b/usr/src/psm/promif/ieee1275/sun4/prom_power_off.c @@ -0,0 +1,48 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1994, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +/* + * This interface allows the client to power off the machine. + * There's no return from this service. + */ +void +prom_power_off() +{ + cell_t ci[3]; + + ci[0] = p1275_ptr2cell("SUNW,power-off"); /* Service name */ + ci[1] = (cell_t) 0; /* #argument cells */ + ci[2] = (cell_t) 0; /* #result cells */ + + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); +} diff --git a/usr/src/psm/promif/ieee1275/sun4/prom_retain.c b/usr/src/psm/promif/ieee1275/sun4/prom_retain.c new file mode 100644 index 0000000000..608aceaff3 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/sun4/prom_retain.c @@ -0,0 +1,68 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1994, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +/* + * Allocate retained physical memory + * Returns 0: Success; Non-zero: failure. + * Returns *phys_hi, *phys_lo only if successful. + */ +int +prom_retain(char *id, size_t size, u_int align, unsigned long long *physaddr) +{ + cell_t ci[11]; + int 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)5; /* #argument cells */ + ci[2] = (cell_t)3; /* #result cells */ + ci[3] = p1275_ptr2cell("SUNW,retain"); /* Arg1: Method name */ + ci[4] = p1275_ihandle2cell(imemory); /* Arg2: memory ihandle */ + ci[5] = p1275_uint2cell(align); /* Arg2: SA1: align */ + ci[6] = p1275_size2cell(size); /* Arg3: SA2: size */ + ci[7] = p1275_ptr2cell(id); /* Arg4: SA3: id name */ + + promif_preprom(); + rv = p1275_cif_handler(&ci); + promif_postprom(); + + if (rv != 0) + return (rv); /* Service "call-method" failed */ + if (ci[8] != 0) /* Res1: catch-result */ + return (-1); /* Method "SUNW,retain" failed */ + + *physaddr = p1275_cells2ull(ci[9], ci[10]); + /* Res3: base.hi, Res4: base.lo */ + return (0); +} diff --git a/usr/src/psm/promif/ieee1275/sun4/prom_set_traptable.c b/usr/src/psm/promif/ieee1275/sun4/prom_set_traptable.c new file mode 100644 index 0000000000..01583d52ea --- /dev/null +++ b/usr/src/psm/promif/ieee1275/sun4/prom_set_traptable.c @@ -0,0 +1,50 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1994, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +/* + * This interface allows the client to safely take over the %tba by + * the prom's service. The prom will take care of the quiescence of + * interrupts and handle any pending soft interrupts. + */ +void +prom_set_traptable(void *tba_addr) +{ + cell_t ci[4]; + + ci[0] = p1275_ptr2cell("SUNW,set-trap-table"); /* Service name */ + ci[1] = (cell_t) 1; /* #argument cells */ + ci[2] = (cell_t) 0; /* #result cells */ + ci[3] = p1275_ptr2cell(tba_addr); /* Arg1: tba address */ + + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); +} diff --git a/usr/src/psm/promif/ieee1275/sun4/prom_sparc.c b/usr/src/psm/promif/ieee1275/sun4/prom_sparc.c new file mode 100644 index 0000000000..baaf607958 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/sun4/prom_sparc.c @@ -0,0 +1,61 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 1991-1993,2003 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +/* + * P1275 Client Interface Functions defined for SPARC. + * This file belongs in a platform dependent area. + */ + +/* + * This function returns NULL or a a verified client interface structure + * pointer to the caller. + */ + +int (*cif_handler)(void *); + +void * +p1275_sparc_cif_init(void *cookie) +{ + cif_handler = (int (*)(void *))cookie; + return ((void *)cookie); +} + +int +p1275_sparc_cif_handler(void *p) +{ + int rv; + + if (cif_handler == NULL) + return (-1); + + rv = client_handler((void *)cif_handler, p); + return (rv); +} diff --git a/usr/src/psm/promif/ieee1275/sun4/prom_vername.c b/usr/src/psm/promif/ieee1275/sun4/prom_vername.c new file mode 100644 index 0000000000..c56baf1692 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/sun4/prom_vername.c @@ -0,0 +1,72 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1991-1995, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +/* + * Return a character string in buf,buflen representing the running + * version of the firmware. Systems that have no concept of such a + * string may return the string "unknown". + * + * Return the actual length of the string, including the NULL terminator. + * Copy at most buflen bytes into the caller's buffer, always providing + * NULL termination. + * + * Returns the actual length of the string, plus copies data in the callers + * buf copying at most buflen bytes. Returns -1 if an internal error occurs. + */ + +int +prom_version_name(char *buf, int buflen) +{ + dnode_t nodeid; + int proplen; + char *unknown = "unknown"; + + *buf = *(buf + buflen - 1) = (char)0; /* Force NULL termination */ + + /* + * On sun4u systems, the /openprom "version" property + * contains the running version of the prom. Some older + * pre-FCS proms may not have the "version" property, so + * in that case we just return "unknown". + */ + + nodeid = prom_finddevice("/openprom"); + if (nodeid == (dnode_t)-1) + return (-1); + + proplen = prom_bounded_getprop(nodeid, "version", buf, buflen - 1); + if (proplen <= 0) { + (void) prom_strncpy(buf, unknown, buflen - 1); + return (prom_strlen(unknown) + 1); + } + + return (proplen); +} diff --git a/usr/src/psm/promif/ieee1275/sun4u/Makefile.files b/usr/src/psm/promif/ieee1275/sun4u/Makefile.files new file mode 100644 index 0000000000..61182791d6 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/sun4u/Makefile.files @@ -0,0 +1,60 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright (c) 1992-2001 by Sun Microsystems, Inc. +# All rights reserved. +# +#pragma ident "%Z%%M% %I% %E% SMI" +# +# psm/promif/ieee1275/sun4u/Makefile.files +# +# This Makefile defines all the promif file modules for the +# directory psm/promif/ieee1275/sun4u. +# + +# +# Note that the kernel doesn't use/need prom_map.o and prom_alloc.o +# + +# +# PROM Platform-dependent routines +# +CORE_OBJS += \ + prom_cpuctl.o \ + prom_efcode.o \ + prom_getunum.o \ + prom_heartbeat.o \ + prom_idprom.o \ + prom_init.o \ + prom_macaddr.o \ + prom_mem.o \ + prom_mmu.o \ + prom_power_off.o \ + prom_retain.o \ + prom_serengeti.o \ + prom_set_traptable.o \ + prom_sparc.o \ + prom_starcat.o \ + prom_starfire.o \ + prom_sunfire.o \ + prom_vercheck.o \ + prom_vername.o diff --git a/usr/src/psm/promif/ieee1275/sun4u/Makefile.rules b/usr/src/psm/promif/ieee1275/sun4u/Makefile.rules new file mode 100644 index 0000000000..b77f7269ed --- /dev/null +++ b/usr/src/psm/promif/ieee1275/sun4u/Makefile.rules @@ -0,0 +1,50 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 1992-2003 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# This Makefile defines all build rules for the promif version for +# IEEE 1275 compliant firmware (generic portions). + +# +# C object build rules +# + +$(OBJS_DIR)/%.o: $(PSMBASE)/promif/ieee1275/sun4u/%.c + $(COMPILE.c) -o $@ $< + $(CTFCONVERT_O) + +$(OBJS_DIR)/%.o: $(PSMBASE)/promif/ieee1275/sun4/%.c + $(COMPILE.c) -o $@ $< + $(CTFCONVERT_O) + +# +# Lint `object' build rules +# +$(LINTS_DIR)/%.ln: $(PSMBASE)/promif/ieee1275/sun4u/%.c + @($(LHEAD) $(LINT.c) $< $(LTAIL)) + +$(LINTS_DIR)/%.ln: $(PSMBASE)/promif/ieee1275/sun4/%.c + @($(LHEAD) $(LINT.c) $< $(LTAIL)) diff --git a/usr/src/psm/promif/ieee1275/sun4u/README.sun4u b/usr/src/psm/promif/ieee1275/sun4u/README.sun4u new file mode 100644 index 0000000000..c417b58da0 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/sun4u/README.sun4u @@ -0,0 +1,31 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 1995 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" + +This directory contains sun4u implementations of promif routines. +The implementation of the functions are platform dependent and/or +the functions use platform-dependent client interfaces that are not +generic. + diff --git a/usr/src/psm/promif/ieee1275/sun4u/prom_heartbeat.c b/usr/src/psm/promif/ieee1275/sun4u/prom_heartbeat.c new file mode 100644 index 0000000000..2a7e6b7da9 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/sun4u/prom_heartbeat.c @@ -0,0 +1,55 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1994, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +/* + * Provide 10 millisecond heartbeat for the PROM. A client that has taken over + * the trap table and clock interrupts, but is not quite ready to take over the + * function of polling the input-device for an abort sequence (L1/A or BREAK) + * may use this function to instruct the PROM to poll the keyboard. If used, + * this function should be called every 10 milliseconds. + */ +int +prom_heartbeat(int msecs) +{ + cell_t ci[5]; + + ci[0] = p1275_ptr2cell("SUNW,heartbeat"); /* Service name */ + ci[1] = (cell_t)1; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_int2cell(msecs); /* Arg1: msecs */ + ci[4] = (cell_t)0; /* Prime the result */ + + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); + + return (p1275_cell2int(ci[4])); /* Res1: abort-flag */ +} diff --git a/usr/src/psm/promif/ieee1275/sun4u/prom_mmu.c b/usr/src/psm/promif/ieee1275/sun4u/prom_mmu.c new file mode 100644 index 0000000000..c5556dc756 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/sun4u/prom_mmu.c @@ -0,0 +1,334 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1991-1994, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * This file contains platform-dependent MMU support routines, + * suitable for mmu methods with 2-cell physical addresses. + * Use of these routines makes the caller platform-dependent, + * since the caller assumes knowledge of the physical layout of + * the machines address space. Generic programs should use the + * standard client interface memory allocators. + */ + +#include <sys/promif.h> +#include <sys/promimpl.h> + +ihandle_t +prom_mmu_ihandle(void) +{ + static ihandle_t immu; + + if (immu != (ihandle_t)0) + return (immu); + + if (prom_getproplen(prom_chosennode(), "mmu") != sizeof (ihandle_t)) + return (immu = (ihandle_t)-1); + + (void) prom_getprop(prom_chosennode(), "mmu", (caddr_t)(&immu)); + return (immu); +} + +/* + * prom_map_phys: + * + * Create an MMU mapping for a given physical address to a given virtual + * address. The given resources are assumed to be owned by the caller, + * and are *not* removed from any free lists. + * + * This routine is suitable for mapping a 2-cell physical address. + */ + +int +prom_map_phys(int mode, size_t size, caddr_t virt, unsigned long long physaddr) +{ + cell_t ci[11]; + int rv; + ihandle_t immu = prom_mmu_ihandle(); + + if ((immu == (ihandle_t)-1)) + return (-1); + + ci[0] = p1275_ptr2cell("call-method"); /* Service name */ + ci[1] = (cell_t)7; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_ptr2cell("map"); /* Arg1: method name */ + ci[4] = p1275_ihandle2cell(immu); /* Arg2: mmu ihandle */ + ci[5] = p1275_int2cell(mode); /* Arg3: SA1: mode */ + ci[6] = p1275_size2cell(size); /* Arg4: SA2: size */ + ci[7] = p1275_ptr2cell(virt); /* Arg5: SA3: virt */ + ci[8] = p1275_ull2cell_high(physaddr); /* Arg6: SA4: phys.hi */ + ci[9] = p1275_ull2cell_low(physaddr); /* Arg7: SA5: phys.low */ + + promif_preprom(); + rv = p1275_cif_handler(&ci); + promif_postprom(); + + if (rv != 0) + return (-1); + if (ci[10] != 0) /* Res1: Catch result */ + return (-1); + return (0); +} + +void +prom_unmap_phys(size_t size, caddr_t virt) +{ + (void) prom_unmap_virt(size, virt); +} + +/* + * Allocate aligned or unaligned virtual address space, unmapped. + */ +caddr_t +prom_allocate_virt(u_int align, size_t size) +{ + cell_t ci[9]; + int rv; + ihandle_t immu = prom_mmu_ihandle(); + + if ((immu == (ihandle_t)-1)) + return ((caddr_t)-1); + + if (align == 0) + align = 1; + + ci[0] = p1275_ptr2cell("call-method"); /* Service name */ + ci[1] = (cell_t)4; /* #argument cells */ + ci[2] = (cell_t)2; /* #result cells */ + ci[3] = p1275_ptr2cell("claim"); /* Arg1: Method name */ + ci[4] = p1275_ihandle2cell(immu); /* Arg2: mmu ihandle */ + ci[5] = p1275_uint2cell(align); /* Arg3: SA1: align */ + ci[6] = p1275_size2cell(size); /* Arg4: SA2: size */ + + promif_preprom(); + rv = p1275_cif_handler(&ci); + promif_postprom(); + + if (rv != 0) + return ((caddr_t)-1); + if (ci[7] != 0) /* Res1: Catch result */ + return ((caddr_t)-1); + return (p1275_cell2ptr(ci[8])); /* Res2: SR1: base */ +} + +/* + * Claim a region of virtual address space, unmapped. + */ +caddr_t +prom_claim_virt(size_t size, caddr_t virt) +{ + cell_t ci[10]; + int rv; + ihandle_t immu = prom_mmu_ihandle(); + + if ((immu == (ihandle_t)-1)) + return ((caddr_t)-1); + + ci[0] = p1275_ptr2cell("call-method"); /* Service name */ + ci[1] = (cell_t)5; /* #argument cells */ + ci[2] = (cell_t)2; /* #result cells */ + ci[3] = p1275_ptr2cell("claim"); /* Arg1: Method name */ + ci[4] = p1275_ihandle2cell(immu); /* Arg2: mmu ihandle */ + ci[5] = (cell_t)0; /* Arg3: align */ + ci[6] = p1275_size2cell(size); /* Arg4: length */ + ci[7] = p1275_ptr2cell(virt); /* Arg5: virt */ + + promif_preprom(); + rv = p1275_cif_handler(&ci); + promif_postprom(); + + if (rv != 0) + return ((caddr_t)-1); + if (ci[8] != 0) /* Res1: Catch result */ + return ((caddr_t)-1); + return (p1275_cell2ptr(ci[9])); /* Res2: base */ +} + +/* + * Free virtual address resource (no unmapping is done). + */ +void +prom_free_virt(size_t size, caddr_t virt) +{ + cell_t ci[7]; + ihandle_t immu = prom_mmu_ihandle(); + + if ((immu == (ihandle_t)-1)) + return; + + ci[0] = p1275_ptr2cell("call-method"); /* Service name */ + ci[1] = (cell_t)4; /* #argument cells */ + ci[2] = (cell_t)0; /* #return cells */ + ci[3] = p1275_ptr2cell("release"); /* Arg1: Method name */ + ci[4] = p1275_ihandle2cell(immu); /* Arg2: mmu ihandle */ + ci[5] = p1275_size2cell(size); /* Arg3: length */ + ci[6] = p1275_ptr2cell(virt); /* Arg4: virt */ + + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); +} + +/* + * Un-map virtual address. Does not free underlying resources. + */ +void +prom_unmap_virt(size_t size, caddr_t virt) +{ + cell_t ci[7]; + ihandle_t immu = prom_mmu_ihandle(); + + if ((immu == (ihandle_t)-1)) + return; + + ci[0] = p1275_ptr2cell("call-method"); /* Service name */ + ci[1] = (cell_t)4; /* #argument cells */ + ci[2] = (cell_t)0; /* #result cells */ + ci[3] = p1275_ptr2cell("unmap"); /* Arg1: Method name */ + ci[4] = p1275_ihandle2cell(immu); /* Arg2: mmu ihandle */ + ci[5] = p1275_size2cell(size); /* Arg3: SA1: size */ + ci[6] = p1275_ptr2cell(virt); /* Arg4: SA2: virt */ + + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); +} + +/* + * Translate virtual address to physical address. + * Returns 0: Success; Non-zero: failure. + * Returns *phys_hi, *phys_lo and *mode only if successful. + */ +int +prom_translate_virt(caddr_t virt, int *valid, + unsigned long long *physaddr, int *mode) +{ + cell_t ci[11]; + int rv; + ihandle_t immu = prom_mmu_ihandle(); + + *valid = 0; + + if ((immu == (ihandle_t)-1)) + return (-1); + + ci[0] = p1275_ptr2cell("call-method"); /* Service name */ + ci[1] = (cell_t)3; /* #argument cells */ + ci[2] = (cell_t)5; /* #result cells */ + ci[3] = p1275_ptr2cell("translate"); /* Arg1: Method name */ + ci[4] = p1275_ihandle2cell(immu); /* Arg2: mmu ihandle */ + ci[5] = p1275_ptr2cell(virt); /* Arg3: virt */ + ci[6] = 0; /* Res1: catch-resule */ + ci[7] = 0; /* Res2: sr1: valid */ + + promif_preprom(); + rv = p1275_cif_handler(&ci); + promif_postprom(); + + if (rv == -1) /* Did the call fail ? */ + return (-1); + if (ci[6] != 0) /* Catch result */ + return (-1); + + if (p1275_cell2int(ci[7]) != -1) /* Valid results ? */ + return (0); + + *mode = p1275_cell2int(ci[8]); /* Res3: sr2: mode, if valid */ + *physaddr = p1275_cells2ull(ci[9], ci[10]); + /* Res4: sr3: phys-hi ... Res5: sr4: phys-lo */ + *valid = -1; /* Indicate valid result */ + return (0); +} + +/* + * prom_itlb_load, prom_dtlb_load: + * + * Manage the Spitfire TLB. Returns 0 if successful, -1 otherwise. + * Flush the address in context zero mapped by tte_data and virt, + * and load the {i,d} tlb entry index with tte_data and virt. + */ + +int +prom_itlb_load(int index, unsigned long long tte_data, caddr_t virt) +{ + cell_t ci[9]; + int rv; + ihandle_t immu = prom_mmu_ihandle(); + + if ((immu == (ihandle_t)-1)) + return (-1); + + ci[0] = p1275_ptr2cell("call-method"); /* Service name */ + ci[1] = (cell_t)5; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_ptr2cell("SUNW,itlb-load"); /* Arg1: method name */ + ci[4] = p1275_ihandle2cell(immu); /* Arg2: mmu ihandle */ + ci[5] = p1275_ptr2cell(virt); /* Arg3: SA1: virt */ + ci[6] = (cell_t)tte_data; /* Arg4: SA2: tte_data */ + ci[7] = p1275_int2cell(index); /* Arg5: SA3: index */ + + promif_preprom(); + rv = p1275_cif_handler(&ci); + promif_postprom(); + + if (rv != 0) + return (-1); + if (ci[8] != 0) /* Res1: Catch result */ + return (-1); + return (0); +} + +int +prom_dtlb_load(int index, unsigned long long tte_data, caddr_t virt) +{ + cell_t ci[9]; + int rv; + ihandle_t immu = prom_mmu_ihandle(); + + if ((immu == (ihandle_t)-1)) + return (-1); + + ci[0] = p1275_ptr2cell("call-method"); /* Service name */ + ci[1] = (cell_t)5; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_ptr2cell("SUNW,dtlb-load"); /* Arg1: method name */ + ci[4] = p1275_ihandle2cell(immu); /* Arg2: mmu ihandle */ + ci[5] = p1275_ptr2cell(virt); /* Arg3: SA1: virt */ + ci[6] = (cell_t)tte_data; /* Arg4: SA2: tte_data */ + ci[7] = p1275_int2cell(index); /* Arg5: SA3: index */ + + promif_preprom(); + rv = p1275_cif_handler(&ci); + promif_postprom(); + + if (rv != 0) + return (-1); + if (ci[8] != 0) /* Res1: Catch result */ + return (-1); + return (0); +} diff --git a/usr/src/psm/promif/ieee1275/sun4u/prom_serengeti.c b/usr/src/psm/promif/ieee1275/sun4u/prom_serengeti.c new file mode 100644 index 0000000000..7e99303d7b --- /dev/null +++ b/usr/src/psm/promif/ieee1275/sun4u/prom_serengeti.c @@ -0,0 +1,218 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2000 by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +/* All Serengeti only promif routines */ + +char * +prom_serengeti_set_console_input(char *new_value) +{ + cell_t ci[5]; + int rv; + + ci[0] = p1275_ptr2cell("SUNW,set-console-input"); + ci[1] = (cell_t)1; /* #argument cells */ + ci[2] = (cell_t)1; /* #return cells */ + ci[3] = p1275_ptr2cell(new_value); + + promif_preprom(); + rv = p1275_cif_handler(&ci); + promif_postprom(); + + if (rv != 0) + return (NULL); + + return (p1275_cell2ptr(ci[4])); +} + +/* + * These interfaces allow the client to attach/detach board. + */ +int +prom_serengeti_attach_board(uint_t node, uint_t board) +{ + cell_t ci[6]; + int rv; + + ci[0] = p1275_ptr2cell("SUNW,Serengeti,add-board"); /* name */ + ci[1] = (cell_t)2; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_uint2cell(board); + ci[4] = p1275_uint2cell(node); + + promif_preprom(); + rv = p1275_cif_handler(&ci); + promif_postprom(); + + if (rv != 0) + return (rv); + if (p1275_cell2int(ci[5]) != 0) /* Res1: Catch result */ + return (-1); + + return (0); +} + +int +prom_serengeti_detach_board(uint_t node, uint_t board) +{ + cell_t ci[6]; + int rv; + + ci[0] = p1275_ptr2cell("SUNW,Serengeti,remove-board"); /* name */ + ci[1] = (cell_t)2; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_uint2cell(board); + ci[4] = p1275_uint2cell(node); + + promif_preprom(); + rv = p1275_cif_handler(&ci); + promif_postprom(); + + if (rv != 0) + return (rv); + if (p1275_cell2int(ci[5]) != 0) /* Res1: Catch result */ + return (-1); + + return (0); +} + +int +prom_serengeti_tunnel_switch(uint_t node, uint_t board) +{ + cell_t ci[6]; + int rv; + + ci[0] = p1275_ptr2cell("SUNW,Serengeti,switch-tunnel"); /* name */ + ci[1] = (cell_t)2; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_uint2cell(board); + ci[4] = p1275_uint2cell(node); + + promif_preprom(); + rv = p1275_cif_handler(&ci); + promif_postprom(); + + if (rv != 0) + return (rv); + if (p1275_cell2int(ci[5]) != 0) /* Res1: Catch result */ + return (-1); + + return (0); +} + +int +prom_serengeti_cpu_off(dnode_t node) +{ + cell_t ci[5]; + int rv; + + ci[0] = p1275_ptr2cell("SUNW,Serengeti,park-cpu"); + ci[1] = (cell_t)1; /* #argument cells */ + ci[2] = (cell_t)1; /* #return cells */ + ci[3] = p1275_dnode2cell(node); + + promif_preprom(); + rv = p1275_cif_handler(&ci); + promif_postprom(); + + if (rv != 0) + return (-1); + + return (p1275_cell2int(ci[4])); +} + +/* + * 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); +} + +int +prom_serengeti_wakeupcpu(dnode_t node) +{ + cell_t ci[5]; + int rv; + + ci[0] = p1275_ptr2cell("SUNW,Serengeti,wakeup-cpu"); /* Service name */ + ci[1] = (cell_t)1; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_dnode2cell(node); /* Arg1: nodeid to wakeup */ + + promif_preprom(); + rv = p1275_cif_handler(&ci); + promif_postprom(); + + if (rv != 0) + return (rv); + else + return (p1275_cell2int(ci[4])); /* Res1: Catch result */ +} diff --git a/usr/src/psm/promif/ieee1275/sun4u/prom_starcat.c b/usr/src/psm/promif/ieee1275/sun4u/prom_starcat.c new file mode 100644 index 0000000000..bd77b7c8f3 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/sun4u/prom_starcat.c @@ -0,0 +1,219 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2000 by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +/* + * This file contains the implementations of all Starcat-specific promif + * routines. Refer to FWARC case 2000/420 for the definitions of the + * platform-specific interfaces provided by Starcat OBP. + */ + +static char *switch_tunnel_cmd = "SUNW,Starcat,switch-tunnel"; +static char *iosram_read_cmd = "SUNW,Starcat,iosram-read"; +static char *iosram_write_cmd = "SUNW,Starcat,iosram-write"; + +/* + * Given the portid of the IOB to which the tunnel should be moved and the type + * of move that should be performed, ask OBP to switch the IOSRAM tunnel from + * its current host IOB to a new location. If the move type is 0, OBP will + * coordinate the change with SMS and will copy data from the current location + * to the new location. If the move type is 1, OBP will simply mark the new + * location valid and start using it, without doing any data copying and without + * communicating with SMS. Return 0 on success, non-zero on failure. + */ +int +prom_starcat_switch_tunnel(uint_t portid, uint_t msgtype) +{ + static uint8_t warned = 0; + cell_t ci[6]; + int rv; + + /* + * Make sure we have the necessary support in OBP. + */ + if (prom_test(switch_tunnel_cmd) == 0) { + ci[0] = p1275_ptr2cell(switch_tunnel_cmd); /* name */ + } else { + if (!warned) { + warned = 1; + prom_printf( + "Warning: No prom support for switch-tunnel!\n"); + } + return (-1); + } + + /* + * Set up the arguments and call into OBP. + */ + ci[1] = (cell_t)2; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_uint2cell(portid); + ci[4] = p1275_uint2cell(msgtype); + + promif_preprom(); + rv = p1275_cif_handler(&ci); + promif_postprom(); + + /* + * p1275_cif_handler will return 0 on success, non-zero on failure. If + * it fails, the return cell from OBP is meaningless, because the OBP + * client interface probably wasn't even invoked. OBP will return 0 on + * failure and non-zero on success for this interface. + */ + if (rv != 0) { + return (rv); + } else if (p1275_cell2int(ci[5]) == 0) { + return (-1); + } else { + return (0); + } +} + +/* + * Request that OBP read 'len' bytes, starting at 'offset' in the IOSRAM chunk + * associated with 'key', into the memory indicated by 'buf'. Although there is + * a driver that provides this functionality, there are certain cases where the + * OS requires access to IOSRAM before the driver is loaded. Return 0 on + * success, non-zero on failure. + */ +int +prom_starcat_iosram_read(uint32_t key, uint32_t offset, uint32_t len, + caddr_t buf) +{ + static uint8_t warned = 0; + cell_t ci[8]; + int rv; + + /* + * Make sure we have the necessary support in OBP. + */ + if (prom_test(iosram_read_cmd) == 0) { + ci[0] = p1275_ptr2cell(iosram_read_cmd); /* name */ + } else { + if (!warned) { + warned = 1; + prom_printf( + "Warning: No prom support for iosram-read!\n"); + } + return (-1); + } + + /* + * Set up the arguments and call into OBP. Note that the argument order + * needs to be reversed to accomodate OBP. The order must remain as it + * is in the function prototype to maintain intercompatibility with the + * IOSRAM driver's equivalent routine. + */ + ci[1] = (cell_t)4; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_ptr2cell(buf); + ci[4] = p1275_uint2cell(len); + ci[5] = p1275_uint2cell(offset); + ci[6] = p1275_uint2cell(key); + + promif_preprom(); + rv = p1275_cif_handler(&ci); + promif_postprom(); + + /* + * p1275_cif_handler will return 0 on success, non-zero on failure. If + * it fails, the return cell from OBP is meaningless, because the OBP + * client interface probably wasn't even invoked. OBP will return 0 on + * success and non-zero on failure for this interface. + */ + if (rv != 0) { + return (rv); + } else if (p1275_cell2int(ci[7]) == 0) { + return (0); + } else { + return (-1); + } +} + +/* + * Request that OBP write 'len' bytes from the memory indicated by 'buf' into + * the IOSRAM chunk associated with 'key', starting at 'offset'. Although there + * is a driver that provides this functionality, there are certain cases where + * the OS requires access to IOSRAM before the driver is loaded. Return 0 on + * success, non-zero on failure. + */ +int +prom_starcat_iosram_write(uint32_t key, uint32_t offset, uint32_t len, + caddr_t buf) +{ + static uint8_t warned = 0; + cell_t ci[8]; + int rv; + + /* + * Make sure we have the necessary support in OBP. + */ + if (prom_test(iosram_write_cmd) == 0) { + ci[0] = p1275_ptr2cell(iosram_write_cmd); /* name */ + } else { + if (!warned) { + warned = 1; + prom_printf( + "Warning: No prom support for iosram-write!\n"); + } + return (-1); + } + + /* + * Set up the arguments and call into OBP. Note that the argument order + * needs to be reversed to accomodate OBP. The order must remain as it + * is in the function prototype to maintain intercompatibility with the + * IOSRAM driver's equivalent routine. + */ + ci[1] = (cell_t)4; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_ptr2cell(buf); + ci[4] = p1275_uint2cell(len); + ci[5] = p1275_uint2cell(offset); + ci[6] = p1275_uint2cell(key); + + promif_preprom(); + rv = p1275_cif_handler(&ci); + promif_postprom(); + + /* + * p1275_cif_handler will return 0 on success, non-zero on failure. If + * it fails, the return cell from OBP is meaningless, because the OBP + * client interface probably wasn't even invoked. OBP will return 0 on + * success and non-zero on failure for this interface. + */ + if (rv != 0) { + return (rv); + } else if (p1275_cell2int(ci[7]) == 0) { + return (0); + } else { + return (-1); + } +} diff --git a/usr/src/psm/promif/ieee1275/sun4u/prom_starfire.c b/usr/src/psm/promif/ieee1275/sun4u/prom_starfire.c new file mode 100644 index 0000000000..3ef8dd983d --- /dev/null +++ b/usr/src/psm/promif/ieee1275/sun4u/prom_starfire.c @@ -0,0 +1,164 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2001 by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +/* + * This file contains the implementations of all Starfire-specific + * promif routines. + */ + +/* + * Probe all of the devices on a board. The board number is + * computed from cpuid. All of the cpus on the board are + * brought into OBP's slave idle loop but are not started. + * Returns zero for success and non-zero for failure. + */ +int +prom_starfire_add_brd(uint_t cpuid) +{ + cell_t ci[5]; + int rv; + + ci[0] = p1275_ptr2cell("SUNW,UE10000,add-brd"); /* name */ + ci[1] = (cell_t)1; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_uint2cell(cpuid); + + promif_preprom(); + rv = p1275_cif_handler(&ci); + promif_postprom(); + + return ((rv) ? -1 : p1275_cell2int(ci[4])); +} + +/* + * Prune the device tree nodes for all devices on the board + * represented by brdnum. Returns zero for success and non-zero + * for failure. + */ +int +prom_starfire_rm_brd(uint_t brdnum) +{ + cell_t ci[5]; + int rv; + + ci[0] = p1275_ptr2cell("SUNW,UE10000,rm-brd"); /* name */ + ci[1] = (cell_t)1; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_uint2cell(brdnum); + + promif_preprom(); + rv = p1275_cif_handler(&ci); + promif_postprom(); + + return ((rv) ? -1 : p1275_cell2int(ci[4])); +} + +/* + * Prepare firmware internal state for the inclusion of the + * cpu represented by cpuid. This operation has no effect on + * the cpu hardware or behavior in the client. + */ +void +prom_starfire_add_cpu(uint_t cpuid) +{ + cell_t ci[4]; + + ci[0] = p1275_ptr2cell("SUNW,UE10000,add-cpu"); /* name */ + ci[1] = (cell_t)1; /* #argument cells */ + ci[2] = (cell_t)0; /* #result cells */ + ci[3] = p1275_uint2cell(cpuid); + + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); +} + +/* + * Prepare firmware internal state for the departure of the cpu + * represented by cpuid. + */ +void +prom_starfire_rm_cpu(uint_t cpuid) +{ + cell_t ci[4]; + + ci[0] = p1275_ptr2cell("SUNW,UE10000,rm-cpu"); /* name */ + ci[1] = (cell_t)1; /* #argument cells */ + ci[2] = (cell_t)0; /* #result cells */ + ci[3] = p1275_uint2cell(cpuid); + + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); +} + +/* + * Mark the cpu represented by cpuid as cpu0. Returns zero for + * success and non-zero for failure. + */ +int +prom_starfire_move_cpu0(uint_t cpuid) +{ + cell_t ci[5]; + int rv; + + ci[0] = p1275_ptr2cell("SUNW,UE10000,move-cpu0"); /* name */ + ci[1] = (cell_t)1; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_uint2cell(cpuid); + + promif_preprom(); + rv = p1275_cif_handler(&ci); + promif_postprom(); + + return ((rv) ? -1 : p1275_cell2int(ci[4])); +} + +/* + * Perform initialization steps required for the console before + * moving cpu0. The console uses the bootbus SRAM of cpu0 for both + * input and output. The offsets of the console buffers are initialized + * for the bootbus SRAM of the new cpu0 represented by cpuid. + */ +void +prom_starfire_init_console(uint_t cpuid) +{ + cell_t ci[4]; + + ci[0] = p1275_ptr2cell("SUNW,UE10000,init-console"); /* name */ + ci[1] = (cell_t)1; /* #argument cells */ + ci[2] = (cell_t)0; /* #result cells */ + ci[3] = p1275_uint2cell(cpuid); + + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); +} diff --git a/usr/src/psm/promif/ieee1275/sun4u/prom_sunfire.c b/usr/src/psm/promif/ieee1275/sun4u/prom_sunfire.c new file mode 100644 index 0000000000..60ea31bb5a --- /dev/null +++ b/usr/src/psm/promif/ieee1275/sun4u/prom_sunfire.c @@ -0,0 +1,102 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1994-1998, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +/* SunFire only */ +int +prom_sunfire_cpu_off(void) +{ + cell_t ci[3]; + + /* Service name */ + ci[0] = p1275_ptr2cell("SUNW,Ultra-Enterprise,cpu-off"); + ci[1] = (cell_t)0; /* #argument cells */ + ci[2] = (cell_t)0; /* #result cells */ + + /* + * This is an unlocked entry into the prom. + * + * promif_preprom(), ... will be called by the controlling + * cpu. The controlling cpu handles prom contention + * while the victim is in transition. + */ + (void) p1275_cif_handler(&ci); + + return (0); +} + +/* + * These interfaces allow the client to attach/detach board. + */ +int +prom_sunfire_attach_board(u_int board) +{ + cell_t ci[5]; + int rv; + + ci[0] = p1275_ptr2cell("SUNW,Ultra-Enterprise,add-brd"); /* name */ + ci[1] = (cell_t)1; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_uint2cell(board); + + promif_preprom(); + rv = p1275_cif_handler(&ci); + promif_postprom(); + + if (rv != 0) + return (rv); + if (p1275_cell2int(ci[4]) != 0) /* Res1: Catch result */ + return (-1); + + return (0); +} + +int +prom_sunfire_detach_board(u_int board) +{ + cell_t ci[5]; + int rv; + + ci[0] = p1275_ptr2cell("SUNW,Ultra-Enterprise,rm-brd"); /* name */ + ci[1] = (cell_t)1; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_uint2cell(board); + + promif_preprom(); + rv = p1275_cif_handler(&ci); + promif_postprom(); + + if (rv != 0) + return (rv); + if (p1275_cell2int(ci[4]) != 0) /* Res1: Catch result */ + return (-1); + + return (0); +} diff --git a/usr/src/psm/promif/ieee1275/sun4u/prom_vercheck.c b/usr/src/psm/promif/ieee1275/sun4u/prom_vercheck.c new file mode 100644 index 0000000000..734a53886b --- /dev/null +++ b/usr/src/psm/promif/ieee1275/sun4u/prom_vercheck.c @@ -0,0 +1,365 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +#ifdef DPRINTF +#define dprintf prom_printf +#endif + +/* + * Check if the prom is 64-bit ready. + */ + +/* + * Table listing the minimum prom versions supported by this kernel. + * The model value is expected to match the model in the flashprom node. + */ +static struct obp_rev_table { + char *model; + char *version; +} obp_min_revs[] = { + {"SUNW,525-1414", "OBP 3.11.2 1997/12/05 10:25"}, /* pulsar */ + {"SUNW,525-1672", "OBP 3.7.107 1998/02/19 17:54"}, /* tazmo */ + {"SUNW,525-1431", "OBP 3.2.16 1998/06/08 16:58"}, /* sunfire */ + { NULL, NULL} +}; + +#define NMINS 60 +#define NHOURS 24 +#define NDAYS 31 +#define NMONTHS 12 + +#define YEAR(y) ((y-1) * (NMONTHS * NDAYS * NHOURS * NMINS)) +#define MONTH(m) ((m-1) * (NDAYS * NHOURS * NMINS)) +#define DAY(d) ((d-1) * (NHOURS * NMINS)) +#define HOUR(h) ((h) * (NMINS)) +#define MINUTE(m) (m) + +static int +strtoi(char *str, char **pos) +{ + int c; + int val = 0; + + for (c = *str++; c >= '0' && c <= '9'; c = *str++) { + val *= 10; + val += c - '0'; + } + if (pos) + *pos = str; + return (val); +} + +/* + * obp_timestamp: based on the OBP flashprom version string of the + * format "OBP x.y.z YYYY/MM/DD HH:MM" calculate a timestamp based + * on the year, month, day, hour and minute by turning that into + * a number of minutes. + */ +static int +obp_timestamp(char *v) +{ + char *c; + int maj, year, month, day, hour, min; + + if (v[0] != 'O' || v[1] != 'B' || v[2] != 'P') + return (-1); + + c = v + 3; + + /* Find first non-space character after OBP */ + while (*c != '\0' && (*c == ' ' || *c == '\t')) + c++; + if (prom_strlen(c) < 5) /* need at least "x.y.z" */ + return (-1); + + maj = strtoi(c, &c); + if (maj < 3) + return (-1); + +#if 0 /* XXX - not used */ + dot = dotdot = 0; + if (*c == '.') { + dot = strtoi(c + 1, &c); + + /* optional? dot-dot release */ + if (*c == '.') + dotdot = strtoi(c + 1, &c); + } +#endif + + /* Find space at the end of version number */ + while (*c != '\0' && *c != ' ') + c++; + if (prom_strlen(c) < 11) /* need at least " xxxx/xx/xx" */ + return (-1); + + /* Point to first character of date */ + c++; + + /* Validate date format */ + if (c[4] != '/' || c[7] != '/') + return (-1); + + year = strtoi(c, NULL); + month = strtoi(c + 5, NULL); + day = strtoi(c + 8, NULL); + + if (year < 1995 || month == 0 || day == 0) + return (-1); + + /* + * Find space at the end of date number + */ + c += 10; + while (*c != '\0' && *c != ' ') + c++; + if (prom_strlen(c) < 6) /* need at least " xx:xx" */ + return (-1); + + /* Point to first character of time */ + c++; + + if (c[2] != ':') + return (-1); + + hour = strtoi(c, NULL); + min = strtoi(c + 3, NULL); + + return (YEAR(year) + MONTH(month) + + DAY(day) + HOUR(hour) + MINUTE(min)); +} + +/* + * Check the prom against the obp_min_revs table and complain if + * the system has an older prom installed. The actual major/minor/ + * dotdot numbers are not checked, only the date/time stamp. + */ + +static struct obp_rev_table *flashprom_ortp; +static dnode_t flashprom_node; +static int flashprom_checked; +static int flashprom_return_code; + +int +check_timestamp(char *model, int tstamp) +{ + int min_tstamp; + struct obp_rev_table *ortp; + + for (ortp = obp_min_revs; ortp->model != NULL; ortp++) { + if (prom_strcmp(model, ortp->model) == 0) { + min_tstamp = obp_timestamp(ortp->version); + if (min_tstamp == -1) { +#ifdef DEBUG + prom_printf("prom_version_check: " + "invalid OBP version string in table " + " (entry %d)", (int)(ortp - obp_min_revs)); +#endif + continue; + } + if (tstamp < min_tstamp) { +#ifdef DPRINTF + dprintf("prom_version_check: " + "Down-rev OBP detected. " + "Please update to at least:\n\t%s\n\n", + ortp->version); +#endif + flashprom_ortp = ortp; + return (1); + } + } + } /* for each obp_rev_table entry */ + + return (0); +} + +static dnode_t +visit(dnode_t node) +{ + int tstamp, plen, i; + char vers[512], model[64]; + static dnode_t openprom_node; + static char version[] = "version"; + static char model_name[] = "model"; + static char flashprom[] = "flashprom"; + + /* + * if name isn't 'flashprom', continue. + */ + if (prom_getproplen(node, OBP_NAME) != sizeof (flashprom)) + return ((dnode_t)0); + (void) prom_getprop(node, OBP_NAME, model); + if (prom_strncmp(model, flashprom, sizeof (flashprom)) != 0) + return ((dnode_t)0); + + plen = prom_getproplen(node, version); + if (plen <= 0 || plen > sizeof (vers)) + return ((dnode_t)0); + (void) prom_getprop(node, version, vers); + vers[plen] = '\0'; + + /* Make sure it's an OBP flashprom */ + if (vers[0] != 'O' && vers[1] != 'B' && vers[2] != 'P') + return ((dnode_t)0); + + plen = prom_getproplen(node, model_name); + if (plen <= 0 || plen > sizeof (model)) + return ((dnode_t)0); + (void) prom_getprop(node, model_name, model); + model[plen] = '\0'; + + tstamp = obp_timestamp(vers); + if (tstamp == -1) { + prom_printf("prom_version_check: node contains " + "improperly formatted version property,\n" + "\tnot checking prom version"); + return ((dnode_t)0); + } + + i = check_timestamp(model, tstamp); + + if (i == 0) + return ((dnode_t)0); + + /* + * We know that "node"'s flashprom image contains downrev firmware, + * however, a multi-board server might be running correct firmware. + * Check for that case by looking at the "/openprom" node, + * which always contains the running version. (We needed the + * "model" value to be able to do this, so we can use it as + * an index value into the table.) + * + * If it turns out we're running 'current' firmware, + * but detect down-rev firmware, use a different return code. + */ + + flashprom_return_code = PROM_VER64_UPGRADE; + + openprom_node = prom_finddevice("/openprom"); + if (openprom_node == OBP_BADNODE) + return (node); + + plen = prom_getproplen(node, version); + if (plen <= 0 || plen > sizeof (vers)) + return (node); + (void) prom_getprop(node, version, vers); + vers[plen] = '\0'; + + if (vers[0] != 'O' && vers[1] != 'B' && vers[2] != 'P') { + prom_printf("prom_version_check: " + "unknown <version> string in </openprom>\n"); + return (node); + } + + tstamp = obp_timestamp(vers); + if (tstamp == -1) { + prom_printf("prom_version_check: " + "</openprom> node <version> property: bad tstamp\n"); + return (node); + } + + i = check_timestamp(model, tstamp); + /* + * If that returned zero, then the running version is + * adequate ... so we can 'suggest' instead of 'require'. + */ + if (i == 0) + flashprom_return_code = PROM_VER64_SUGGEST; + + return (node); +} + +/* + * visit each node in the device tree, until we get a non-null answer + */ +static dnode_t +walk(dnode_t node) +{ + dnode_t id; + + if (visit(node)) + return (node); + + for (node = prom_childnode(node); node; node = prom_nextnode(node)) + if ((id = walk(node)) != (dnode_t)0) + return (id); + + return ((dnode_t)0); +} + +/* + * Check if the prom is 64-bit ready. + * + * If it's ready (or the test doesn't apply), return PROM_VER64_OK. + * If downrev firmware is running, return PROM_VER64_UPGRADE. + * If downrev firmware is detected (but not running), return PROM_VER64_SUGGEST. + * + * For PROM_VER64_UPGRADE and PROM_VER64_SUGGEST return code values: + * Return the nodeid of the flashprom node in *nodeid. + * and a printable message in *buf, buflen. + */ +int +prom_version_check(char *buf, size_t buflen, dnode_t *nodeid) +{ + char *p; + dnode_t node = flashprom_node; + size_t i; + + /* + * If we already checked, we already know the answer. + */ + if (flashprom_checked == 0) { + flashprom_node = node = walk(prom_rootnode()); + flashprom_checked = 1; + } + + if (nodeid) + *nodeid = node; + + if (node == (dnode_t)0) { + if (buf && buflen) + *buf = '\0'; + return (PROM_VER64_OK); + } + + /* bzero the callers buffer */ + for (i = buflen, p = buf; i != 0; --i, ++p) + *p = '\0'; + + /* + * Do a bounded copy of the output string into the callers buffer + */ + if (buflen <= 1) + return (flashprom_return_code); + + (void) prom_strncpy(buf, flashprom_ortp->version, buflen - 1); + return (flashprom_return_code); +} diff --git a/usr/src/psm/promif/ieee1275/sun4v/Makefile.files b/usr/src/psm/promif/ieee1275/sun4v/Makefile.files new file mode 100644 index 0000000000..8de916c472 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/sun4v/Makefile.files @@ -0,0 +1,56 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#pragma ident "%Z%%M% %I% %E% SMI" +# +# psm/promif/ieee1275/sun4u/Makefile.files +# +# This Makefile defines all the promif file modules for the +# directory psm/promif/ieee1275/sun4u. +# + +# +# Note that the kernel doesn't use/need prom_map.o and prom_alloc.o +# + +# +# PROM Platform-dependent routines +# +CORE_OBJS += \ + prom_cpuctl.o \ + prom_efcode.o \ + prom_getunum.o \ + prom_idprom.o \ + prom_heartbeat.o \ + prom_init.o \ + prom_macaddr.o \ + prom_mem.o \ + prom_mmu.o \ + prom_power_off.o \ + prom_retain.o \ + prom_set_mmfsa_traptable.o \ + prom_sparc.o \ + prom_vercheck.o \ + prom_vername.o diff --git a/usr/src/psm/promif/ieee1275/sun4v/Makefile.rules b/usr/src/psm/promif/ieee1275/sun4v/Makefile.rules new file mode 100644 index 0000000000..bf5392e272 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/sun4v/Makefile.rules @@ -0,0 +1,57 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# This Makefile defines all build rules for the promif version for +# IEEE 1275 compliant firmware (generic portions). + +# +# C object build rules +# + +$(OBJS_DIR)/%.o: $(PSMBASE)/promif/ieee1275/sun4v/%.c + $(COMPILE.c) -o $@ $< + $(CTFCONVERT_O) + +$(OBJS_DIR)/%.o: $(PSMBASE)/promif/ieee1275/sun4u/%.c + $(COMPILE.c) -o $@ $< + $(CTFCONVERT_O) + +$(OBJS_DIR)/%.o: $(PSMBASE)/promif/ieee1275/sun4/%.c + $(COMPILE.c) -o $@ $< + $(CTFCONVERT_O) + +# +# Lint `object' build rules +# +$(LINTS_DIR)/%.ln: $(PSMBASE)/promif/ieee1275/sun4v/%.c + @($(LHEAD) $(LINT.c) $< $(LTAIL)) + +$(LINTS_DIR)/%.ln: $(PSMBASE)/promif/ieee1275/sun4u/%.c + @($(LHEAD) $(LINT.c) $< $(LTAIL)) + +$(LINTS_DIR)/%.ln: $(PSMBASE)/promif/ieee1275/sun4/%.c + @($(LHEAD) $(LINT.c) $< $(LTAIL)) diff --git a/usr/src/psm/promif/ieee1275/sun4v/prom_set_mmfsa_traptable.c b/usr/src/psm/promif/ieee1275/sun4v/prom_set_mmfsa_traptable.c new file mode 100644 index 0000000000..9cd3604a3b --- /dev/null +++ b/usr/src/psm/promif/ieee1275/sun4v/prom_set_mmfsa_traptable.c @@ -0,0 +1,52 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +/* + * This interface allows the client to safely take over the %tba by + * the prom's service. The prom will take care of the quiescence of + * interrupts and handle any pending soft interrupts. + * This call also sets the MMU fault status area for the cpu. + */ +void +prom_set_mmfsa_traptable(void *tba_addr, uint64_t mmfsa_ra) +{ + cell_t ci[5]; + + ci[0] = p1275_ptr2cell("SUNW,set-trap-table"); /* Service name */ + ci[1] = (cell_t)2; /* #argument cells */ + ci[2] = (cell_t)0; /* #result cells */ + ci[3] = p1275_ptr2cell(tba_addr); /* Arg1: tba address */ + ci[4] = p1275_ptr2cell(mmfsa_ra); /* Arg2: mmfsa RA */ + + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); +} |
