diff options
Diffstat (limited to 'usr/src/lib')
43 files changed, 4291 insertions, 55 deletions
diff --git a/usr/src/lib/Makefile b/usr/src/lib/Makefile index a46006f5d5..b6caadbd20 100644 --- a/usr/src/lib/Makefile +++ b/usr/src/lib/Makefile @@ -221,6 +221,7 @@ SUBDIRS += \ sparc_SUBDIRS= .WAIT \ efcode \ libc_psr .WAIT \ + libdscp \ libprtdiag .WAIT \ libprtdiag_psr \ librsc \ @@ -379,6 +380,7 @@ $(CLOSED_BUILD)HDRSUBDIRS += \ $(CLOSED)/lib/smartcard sparc_HDRSUBDIRS= \ + libdscp \ libwrsmconf all := TARGET= all diff --git a/usr/src/lib/efcode/Makefile b/usr/src/lib/efcode/Makefile index 4806e7a9bc..660a81d0e2 100644 --- a/usr/src/lib/efcode/Makefile +++ b/usr/src/lib/efcode/Makefile @@ -2,9 +2,8 @@ # 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. +# Common Development and Distribution License (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. @@ -20,16 +19,16 @@ # CDDL HEADER END # # -# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# -# ident "%Z%%M% %I% %E% SMI" +#ident "%Z%%M% %I% %E% SMI" # include ../Makefile.lib -SUBDIRS = engine fcdriver extend packages pci gp2 upa interpreter efdaemon +SUBDIRS = engine fcdriver extend packages pci gp2 upa interpreter efdaemon \ + jupiter TESTDIRS = fcode_test EFCODEDIRS= $(ROOTLIBDIR)/efcode $(ROOTLIBDIR)/efcode/$(MACH64) @@ -62,10 +61,10 @@ FRC: # Interdependencies between shared objects follow. # -extend fcdriver packages pci gp2 upa interpreter efdaemon: engine +extend fcdriver packages pci gp2 upa interpreter efdaemon jupiter: engine fcdriver: packages -gp2 pci interpreter: fcdriver +gp2 pci interpreter jupiter: fcdriver interpreter: packages extend diff --git a/usr/src/lib/efcode/engine/package.c b/usr/src/lib/efcode/engine/package.c index b32773f45d..be241d01ac 100644 --- a/usr/src/lib/efcode/engine/package.c +++ b/usr/src/lib/efcode/engine/package.c @@ -2,9 +2,8 @@ * 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. + * Common Development and Distribution License (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. @@ -20,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 2000 by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -461,6 +460,8 @@ dollar_open_package(fcode_env_t *env) if (ok) { open_package(env); } else { + (void) POP(DS); + (void) POP(DS); PUSH(DS, 0); } } diff --git a/usr/src/lib/efcode/jupiter/Makefile b/usr/src/lib/efcode/jupiter/Makefile new file mode 100644 index 0000000000..2cb77e4732 --- /dev/null +++ b/usr/src/lib/efcode/jupiter/Makefile @@ -0,0 +1,28 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (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 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.subdirs diff --git a/usr/src/lib/efcode/jupiter/Makefile.com b/usr/src/lib/efcode/jupiter/Makefile.com new file mode 100644 index 0000000000..4e005dd494 --- /dev/null +++ b/usr/src/lib/efcode/jupiter/Makefile.com @@ -0,0 +1,34 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (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 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +OBJECTS = jupiter.o +LIBRARY = lfc_jupiter.a +SYMLINKS = lfc_jupiter_jupiter.so + +include ../../Makefile.efcode + +CPPFLAGS += -I$(SRC)/uts/sun4 -I$(SRC)/uts/sun4u diff --git a/usr/src/lib/efcode/jupiter/jupiter.c b/usr/src/lib/efcode/jupiter/jupiter.c new file mode 100644 index 0000000000..2fc159bc20 --- /dev/null +++ b/usr/src/lib/efcode/jupiter/jupiter.c @@ -0,0 +1,437 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (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 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> + +#include <fcode/private.h> +#include <fcode/log.h> + +#include <fcdriver/fcdriver.h> + +#include <sys/opl_cfg.h> + +/* VA for HardWare Descriptor */ +static hwd_cmu_chan_t hwd_va_cmu; +static hwd_leaf_t hwd_va_pci; + +/* Macro to get I/O portid */ +#define DO_GET_IO_PORTID(env, lo, hi, portid) \ + PUSH(DS, lo); \ + PUSH(DS, hi); \ + do_get_io_portid(env); \ + portid = (uint32_t)POP(DS) + +fstack_t +mem_map_in(fcode_env_t *env, fstack_t hi, fstack_t lo, fstack_t len) +{ + private_data_t *pdp = DEVICE_PRIVATE(env); + fc_cell_t virt; + fstack_t mcookie = NULL; + char *service = "map-in"; + int error; + int offset = 0; + + /* + * The calculation of the offset, lo and len are left here + * due to historical precedence. + */ + + offset = lo & PAGEOFFSET; + lo &= PAGEMASK; + len = (len + offset + PAGEOFFSET) & PAGEMASK; + + error = fc_run_priv(pdp->common, service, 3, 1, fc_size2cell(len), + fc_uint32_t2cell(hi), fc_uint32_t2cell(lo), &virt); + + if (error) + throw_from_fclib(env, 1, "jupiter:%s: failed\n", service); + + mcookie = mapping_to_mcookie(virt, len, NULL, NULL); + + if (mcookie == NULL) + throw_from_fclib(env, 1, + "jupiter:%s: mapping_to_mcookie failed\n", service); + + mcookie += offset; + + debug_msg(DEBUG_REG_ACCESS, "jupiter:%s: %llx -> %x\n", service, + (long long)virt, (uint32_t)mcookie); + + return (mcookie); +} + +static void +mem_map_out(fcode_env_t *env, fstack_t mcookie, fstack_t len) +{ + private_data_t *pdp = DEVICE_PRIVATE(env); + fc_cell_t virt; + char *service = "map-out"; + int error; + int offset; + + /* + * The calculation of the offset, lo and len are left here + * due to historical precedence. + */ + + offset = mcookie & PAGEOFFSET; + mcookie &= PAGEMASK; + len = (len + offset + PAGEOFFSET) & PAGEMASK; + + if (!is_mcookie(mcookie)) { + log_message(MSG_ERROR, "jupiter:%s: %x not an mcookie!\n", + service, (int)mcookie); + virt = mcookie; + } else { + virt = mcookie_to_addr(mcookie); + debug_msg(DEBUG_REG_ACCESS, "jupiter:%s: %x -> %llx\n", + service, (int)mcookie, (long long)virt); + delete_mapping(mcookie); + } + + error = fc_run_priv(pdp->common, service, 2, 0, + fc_size2cell(len), virt); + if (error) + log_message(MSG_ERROR, "jupiter:%s: failed\n", service); +} + +static void +do_map_in(fcode_env_t *env) +{ + fstack_t phi, plo, len, addr; + + CHECK_DEPTH(env, 3, "jupiter:map-in"); + len = POP(DS); + phi = POP(DS); + plo = POP(DS); + addr = mem_map_in(env, phi, plo, len); + PUSH(DS, addr); +} + +static void +do_map_out(fcode_env_t *env) +{ + fstack_t addr, len; + + CHECK_DEPTH(env, 2, "jupiter:map-out"); + len = POP(DS); + addr = POP(DS); + mem_map_out(env, addr, len); +} + +static void +do_get_io_portid(fcode_env_t *env) +{ + fstack_t phi, plo; + unsigned int portid, lsb, ch, leaf; + + CHECK_DEPTH(env, 2, "jupiter:get-portid"); + + phi = POP(DS); + plo = POP(DS); + + lsb = OPL_ADDR_TO_LSB(phi); + ch = OPL_ADDR_TO_CHANNEL(phi); + leaf = OPL_ADDR_TO_LEAF(phi, plo); + + portid = OPL_IO_PORTID(lsb, ch, leaf); + + debug_msg(DEBUG_REG_ACCESS, "jupiter:get-portid ( %x %x ) -> %x\n", + (int)phi, (int)plo, (int)portid); + PUSH(DS, portid); +} + +static void +do_encode_unit(fcode_env_t *env) +{ + char enc_buf[64]; + fstack_t hi, lo; + uint32_t id; + long long off; + + CHECK_DEPTH(env, 2, "jupiter:encode-unit"); + + hi = POP(DS); + lo = POP(DS); + off = (long long)(((hi & 0x1F) << 32) | lo); + + /* Convert physical address to portid */ + DO_GET_IO_PORTID(env, lo, hi, id); + + if (off) { + (void) sprintf(enc_buf, "%x,%llx", id, off); + } else { + (void) sprintf(enc_buf, "%x", id); + } + + debug_msg(DEBUG_REG_ACCESS, "jupiter:encode_unit ( %x %x ) -> '%s'\n", + (uint32_t)hi, (uint32_t)lo, enc_buf); + + push_a_string(env, STRDUP(enc_buf)); +} + +static void +do_decode_unit(fcode_env_t *env) +{ + uint32_t hi; + long long lo; + unsigned int portid, lsb, ch; + char *buf; + + CHECK_DEPTH(env, 2, "jupiter:decode-unit"); + + buf = pop_a_string(env, NULL); + if (sscanf(buf, "%x,%llx", &portid, &lo) != 2) { + if (sscanf(buf, "%x", &portid) != 1) { + throw_from_fclib(env, 1, "jupiter:decode_unit:%s", + buf); + } + lo = 0; + } + + lsb = OPL_IO_PORTID_TO_LSB(portid); + ch = OPL_PORTID_TO_CHANNEL(portid); + hi = OPL_ADDR_HI(lsb, ch); + + debug_msg(DEBUG_REG_ACCESS, + "jupiter:decode_unit ( '%s' ) -> %x %llx\n", buf, hi, lo); + + PUSH(DS, (fstack_t)lo); + PUSH(DS, (fstack_t)hi); +} + +static void +do_device_id(fcode_env_t *env) +{ + common_data_t *cdp = COMMON_PRIVATE(env); + char *buf = NULL; + uint32_t hi; + long long lo; + uint32_t portid, ch, leaf; + + CHECK_DEPTH(env, 2, "jupiter:device-id"); + + hi = POP(DS); + lo = POP(DS); + + portid = 0; + if (cdp && cdp->fc.unit_address && + ((buf = strdup(cdp->fc.unit_address)) != NULL)) { + /* + * Get portid number from unit_address + * Because of no leaf information in physical address + */ + if (sscanf(buf, "%x,%llx", &portid, &lo) != 2) { + if (sscanf(buf, "%x", &portid) != 1) { + throw_from_fclib(env, 1, + "jupiter:do_device_id: invalid %s", buf); + } + } + } else { + /* + * Non existence unit_address case. + * Convert physical address to portid. + */ + throw_from_fclib(env, 1, + "jupiter:do_device_id: failed unit address"); + DO_GET_IO_PORTID(env, lo, hi, portid); + } + + debug_msg(DEBUG_FIND_FCODE, + "jupiter:do_device_id:(%x,%llx)\n", portid, lo); + + /* Pick up each ID from portid */ + ch = OPL_PORTID_TO_CHANNEL(portid); + leaf = OPL_PORTID_TO_LEAF(portid); + + if (ch == OPL_CMU_CHANNEL) { + /* + * CMU-CH: PCICMU CHANNEL + */ + debug_msg(DEBUG_FIND_FCODE, + "jupiter:do_device_id:cmu-ch\n"); + push_a_string(env, "cmu-ch"); + } else if (OPL_OBERON_CHANNEL(ch) && OPL_VALID_LEAF(leaf)) { + /* + * PCI-CH: Oberon Leaves CHANNEL + */ + if (leaf) { + /* Leaf B */ + debug_msg(DEBUG_FIND_FCODE, + "jupiter:do_device_id:jup-oberon-pci1\n"); + push_a_string(env, "jup-oberon-pci1"); + } else { + /* Leaf A */ + debug_msg(DEBUG_FIND_FCODE, + "jupiter:do_device_id:jup-oberon-pci0\n"); + push_a_string(env, "jup-oberon-pci0"); + } + } else { + /* Not matched to any channels */ + throw_from_fclib(env, 1, + "jupiter:do_device_id: invalid portid %x", portid); + push_a_string(env, ""); + } + + /* Free the duplicated buf */ + if (buf != NULL) + free(buf); +} + +static void +do_get_hwd_va(fcode_env_t *env) +{ + private_data_t *pdp = DEVICE_PRIVATE(env); + char *service = "get-hwd-va"; + char *buf; + uint32_t portid = 0; + int ch; + int error; + fc_cell_t status; + void *hwd_va; + + CHECK_DEPTH(env, 2, "jupiter:get-hwd-va"); + + /* Get a portid with string format */ + buf = pop_a_string(env, NULL); + + /* Convert to the integer from the string */ + if (sscanf(buf, "%x", &portid) != 1) { + throw_from_fclib(env, 1, "jupiter:%s: invalid portid", + service); + } + + ch = OPL_PORTID_TO_CHANNEL(portid); + if (!OPL_VALID_CHANNEL(ch)) { + throw_from_fclib(env, 1, "jupiter:%s: invalid poritd", + service); + hwd_va = 0; + goto out; + } + + if (ch == OPL_CMU_CHANNEL) { + hwd_va = (void *)&hwd_va_cmu; + } else { + hwd_va = (void *)&hwd_va_pci; + } + + /* + * Get the virtual address of hwd specified with portid. + */ + error = fc_run_priv(pdp->common, service, 2, 1, + fc_uint32_t2cell(portid), fc_ptr2cell(hwd_va), &status); + + if (error || !status) + throw_from_fclib(env, 1, "jupiter:%s: failed\n", service); + +out: + PUSH(DS, (fstack_t)hwd_va); +} + +static void +do_get_intrp_name(fcode_env_t *env) +{ + /* + * Just pass the "eFCode" string. + */ + + debug_msg(DEBUG_FIND_FCODE, + "jupiter: do_get_intrp_name: eFCode\n"); + + push_a_string(env, "eFCode"); +} + +static void +do_master_interrupt(fcode_env_t *env) +{ + int portid; + token_t xt; + + CHECK_DEPTH(env, 2, "jupiter:master-interrput"); + portid = POP(DS); + xt = POP(DS); + + PUSH(DS, FALSE); + debug_msg(DEBUG_REG_ACCESS, + "jupiter:master-interrupt ( %x %x ) -> %x\n", + portid, xt, (int)FALSE); +} + +static void +do_register_vector_entry(fcode_env_t *env) +{ + int ign, ino, level; + + CHECK_DEPTH(env, 3, "jupiter:register-vector-entry"); + ign = POP(DS); + ino = POP(DS); + level = POP(DS); + + PUSH(DS, FALSE); + debug_msg(DEBUG_REG_ACCESS, + "jupiter:register-vector-entry ( %x %x %x ) -> %x\n", + ign, ino, level, (int)FALSE); +} + +static void +do_get_interrupt_target(fcode_env_t *env) +{ + int mid = -1; + + PUSH(DS, mid); + debug_msg(DEBUG_REG_ACCESS, + "jupiter:get-interrupt-target ( ) -> %x\n", mid); +} + + +#pragma init(_init) + +static void +_init(void) +{ + fcode_env_t *env = initial_env; + + ASSERT(env); + ASSERT(env->current_device); + NOTICE; + + create_int_prop(env, "#address-cells", 2); + + FORTH(0, "map-in", do_map_in); + FORTH(0, "map-out", do_map_out); + FORTH(0, "get-portid", do_get_io_portid); + FORTH(0, "decode-unit", do_decode_unit); + FORTH(0, "encode-unit", do_encode_unit); + FORTH(0, "device-id", do_device_id); + FORTH(0, "get-hwd-va", do_get_hwd_va); + FORTH(0, "get-fcinterp-name", do_get_intrp_name); + FORTH(0, "master-interrupt", do_master_interrupt); + FORTH(0, "register-vector-entry", do_register_vector_entry); + FORTH(0, "get-interrupt-target", do_get_interrupt_target); +} diff --git a/usr/src/lib/efcode/jupiter/sparcv9/Makefile b/usr/src/lib/efcode/jupiter/sparcv9/Makefile new file mode 100644 index 0000000000..99913538b5 --- /dev/null +++ b/usr/src/lib/efcode/jupiter/sparcv9/Makefile @@ -0,0 +1,33 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (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 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com +include $(SRC)/lib/Makefile.lib.64 + +DYNFLAGS += $(FCODE64) $(FCDRIVER64) + +install: all $(ROOTLIBS64) $(ROOTSYMLINKS64) diff --git a/usr/src/lib/efcode/packages/memalloc.c b/usr/src/lib/efcode/packages/memalloc.c index 3bb4a928ff..5e8d365d17 100644 --- a/usr/src/lib/efcode/packages/memalloc.c +++ b/usr/src/lib/efcode/packages/memalloc.c @@ -2,9 +2,8 @@ * 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. + * Common Development and Distribution License (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. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 1999-2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -35,11 +34,9 @@ #include <fcdriver/fcdriver.h> -static void schizo_vtop(fcode_env_t *, fc_cell_t, fstack_t *, fstack_t *); - /* - * claim under /openprom/client-services is only used by schizo Fcode, we - * call "schizo,claim-memory" service. + * claim under /openprom/client-services is used by schizo and oberon Fcode, we + * call "claim-memory" service. */ void claim(fcode_env_t *env) @@ -50,11 +47,11 @@ claim(fcode_env_t *env) fc_cell_t vaddr; int error; - CHECK_DEPTH(env, 3, "schizo,claim-memory"); + CHECK_DEPTH(env, 3, "claim-memory"); hint = (void *)POP(DS); size = POP(DS); align = POP(DS); - error = fc_run_priv(env->private, "schizo,claim-memory", 3, 1, + error = fc_run_priv(env->private, "claim-memory", 3, 1, fc_int2cell(align), fc_size2cell(size), fc_ptr2cell(hint), &vaddr); if (error) throw_from_fclib(env, 1, "client-services/claim failed\n"); @@ -69,10 +66,10 @@ release(fcode_env_t *env) void *addr; int error; - CHECK_DEPTH(env, 2, "schizo,release-memory"); + CHECK_DEPTH(env, 2, "release-memory"); addr = (void *)POP(DS); size = POP(DS); - error = fc_run_priv(env->private, "schizo,release-memory", 2, 0, + error = fc_run_priv(env->private, "release-memory", 2, 0, fc_size2cell(size), fc_ptr2cell(addr)); if (error) throw_from_fclib(env, 1, "client-services/release failed\n"); @@ -86,9 +83,9 @@ fc_vtop(fcode_env_t *env) fc_cell_t physlo, physhi; int error; - CHECK_DEPTH(env, 1, "schizo,vtop"); + CHECK_DEPTH(env, 1, "vtop"); vaddr = (void *)POP(DS); - error = fc_run_priv(env->private, "schizo,vtop", 1, 2, + error = fc_run_priv(env->private, "vtop", 1, 2, fc_ptr2cell(vaddr), &physlo, &physhi); if (error) throw_from_fclib(env, 1, "fc_vtop: '>physical' failed\n"); diff --git a/usr/src/lib/libc_psr/Makefile b/usr/src/lib/libc_psr/Makefile index df8c308012..2521a042c0 100644 --- a/usr/src/lib/libc_psr/Makefile +++ b/usr/src/lib/libc_psr/Makefile @@ -2,9 +2,8 @@ # 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. +# Common Development and Distribution License (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. @@ -22,7 +21,7 @@ # #ident "%Z%%M% %I% %E% SMI" # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # lib/libc_psr/Makefile @@ -30,7 +29,7 @@ include ../Makefile.lib -SUBDIRS= sun4u sun4u-us3 sun4u_hwcap1 sun4u_hwcap2 sun4v sun4v_hwcap1 etc +SUBDIRS= sun4u sun4u-opl sun4u-us3 sun4u_hwcap1 sun4u_hwcap2 sun4v sun4v_hwcap1 etc all := TARGET= all install := TARGET= install diff --git a/usr/src/lib/libc_psr/spec/Makefile b/usr/src/lib/libc_psr/spec/Makefile index 175550e312..7742b756e6 100644 --- a/usr/src/lib/libc_psr/spec/Makefile +++ b/usr/src/lib/libc_psr/spec/Makefile @@ -2,9 +2,8 @@ # 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. +# Common Development and Distribution License (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. @@ -22,12 +21,12 @@ # #pragma ident "%Z%%M% %I% %E% SMI" # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # usr/src/lib/libc_psr/spec/Makefile -SUBDIRS= sun4u sun4u_hwcap1 sun4u_hwcap2 sun4v_hwcap1 +SUBDIRS= sun4u sun4u-opl sun4u_hwcap1 sun4u_hwcap2 sun4v_hwcap1 all := TARGET= all install := TARGET= install diff --git a/usr/src/lib/libc_psr/spec/sun4u-opl/Makefile b/usr/src/lib/libc_psr/spec/sun4u-opl/Makefile new file mode 100644 index 0000000000..e41b66e7f1 --- /dev/null +++ b/usr/src/lib/libc_psr/spec/sun4u-opl/Makefile @@ -0,0 +1,29 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (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 +# +# +#pragma ident "%Z%%M% %I% %E% SMI" +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# lib/libc_psr/spec/sun4u-opl/Makefile + +include $(SRC)/lib/Makefile.spec.arch diff --git a/usr/src/lib/libc_psr/spec/sun4u-opl/Makefile.links b/usr/src/lib/libc_psr/spec/sun4u-opl/Makefile.links new file mode 100644 index 0000000000..53c0bd026e --- /dev/null +++ b/usr/src/lib/libc_psr/spec/sun4u-opl/Makefile.links @@ -0,0 +1,37 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (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 +# +#pragma ident "%Z%%M% %I% %E% SMI" +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# lib/libc_psr/spec/sun4u-opl/Makefile.links + +include $(SRC)/Makefile.psm + +MODULE = abi + +# +# links in /usr/platform +# +LINKED_PLATFORMS = SUNW,SPARC-Enterprise + +include $(SRC)/lib/libc_psr/spec/Makefile.com diff --git a/usr/src/lib/libc_psr/spec/sun4u-opl/c_psr-sparc.spec b/usr/src/lib/libc_psr/spec/sun4u-opl/c_psr-sparc.spec new file mode 100644 index 0000000000..ade9554bdc --- /dev/null +++ b/usr/src/lib/libc_psr/spec/sun4u-opl/c_psr-sparc.spec @@ -0,0 +1,66 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (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 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#pragma ident "%Z%%M% %I% %E% SMI" +# +# lib/libc_psr/spec/sun4u-opl/c_psr-sparc.spec + +function memcmp extends libc/spec/gen.spec +arch sparc +version SUNWprivate_1.1 +end + +function _memcmp extends libc/spec/private.spec +arch sparc +version SUNWprivate_1.1 +end + +function memcpy extends libc/spec/gen.spec +arch sparc +version SUNWprivate_1.1 +end + +function _memcpy extends libc/spec/private.spec +arch sparc +version SUNWprivate_1.1 +end + +function memmove extends libc/spec/gen.spec +arch sparc +version SUNWprivate_1.1 +end + +function _memmove extends libc/spec/private.spec +arch sparc +version SUNWprivate_1.1 +end + +function memset extends libc/spec/gen.spec +arch sparc +version SUNWprivate_1.1 +end + +function _memset extends libc/spec/private.spec +arch sparc +version SUNWprivate_1.1 +end diff --git a/usr/src/lib/libc_psr/spec/sun4u-opl/c_psr-sparcv9.spec b/usr/src/lib/libc_psr/spec/sun4u-opl/c_psr-sparcv9.spec new file mode 100644 index 0000000000..07acdd7e66 --- /dev/null +++ b/usr/src/lib/libc_psr/spec/sun4u-opl/c_psr-sparcv9.spec @@ -0,0 +1,67 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (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 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#pragma ident "%Z%%M% %I% %E% SMI" +# +# lib/libc_psr/spec/sun4u-opl/c_psr-sparcv9.spec + +function memcmp extends libc/spec/gen.spec +arch sparcv9 +version SUNWprivate_1.1 +end + +function _memcmp extends libc/spec/private.spec +arch sparcv9 +version SUNWprivate_1.1 +end + +function memcpy extends libc/spec/gen.spec +arch sparcv9 +version SUNWprivate_1.1 +end + +function _memcpy extends libc/spec/private.spec +arch sparcv9 +version SUNWprivate_1.1 +end + +function memmove extends libc/spec/gen.spec +arch sparcv9 +version SUNWprivate_1.1 +end + +function _memmove extends libc/spec/private.spec +arch sparcv9 +version SUNWprivate_1.1 +end + +function memset extends libc/spec/gen.spec +arch sparcv9 +version SUNWprivate_1.1 +end + +function _memset extends libc/spec/private.spec +arch sparcv9 +version SUNWprivate_1.1 +end diff --git a/usr/src/lib/libc_psr/spec/sun4u-opl/sparc/Makefile b/usr/src/lib/libc_psr/spec/sun4u-opl/sparc/Makefile new file mode 100644 index 0000000000..edd059ba21 --- /dev/null +++ b/usr/src/lib/libc_psr/spec/sun4u-opl/sparc/Makefile @@ -0,0 +1,51 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (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 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#pragma ident "%Z%%M% %I% %E% SMI" +# +# lib/libc_psr/spec/sun4u-opl/sparc/Makefile + +.KEEP_STATE: + +LIBRARY = libc_psr.a +VERS = .1 + +PLATFORM= SUNW,SPARC-Enterprise +ALT_PLAT= sun4u-opl +CLASS = 32 + +OBJECTS = c_psr-$(MACH).o + +SPECVERS = -$(MACH) + +include $(SRC)/lib/Makefile.lib +include $(SRC)/lib/libc_psr/spec/$(ALT_PLAT)/Makefile.links + +# Uncomment the following if the linker complains +#sparc_C_PICFLAGS = -K PIC + +include $(SRC)/lib/Makefile.spec +include $(SRC)/lib/Makefile.spec.psm + +$(DISABLE_APPTRACE)install: $(ROOTABILIB) diff --git a/usr/src/lib/libc_psr/spec/sun4u-opl/sparcv9/Makefile b/usr/src/lib/libc_psr/spec/sun4u-opl/sparcv9/Makefile new file mode 100644 index 0000000000..557004d67e --- /dev/null +++ b/usr/src/lib/libc_psr/spec/sun4u-opl/sparcv9/Makefile @@ -0,0 +1,51 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (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 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#pragma ident "%Z%%M% %I% %E% SMI" +# +# lib/libc_psr/spec/sun4u-opl/sparcv9/Makefile + +.KEEP_STATE: + +LIBRARY = libc_psr.a +VERS = .1 + +PLATFORM= SUNW,SPARC-Enterprise +ALT_PLAT= sun4u-opl +CLASS = 64 + +OBJECTS = c_psr-$(MACH64).o + +SPECVERS= -$(MACH64) + +include $(SRC)/lib/Makefile.lib +include $(SRC)/lib/Makefile.lib.64 +include $(SRC)/lib/libc_psr/spec/$(ALT_PLAT)/Makefile.links + +# Uncomment the following if the linker complains +#sparcv9_C_PICFLAGS = -K PIC + +include $(SRC)/lib/Makefile.spec +include $(SRC)/lib/Makefile.spec.psm + +$(DISABLE_APPTRACE)install: $(ROOTABILIB) diff --git a/usr/src/lib/libc_psr/spec/sun4u-opl/versions-sparc b/usr/src/lib/libc_psr/spec/sun4u-opl/versions-sparc new file mode 100644 index 0000000000..048669407d --- /dev/null +++ b/usr/src/lib/libc_psr/spec/sun4u-opl/versions-sparc @@ -0,0 +1,31 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (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 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#pragma ident "%Z%%M% %I% %E% SMI" +# +# vers file for libc_psr/sun4u-opl/sparc +# +sparc { + SUNWprivate_1.1; +} diff --git a/usr/src/lib/libc_psr/spec/sun4u-opl/versions-sparcv9 b/usr/src/lib/libc_psr/spec/sun4u-opl/versions-sparcv9 new file mode 100644 index 0000000000..2c57d5f9db --- /dev/null +++ b/usr/src/lib/libc_psr/spec/sun4u-opl/versions-sparcv9 @@ -0,0 +1,30 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (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 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#pragma ident "%Z%%M% %I% %E% SMI" +# +# vers file for libc_psr/sun4u-opl/sparcv9 +# +sparcv9 { + SUNWprivate_1.1; +} diff --git a/usr/src/lib/libc_psr/sun4u-opl/Makefile b/usr/src/lib/libc_psr/sun4u-opl/Makefile new file mode 100644 index 0000000000..65799c0b96 --- /dev/null +++ b/usr/src/lib/libc_psr/sun4u-opl/Makefile @@ -0,0 +1,61 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (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 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# lib/libc_psr/sun4u-opl/Makefile +# + +include ../../Makefile.lib + +PLATFORM= SUNW,SPARC-Enterprise +ALT_PLAT= sun4u-opl + +SUBDIRS= $(MACH) +SUBDIRS64= $(MACH64) + +all := TARGET= all +install := TARGET= install +clean := TARGET= clean +clobber := TARGET= clobber + +.KEEP_STATE: + +all install clean clobber : lib32 \ + $(BUILD64) lib64 + +lint: + @ $(ECHO) "Nothing to lint here: skipping" + +lib32: spec .WAIT $(SUBDIRS) + +lib64: $(SUBDIRS64) + +$(SUBDIRS) $(SUBDIRS64): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +spec: FRC + @cd ../spec/$(ALT_PLAT); pwd; $(MAKE) $(TARGET) + +FRC: diff --git a/usr/src/lib/libc_psr/sun4u-opl/Makefile.com b/usr/src/lib/libc_psr/sun4u-opl/Makefile.com new file mode 100644 index 0000000000..c2cb4edd2d --- /dev/null +++ b/usr/src/lib/libc_psr/sun4u-opl/Makefile.com @@ -0,0 +1,72 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (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 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +# +# Create default so empty rules don't +# confuse make +# + +LIBRARY = libc_psr.a +VERS = .1 + +include $(SRC)/lib/Makefile.lib +include $(SRC)/Makefile.psm + +# +# Since libc_psr is strictly assembly, deactivate the CTF build logic. +# +CTFCONVERT_POST = : +CTFMERGE_LIB = : + +LIBS = $(DYNLIB) +IFLAGS = -I$(SRC)/lib/libc/inc -I$(SRC)/uts/sun4u \ + -I$(ROOT)/usr/platform/sun4u/include +CPPFLAGS = -D_REENTRANT -D$(MACH) $(IFLAGS) $(CPPFLAGS.master) +ASDEFS = -D__STDC__ -D_ASM $(CPPFLAGS) +ASFLAGS = -P $(ASDEFS) + +# +# Used when building links in /platform/$(PLATFORM)/lib +# +LINKED_PLATFORMS = SUNW,SPARC-Enterprise + +# +# install rule +# +$(ROOT_PSM_LIB_DIR)/%: % $(ROOT_PSM_LIB_DIR) + $(INS.file) + +# +# build rules +# +pics/%.o: ../../$(PLATFORM)/common/%.s + $(AS) $(ASFLAGS) $< -o $@ + $(POST_PROCESS_O) + +pics/%.o: ../../$(COMPAT_PLAT)/common/%.s + $(AS) $(ASFLAGS) $< -o $@ + $(POST_PROCESS_O) diff --git a/usr/src/lib/libc_psr/sun4u-opl/common/memcpy.s b/usr/src/lib/libc_psr/sun4u-opl/common/memcpy.s new file mode 100644 index 0000000000..cf41195e78 --- /dev/null +++ b/usr/src/lib/libc_psr/sun4u-opl/common/memcpy.s @@ -0,0 +1,716 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (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 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +.ident "%Z%%M% %I% %E% SMI" + + .file "memcpy.s" +/* + * memcpy(s1, s2, len) + * + * Copy s2 to s1, always copy n bytes. + * Note: this C code does not work for overlapped copies. + * Memmove() and bcopy() do. + * + * Fast assembler language version of the following C-program for memcpy + * which represents the `standard' for the C-library. + * + * void * + * memcpy(void *s, const void *s0, size_t n) + * { + * if (n != 0) { + * char *s1 = s; + * const char *s2 = s0; + * do { + * *s1++ = *s2++; + * } while (--n != 0); + * } + * return (s); + * } + */ + +#include <sys/asm_linkage.h> +#include <sys/sun4asi.h> +#include <sys/trap.h> + +#define ICACHE_LINE_SIZE 32 +#define BLOCK_SIZE 64 +#define FPRS_FEF 0x4 + +#define SHORTCOPY 3 +#define SMALL_MAX 39 +#define MEDIUM_MAX 255 +#define MED_WMAX 256 /* max copy for medium word-aligned case */ +#define MED_MAX 65536 /* max copy for medium longword-aligned case */ + + ANSI_PRAGMA_WEAK(memmove,function) + ANSI_PRAGMA_WEAK(memcpy,function) + +#include "synonyms.h" + + ENTRY(memmove) + cmp %o1, %o0 ! if from address is >= to use forward copy + bgeu %ncc, .forcpy ! else use backward if ... + sub %o0, %o1, %o4 ! get difference of two addresses + cmp %o2, %o4 ! compare size and difference of addresses + bleu %ncc, .forcpy ! if size is bigger, do overlapped copy + nop + + ! + ! an overlapped copy that must be done "backwards" + ! +.ovbc: + mov %o0, %g1 ! save dest address for return val + add %o1, %o2, %o1 ! get to end of source space + add %o0, %o2, %o0 ! get to end of destination space + +.chksize: + cmp %o2, 8 + bgeu,pn %ncc, .dbalign + andcc %o0, 7, %g0 ! Is DST 8 byte aligned? + +.byte: +1: deccc %o2 ! decrement count + blu,pn %ncc, .exit ! loop until done + dec %o0 ! decrement to address + dec %o1 ! decrement from address + ldub [%o1], %o3 ! read a byte + ba 1b ! loop until done + stb %o3, [%o0] ! write byte + +.dbalign: + bz %ncc, .dbbck + nop + dec %o1 + dec %o0 + dec %o2 + ldub [%o1], %o3 + ba .chksize + stb %o3, [%o0] + +.dbbck: + rd %fprs, %o3 ! o3 = fprs + + ! if fprs.fef == 0, set it. Checking it, requires 2 instructions. + ! So set it anyway, without checking. + wr %g0, 0x4, %fprs ! fprs.fef = 1 + + alignaddr %o1, %g0, %o5 ! align src + ldd [%o5], %d0 ! get first 8 byte block + sub %o5, 8, %o5 + andn %o2, 7, %o4 + sub %o1, %o4, %o1 + +2: + sub %o0, 8, %o0 ! since we are at the end + ! when we first enter the loop + ldd [%o5], %d2 + sub %o2, 8, %o2 ! 8 less bytes to copy + sub %o5, 8, %o5 + cmp %o2, 8 ! do we have < 8 bytes remaining + faligndata %d2, %d0, %d8 ! extract 8 bytes out + std %d8, [%o0] ! store the current 8 bytes + bgeu,pt %ncc, 2b + fmovd %d2, %d0 + + and %o3, 0x4, %o3 ! fprs.du = fprs.dl = 0 + ba .byte + wr %o3, %g0, %fprs ! fprs = o3 restore fprs + +.exit: + retl + mov %g1, %o0 + SET_SIZE(memmove) + + + .align ICACHE_LINE_SIZE + ENTRY(memcpy) + ! adjust instruction alignment + nop ! Do not remove, these nops affect + nop ! icache alignment and performance +.forcpy: + prefetch [%o1], #n_reads + prefetch [%o0], #n_reads + cmp %o2, SMALL_MAX ! check for not small case + bgu,pn %ncc, .medium ! go to larger cases + mov %o0, %g1 ! save %o0 + cmp %o2, SHORTCOPY ! check for really short case + ble,pt %ncc, .smallleft ! + or %o0, %o1, %o3 ! prepare alignment check + andcc %o3, 0x3, %g0 ! test for alignment + bz,pt %ncc, .smallword ! branch to word aligned case + sub %o2, 3, %o2 ! adjust count to allow cc zero test +.smallnotalign4: + ldub [%o1], %o3 ! read byte + subcc %o2, 4, %o2 ! reduce count by 4 + stb %o3, [%o0] ! write byte + ldub [%o1+1], %o3 ! repeat for a total of 4 bytes + add %o1, 4, %o1 ! advance SRC by 4 + stb %o3, [%o0+1] + ldub [%o1-2], %o3 + add %o0, 4, %o0 ! advance DST by 4 + stb %o3, [%o0-2] + ldub [%o1-1], %o3 + bgu,pt %ncc, .smallnotalign4 ! loop til 3 or fewer bytes remain + stb %o3, [%o0-1] + add %o2, 3, %o2 ! restore count +.smallleft: + tst %o2 + bz,pt %ncc, .smallexit + nop +.smallleft3: ! 1, 2, or 3 bytes remain + ldub [%o1], %o3 ! load one byte + deccc %o2 ! reduce count for cc test + bz,pt %ncc, .smallexit + stb %o3, [%o0] ! store one byte + ldub [%o1+1], %o3 ! load second byte + deccc %o2 + bz,pt %ncc, .smallexit + stb %o3, [%o0+1] ! store second byte + ldub [%o1+2], %o3 ! load third byte + stb %o3, [%o0+2] ! store third byte + retl + mov %g1, %o0 ! restore %o0 + + .align 8 + nop ! affects loop icache alignment +.smallwords: + lduw [%o1], %o3 ! read word +.smallwordx: + subcc %o2, 8, %o2 ! update count + stw %o3, [%o0] ! write word + add %o1, 8, %o1 ! update SRC + lduw [%o1-4], %o3 ! read word + add %o0, 8, %o0 ! update DST + bgu,pt %ncc, .smallwords ! loop until done + stw %o3, [%o0-4] ! write word + addcc %o2, 7, %o2 ! restore count + bz,pt %ncc, .smallexit ! check for completion + nop + cmp %o2, 4 ! check for 4 or more bytes left + blt .smallleft3 ! if not, go to finish up + nop + lduw [%o1], %o3 + add %o1, 4, %o1 + subcc %o2, 4, %o2 + stw %o3, [%o0] + add %o0, 4, %o0 + bnz,pt %ncc, .smallleft3 + nop + retl + mov %g1, %o0 ! restore %o0 + +.smallword: + subcc %o2, 4, %o2 ! update count + bgu,pt %ncc, .smallwordx + lduw [%o1], %o3 ! read word + addcc %o2, 3, %o2 ! restore count + bz,pt %ncc, .smallexit + stw %o3, [%o0] ! write word + deccc %o2 ! reduce count for cc test + ldub [%o1+4], %o3 ! load one byte + bz,pt %ncc, .smallexit + stb %o3, [%o0+4] ! store one byte + ldub [%o1+5], %o3 ! load second byte + deccc %o2 + bz,pt %ncc, .smallexit + stb %o3, [%o0+5] ! store second byte + ldub [%o1+6], %o3 ! load third byte + stb %o3, [%o0+6] ! store third byte +.smallexit: + retl + mov %g1, %o0 ! restore %o0 + .align 16 +.medium: + neg %o0, %o5 + neg %o1, %o3 + andcc %o5, 7, %o5 ! bytes till DST 8 byte aligned + and %o3, 7, %o3 ! bytes till SRC 8 byte aligned + + bz %ncc, 2f + sub %o5, %o3, %o3 ! -(bytes till SRC aligned after DST aligned) + ! o3={-7, -6, ... 7} o3>0 => SRC overaligned + + sub %o2, %o5, %o2 ! update count + +1: + ldub [%o1], %o4 + deccc %o5 + inc %o1 + stb %o4, [%o0] + bgu,pt %ncc, 1b + inc %o0 + + ! Now DST is 8-byte aligned. o0, o1, o2 are current. + +2: + andcc %o1, 0x3, %g0 ! test alignment + prefetch [%o1 + (1 * BLOCK_SIZE)], #n_reads + bnz,pt %ncc, .mediumsetup ! branch to skip aligned cases + ! if src, dst not aligned + prefetch [%o0 + (1 * BLOCK_SIZE)], #n_reads + +/* + * Handle all cases where src and dest are aligned on word + * or long word boundaries. Use unrolled loops for better + * performance. This option wins over standard large data + * move when source and destination is in cache for medium + * to short data moves. + */ + andcc %o1, 0x7, %g0 ! test word alignment + prefetch [%o1 + (2 * BLOCK_SIZE)], #n_reads + bz,pt %ncc, .medlword ! branch to long word aligned case + prefetch [%o0 + (2 * BLOCK_SIZE)], #n_reads + + cmp %o2, MED_WMAX ! limit to store buffer size + bgu,pt %ncc, .mediumrejoin ! otherwise rejoin main loop + prefetch [%o1 + (3 * BLOCK_SIZE)], #n_reads + subcc %o2, 15, %o2 ! adjust length to allow cc test + prefetch [%o0 + (3 * BLOCK_SIZE)], #n_reads + ! for end of loop + ble,pt %ncc, .medw15 ! skip big loop if less than 16 + .empty +.medw16: + prefetch [%o1 + (4 * BLOCK_SIZE)], #n_reads + ld [%o1], %o4 ! load + subcc %o2, 16, %o2 ! decrement length count + prefetch [%o0 + (4 * BLOCK_SIZE)], #n_reads + stw %o4, [%o0] ! and store + ld [%o1+4], %o3 ! a block of 16 bytes + add %o1, 16, %o1 ! increase src ptr by 16 + stw %o3, [%o0+4] + ld [%o1-8], %o4 + add %o0, 16, %o0 ! increase dst ptr by 16 + stw %o4, [%o0-8] + ld [%o1-4], %o3 + bgu,pt %ncc, .medw16 ! repeat if at least 16 bytes left + stw %o3, [%o0-4] +.medw15: + addcc %o2, 15, %o2 ! restore count + bz,pt %ncc, .medwexit ! exit if finished + nop + cmp %o2, 8 + blt,pt %ncc, .medw7 ! skip if 7 or fewer bytes left + nop ! + ld [%o1], %o4 ! load 4 bytes + subcc %o2, 8, %o2 ! decrease count by 8 + stw %o4, [%o0] ! and store 4 bytes + add %o1, 8, %o1 ! increase src ptr by 8 + ld [%o1-4], %o3 ! load 4 bytes + add %o0, 8, %o0 ! increase dst ptr by 8 + stw %o3, [%o0-4] ! and store 4 bytes + bz %ncc, .medwexit ! exit if finished + nop +.medw7: ! count is ge 1, less than 8 + cmp %o2, 3 ! check for 4 bytes left + ble,pt %ncc, .medw3 ! skip if 3 or fewer bytes left + nop ! + ld [%o1], %o4 ! load 4 bytes + sub %o2, 4, %o2 ! decrease count by 4 + add %o1, 4, %o1 ! increase src ptr by 4 + stw %o4, [%o0] ! and store 4 bytes + add %o0, 4, %o0 ! increase dst ptr by 4 + tst %o2 ! check for zero bytes left + bz %ncc, .medwexit ! exit if finished + nop +.medw3: ! count is known to be 1, 2, or 3 + deccc %o2 ! reduce count by one + ldub [%o1], %o3 ! load one byte + bz,pt %ncc, .medwexit ! exit if last byte + stb %o3, [%o0] ! store one byte + ldub [%o1+1], %o3 ! load second byte + deccc %o2 ! reduce count by one + bz,pt %ncc, .medwexit ! exit if last byte + stb %o3, [%o0+1] ! store second byte + ldub [%o1+2], %o3 ! load third byte + stb %o3, [%o0+2] ! store third byte +.medwexit: + retl + mov %g1, %o0 ! restore %o0 + +/* + * Special case for handling when src and dest are both long word aligned + * and total data to move is between SMALL_MAX and MED_MAX bytes + */ + + .align 16 + nop +.medlword: ! long word aligned + ! length > SMALL_MAX + set MED_MAX, %o4 + cmp %o2, %o4 + bgu,pt %ncc, .mediumrejoin ! otherwise rejoin main loop + prefetch [%o1 + (3 * BLOCK_SIZE)], #n_reads + prefetch [%o0 + (3 * BLOCK_SIZE)], #n_reads + subcc %o2, 31, %o2 ! adjust length to allow cc test + ! for end of loop + ble,pt %ncc, .medl31 ! skip big loop if less than 32 + .empty +.medl32: + prefetch [%o1 + (4 * BLOCK_SIZE)], #n_reads + ldx [%o1], %o4 ! load + subcc %o2, 32, %o2 ! decrement length count + prefetch [%o0 + (4 * BLOCK_SIZE)], #n_reads + stx %o4, [%o0] ! and store + ldx [%o1+8], %o3 ! a block of 32 bytes + add %o1, 32, %o1 ! increase src ptr by 32 + stx %o3, [%o0+8] + ldx [%o1-16], %o4 + add %o0, 32, %o0 ! increase dst ptr by 32 + stx %o4, [%o0-16] + ldx [%o1-8], %o3 + bgu,pt %ncc, .medl32 ! repeat if at least 32 bytes left + stx %o3, [%o0-8] +.medl31: + addcc %o2, 16, %o2 ! adjust remaining count + ble,pt %ncc, .medl15 ! skip if 15 or fewer bytes left + nop ! + ldx [%o1], %o4 ! load and store 16 bytes + add %o1, 16, %o1 ! increase src ptr by 16 + stx %o4, [%o0] ! + sub %o2, 16, %o2 ! decrease count by 16 + ldx [%o1-8], %o3 ! + add %o0, 16, %o0 ! increase dst ptr by 16 + stx %o3, [%o0-8] +.medl15: + addcc %o2, 15, %o2 ! restore count + bz,pt %ncc, .medwexit ! exit if finished + nop + cmp %o2, 8 + blt,pt %ncc, .medw7 ! skip if 7 or fewer bytes left + nop + ldx [%o1], %o4 ! load 8 bytes + add %o1, 8, %o1 ! increase src ptr by 8 + stx %o4, [%o0] ! and store 8 bytes + subcc %o2, 8, %o2 ! decrease count by 8 + bz %ncc, .medwexit ! exit if finished + add %o0, 8, %o0 ! increase dst ptr by 8 + ba .medw7 + nop + + .align 8 +.mediumsetup: + prefetch [%o1 + (2 * BLOCK_SIZE)], #one_read + prefetch [%o1 + (3 * BLOCK_SIZE)], #one_read +.mediumrejoin: + rd %fprs, %o4 ! check for unused FPU + + add %o1, 8, %o1 ! prepare to round SRC upward + + sethi %hi(0x1234567f), %o5 ! For GSR.MASK + or %o5, 0x67f, %o5 + + andcc %o4, FPRS_FEF, %o4 ! test FEF, fprs.du = fprs.dl = 0 + prefetch [%o1 + (4 * BLOCK_SIZE)], #one_read + bz,a %ncc, 3f + wr %g0, FPRS_FEF, %fprs ! fprs.fef = 1 +3: + cmp %o2, MEDIUM_MAX + prefetch [%o1 + (5 * BLOCK_SIZE)], #one_read + bmask %o5, %g0, %g0 + + ! Compute o5 (number of bytes that need copying using the main loop). + ! First, compute for the medium case. + ! Then, if large case, o5 is replaced by count for block alignment. + ! Be careful not to read past end of SRC + ! Currently, o2 is the actual count remaining + ! o3 is how much sooner we'll cross the alignment boundary + ! in SRC compared to in DST + ! + ! Examples: Let # denote bytes that should not be accessed + ! Let x denote a byte already copied to align DST + ! Let . and - denote bytes not yet copied + ! Let | denote double alignment boundaries + ! + ! DST: ######xx|........|--------|..###### o2 = 18 + ! o0 + ! + ! o3 = -3: SRC: ###xx...|.....---|-----..#|######## o5 = 8 + ! o1 + ! + ! o3 = 0: SRC: ######xx|........|--------|..###### o5 = 16-8 = 8 + ! o1 + ! + ! o3 = +1: SRC: #######x|x.......|.-------|-..##### o5 = 16-8 = 8 + ! o1 + + or %g0, -8, %o5 + alignaddr %o1, %g0, %o1 ! set GSR.ALIGN and align o1 + + movrlz %o3, %g0, %o5 ! subtract 8 from o2+o3 only if o3>=0 + add %o5, %o2, %o5 + add %o5, %o3, %o5 + + bleu %ncc, 4f + andn %o5, 7, %o5 ! 8 byte aligned count + neg %o0, %o5 ! 'large' case + and %o5, BLOCK_SIZE-1, %o5 ! bytes till DST block aligned +4: + prefetch [%o1 + (6 * BLOCK_SIZE)], #one_read + brgez,a %o3, .beginmedloop + ldd [%o1-8], %d0 + + add %o1, %o3, %o1 ! back up o1 +5: + ldda [%o1]ASI_FL8_P, %d2 + inc %o1 + andcc %o1, 7, %g0 + bnz %ncc, 5b + bshuffle %d0, %d2, %d0 ! shifts d0 left 1 byte and or's in d2 + +.beginmedloop: + prefetch [%o1 + (7 * BLOCK_SIZE)], #one_read + tst %o5 + bz %ncc, .endmedloop + sub %o2, %o5, %o2 ! update count for later + + ! Main loop to write out doubles. Note: o5 & 7 == 0 + + ldx [%o1], %d2 + subcc %o5, 8, %o5 ! update local count + bz,pn %ncc, 1f + add %o1, 8, %o1 ! update SRC + +.medloop: + faligndata %d0, %d2, %d4 + ldd [%o1], %d0 + subcc %o5, 8, %o5 ! update local count + add %o1, 16, %o1 ! update SRC + std %d4, [%o0] + bz,pn %ncc, 2f + faligndata %d2, %d0, %d6 + ldd [%o1 - 8], %d2 + subcc %o5, 8, %o5 ! update local count + std %d6, [%o0 + 8] + bnz,pt %ncc, .medloop + add %o0, 16, %o0 ! update DST + +1: + faligndata %d0, %d2, %d4 + fmovd %d2, %d0 + std %d4, [%o0] + ba .endmedloop + add %o0, 8, %o0 + +2: + std %d6, [%o0 + 8] + sub %o1, 8, %o1 + add %o0, 16, %o0 + + +.endmedloop: + ! Currently, o1 is pointing to the next double-aligned byte in SRC + ! The 8 bytes starting at [o1-8] are available in d0 + ! At least one, and possibly all, of these need to be written. + + prefetch [%o1 + (8 * BLOCK_SIZE)], #one_read + cmp %o2, BLOCK_SIZE + bgu %ncc, .large ! otherwise, less than 16 bytes left + +#if 0 + + /* This code will use partial stores. */ + + mov %g0, %o5 + and %o3, 7, %o3 ! Number of bytes needed to completely + ! fill %d0 with good (unwritten) data. + + subcc %o2, 8, %o2 ! update count (maybe too much) + movl %ncc, %o2, %o5 + addcc %o3, %o5, %o5 ! extra bytes we can stuff into %d0 + sub %o3, %o5, %o3 ! update o3 (# bad bytes in %d0) + + bz %ncc, 2f + alignaddr %o3, %g0, %g0 ! set GSR.ALIGN + +1: + deccc %o5 + ldda [%o1]ASI_FL8_P, %d2 + inc %o1 + bgu %ncc, 1b + bshuffle %d0, %d2, %d0 ! shifts d0 left 1 byte and or's in d2 + +2: + not %o3 + faligndata %d0, %d0, %d0 ! shift bytes to the left + and %o3, 7, %o3 ! last byte to be stored in [%o0+%o3] + edge8n %g0, %o3, %o5 + stda %d0, [%o0]%o5, ASI_PST8_P + brlez %o2, .mediumexit + add %o0, %o3, %o0 ! update DST to last stored byte +3: + inc %o0 + deccc %o2 + ldub [%o1], %o3 + stb %o3, [%o0] + bgu %ncc, 3b + inc %o1 + +#else + + andcc %o3, 7, %o5 ! Number of bytes needed to completely + ! fill %d0 with good (unwritten) data. + bz %ncc, 2f + sub %o5, 8, %o3 ! -(number of good bytes in %d0) + cmp %o2, 8 + bl,a %ncc, 3f ! Not enough bytes to fill %d0 + add %o1, %o3, %o1 ! Back up %o1 + +1: + deccc %o5 + ldda [%o1]ASI_FL8_P, %d2 + inc %o1 + bgu %ncc, 1b + bshuffle %d0, %d2, %d0 ! shifts d0 left 1 byte and or's in d2 + +2: + subcc %o2, 8, %o2 + std %d0, [%o0] + bz %ncc, .mediumexit + add %o0, 8, %o0 +3: + ldub [%o1], %o3 + deccc %o2 + inc %o1 + stb %o3, [%o0] + bgu %ncc, 3b + inc %o0 +#endif + +.mediumexit: + wr %o4, %g0, %fprs ! fprs = o4 restore fprs + retl + mov %g1, %o0 + + + .align 8 +.large: + + ! %o0 I/O DST is 64-byte aligned + ! %o1 I/O 8-byte aligned (and we've set GSR.ALIGN) + ! %d0 I/O already loaded with SRC data from [%o1-8] + ! %o2 I/O count (number of bytes that need to be written) + ! %o3 I Not written. If zero, then SRC is double aligned. + ! %o4 I Not written. Holds fprs. + ! %o5 O The number of doubles that remain to be written. + + ! Load the rest of the current block + ! Recall that %o1 is further into SRC than %o0 is into DST + + prefetch [%o1 + (9 * BLOCK_SIZE)], #one_read + ldd [%o1], %f2 + ldd [%o1 + 0x8], %f4 + faligndata %f0, %f2, %f32 + ldd [%o1 + 0x10], %f6 + faligndata %f2, %f4, %f34 + ldd [%o1 + 0x18], %f8 + faligndata %f4, %f6, %f36 + ldd [%o1 + 0x20], %f10 + or %g0, -8, %o5 ! if %o3 >= 0, %o5 = -8 + faligndata %f6, %f8, %f38 + ldd [%o1 + 0x28], %f12 + movrlz %o3, %g0, %o5 ! if %o3 < 0, %o5 = 0 (needed later) + faligndata %f8, %f10, %f40 + ldd [%o1 + 0x30], %f14 + faligndata %f10, %f12, %f42 + ldd [%o1 + 0x38], %f0 + sub %o2, BLOCK_SIZE, %o2 ! update count + add %o1, BLOCK_SIZE, %o1 ! update SRC + + ! This point is 32-byte aligned since 24 instructions appear since + ! the previous alignment directive. + + + ! Main loop. Write previous block. Load rest of current block. + ! Some bytes will be loaded that won't yet be written. +1: + ldd [%o1], %f2 + faligndata %f12, %f14, %f44 + ldd [%o1 + 0x8], %f4 + faligndata %f14, %f0, %f46 + stda %f32, [%o0]ASI_BLK_P + sub %o2, BLOCK_SIZE, %o2 ! update count + ldd [%o1 + 0x10], %f6 + faligndata %f0, %f2, %f32 + ldd [%o1 + 0x18], %f8 + faligndata %f2, %f4, %f34 + ldd [%o1 + 0x20], %f10 + faligndata %f4, %f6, %f36 + ldd [%o1 + 0x28], %f12 + faligndata %f6, %f8, %f38 + ldd [%o1 + 0x30], %f14 + prefetch [%o1 + (2 * BLOCK_SIZE)], #n_reads + faligndata %f8, %f10, %f40 + ldd [%o1 + 0x38], %f0 + faligndata %f10, %f12, %f42 + prefetch [%o1 + (10 * BLOCK_SIZE)], #one_read + add %o0, BLOCK_SIZE, %o0 ! update DST + cmp %o2, BLOCK_SIZE + 8 + ! second prefetch important to correct for occasional dropped + prefetch [%o1 + (6 * BLOCK_SIZE) + 8], #one_read + bgu,pt %ncc, 1b + add %o1, BLOCK_SIZE, %o1 ! update SRC + + faligndata %f12, %f14, %f44 + faligndata %f14, %f0, %f46 + stda %f32, [%o0]ASI_BLK_P ! store 64 bytes, bypass cache + cmp %o2, BLOCK_SIZE + bne %ncc, 2f ! exactly 1 block remaining? + add %o0, BLOCK_SIZE, %o0 ! update DST + brz,a %o3, 3f ! is SRC double aligned? + ldd [%o1], %f2 + +2: + add %o5, %o2, %o5 ! %o5 was already set to 0 or -8 + add %o5, %o3, %o5 + + membar #StoreLoad|#StoreStore + + ba .beginmedloop + andn %o5, 7, %o5 ! 8 byte aligned count + + + ! This is when there is exactly 1 block remaining and SRC is aligned +3: + ldd [%o1 + 0x8], %f4 + ldd [%o1 + 0x10], %f6 + fsrc1 %f0, %f32 + ldd [%o1 + 0x18], %f8 + fsrc1 %f2, %f34 + ldd [%o1 + 0x20], %f10 + fsrc1 %f4, %f36 + ldd [%o1 + 0x28], %f12 + fsrc1 %f6, %f38 + ldd [%o1 + 0x30], %f14 + fsrc1 %f8, %f40 + fsrc1 %f10, %f42 + fsrc1 %f12, %f44 + fsrc1 %f14, %f46 + stda %f32, [%o0]ASI_BLK_P + membar #StoreLoad|#StoreStore + wr %o4, 0, %fprs + retl + mov %g1, %o0 + + SET_SIZE(memcpy) diff --git a/usr/src/lib/libc_psr/sun4u-opl/sparc/Makefile b/usr/src/lib/libc_psr/sun4u-opl/sparc/Makefile new file mode 100644 index 0000000000..2eb91a6117 --- /dev/null +++ b/usr/src/lib/libc_psr/sun4u-opl/sparc/Makefile @@ -0,0 +1,70 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (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 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# Platform specific Makefile for libc_psr. +# +PLATFORM = SUNW,SPARC-Enterprise +ALT_PLAT = sun4u-opl + +COMPAT_PLAT = sun4u-us3 +CLASS = 32 + +OBJECTS = memcpy.o memset.o memcmp.o + +include ../Makefile.com + +MAPDIR= ../../spec/$(ALT_PLAT)/$(MACH) +MAPFILE= $(MAPDIR)/mapfile-$(MACH) +MAPFILES= $(MAPFILE) $(MAPFILE-FLTR) +MAPOPTS= $(MAPFILES:%=-M %) +DYNFLAGS += $(MAPOPTS) +CLOBBERFILES += $(MAPFILE) +ASFLAGS += -xarch=v8plusb + +# Redefine shared object build rule to use $(LD) directly (this avoids .init +# and .fini sections being added). + +BUILD.SO= $(LD) -o $@ -G $(DYNFLAGS) $(PICS) $(LDLIBS) + +$(DYNLIB): $(MAPFILES) + +$(MAPFILE): + @cd $(MAPDIR); $(MAKE) `basename $@` + +.KEEP_STATE: + +MODULE = libc_psr.so.1 +LIBC_PSR_DIR = $(ROOT_PSM_LIB_DIR) +LIBC_PSR_LIB = $(LIBC_PSR_DIR)/$(MODULE) + +$(LIBC_PSR_DIRS): + -$(INS.dir.root.bin) + +all: $(LIBS) + +install: all $(LIBC_PSR_DIR) $(ROOT_PSM_LIBS) + +include ../../Makefile.targ diff --git a/usr/src/lib/libc_psr/sun4u-opl/sparcv9/Makefile b/usr/src/lib/libc_psr/sun4u-opl/sparcv9/Makefile new file mode 100644 index 0000000000..7c6de5d904 --- /dev/null +++ b/usr/src/lib/libc_psr/sun4u-opl/sparcv9/Makefile @@ -0,0 +1,73 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (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 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# Platform specific Makefile for libc_psr. +# +PLATFORM = SUNW,SPARC-Enterprise +ALT_PLAT = sun4u-opl +COMPAT_PLAT = sun4u-us3 +CLASS = 64 + +OBJECTS = memcpy.o memset.o memcmp.o + +include ../Makefile.com + +MAPDIR= ../../spec/$(ALT_PLAT)/$(MACH64) +MAPFILE= $(MAPDIR)/mapfile-$(MACH64) +MAPFILES= $(MAPFILE) $(MAPFILE-FLTR) +MAPOPTS= $(MAPFILES:%=-M %) +DYNFLAGS += $(MAPOPTS) +CLOBBERFILES += $(MAPFILE) + +ASDEFS += -D__sparcv9 +ASFLAGS += -xarch=v9b + +include $(SRC)/Makefile.master.64 + +# Redefine shared object build rule to use $(LD) directly (this avoids .init +# and .fini sections being added). + +BUILD.SO= $(LD) -o $@ -G $(DYNFLAGS) $(PICS) $(LDLIBS) + +$(DYNLIB): $(MAPFILES) + +$(MAPFILE): + @cd $(MAPDIR); $(MAKE) `basename $@` + +.KEEP_STATE: + +MODULE = libc_psr.so.1 +LIBC_PSR64_DIR = $(ROOT_PSM_LIB_DIR)/$(MACH64) +LIBC_PSR64_LIB = $(LIBC_PSR64_DIR)/$(MODULE) + +$(LIBC_PSR64_DIRS): + -$(INS.dir.root.bin) + +all: $(LIBS) + +install: all $(LIBC_PSR64_DIR) $(ROOT_PSM_LIB64_DIR)/$(LIBS) + +include ../../Makefile.targ diff --git a/usr/src/lib/libdscp/Makefile b/usr/src/lib/libdscp/Makefile new file mode 100644 index 0000000000..8eff9de752 --- /dev/null +++ b/usr/src/lib/libdscp/Makefile @@ -0,0 +1,62 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (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 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# lib/libdscp/Makefile +# +#ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.lib + +SUBDIRS= spec .WAIT sparc svc + +all := TARGET= all +install := TARGET= install +clean := TARGET= clean +clobber := TARGET= clobber +lint := TARGET= lint + +# definitions for install_h target +HDRS= libdscp.h +ROOTHDRDIR= $(ROOT)/usr/include +ROOTHDRS= $(HDRS:%=$(ROOTHDRDIR)/%) +CHECKHDRS= $(HDRS:%.h=%.check) + +.KEEP_STATE: + +all install clean clobber lint: $(SUBDIRS) + +# install rule for install_h target + +$(ROOTHDRDIR)/%: % + $(INS.file) + +install_h: $(ROOTHDRS) + +check: $(CHECKHDRS) + +spec sparc svc: FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: diff --git a/usr/src/lib/libdscp/Makefile.com b/usr/src/lib/libdscp/Makefile.com new file mode 100644 index 0000000000..5c9e76421c --- /dev/null +++ b/usr/src/lib/libdscp/Makefile.com @@ -0,0 +1,68 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (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 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# lib/libdscp/Makefile.com +# +#ident "%Z%%M% %I% %E% SMI" +# + +LIBRARY= libdscp.a +VERS= .1 +MANIFEST= dscp.xml +OBJECTS= libdscp.o + +include ../../Makefile.lib +include ../../Makefile.rootfs + +LIBS = $(DYNLIB) $(LINTLIB) +LDLIBS += -lc -lsocket -lnsl +$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC) + +SRCDIR = .. +MAPDIR = ../spec/$(TRANSMACH) +SPECMAPFILE = $(MAPDIR)/mapfile + +CPPFLAGS += -I.. +CFLAGS += $(CCVERBOSE) + +.KEEP_STATE: + +# Defintions for installation of the library +USR_PLAT_DIR = $(ROOT)/usr/platform +USR_PSM_DIR = $(USR_PLAT_DIR)/SUNW,SPARC-Enterprise +USR_PSM_LIB_DIR = $(USR_PSM_DIR)/lib +ROOTLIBDIR= $(USR_PSM_LIB_DIR) + +$(ROOTLIBDIR): + $(INS.dir) + +.KEEP_STATE: + +all: $(LIBS) + +install: all .WAIT $(ROOTLIBDIR) $(ROOTLIB) + +lint: lintcheck + +include ../../Makefile.targ diff --git a/usr/src/lib/libdscp/libdscp.c b/usr/src/lib/libdscp/libdscp.c new file mode 100644 index 0000000000..63c49383d0 --- /dev/null +++ b/usr/src/lib/libdscp/libdscp.c @@ -0,0 +1,542 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (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 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <sys/socket.h> +#include <sys/sockio.h> +#include <net/if.h> +#include <net/pfkeyv2.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <libdscp.h> + +/* + * Define the file containing the configured DSCP interface name + */ +#define DSCP_CONFIGFILE "/var/run/dscp.ifname" + +/* + * Forward declarations + */ +static int get_ifname(char *); +static int convert_ipv6(struct sockaddr_in6 *, uint32_t *); +static int convert_ipv4(struct sockaddr_in *, + struct sockaddr_in6 *, int *); + +/* + * dscpBind() + * + * Properly bind a socket to the local DSCP address. + * Optionally bind it to a specific port. + */ +int +dscpBind(int domain_id, int sockfd, int port) +{ + int len; + int len6; + int error; + struct sockaddr_in addr; + struct sockaddr_in6 addr6; + + /* Check arguments */ + if ((sockfd < 0) || (port >= IPPORT_RESERVED)) { + return (DSCP_ERROR_INVALID); + } + + /* Get the local DSCP address used to communicate with the SP */ + error = dscpAddr(domain_id, DSCP_ADDR_LOCAL, + (struct sockaddr *)&addr, &len); + + if (error != DSCP_OK) { + return (error); + } + + /* + * If the caller specified a port, then update the socket address + * to also specify the same port. + */ + if (port != 0) { + addr.sin_port = htons(port); + } + + /* + * Bind the socket. + * + * EINVAL means it is already bound. + * EAFNOSUPPORT means try again using IPv6. + */ + if (bind(sockfd, (struct sockaddr *)&addr, len) < 0) { + + if (errno == EINVAL) { + return (DSCP_ERROR_ALREADY); + } + + if (errno != EAFNOSUPPORT) { + return (DSCP_ERROR); + } + + if (convert_ipv4(&addr, &addr6, &len6) < 0) { + return (DSCP_ERROR); + } + + if (bind(sockfd, (struct sockaddr *)&addr6, len6) < 0) { + if (errno == EINVAL) { + return (DSCP_ERROR_ALREADY); + } + return (DSCP_ERROR); + } + } + + return (DSCP_OK); +} + +/* + * dscpSecure() + * + * Enable DSCP security mechanisms on a socket. + * + * DSCP uses the IPSec AH (Authentication Headers) protocol with + * the SHA-1 algorithm. + */ +/*ARGSUSED*/ +int +dscpSecure(int domain_id, int sockfd) +{ + ipsec_req_t opt; + + /* Check arguments */ + if (sockfd < 0) { + return (DSCP_ERROR_INVALID); + } + + /* + * Construct a socket option argument that specifies the protocols + * and algorithms required for DSCP's use of IPSec. + */ + (void) memset(&opt, 0, sizeof (opt)); + opt.ipsr_ah_req = IPSEC_PREF_REQUIRED; + opt.ipsr_esp_req = IPSEC_PREF_NEVER; + opt.ipsr_self_encap_req = IPSEC_PREF_NEVER; + opt.ipsr_auth_alg = SADB_AALG_MD5HMAC; + + /* + * Set the socket option that enables IPSec usage upon the socket, + * using the socket option argument constructed above. + */ + if (setsockopt(sockfd, IPPROTO_IP, IP_SEC_OPT, (const char *)&opt, + sizeof (opt)) < 0) { + return (DSCP_ERROR); + } + + return (DSCP_OK); +} + +/* + * dscpAuth() + * + * Test whether a connection should be accepted or refused. + * The address of the connection request is compared against + * the remote address of the specified DSCP link. + */ +/*ARGSUSED*/ +int +dscpAuth(int domain_id, struct sockaddr *saddr, int len) +{ + int dlen; + struct sockaddr daddr; + struct sockaddr_in *sin; + struct sockaddr_in6 *sin6; + uint32_t spaddr; + uint32_t reqaddr; + + /* Check arguments */ + if (saddr == NULL) { + return (DSCP_ERROR_INVALID); + } + + /* + * Get the remote IP address associated with the SP. + */ + if (dscpAddr(0, DSCP_ADDR_REMOTE, &daddr, &dlen) != DSCP_OK) { + return (DSCP_ERROR_DB); + } + + /* + * Convert the request's address to a 32-bit integer. + * + * This may require a conversion if the caller is + * using an IPv6 socket. + */ + switch (saddr->sa_family) { + case AF_INET: + /* LINTED E_BAD_PTR_CAST_ALIGN */ + sin = (struct sockaddr_in *)saddr; + reqaddr = ntohl(*((uint32_t *)&(sin->sin_addr))); + break; + case AF_INET6: + /* LINTED E_BAD_PTR_CAST_ALIGN */ + sin6 = (struct sockaddr_in6 *)saddr; + if (convert_ipv6(sin6, &reqaddr) < 0) { + return (DSCP_ERROR); + } + break; + default: + return (DSCP_ERROR); + } + + /* + * Convert the SP's address to a 32-bit integer. + */ + /* LINTED E_BAD_PTR_CAST_ALIGN */ + sin = (struct sockaddr_in *)&daddr; + spaddr = ntohl(*((uint32_t *)&(sin->sin_addr))); + + /* + * Compare the addresses. Reject if they don't match. + */ + if (reqaddr != spaddr) { + return (DSCP_ERROR_REJECT); + } + + return (DSCP_OK); +} + +/* + * dscpAddr() + * + * Get the addresses associated with a specific DSCP link. + */ +/*ARGSUSED*/ +int +dscpAddr(int domain_id, int which, struct sockaddr *saddr, int *lenp) +{ + int error; + int sockfd; + uint64_t flags; + char ifname[LIFNAMSIZ]; + struct lifreq lifr; + + /* Check arguments */ + if (((saddr == NULL) || (lenp == NULL)) || + ((which != DSCP_ADDR_LOCAL) && (which != DSCP_ADDR_REMOTE))) { + return (DSCP_ERROR_INVALID); + } + + /* + * Get the DSCP interface name. + */ + if (get_ifname(ifname) != 0) { + return (DSCP_ERROR_DB); + } + + /* + * Open a socket. + */ + if ((sockfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { + return (DSCP_ERROR_DB); + } + + /* + * Get the interface flags. + */ + (void) memset(&lifr, 0, sizeof (lifr)); + (void) strncpy(lifr.lifr_name, ifname, sizeof (lifr.lifr_name)); + if (ioctl(sockfd, SIOCGLIFFLAGS, (char *)&lifr) < 0) { + (void) close(sockfd); + return (DSCP_ERROR_DB); + } + flags = lifr.lifr_flags; + + /* + * The interface must be a PPP link using IPv4. + */ + if (((flags & IFF_IPV4) == 0) || + ((flags & IFF_POINTOPOINT) == 0)) { + (void) close(sockfd); + return (DSCP_ERROR_DB); + } + + /* + * Get the local or remote address, depending upon 'which'. + */ + (void) strncpy(lifr.lifr_name, ifname, sizeof (lifr.lifr_name)); + if (which == DSCP_ADDR_LOCAL) { + error = ioctl(sockfd, SIOCGLIFADDR, (char *)&lifr); + } else { + error = ioctl(sockfd, SIOCGLIFDSTADDR, (char *)&lifr); + } + if (error < 0) { + (void) close(sockfd); + return (DSCP_ERROR_DB); + } + + /* + * Copy the sockaddr value back to the caller. + */ + (void) memset(saddr, 0, sizeof (struct sockaddr)); + (void) memcpy(saddr, &lifr.lifr_addr, sizeof (struct sockaddr_in)); + *lenp = sizeof (struct sockaddr_in); + + (void) close(sockfd); + return (DSCP_OK); +} + +/* + * dscpIdent() + * + * Determine the domain of origin associated with a sockaddr. + * (Map a sockaddr to a domain ID.) + * + * In the Solaris version, the remote socket address should always + * be the SP. A call to dscpAuth() is used to confirm this, and + * then DSCP_IDENT_SP is returned as a special domain ID. + */ +int +dscpIdent(struct sockaddr *saddr, int len, int *domainp) +{ + int error; + + /* Check arguments */ + if ((saddr == NULL) || (domainp == NULL)) { + return (DSCP_ERROR_INVALID); + } + + /* Confirm that the address is the SP */ + error = dscpAuth(0, saddr, len); + if (error != DSCP_OK) { + if (error == DSCP_ERROR_REJECT) { + return (DSCP_ERROR); + } + return (error); + } + + *domainp = DSCP_IDENT_SP; + return (DSCP_OK); +} + +/* + * get_ifname() + * + * Retrieve the interface name used by DSCP. + * It should be available from a file in /var/run. + * + * Returns: 0 upon success, -1 upon failure. + */ +static int +get_ifname(char *ifname) +{ + int i; + int fd; + int len; + int size; + int count; + int end; + int begin; + struct stat stbuf; + + /* + * Initialize the interface name. + */ + (void) memset(ifname, 0, LIFNAMSIZ); + + /* + * Test for a a valid configuration file. + */ + if ((stat(DSCP_CONFIGFILE, &stbuf) < 0) || + (S_ISREG(stbuf.st_mode) == 0) || + (stbuf.st_size > LIFNAMSIZ)) { + return (-1); + } + + /* + * Open the configuration file and read its contents + */ + + if ((fd = open(DSCP_CONFIGFILE, O_RDONLY)) < 0) { + return (-1); + } + + count = 0; + size = stbuf.st_size; + do { + i = read(fd, &ifname[count], size - count); + if (i <= 0) { + (void) close(fd); + return (-1); + } + count += i; + } while (count < size); + + (void) close(fd); + + /* + * Analyze the interface name that was just read, + * and clean it up as necessary. The result should + * be a simple NULL terminated string such as "sppp0" + * with no extra whitespace or other characters. + */ + + /* Detect the beginning of the interface name */ + for (begin = -1, i = 0; i < size; i++) { + if (isalnum(ifname[i]) != 0) { + begin = i; + break; + } + } + + /* Fail if no such beginning was found */ + if (begin < 0) { + return (-1); + } + + /* Detect the end of the interface name */ + for (end = size - 1, i = begin; i < size; i++) { + if (isalnum(ifname[i]) == 0) { + end = i; + break; + } + } + + /* Compute the length of the name */ + len = end - begin; + + /* Remove leading whitespace */ + if (begin > 0) { + (void) memmove(ifname, &ifname[begin], len); + } + + /* Clear out any remaining garbage */ + if (len < size) { + (void) memset(&ifname[len], 0, size - len); + } + + return (0); +} + +/* + * convert_ipv6() + * + * Converts an IPv6 socket address into an equivalent IPv4 + * address. The conversion is to a 32-bit integer because + * that is sufficient for how libdscp uses IPv4 addresses. + * + * The IPv4 address is additionally converted from network + * byte order to host byte order. + * + * Returns: 0 upon success, with 'addrp' updated. + * -1 upon failure, with 'addrp' undefined. + */ +static int +convert_ipv6(struct sockaddr_in6 *addr6, uint32_t *addrp) +{ + uint32_t addr; + char *ipv4str; + char ipv6str[INET6_ADDRSTRLEN]; + + /* + * Convert the IPv6 address into a string. + */ + if (inet_ntop(AF_INET6, &addr6->sin6_addr, ipv6str, + sizeof (ipv6str)) == NULL) { + return (-1); + } + + /* + * Use the IPv6 string to construct an IPv4 string. + */ + if ((ipv4str = strrchr(ipv6str, ':')) != NULL) { + ipv4str++; + } else { + return (-1); + } + + /* + * Convert the IPv4 string into a 32-bit integer. + */ + if (inet_pton(AF_INET, ipv4str, &addr) <= 0) { + return (-1); + } + + *addrp = ntohl(addr); + return (0); +} + +/* + * convert_ipv4() + * + * Convert an IPv4 socket address into an equivalent IPv6 address. + * + * Returns: 0 upon success, with 'addr6' and 'lenp' updated. + * -1 upon failure, with 'addr6' and 'lenp' undefined. + */ +static int +convert_ipv4(struct sockaddr_in *addr, struct sockaddr_in6 *addr6, int *lenp) +{ + int len; + uint32_t ipv4addr; + char ipv4str[INET_ADDRSTRLEN]; + char ipv6str[INET6_ADDRSTRLEN]; + + /* + * Convert the IPv4 socket address into a string. + */ + ipv4addr = *((uint32_t *)&(addr->sin_addr)); + if (inet_ntop(AF_INET, &ipv4addr, ipv4str, sizeof (ipv4str)) == NULL) { + return (-1); + } + + /* + * Use the IPv4 string to construct an IPv6 string. + */ + len = snprintf(ipv6str, INET6_ADDRSTRLEN, "::ffff:%s", ipv4str); + if (len >= INET6_ADDRSTRLEN) { + return (-1); + } + + /* + * Convert the IPv6 string to an IPv6 socket address. + */ + (void) memset(addr6, 0, sizeof (*addr6)); + addr6->sin6_family = AF_INET6; + addr6->sin6_port = addr->sin_port; + if (inet_pton(AF_INET6, ipv6str, &addr6->sin6_addr) <= 0) { + return (-1); + } + + *lenp = sizeof (struct sockaddr_in6); + + return (0); +} diff --git a/usr/src/lib/libdscp/libdscp.h b/usr/src/lib/libdscp/libdscp.h new file mode 100644 index 0000000000..aa3b76cdde --- /dev/null +++ b/usr/src/lib/libdscp/libdscp.h @@ -0,0 +1,72 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (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 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _LIBDSCP_H +#define _LIBDSCP_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/socket.h> +#include <netinet/in.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * DSCP Error Codes + */ +typedef enum { + DSCP_OK = 0, /* Success */ + DSCP_ERROR, /* General Error */ + DSCP_ERROR_ALREADY, /* Socket Already Bound */ + DSCP_ERROR_INVALID, /* Invalid Arguments */ + DSCP_ERROR_NOENT, /* Lookup Failure From dscpIdent() */ + DSCP_ERROR_DB, /* Error Reading Database */ + DSCP_ERROR_REJECT /* Rejection From dscpAuth() */ +} dscp_err_t; + +/* + * Possible values for the 'which' parameter to dscpAddr(). + */ +#define DSCP_ADDR_LOCAL (1) /* Get the domain's local IP address */ +#define DSCP_ADDR_REMOTE (2) /* Get the SP's remote IP address */ + +/* + * Define a special value used to represent the SP as a domain ID. + */ +#define DSCP_IDENT_SP (-1) + +int dscpBind(int domain, int sockfd, int port); +int dscpSecure(int domain, int sockfd); +int dscpAuth(int domain, struct sockaddr *saddr, int len); +int dscpAddr(int domain, int which, struct sockaddr *saddr, int *lenp); +int dscpIdent(struct sockaddr *saddr, int len, int *domainp); + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBDSCP_H */ diff --git a/usr/src/lib/libdscp/llib-ldscp b/usr/src/lib/libdscp/llib-ldscp new file mode 100644 index 0000000000..b4ce6b9926 --- /dev/null +++ b/usr/src/lib/libdscp/llib-ldscp @@ -0,0 +1,32 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (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 + */ +/*LINTLIBRARY*/ +/*PROTOLIB1*/ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + * usr/src/lib/libdscp/llib-ldscp + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <libdscp.h> diff --git a/usr/src/lib/libdscp/sparc/Makefile b/usr/src/lib/libdscp/sparc/Makefile new file mode 100644 index 0000000000..22bf606d7a --- /dev/null +++ b/usr/src/lib/libdscp/sparc/Makefile @@ -0,0 +1,35 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (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 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# lib/libdscp/sparc/Makefile +# +#ident "%Z%%M% %I% %E% SMI" +# + +MAPDIR= ../spec/sparc +include ../Makefile.com + +all: $(LIBS) + +install: all $(ROOTLIBS) $(ROOTLINKS) diff --git a/usr/src/lib/libdscp/spec/Makefile b/usr/src/lib/libdscp/spec/Makefile new file mode 100644 index 0000000000..048c9a5306 --- /dev/null +++ b/usr/src/lib/libdscp/spec/Makefile @@ -0,0 +1,61 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (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 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# lib/libdscp/spec/Makefile +# +#ident "%Z%%M% %I% %E% SMI" +# + +SUBDIRS= sparc + +all := TARGET= all +install := TARGET= install +clean := TARGET= clean +clobber := TARGET= clobber +lint := TARGET= lint + +.KEEP_STATE: + +all install clean clobber: ${SUBDIRS} + +${SUBDIRS}: FRC + @cd $@; pwd; ${MAKE} ${TARGET} + +# +# This will make sure that any target not +# explicitly defined will not break the build. +# +# XXX pmake on intel does not like the following rules +# %: ignore_and_exit_quietly +# ignore_and_exit_quietly: +# +# So here it is manually +# +IGNORE= _msg catalog install_h delete \ + package tcov debug private_t \ + check analyze test dynamic lint + +${IGNORE}: + +FRC: diff --git a/usr/src/lib/libdscp/spec/Makefile.targ b/usr/src/lib/libdscp/spec/Makefile.targ new file mode 100644 index 0000000000..c9f02d8818 --- /dev/null +++ b/usr/src/lib/libdscp/spec/Makefile.targ @@ -0,0 +1,35 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (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 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# lib/libdscp/spec/Makefile.targ +# +#ident "%Z%%M% %I% %E% SMI" +# + +LIBRARY = libdscp.a +VERS = .1 + +OBJECTS = libdscp.o + +SPECCPP = -I../.. diff --git a/usr/src/lib/libdscp/spec/libdscp.spec b/usr/src/lib/libdscp/spec/libdscp.spec new file mode 100644 index 0000000000..91cdd7c540 --- /dev/null +++ b/usr/src/lib/libdscp/spec/libdscp.spec @@ -0,0 +1,56 @@ +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (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 +# +# lib/libdscp/spec/libdscp.spec +# +#ident "%Z%%M% %I% %E% SMI" + +function dscpBind +include <libdscp.h> +declaration int dscpBind(int, int, int) +version SUNWprivate_1.1 +end + +function dscpSecure +include <libdscp.h> +declaration int dscpSecure(int, int) +version SUNWprivate_1.1 +end + +function dscpAuth +include <libdscp.h> +declaration int dscpAuth(int, struct sockaddr *, int) +version SUNWprivate_1.1 +end + +function dscpAddr +include <libdscp.h> +declaration int dscpAddr(int, int, struct sockaddr *, int *) +version SUNWprivate_1.1 +end + +function dscpIdent +include <libdscp.h> +declaration int dscpIdent(struct sockaddr *, int, int *) +version SUNWprivate_1.1 +end diff --git a/usr/src/lib/libdscp/spec/sparc/Makefile b/usr/src/lib/libdscp/spec/sparc/Makefile new file mode 100644 index 0000000000..79205aad21 --- /dev/null +++ b/usr/src/lib/libdscp/spec/sparc/Makefile @@ -0,0 +1,38 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (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 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# lib/libdscp/spec/sparc/Makefile +# +#ident "%Z%%M% %I% %E% SMI" +# + +.KEEP_STATE: + +include ../Makefile.targ + +include $(SRC)/lib/Makefile.lib + +include $(SRC)/lib/Makefile.spec + +install: $(ROOTABILIB) diff --git a/usr/src/lib/libdscp/spec/versions b/usr/src/lib/libdscp/spec/versions new file mode 100644 index 0000000000..bbebe2a784 --- /dev/null +++ b/usr/src/lib/libdscp/spec/versions @@ -0,0 +1,31 @@ +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (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 +# +# usr/src/lib/libdscp/spec/versions +# +#ident "%Z%%M% %I% %E% SMI" +# + +sparc { + SUNWprivate_1.1; +} diff --git a/usr/src/lib/libdscp/svc/Makefile b/usr/src/lib/libdscp/svc/Makefile new file mode 100644 index 0000000000..8a34b10cca --- /dev/null +++ b/usr/src/lib/libdscp/svc/Makefile @@ -0,0 +1,56 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (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 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# lib/libdscp/svc/Makefile.com +# +#ident "%Z%%M% %I% %E% SMI" +# + +MANIFEST= dscp.xml +SVCMETHOD= svc-dscp + +include ../../../cmd/Makefile.cmd + +.KEEP_STATE: + +# definitions for installing the manifest +ROOTMANIFESTDIR = $(ROOTSVCPLATFORMSUN4U) +$(ROOTMANIFEST) := FILEMODE = 0444 + +# definitions for installing the PPP options +OPTIONS = dscp.ppp.options +ROOTOPTIONSDIR = $(ROOT)/usr/platform/SUNW,SPARC-Enterprise/lib +ROOTOPTIONS = $(OPTIONS:%=$(ROOTOPTIONSDIR)/%) + +$(ROOTOPTIONSDIR): + $(INS.dir) + +$(ROOTOPTIONSDIR)/%: % + $(INS.file) + +all clean clobber lint: + +install: $(ROOTMANIFEST) $(ROOTSVCMETHOD) $(ROOTOPTIONS) + +check: $(CHKMANIFEST) diff --git a/usr/src/lib/libdscp/svc/dscp.ppp.options b/usr/src/lib/libdscp/svc/dscp.ppp.options new file mode 100644 index 0000000000..d46df31de3 --- /dev/null +++ b/usr/src/lib/libdscp/svc/dscp.ppp.options @@ -0,0 +1,112 @@ +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (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 +# +# dscp.ppp.options +# +#ident "%Z%%M% %I% %E% SMI" +# + +# +# These are options for running pppd(1M) to provide a DSCP +# link between a service processor and a domain in OPL. All +# options are explicitly set here so that site customizations +# of the global options files will not affect DSCP. +# + +# +# Generic pppd options. +# +persist +noplink +lock +nolog +maxfail 0 +holdoff 5 +noproxyarp +linkname dscp + +# +# Physical link properties. +# +sync +local +nocrtscts +nocdtrcts +default-fcs +mtu 1500 +mru 1500 + +# +# Configure LCP. +# +passive +noendpoint +lcp-echo-failure 6 +lcp-echo-interval 5 +lcp-max-configure 10 +lcp-max-failure 10 +lcp-max-terminate 3 +lcp-restart 3 + +# +# Configure the IPv4 NCP. +# IP addresses are given by the peer. +# +0:0 +noipv6 +noipdefault +nodefaultroute +ipcp-accept-local +ipcp-accept-remote +ipcp-max-configure 10 +ipcp-max-failure 10 +ipcp-max-terminate 3 +ipcp-restart 3 + +# +# Disable all authentication. +# +noauth +noident +nopam +refuse-pap +refuse-chap +refuse-mschap +refuse-mschapv2 + +# +# Disable all compression. +# +novj +noccp +nopcomp +noaccomp +nobsdcomp + +# +# Disable all scripts. +# +init /bin/true +welcome /bin/true +connect /bin/true +disconnect /bin/true diff --git a/usr/src/lib/libdscp/svc/dscp.xml b/usr/src/lib/libdscp/svc/dscp.xml new file mode 100644 index 0000000000..f3f6565098 --- /dev/null +++ b/usr/src/lib/libdscp/svc/dscp.xml @@ -0,0 +1,121 @@ +<?xml version="1.0"?> +<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1"> +<!-- + Copyright 2006 Sun Microsystems, Inc. All rights reserved. + Use is subject to license terms. + + CDDL HEADER START + + The contents of this file are subject to the terms of the + Common Development and Distribution License (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 + + ident "%Z%%M% %I% %E% SMI" + + NOTE: This service manifest is not editable; its contents will + be overwritten by package or patch operations, including + operating system upgrade. Make customizations in a different + file. +--> + +<service_bundle type='manifest' name='SUNW:dscp'> + +<service + name='platform/sun4u/dscp' + type='service' + version='1'> + + <create_default_instance enabled='false' /> + + <single_instance /> + + <dependency + name='network' + grouping='require_any' + restart_on='error' + type='service'> + <service_fmri value='svc:/milestone/network' /> + </dependency> + + <dependency + name='local-filesystems' + type='service' + grouping='require_all' + restart_on='none'> + <service_fmri value='svc:/system/filesystem/local' /> + </dependency> + + <dependency + name='sckmd' + type='service' + grouping='optional_all' + restart_on='none'> + <service_fmri value='svc:/platform/sun4u/sckmd:default' /> + </dependency> + + <dependent + name='dcs' + grouping='optional_all' + restart_on='none'> + <service_fmri value='svc:/platform/sun4u/dcs:default' /> + </dependent> + + <dependent + name='fmd' + grouping='optional_all' + restart_on='none'> + <service_fmri value='svc:/system/fmd:default' /> + </dependent> + + <exec_method + type='method' + name='start' + exec='/lib/svc/method/svc-dscp %m' + timeout_seconds='60' /> + + <exec_method + type='method' + name='refresh' + exec='/lib/svc/method/svc-dscp %m' + timeout_seconds='60' /> + + <exec_method + type='method' + name='stop' + exec='/lib/svc/method/svc-dscp %m' + timeout_seconds='60' /> + + <property_group name='application' type='framework'> + <stability value='Evolving' /> + <propval name='auto_enable' type='boolean' value='true' /> + </property_group> + + <stability value='Evolving' /> + + <template> + <common_name> + <loctext xml:lang='C'> + DSCP Service + </loctext> + </common_name> + <documentation> + <manpage title='??' section='1M' + manpath='/usr/share/man' /> + </documentation> + </template> +</service> + +</service_bundle> diff --git a/usr/src/lib/libdscp/svc/svc-dscp b/usr/src/lib/libdscp/svc/svc-dscp new file mode 100644 index 0000000000..f8f79e81a2 --- /dev/null +++ b/usr/src/lib/libdscp/svc/svc-dscp @@ -0,0 +1,111 @@ +#!/bin/sh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (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 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +# +# Start script for the SPARC-Enterprise DSCP service. +# + +. /lib/svc/share/smf_include.sh + +OPL=SUNW,SPARC-Enterprise +FJOPL=FJSV,SPARC-Enterprise +TMPOPL=SUNW,OPL-Enterprise +OPL_LIB=/usr/platform/${OPL}/lib +DM2S_DEVICE=/dev/dm2s0 +PPP_OPTIONS=${OPL_LIB}/dscp.ppp.options +DSCP_IFNAME=/var/run/dscp.ifname +PRTDSCP=/usr/platform/${OPL}/sbin/prtdscp +PLATFORM=`/sbin/uname -i` +SLEEP=/bin/sleep +PKILL=/bin/pkill + +LD_LIBRARY_PATH=/lib:${OPL_LIB}; export LD_LIBRARY_PATH + +# This service can only run on OPL. +if [ "${PLATFORM}" != "${OPL}" -a \ + "${PLATFORM}" != "${FJOPL}" -a \ + "${PLATFORM}" != "${TMPOPL}" ]; then + + exit $SMF_EXIT_ERR_CONFIG +fi + +case "$1" in +'start') + + if [ ! -x /usr/bin/pppd ]; then + exit $SMF_EXIT_ERR_CONFIG + fi + + if [ ! -c $DM2S_DEVICE ]; then + exit $SMF_EXIT_ERR_CONFIG + fi + + if [ ! -f $PPP_OPTIONS ]; then + exit $SMF_EXIT_ERR_CONFIG + fi + + SUCCESS=0 + for UNIT in 0 1 2 3 4 5 6 7 8 9; do + /usr/bin/pppd $DM2S_DEVICE unit $UNIT file $PPP_OPTIONS + if [ ! "$?" = "1" ]; then + echo "sppp$UNIT" > $DSCP_IFNAME + SUCCESS=1 + break + fi + done + + if [ $SUCCESS -ne 1 ]; then + exit $SMF_EXIT_ERR_FATAL + fi + + # Wait for the DSCP link to come up, but only for 30 seconds + for RETRY in 0 1 2 3 4 5; do + ${PRTDSCP} >/dev/null 2>&1 + if [ $? -eq 0 ]; then + exit $SMF_EXIT_OK + fi + ${SLEEP} 5 + done + + # Stop pppd before we return failure + ${PKILL} -TERM -f "pppd ${DM2S_DEVICE}" + ${SLEEP} 1 + ${PKILL} -KILL -f "pppd ${DM2S_DEVICE}" + rm -f $DSCP_IFNAME + exit $SMF_EXIT_ERR_FATAL + ;; + +'stop') + # First try SIGTERM and then SIGKILL + ${PKILL} -TERM -f "pppd ${DM2S_DEVICE}" + ${SLEEP} 1 + ${PKILL} -KILL -f "pppd ${DM2S_DEVICE}" + rm -f $DSCP_IFNAME + exit $SMF_EXIT_OK + ;; +esac diff --git a/usr/src/lib/libprtdiag/common/cpu.c b/usr/src/lib/libprtdiag/common/cpu.c index 4248f3415c..b39479f254 100644 --- a/usr/src/lib/libprtdiag/common/cpu.c +++ b/usr/src/lib/libprtdiag/common/cpu.c @@ -2,9 +2,8 @@ * 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. + * Common Development and Distribution License (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. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -59,18 +58,18 @@ * is passed in or the clock-frequency property does not exist, the * function returns 0. */ -int +uint_t get_cpu_freq(Prom_node *pnode) { Prop *prop; - int *value; + uint_t *value; /* find the property */ if ((prop = find_prop(pnode, "clock-frequency")) == NULL) { return (0); } - if ((value = (int *)get_prop_val(prop)) == NULL) { + if ((value = (uint_t *)get_prop_val(prop)) == NULL) { return (0); } diff --git a/usr/src/lib/libprtdiag/inc/libprtdiag.h b/usr/src/lib/libprtdiag/inc/libprtdiag.h index 0354aea6a3..e9361b8e9c 100644 --- a/usr/src/lib/libprtdiag/inc/libprtdiag.h +++ b/usr/src/lib/libprtdiag/inc/libprtdiag.h @@ -2,9 +2,8 @@ * 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. + * Common Development and Distribution License (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. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 1999-2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -91,7 +90,7 @@ void display_platform_specific_header(void); void display_cpu_devices(Sys_tree *); void display_cpus(Board_node *); void display_mid(int mid); -int get_cpu_freq(Prom_node *); +uint_t get_cpu_freq(Prom_node *); int get_ecache_size(Prom_node *); /* diff --git a/usr/src/lib/libprtdiag_psr/sparc/Makefile b/usr/src/lib/libprtdiag_psr/sparc/Makefile index e9d36c0d44..1a5121e2bc 100644 --- a/usr/src/lib/libprtdiag_psr/sparc/Makefile +++ b/usr/src/lib/libprtdiag_psr/sparc/Makefile @@ -2,9 +2,8 @@ # 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. +# Common Development and Distribution License (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. @@ -20,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -29,7 +28,7 @@ PRTDIAG_PLATFORMS= desktop tazmo javelin sunfire starfire serengeti \ montecarlo littleneck starcat daktari cherrystone \ - lw8 snowbird ontario schumacher + lw8 snowbird ontario schumacher opl all := TARGET= all lint := TARGET= lint diff --git a/usr/src/lib/libprtdiag_psr/sparc/opl/Makefile b/usr/src/lib/libprtdiag_psr/sparc/opl/Makefile new file mode 100644 index 0000000000..16eb8eb1e5 --- /dev/null +++ b/usr/src/lib/libprtdiag_psr/sparc/opl/Makefile @@ -0,0 +1,74 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (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 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# +# lib/libprtdiag_psr/sparc/opl/Makefile + +UTSBASE = ../../../../../src/uts + +PLATFORM_OBJECTS= opl.o + +include ../Makefile.com + +IFLAGS += -I$(USR_PLAT_DIR)/sun4u/include -I ../../../libprtdiag/inc +LINTFLAGS += $(IFLAGS) + +LDLIBS += -ldevinfo -lkstat + +#IMPLEMENTED_PLATFORM = SUNW,OPL-Enterprise +#PLATFORM=$(IMPLEMENTED_PLATFORM) +PLATFORM = SUNW,SPARC-Enterprise + +.KEEP_STATE: + +PLATLIBS= $(USR_PLAT_DIR)/$(PLATFORM)/lib/ + +install: all $(USR_PSM_LIBS) + +$(USR_PSM_LIB_DIR): + cd $(UTSBASE)/sun4u/opl; $(MAKE) $(USR_PSM_LIB_DIR) + +# +# install rule +# +$(USR_PSM_LIB_DIR)/%: % $(USR_PSM_LIB_DIR) + $(INS.file) + +POFILE= libprtdiag_psr_opl.po +POFILES= opl.po + +_msg: $(MSGDOMAIN) $(POFILE) + $(RM) $(MSGDOMAIN)/$(POFILE) + $(CP) $(POFILE) $(MSGDOMAIN) + +$(POFILE): $(POFILES) + $(RM) $@ + $(CAT) $(POFILES) > $@ + +$(POFILES): + $(RM) messages.po + $(XGETTEXT) $(XGETFLAGS) `$(GREP) -l gettext common/opl.c` + $(SED) -e '/^# msg/d' -e '/^domain/d' messages.po > $@ + $(RM) messages.po diff --git a/usr/src/lib/libprtdiag_psr/sparc/opl/common/opl.c b/usr/src/lib/libprtdiag_psr/sparc/opl/common/opl.c new file mode 100644 index 0000000000..9bce08b95a --- /dev/null +++ b/usr/src/lib/libprtdiag_psr/sparc/opl/common/opl.c @@ -0,0 +1,850 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (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 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + * Opl Platform specific functions. + * + * called when : + * machine_type == MTYPE_OPL + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <ctype.h> +#include <string.h> +#include <varargs.h> +#include <fcntl.h> +#include <assert.h> +#include <sys/param.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/utsname.h> +#include <sys/systeminfo.h> +#include <sys/openpromio.h> +#include <libintl.h> +#include <syslog.h> +#include <sys/dkio.h> +#include <pdevinfo.h> +#include <libprtdiag.h> +#include <libdevinfo.h> +#include <kstat.h> + +/* + * Globals and externs + */ +#define KBYTE 1024 +#define MBYTE (KBYTE * KBYTE) +#define HZ_TO_MHZ(x) ((((uint64_t)(x)) + 500000) / 1000000) +#define SCF_SECURE_MODE_KSTAT_NAMED "secure_mode" +#define SCF_STAT_MODE_UNLOCK 0 +#define SCF_STAT_MODE_LOCK 1 +#define SCF_SYSTEM_KSTAT_NAME "scf" +#ifndef TEXT_DOMAIN +#define TEXT_DOMAIN "SYS_TEST" +#endif /* TEXT_DOMAIN */ +#define IS_PCI_BRIDGE(name, type) \ + (((name) != NULL) && ((type) != NULL) && \ + (strncmp((name), "pci", 3) == 0) && \ + (strncmp((type), "pci", 3) == 0)) + +/* + * Global functions and variables + * these functions will overlay the symbol table of libprtdiag + * at runtime (Opl systems only) + */ +struct cs_status { + int cs_number; + int status; + int avail_hi; + int avail_lo; + int dimm_hi; + int dimm_lo; + int dimms; +}; + +int do_prominfo(int syserrlog, char *pgname, int log_flag, int prt_flag); +void *get_prop_val(Prop *prop); +void display_pci(Board_node *); +void display_ffb(Board_node *, int); +void display_sbus(Board_node *board); +void display_cpu_devices(Sys_tree *tree); +void display_cpus(Board_node *board); +void display_memoryconf(Sys_tree *tree, struct grp_info *grps); +void display_io_cards(struct io_card *list); +void display_diaginfo(int flag, Prom_node *root, Sys_tree *tree, + struct system_kstat_data *kstats); +Prop *find_prop(Prom_node *pnode, char *name); + +/* Local functions */ +static void opl_disp_environ(void); +static void opl_disp_hw_revisions(Sys_tree *tree, Prom_node *root); +static uint64_t print_opl_memory_line(int lsb, struct cs_status *cs_stat, + int ngrps); +static uint64_t get_opl_mem_regs(Board_node *bnode); +void add_node(Sys_tree *root, Prom_node *pnode); +static int get_prop_size(Prop *prop); + +/* + * Display all the leaf PCI nodes on this board that have "reg" property. + * If the "reg" property is NULL for a leaf node, skip parsing its sibling + * nodes and display the parent node properties. + */ +void +display_pci(Board_node *board) +{ + struct io_card *card_list = NULL; + struct io_card card; + Prom_node *pci, *card_node; + char *name, *type; + int *int_val; + + if (board == NULL) + return; + + /* Initialize common information */ + card.board = board->board_num; + + pci = board->nodes; + while (pci != NULL) { + name = get_node_name(pci); + + /* Skip non-PCI board nodes */ + if ((name == NULL) || (strcmp(name, "pci") != 0)) { + pci = pci->sibling; + continue; + } + + type = (char *)get_prop_val(find_prop(pci, "device_type")); + + /* + * Skip PCI/ebus devices + * They have name == "pci" and type == "pci" + */ + if (strcmp(type, "pci") == 0) { + pci = pci->sibling; + continue; + } + + card_node = pci; + while (card_node != NULL) { + int pci_parent_bridge = 0; + + /* If it does have a child, skip to leaf child */ + if (card_node->child != NULL) { + card_node = card_node->child; + continue; + } + + /* Get name of the card */ + name = (char *)get_prop_val(find_prop + (card_node, "name")); + + /* Get type of card */ + type = (char *)get_prop_val(find_prop + (card_node, "device_type")); + + /* Leaf pci-bridges are to be ignored */ + if (!IS_PCI_BRIDGE(name, type)) { + + /* Get reg property of the node */ + int_val = (int *)get_prop_val(find_prop + (card_node, "reg")); + + /* + * If no "reg" property check to see + * whether parent node has reg property. + * and check if parent is a bridge + */ + if (int_val == NULL) { + Prom_node *cparent = card_node->parent; + if (cparent == NULL) + break; + + name = (char *)get_prop_val(find_prop + (cparent, "name")); + + type = (char *)get_prop_val(find_prop + (cparent, "device_type")); + + /* check if parent is a bridge */ + if (IS_PCI_BRIDGE(name, type)) + pci_parent_bridge = 1; + + int_val = (int *)get_prop_val( + find_prop(cparent, "reg")); + + if (int_val != NULL) + /* Switch to parent */ + card_node = cparent; + else + /* parent node has no reg */ + break; + } + + if (!pci_parent_bridge) { + + name = (char *)get_prop_val(find_prop + (card_node, "name")); + + if (name == NULL) + card.name[0] = '\0'; + else { + (void) snprintf(card.name, + MAXSTRLEN, "%s", name); + } + + /* Get the model of this card */ + name = (char *)get_prop_val(find_prop + (card_node, "model")); + + if (name == NULL) { + (void) snprintf(card.model, + MAXSTRLEN, "%s", "N/A"); + } else { + (void) snprintf(card.model, + MAXSTRLEN, "%s", name); + } + + /* insert card to the list */ + card_list = insert_io_card + (card_list, &card); + + } + + } + + /* + * Parse sibling nodes. + * Then move up the parent's sibling upto the top + * intermediate node + * Stop if pci board node is reached. + */ + if (card_node->sibling != NULL) + card_node = card_node->sibling; + else { + Prom_node *cparent; + cparent = card_node->parent; + card_node = NULL; + while (cparent != NULL) { + if (cparent == pci) + break; + if (cparent->sibling != NULL) { + card_node = cparent->sibling; + break; + } + cparent = cparent->parent; + } + } + + } + + /* On to the next board node */ + pci = pci->sibling; + + } + + display_io_cards(card_list); + free_io_cards(card_list); +} + +/* + * There are no FFB's on OPL. + */ +/*ARGSUSED*/ +void +display_ffb(Board_node *board, int table) +{ +} + +/* + * There are no Sbus's on OPL. + */ +/*ARGSUSED*/ +void +display_sbus(Board_node *board) +{ +} + +/* + * Details of I/O information. Print out all the io cards. + */ +void +display_io_cards(struct io_card *list) +{ + char *hdrfmt = "%-6.6s %-14.14s %-12.12s\n"; + + struct io_card *p; + + if (list == NULL) + return; + + (void) textdomain(TEXT_DOMAIN); + + log_printf(hdrfmt, gettext("LSB"), gettext("Name"), gettext("Model"), + 0); + + log_printf(hdrfmt, "---", "-----------------", "------------", 0); + + for (p = list; p != NULL; p = p->next) { + + /* Board number */ + log_printf(" %02d ", p->board, 0); + + /* Card name */ + log_printf("%-15.15s", p->name, 0); + + /* Card model */ + log_printf("%-12.12s", p->model, 0); + + log_printf("\n", 0); + } + log_printf("\n", 0); +} + +/* + * Details of CPU information. + */ +void +display_cpu_devices(Sys_tree *tree) +{ + Board_node *bnode; + char *hdrfmt = + "%-5.5s %-8.8s %-20.20s %-8.8s %-8.8s %-8.8s %-8.8s\n"; + + (void) textdomain(TEXT_DOMAIN); + + /* + * Display the table header for CPUs . Then display the CPU + * frequency, cache size, and processor revision of all cpus. + */ + log_printf("\n", 0); + log_printf("====================================", 0); + log_printf(gettext(" CPUs "), 0); + log_printf("====================================", 0); + log_printf("\n\n", 0); + + log_printf(hdrfmt, + "", + gettext("CPU"), + gettext(" CPU "), + gettext("Run"), + gettext("L2$"), + gettext("CPU"), + gettext("CPU"), 0); + + log_printf(hdrfmt, + gettext("LSB"), + gettext("Chip"), + gettext(" ID "), + gettext("MHz"), + gettext(" MB"), + gettext("Impl."), + gettext("Mask"), 0); + + log_printf(hdrfmt, + "---", "----", "--------------------", "----", + "---", "-----", "----", 0); + + /* Now display all of the cpus on each board */ + for (bnode = tree->bd_list; bnode != NULL; bnode = bnode->next) { + display_cpus(bnode); + } + + log_printf("\n", 0); +} + +/* + * Display the CPUs present on this board. + */ +void +display_cpus(Board_node *board) +{ + int *impl, *mask, *cpuid, *portid, *l2cache_size; + uint_t freq; /* CPU clock frequency */ + Prom_node *pnode, *cpu; + char *name; + + (void) textdomain(TEXT_DOMAIN); + + /* + * Get the Cpus' properties for display + */ + for (pnode = board->nodes; pnode != NULL; pnode = pnode->sibling) { + char cpu_str[MAXSTRLEN], fcpu_str[MAXSTRLEN] = {0}; + + name = get_node_name(pnode); + if ((name == NULL) || (strncmp(name, "cmp", 3) != 0)) { + continue; + } + + portid = (int *)get_prop_val(find_prop(pnode, "portid")); + freq = (HZ_TO_MHZ(get_cpu_freq(pnode->child))); + l2cache_size = + (int *)get_prop_val + (find_prop(pnode->child, "l2-cache-size")); + impl = + (int *)get_prop_val + (find_prop(pnode->child, "implementation#")); + mask = (int *)get_prop_val(find_prop(pnode->child, "mask#")); + + /* Lsb id */ + log_printf(" %02d ", board->board_num, 0); + + if (portid != NULL) + log_printf("%3d ", (((*portid)>>3)&0x3), 0); + + /* + * Specific parsing of the CMP/CORE/CPU chain. + * The internal cpu tree built by walk_di_tree() + * in common code can be illustrated by the diagram + * below: + * + * cmp->cpu->cpu->cpu->cpu->(next board nodes) + * / \ + * core core + * where "/" or "\" are children + * and "->" are siblings + */ + for (cpu = pnode->sibling; cpu != NULL; ) { + Prom_node *cpu_next = NULL; + + name = get_node_name(cpu); + if ((name == NULL) || (strncmp(name, "cpu", 3) != 0)) { + break; + } + + /* Id assigned to Virtual processor core */ + cpuid = (int *)get_prop_val(find_prop(cpu, "cpuid")); + cpu_next = cpu->sibling; + + if (cpu_next != NULL) { + name = get_node_name(cpu_next); + + if ((name == NULL) || + (strncmp(name, "cpu", 3) != 0)) { + cpu_next = NULL; + } + } + + if (cpuid != NULL) { + /* Used for printing in comma format */ + (void) sprintf(cpu_str, "%4d", *cpuid); + (void) strlcat(fcpu_str, cpu_str, MAXSTRLEN); + + if (cpu_next != NULL) + (void) strlcat(fcpu_str, ",", MAXSTRLEN); + } else { + (void) sprintf(cpu_str, "%4s", "N/A"); + (void) strlcat(fcpu_str, cpu_str, MAXSTRLEN); + + if (cpu_next != NULL) + (void) strlcat(fcpu_str, ",", MAXSTRLEN); + } + cpu = cpu_next; + } + + log_printf("%-20.20s", fcpu_str, 0); + + /* Running frequency */ + if (freq != 0) + log_printf(" %4ld ", freq, 0); + else + log_printf(" %4s ", "N/A", 0); + + /* L2 cache size */ + if (l2cache_size == NULL) + log_printf(" %3s ", "N/A", 0); + else { + log_printf("%4.1f ", + (float)(*l2cache_size) / (float)(1<<20), 0); + } + + + /* Implementation number of processor */ + if (impl != NULL) + log_printf("%4d ", *impl, 0); + else + log_printf("%4s ", "N/A", 0); + + /* Mask Set version */ + /* Bits 31:24 of VER register is mask. */ + /* Mask value : Non MTP mode - 00-7f, MTP mode - 80-ff */ + if (mask == NULL) + log_printf("%4s", "N/A", 0); + else + log_printf("%4d", (*mask)&0xff, 0); + + log_printf("\n", 0); + + } +} + +/* + * Gather memory information: Details of memory information. + */ +static uint64_t +get_opl_mem_regs(Board_node *bnode) +{ + Prom_node *pnode; + struct cs_status *cs_stat; + uint64_t total_mem = 0; + int cs_size, ngrps; + + pnode = dev_find_node(bnode->nodes, "pseudo-mc"); + while (pnode != NULL) { + + cs_size = get_prop_size(find_prop(pnode, "cs-status")); + + if (cs_size > 0) { + + /* OBP returns lists of 7 ints */ + cs_stat = (struct cs_status *)get_prop_val + (find_prop(pnode, "cs-status")); + + /* cs_size must be at least 28 */ + ngrps = cs_size/sizeof (struct cs_status); + + if (cs_stat != NULL) { + total_mem += + print_opl_memory_line(bnode->board_num, + cs_stat, ngrps); + } + } + + pnode = dev_next_node(pnode, "pseudo-mc"); + } + return (total_mem); +} + +/* + * Display memory information. + */ +/*ARGSUSED*/ +void +display_memoryconf(Sys_tree *tree, struct grp_info *grps) +{ + Board_node *bnode = tree->bd_list; + uint64_t total_mem = 0, total_sys_mem = 0; + char *hdrfmt = "\n%-5.5s %-6.6s %-12.12s %-10.10s" + " %-8.8s %-10.10s"; + + (void) textdomain(TEXT_DOMAIN); + + log_printf("======================", 0); + log_printf(gettext(" Memory Configuration "), 0); + log_printf("======================", 0); + log_printf("\n", 0); + + log_printf(hdrfmt, + "", + gettext("Memory"), + gettext("Available"), + gettext("Memory"), + gettext("DIMM"), + gettext("Number of"), + 0); + + log_printf(hdrfmt, + gettext("LSB"), + gettext("Group"), + gettext("Size"), + gettext("Status"), + gettext("Size"), + gettext("DIMMs"), 0); + + log_printf(hdrfmt, + "---", "-------", "------------", "-------", "-----", + "---------", 0); + + log_printf("\n", 0); + + for (bnode = tree->bd_list; bnode != NULL; bnode = bnode->next) { + total_mem += get_opl_mem_regs(bnode); + } + + /* + * Sanity check to ensure that the total amount of system + * memory matches the total number of memory that + * we find here. Display error message if there is a mis-match. + */ + total_sys_mem = (((uint64_t)sysconf(_SC_PAGESIZE) * (uint64_t)sysconf + (_SC_PHYS_PAGES)) / MBYTE); + + if (total_mem != total_sys_mem) { + log_printf(dgettext(TEXT_DOMAIN, + "\nError:total available size [%lldMB] does not match" + " total system memory [%lldMB]\n"), + total_mem, total_sys_mem, 0); + } + +} + +/* + * This function provides Opl's formatting of the memory config + * information that get_opl_mem_regs() has gathered. + */ +static uint64_t +print_opl_memory_line(int lsb, struct cs_status *cs_stat, int ngrps) +{ + int i; + uint64_t total_board_mem = 0; + + (void) textdomain(TEXT_DOMAIN); + + + for (i = 0; i < ngrps; i++) { + int64_t mem_size = 0; + + mem_size = ((((int64_t)cs_stat[i].avail_hi)<<32) + + cs_stat[i].avail_lo); + + if (mem_size == 0) continue; + + /* Lsb Id */ + log_printf(" %02d ", lsb, 0); + + /* Memory Group Number */ + if ((cs_stat[i].cs_number) == 0) + log_printf("%-6.6s", "A", 0); + else + log_printf("%-6.6s", "B", 0); + + /* Memory Group Size */ + log_printf(" %4lldMB ", mem_size/MBYTE, 0); + + total_board_mem += (mem_size/MBYTE); + + /* Memory Group Status */ + log_printf("%-11.11s", + cs_stat[i].status ? "partial": "okay", 0); + + /* DIMM Size */ + log_printf("%4lldMB ", + ((((int64_t)cs_stat[i].dimm_hi)<<32) + + cs_stat[i].dimm_lo)/MBYTE, 0); + + /* Number of DIMMs */ + log_printf("%9d\n", cs_stat[i].dimms); + } + return (total_board_mem); +} + +/* + * Details of hardware revision and environmental status. + */ +/*ARGSUSED*/ +void +display_diaginfo(int flag, Prom_node *root, Sys_tree *tree, + struct system_kstat_data *kstats) +{ + /* Print the PROM revisions */ + if (flag) + opl_disp_hw_revisions(tree, root); +} + +/* + * Gather and display hardware revision and environmental status + */ +/*ARGSUSED*/ +static void +opl_disp_hw_revisions(Sys_tree *tree, Prom_node *root) +{ + char *version; + Prom_node *pnode; + + (void) textdomain(TEXT_DOMAIN); + + /* Print the header */ + log_printf("\n", 0); + log_printf("====================", 0); + log_printf(gettext(" Hardware Revisions "), 0); + log_printf("====================", 0); + log_printf("\n\n", 0); + + /* Display Prom revision header */ + log_printf(gettext("System PROM revisions:"), 0); + log_printf("\n----------------------\n", 0); + log_printf("\n", 0); + + /* Display OBP version info */ + pnode = dev_find_node(root, "openprom"); + if (pnode != NULL) { + version = (char *)get_prop_val(find_prop(pnode, "version")); + if (version != NULL) + log_printf("%s\n\n", version, 0); + else + log_printf("%s\n\n", "N/A", 0); + } + + /* Print the header */ + log_printf("\n", 0); + log_printf("===================", 0); + log_printf(gettext(" Environmental Status "), 0); + log_printf("===================", 0); + log_printf("\n\n", 0); + + opl_disp_environ(); +} + +/* + * Gather environmental information + */ +static void +opl_disp_environ(void) +{ + kstat_ctl_t *kc; + kstat_t *ksp; + kstat_named_t *k; + + if ((kc = kstat_open()) == NULL) + return; + + if ((ksp = kstat_lookup + (kc, "scfd", 0, SCF_SYSTEM_KSTAT_NAME)) == NULL) { + (void) kstat_close(kc); + return; + } + + if (kstat_read(kc, ksp, NULL) == -1) { + (void) kstat_close(kc); + return; + } + + if ((k = (kstat_named_t *)kstat_data_lookup + (ksp, SCF_SECURE_MODE_KSTAT_NAMED)) == NULL) { + (void) kstat_close(kc); + return; + } + + if (k->value.c[0] == SCF_STAT_MODE_LOCK) + log_printf("Mode switch is in LOCK mode ", 0); + else if (k->value.c[0] == SCF_STAT_MODE_UNLOCK) + log_printf("Mode switch is in UNLOCK mode", 0); + else + log_printf("Mode switch is in UNKNOWN mode", 0); + + log_printf("\n", 0); + + (void) kstat_close(kc); +} + + +/* + * Calls do_devinfo() in order to use the libdevinfo device tree + * instead of OBP's device tree. + */ +int +do_prominfo(int syserrlog, char *pgname, int log_flag, int prt_flag) +{ + return (do_devinfo(syserrlog, pgname, log_flag, prt_flag)); +} + +/* + * Return the property value for the Prop + * passed in. (When using libdevinfo) + */ +void * +get_prop_val(Prop *prop) +{ + if (prop == NULL) + return (NULL); + + return ((void *)(prop->value.val_ptr)); +} + +/* + * Return the property size for the Prop + * passed in. (When using libdevinfo) + */ +static int +get_prop_size(Prop *prop) +{ + + if ((prop != NULL) && (prop->size > 0)) + return (prop->size); + else + return (0); +} + + +/* + * Search a Prom node and retrieve the property with the correct + * name. (When using libdevinfo) + */ +Prop * +find_prop(Prom_node *pnode, char *name) +{ + Prop *prop; + + if (pnode == NULL) + return (NULL); + + for (prop = pnode->props; prop != NULL; prop = prop->next) { + if (prop->name.val_ptr != NULL && + strcmp((char *)(prop->name.val_ptr), name) == 0) + break; + } + + return (prop); +} + +/* + * This function adds a board node to the board structure where that + * that node's physical component lives. + */ +void +add_node(Sys_tree *root, Prom_node *pnode) +{ + int board; + Board_node *bnode; + Prom_node *p; + char *type; + + if ((board = get_board_num(pnode)) == -1) { + type = get_node_type(pnode); + if ((type != NULL) && (strcmp(type, "cpu") == 0)) + board = get_board_num((pnode->parent)->parent); + } + + /* find the node with the same board number */ + if ((bnode = find_board(root, board)) == NULL) { + bnode = insert_board(root, board); + bnode->board_type = UNKNOWN_BOARD; + } + + /* now attach this prom node to the board list */ + /* Insert this node at the end of the list */ + pnode->sibling = NULL; + if (bnode->nodes == NULL) + bnode->nodes = pnode; + else { + p = bnode->nodes; + while (p->sibling != NULL) + p = p->sibling; + p->sibling = pnode; + } + +} |