changeset 3325:72fd98750a13

PSARC 2006/692 N2 PIU FMA PSARC 2006/716 Niagara-2 CPU memory FMA PSARC 2006/717 FMA for NIU/Neptune Ethernet subsystem 6255063 Memory SERD engines should be per-page per DIMM, not per DIMM 6346507 sparc cpumem-diagnosis needs to implement rules 4A and 4B 6349876 Modify diag policy for fault.cpu.ultraSPARC-T1.freg to offline thread 6350627 "fault.memory.bank" calls out multiple FRUs with a single fault, should be one fault per FRU 6380684 sun4v platform topology for CPU's is incorrect 6426478 anchored page retire for Superior, Ontario 6437505 enhance cpumem diagnosis engine for Niagara-2 6440395 mem.so needs to explicitly initialize dm_drgen 6450416 add Niagara-II (US-T2) support to CPU/Mem error injector. 6456918 Niagara-2 CPU faults must contain FRU part number and serial number 6457153 Niagara-2 DIMM faults must contain FRU part number in addition to serial number 6476919 New topo enumerators needed for Huron 1U/2U 6486952 NIU FMA support for ultraSPARC-T2 processor 6486965 Need topo map for Huron 1U/2U 6486977 Support for N2 PIU Error Handling 6487493 Add FMA Support for N2 NIU Nexus 6488652 Add error handling code in Niagara Crypto drivers 6489560 Driver reports dfifo_ue errors when running traffic on the 3rd QGC port 6489680 ZCP errors seen after plumbing the interface. 6489681 Cannot use ndd to enable JF, MAC MTU does not change 6489683 Memory leak in the driver while doing unplumb/plumb 6490519 fmtopo -d core dump when a hc-schemed fmri has a serial number 6492541 Neptune (nxge) panics when being initialzed and plumbed by LDoms 1.0 6496399 pfifo_over/pfifo_und errors seen with netinstall with autoneg mismatched or taking cable in/out 6500548 Rx jumbo does not work for jumbo packets larger than that largest Rx data buffer partition (8K) 6503808 Link aggregation does not work with nxge; system panics when changing link speed 6503820 Driver panics with the 1st Rx packet on P1.1 cards on Solarisx86 with 1.21 driver. 6505435 #ifdef LINUX junk lurking in nxge sources
author sd77468
date Fri, 22 Dec 2006 12:42:28 -0800
parents 7c249df09f8c
children 4f5ce2d4d4f5
files usr/src/cmd/fm/dicts/SUN4.dict usr/src/cmd/fm/dicts/SUN4.po usr/src/cmd/fm/dicts/SUN4V.dict usr/src/cmd/fm/dicts/SUN4V.po usr/src/cmd/fm/eversholt/files/sparc/sun4/fire.esc usr/src/cmd/fm/eversholt/files/sparc/sun4v/Makefile usr/src/cmd/fm/eversholt/files/sparc/sun4v/n2piu.esc usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpu.c usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpu.h usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpuerr.c usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_dimm.c usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_dimm.h usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_main.c usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_mem.c usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_mem.h usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_memerr.c usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_page.c usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_page.h usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_pageerr.c usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_state.c usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_state.h usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_cpu_arch.c usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_dp_page.c usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_memerr_arch.c usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_opl.c usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_opl.h usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_oplerr.c usr/src/cmd/fm/modules/sun4v/cpumem-diagnosis/cmd_cpu_arch.c usr/src/cmd/fm/modules/sun4v/cpumem-diagnosis/cmd_memerr_arch.c usr/src/cmd/fm/modules/sun4v/cpumem-retire/cma_main.c usr/src/cmd/fm/modules/sun4v/cpumem-retire/cma_page.c usr/src/cmd/fm/schemes/cpu/cpu.c usr/src/cmd/fm/schemes/cpu/sparc/cpu_mdesc.c usr/src/cmd/fm/schemes/cpu/sparc/cpu_mdesc.h usr/src/cmd/fm/schemes/mem/mem.h usr/src/cmd/fm/schemes/mem/mem_unum.c usr/src/cmd/fm/schemes/mem/sparc/mem_disc.c usr/src/lib/fm/Makefile usr/src/lib/fm/topo/libtopo/common/cpu.c usr/src/lib/fm/topo/libtopo/common/hc.c usr/src/lib/fm/topo/libtopo/common/topo_hc.h usr/src/lib/fm/topo/libtopo/sparc/Makefile usr/src/lib/fm/topo/libtopo/sparcv9/Makefile usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/Makefile usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/SPARC-Enterprise-T1000-hc-topology.xml usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/SPARC-Enterprise-T5120-hc-topology.xml usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/SPARC-Enterprise-T5220-hc-topology.xml usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/Sun-Blade-T6300-hc-topology.xml usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/Sun-Fire-T1000-hc-topology.xml usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/Sun-Fire-T200-hc-topology.xml usr/src/lib/fm/topo/maps/sun4v/sun4v-hc-topology.xml usr/src/lib/fm/topo/modules/common/pcibus/did_props.c usr/src/lib/fm/topo/modules/common/pcibus/util.c usr/src/lib/fm/topo/modules/sun4/chip/Makefile.chip usr/src/lib/fm/topo/modules/sun4/chip/chip.c usr/src/lib/fm/topo/modules/sun4u/chip/Makefile usr/src/lib/fm/topo/modules/sun4u/chip/chip_sun4u.c usr/src/lib/fm/topo/modules/sun4v/Makefile usr/src/lib/fm/topo/modules/sun4v/chip/Makefile usr/src/lib/fm/topo/modules/sun4v/chip/chip_sun4v.c usr/src/lib/fm/topo/modules/sun4v/motherboard/Makefile usr/src/lib/fm/topo/modules/sun4v/motherboard/motherboard.c usr/src/lib/fm/topo/modules/sun4v/niu/Makefile usr/src/lib/fm/topo/modules/sun4v/niu/niu.c usr/src/lib/fm/topo/modules/sun4v/pcibus/pci_sun4v.h usr/src/lib/fm/topo/modules/sun4v/platform-cpu/Makefile usr/src/lib/fm/topo/modules/sun4v/platform-cpu/cpu.c usr/src/pkgdefs/SUNWfmd/prototype_sparc usr/src/pkgdefs/SUNWonmtst.v/prototype_sparc usr/src/uts/sparc/sys/fm/cpu/UltraSPARC-T1.h usr/src/uts/sun4/io/px/pcie_pwr.c usr/src/uts/sun4/io/px/px_var.h usr/src/uts/sun4v/Makefile.files usr/src/uts/sun4v/io/niumx/niumx.c usr/src/uts/sun4v/io/niumx/niumx_var.h usr/src/uts/sun4v/io/nxge/npi/npi_mac.c usr/src/uts/sun4v/io/nxge/nxge_classify.c usr/src/uts/sun4v/io/nxge/nxge_espc.c usr/src/uts/sun4v/io/nxge/nxge_fflp.c usr/src/uts/sun4v/io/nxge/nxge_fflp_hash.c usr/src/uts/sun4v/io/nxge/nxge_fm.c usr/src/uts/sun4v/io/nxge/nxge_hcall.s usr/src/uts/sun4v/io/nxge/nxge_hw.c usr/src/uts/sun4v/io/nxge/nxge_ipp.c usr/src/uts/sun4v/io/nxge/nxge_kstats.c usr/src/uts/sun4v/io/nxge/nxge_mac.c usr/src/uts/sun4v/io/nxge/nxge_main.c usr/src/uts/sun4v/io/nxge/nxge_ndd.c usr/src/uts/sun4v/io/nxge/nxge_rxdma.c usr/src/uts/sun4v/io/nxge/nxge_send.c usr/src/uts/sun4v/io/nxge/nxge_txc.c usr/src/uts/sun4v/io/nxge/nxge_txdma.c usr/src/uts/sun4v/io/nxge/nxge_virtual.c usr/src/uts/sun4v/io/nxge/nxge_zcp.c usr/src/uts/sun4v/nxge/Makefile usr/src/uts/sun4v/sys/Makefile usr/src/uts/sun4v/sys/bignum.h usr/src/uts/sun4v/sys/n2cp.h usr/src/uts/sun4v/sys/ncp.h usr/src/uts/sun4v/sys/ncs.h usr/src/uts/sun4v/sys/niagararegs.h usr/src/uts/sun4v/sys/nxge/nxge.h usr/src/uts/sun4v/sys/nxge/nxge_common.h usr/src/uts/sun4v/sys/nxge/nxge_common_impl.h usr/src/uts/sun4v/sys/nxge/nxge_fflp_hw.h usr/src/uts/sun4v/sys/nxge/nxge_flow.h usr/src/uts/sun4v/sys/nxge/nxge_fm.h usr/src/uts/sun4v/sys/nxge/nxge_impl.h usr/src/uts/sun4v/sys/nxge/nxge_ipp.h usr/src/uts/sun4v/sys/nxge/nxge_ipp_hw.h usr/src/uts/sun4v/sys/nxge/nxge_rxdma.h
diffstat 111 files changed, 6045 insertions(+), 2391 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/fm/dicts/SUN4.dict	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/dicts/SUN4.dict	Fri Dec 22 12:42:28 2006 -0800
@@ -1,13 +1,12 @@
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# 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, 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.
@@ -44,3 +43,4 @@
 fault.io.fire.asic fault.io.fire.pci.device fault.io.fire.pciex.device=12
 fault.io.fire.asic fault.io.fire.pci.device=13
 fault.io.fire.hbus=14
+fault.io.fire.datapath fault.io.fire.hbus=15
--- a/usr/src/cmd/fm/dicts/SUN4.po	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/dicts/SUN4.po	Fri Dec 22 12:42:28 2006 -0800
@@ -265,3 +265,19 @@
 msgstr "Loss of services provided by the device instances associated with this fault"
 msgid "SUN4-8000-FC.action"
 msgstr "\nUse fmdump -v -u EVENT_ID and fmdump -eV -u\nEVENT_ID to collect information to \nhelp Sun Service personnel identify the device in need of repair. Schedule \na repair procedure to replace the affected device.\n"
+#
+# code: SUN4-8000-GQ
+# keys: fault.io.fire.datapath fault.io.fire.hbus
+#
+msgid "SUN4-8000-GQ.type"
+msgstr "Fault"
+msgid "SUN4-8000-GQ.severity"
+msgstr "Critical"
+msgid "SUN4-8000-GQ.description"
+msgstr "Fault in either the PCIe asic's internal hostbus or connector between IO and CPU Board\n  Refer to %s for more information."
+msgid "SUN4-8000-GQ.response"
+msgstr "One or more device instances may be disabled\n"
+msgid "SUN4-8000-GQ.impact"
+msgstr "Loss of services provided by the device\ninstances associated with this fault\n"
+msgid "SUN4-8000-GQ.action"
+msgstr "Schedule a repair procedure to replace the affected\ndevice if necessary, or contact Sun for support.\n"
--- a/usr/src/cmd/fm/dicts/SUN4V.dict	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/dicts/SUN4V.dict	Fri Dec 22 12:42:28 2006 -0800
@@ -1,13 +1,12 @@
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# 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, 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.
@@ -27,7 +26,7 @@
 # DO NOT EDIT -- this file is generated by the Event Registry.
 #
 
-FMDICT: name=SUN4V version=1 maxkey=1
+FMDICT: name=SUN4V version=1 maxkey=1 dictid=0x3456
 
 fault.cpu.ultraSPARC-T1.ireg=1
 fault.cpu.ultraSPARC-T1.freg=2
@@ -42,3 +41,26 @@
 fault.memory.page=11
 fault.memory.dimm=12
 fault.memory.bank=13
+fault.memory.link-c=14
+fault.cpu.ultraSPARC-T2.ireg=15
+fault.cpu.ultraSPARC-T2.freg=16
+fault.cpu.ultraSPARC-T2.misc_reg=17
+fault.cpu.ultraSPARC-T2.itlb=18
+fault.cpu.ultraSPARC-T2.dtlb=19
+fault.cpu.ultraSPARC-T2.icache=20
+fault.cpu.ultraSPARC-T2.dcache=21
+fault.cpu.ultraSPARC-T2.mau=22
+fault.cpu.ultraSPARC-T2.l2data-c=23
+fault.cpu.ultraSPARC-T2.l2cachetag=24
+fault.cpu.ultraSPARC-T2.l2cachectl=25
+fault.memory.link-u=26
+fault.cpu.ultraSPARC-T2.l2data-u=27
+fault.cpu.ultraSPARC-T1.l2data-c=28
+fault.cpu.ultraSPARC-T1.l2data-u=29
+fault.memory.datapath=30
+fault.io.n2.ncu=31
+fault.io.n2.dmu=32
+fault.io.n2.niu=33
+fault.io.n2.siu=34
+fault.io.n2.soc=35
+fault.io.n2.crossbar=36
--- a/usr/src/cmd/fm/dicts/SUN4V.po	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/dicts/SUN4V.po	Fri Dec 22 12:42:28 2006 -0800
@@ -233,3 +233,371 @@
 msgstr "Total system memory capacity will be reduced as pages are retired."
 msgid "SUN4V-8000-E2.action"
 msgstr "Schedule a repair procedure to replace the affected memory module. Use fmdump -v -u <EVENT_ID> to identify the module."
+#
+# code: SUN4V-8000-FJ
+# keys: fault.memory.link-c
+#
+msgid "SUN4V-8000-FJ.type"
+msgstr "Fault"
+msgid "SUN4V-8000-FJ.severity"
+msgstr "Major"
+msgid "SUN4V-8000-FJ.description"
+msgstr "A problem was detected in the interconnect between a memory DIMM module and\nits memory controller. \n  Refer to %s for more information."
+msgid "SUN4V-8000-FJ.response"
+msgstr "No automated response.\n"
+msgid "SUN4V-8000-FJ.impact"
+msgstr "System performance may be impacted.\n"
+msgid "SUN4V-8000-FJ.action"
+msgstr "At convenient time, try reseating the memory module(s).  If problem persists,\ncontact Sun to schedule part replacement.\n"
+#
+# code: SUN4V-8000-GE
+# keys: fault.cpu.ultraSPARC-T2.ireg
+#
+msgid "SUN4V-8000-GE.type"
+msgstr "Fault"
+msgid "SUN4V-8000-GE.severity"
+msgstr "Minor"
+msgid "SUN4V-8000-GE.description"
+msgstr "The number of integer register errors associated with this thread has exceeded acceptable levels.\n  Refer to %s for more information."
+msgid "SUN4V-8000-GE.response"
+msgstr "The fault manager will attempt to remove the affected thread\nfrom service.\n"
+msgid "SUN4V-8000-GE.impact"
+msgstr "System performance may be affected. \n"
+msgid "SUN4V-8000-GE.action"
+msgstr "Schedule a repair procedure to replace the affected CPU, the identity of which can be determined using fmdump -v -u <EVENT_ID>.\n"
+#
+# code: SUN4V-8000-HP
+# keys: fault.cpu.ultraSPARC-T2.freg
+#
+msgid "SUN4V-8000-HP.type"
+msgstr "Fault"
+msgid "SUN4V-8000-HP.severity"
+msgstr "Minor"
+msgid "SUN4V-8000-HP.description"
+msgstr "The number of floating register errors associated with this thread has exceeded acceptable levels.\n  Refer to %s for more information."
+msgid "SUN4V-8000-HP.response"
+msgstr "The fault manager will attempt to remove the affected thread\nfrom service.\n"
+msgid "SUN4V-8000-HP.impact"
+msgstr "System performance may be affected. \n"
+msgid "SUN4V-8000-HP.action"
+msgstr "Schedule a repair procedure to replace the affected CPU, the identity of which can be determined using fmdump -v -u <EVENT_ID>.\n"
+#
+# code: SUN4V-8000-JA
+# keys: fault.cpu.ultraSPARC-T2.misc_reg
+#
+msgid "SUN4V-8000-JA.type"
+msgstr "Fault"
+msgid "SUN4V-8000-JA.severity"
+msgstr "Minor"
+msgid "SUN4V-8000-JA.description"
+msgstr "The number of ancillary register errors associated with this thread has exceeded acceptable levels.\n  Refer to %s for more information."
+msgid "SUN4V-8000-JA.response"
+msgstr "The fault manager will attempt to remove the affected thread\nfrom service.\n"
+msgid "SUN4V-8000-JA.impact"
+msgstr "System performance may be affected. \n"
+msgid "SUN4V-8000-JA.action"
+msgstr "Schedule a repair procedure to replace the affected CPU, the identity of which can be determined using fmdump -v -u <EVENT_ID>.\n"
+#
+# code: SUN4V-8000-KS
+# keys: fault.cpu.ultraSPARC-T2.itlb
+#
+msgid "SUN4V-8000-KS.type"
+msgstr "Fault"
+msgid "SUN4V-8000-KS.severity"
+msgstr "Major"
+msgid "SUN4V-8000-KS.description"
+msgstr "The number of ITLB errors associated with this thread has exceeded acceptable levels.\n  Refer to %s for more information."
+msgid "SUN4V-8000-KS.response"
+msgstr "The fault manager will attempt to remove all threads associated with\nthis resource from service.\n"
+msgid "SUN4V-8000-KS.impact"
+msgstr "System performance is likely to be affected. \n"
+msgid "SUN4V-8000-KS.action"
+msgstr "Schedule a repair procedure to replace the affected resource, the identity of which can be determined using fmdump -v -u <EVENT_ID>.\n"
+#
+# code: SUN4V-8000-L5
+# keys: fault.cpu.ultraSPARC-T2.dtlb
+#
+msgid "SUN4V-8000-L5.type"
+msgstr "Fault"
+msgid "SUN4V-8000-L5.severity"
+msgstr "Major"
+msgid "SUN4V-8000-L5.description"
+msgstr "The number of DTLB errors associated with this thread has exceeded acceptable levels.\n  Refer to %s for more information."
+msgid "SUN4V-8000-L5.response"
+msgstr "The fault manager will attempt to remove all threads associated with\nthis resource from service.\n"
+msgid "SUN4V-8000-L5.impact"
+msgstr "System performance is likely to be affected. \n"
+msgid "SUN4V-8000-L5.action"
+msgstr "Schedule a repair procedure to replace the affected resource, the identity of which can be determined using fmdump -v -u <EVENT_ID>.\n"
+#
+# code: SUN4V-8000-MY
+# keys: fault.cpu.ultraSPARC-T2.icache
+#
+msgid "SUN4V-8000-MY.type"
+msgstr "Fault"
+msgid "SUN4V-8000-MY.severity"
+msgstr "Major"
+msgid "SUN4V-8000-MY.description"
+msgstr "The number of I-cache errors associated with this thread has exceeded acceptable levels.\n  Refer to %s for more information."
+msgid "SUN4V-8000-MY.response"
+msgstr "The fault manager will attempt to remove all threads associated with\nthis resource from service.\n"
+msgid "SUN4V-8000-MY.impact"
+msgstr "System performance is likely to be affected. \n"
+msgid "SUN4V-8000-MY.action"
+msgstr "Schedule a repair procedure to replace the affected resource, the identity of which can be determined using fmdump -v -u <EVENT_ID>.\n"
+#
+# code: SUN4V-8000-N3
+# keys: fault.cpu.ultraSPARC-T2.dcache
+#
+msgid "SUN4V-8000-N3.type"
+msgstr "Fault"
+msgid "SUN4V-8000-N3.severity"
+msgstr "Major"
+msgid "SUN4V-8000-N3.description"
+msgstr "The number of D-cache errors associated with this thread has exceeded acceptable levels.\n  Refer to %s for more information."
+msgid "SUN4V-8000-N3.response"
+msgstr "The fault manager will attempt to remove all threads associated with\nthis resource from service.\n"
+msgid "SUN4V-8000-N3.impact"
+msgstr "System performance is likely to be affected. \n"
+msgid "SUN4V-8000-N3.action"
+msgstr "Schedule a repair procedure to replace the affected resource, the identity of which can be determined using fmdump -v -u <EVENT_ID>.\n"
+#
+# code: SUN4V-8000-PH
+# keys: fault.cpu.ultraSPARC-T2.mau
+#
+msgid "SUN4V-8000-PH.type"
+msgstr "Fault"
+msgid "SUN4V-8000-PH.severity"
+msgstr "Major"
+msgid "SUN4V-8000-PH.description"
+msgstr "The number of modular arithmetic unit errors associated with this thread has exceeded acceptable levels.\n  Refer to %s for more information."
+msgid "SUN4V-8000-PH.response"
+msgstr "The fault manager will attempt to remove all threads associated with\nthis resource from service.\n"
+msgid "SUN4V-8000-PH.impact"
+msgstr "System performance is likely to be affected. \n"
+msgid "SUN4V-8000-PH.action"
+msgstr "Schedule a repair procedure to replace the affected resource, the identity of which can be determined using fmdump -v -u <EVENT_ID>.\n"
+#
+# code: SUN4V-8000-QD
+# keys: fault.cpu.ultraSPARC-T2.l2data-c
+#
+msgid "SUN4V-8000-QD.type"
+msgstr "Fault"
+msgid "SUN4V-8000-QD.severity"
+msgstr "Critical"
+msgid "SUN4V-8000-QD.description"
+msgstr "The number of level 2 cache correctable data errors has exceeded acceptable levels.\n  Refer to %s for more information."
+msgid "SUN4V-8000-QD.response"
+msgstr "No automated response.\n"
+msgid "SUN4V-8000-QD.impact"
+msgstr "System performance is likely to be affected. \n"
+msgid "SUN4V-8000-QD.action"
+msgstr "Schedule a repair procedure to replace the affected resource, the identity of which can be determined using fmdump -v -u <EVENT_ID>.\n"
+#
+# code: SUN4V-8000-R4
+# keys: fault.cpu.ultraSPARC-T2.l2cachetag
+#
+msgid "SUN4V-8000-R4.type"
+msgstr "Fault"
+msgid "SUN4V-8000-R4.severity"
+msgstr "Critical"
+msgid "SUN4V-8000-R4.description"
+msgstr "The number of level 2 cache tag errors has exceeded acceptable levels.\n  Refer to %s for more information."
+msgid "SUN4V-8000-R4.response"
+msgstr "No automated response.\n"
+msgid "SUN4V-8000-R4.impact"
+msgstr "System performance is likely to be affected. \n"
+msgid "SUN4V-8000-R4.action"
+msgstr "Schedule a repair procedure to replace the affected resource, the identity of which can be determined using fmdump -v -u <EVENT_ID>.\n"
+#
+# code: SUN4V-8000-SR
+# keys: fault.cpu.ultraSPARC-T2.l2cachectl
+#
+msgid "SUN4V-8000-SR.type"
+msgstr "Fault"
+msgid "SUN4V-8000-SR.severity"
+msgstr "Critical"
+msgid "SUN4V-8000-SR.description"
+msgstr "The number of level 2 cache control errors has exceeded acceptable levels.\n  Refer to %s for more information."
+msgid "SUN4V-8000-SR.response"
+msgstr "No automated response.\n"
+msgid "SUN4V-8000-SR.impact"
+msgstr "System performance is likely to be affected. System may be unstable.\n"
+msgid "SUN4V-8000-SR.action"
+msgstr "Schedule a repair procedure to replace the affected resource, the identity of which can be determined using fmdump -v -u <EVENT_ID>.\n"
+#
+# code: SUN4V-8000-TC
+# keys: fault.memory.link-u
+#
+msgid "SUN4V-8000-TC.type"
+msgstr "Fault"
+msgid "SUN4V-8000-TC.severity"
+msgstr "Critical"
+msgid "SUN4V-8000-TC.description"
+msgstr "A problem was detected in the interconnect between a memory DIMM module and\nits memory controller. \n  Refer to %s for more information."
+msgid "SUN4V-8000-TC.response"
+msgstr "No automated response.\n"
+msgid "SUN4V-8000-TC.impact"
+msgstr "System performance may be impacted.\n"
+msgid "SUN4V-8000-TC.action"
+msgstr "At convenient time, try reseating the memory module.  If problem persists,\ncontact Sun to schedule part replacement.\n"
+#
+# code: SUN4V-8000-UQ
+# keys: fault.cpu.ultraSPARC-T2.l2data-u
+#
+msgid "SUN4V-8000-UQ.type"
+msgstr "Fault"
+msgid "SUN4V-8000-UQ.severity"
+msgstr "Critical"
+msgid "SUN4V-8000-UQ.description"
+msgstr "The number of level 2 cache uncorrectable data errors has exceeded acceptable levels.\n  Refer to %s for more information."
+msgid "SUN4V-8000-UQ.response"
+msgstr "No automated response.\n"
+msgid "SUN4V-8000-UQ.impact"
+msgstr "System performance is likely to be affected. \n"
+msgid "SUN4V-8000-UQ.action"
+msgstr "Schedule a repair procedure to replace the affected resource, the identity of which can be determined using fmdump -v -u <EVENT_ID>.\n"
+#
+# code: SUN4V-8000-VE
+# keys: fault.cpu.ultraSPARC-T1.l2data-c
+#
+msgid "SUN4V-8000-VE.type"
+msgstr "Fault"
+msgid "SUN4V-8000-VE.severity"
+msgstr "Critical"
+msgid "SUN4V-8000-VE.description"
+msgstr "The number of level 2 cache correctable data errors has exceeded acceptable levels.\n  Refer to %s for more information."
+msgid "SUN4V-8000-VE.response"
+msgstr "No automated response.\n"
+msgid "SUN4V-8000-VE.impact"
+msgstr "System performance is likely to be affected. \n"
+msgid "SUN4V-8000-VE.action"
+msgstr "Schedule a repair procedure to replace the affected resource, the identity of which can be determined using fmdump -v -u <EVENT_ID>.\n"
+#
+# code: SUN4V-8000-WJ
+# keys: fault.cpu.ultraSPARC-T1.l2data-u
+#
+msgid "SUN4V-8000-WJ.type"
+msgstr "Fault"
+msgid "SUN4V-8000-WJ.severity"
+msgstr "Critical"
+msgid "SUN4V-8000-WJ.description"
+msgstr "The number of level 2 cache uncorrectable data errors has exceeded acceptable levels.\n  Refer to %s for more information."
+msgid "SUN4V-8000-WJ.response"
+msgstr "No automated response.\n"
+msgid "SUN4V-8000-WJ.impact"
+msgstr "System performance is likely to be affected. \n"
+msgid "SUN4V-8000-WJ.action"
+msgstr "Schedule a repair procedure to replace the affected resource, the identity of which can be determined using fmdump -v -u <EVENT_ID>.\n"
+#
+# code: SUN4V-8000-X2
+# keys: fault.memory.datapath
+#
+msgid "SUN4V-8000-X2.type"
+msgstr "Fault"
+msgid "SUN4V-8000-X2.severity"
+msgstr "Major"
+msgid "SUN4V-8000-X2.description"
+msgstr "Errors have been detected on multiple memory modules, suggesting that a problem exists somewhere else in the system.\n  Refer to %s for more information."
+msgid "SUN4V-8000-X2.response"
+msgstr "Error reports from the affected components will be logged for examination by Sun.\n"
+msgid "SUN4V-8000-X2.impact"
+msgstr "System performance and stability may be affected. \n"
+msgid "SUN4V-8000-X2.action"
+msgstr "Contact your service provider for further diagnosis.\n"
+#
+# code: SUN4V-8000-YX
+# keys: fault.io.n2.ncu
+#
+msgid "SUN4V-8000-YX.type"
+msgstr "Fault"
+msgid "SUN4V-8000-YX.severity"
+msgstr "Critical"
+msgid "SUN4V-8000-YX.description"
+msgstr "A problem was detected in the NCU subsystem of the N2's SOC\n  Refer to %s for more information."
+msgid "SUN4V-8000-YX.response"
+msgstr "One or more device instances may be disabled\n"
+msgid "SUN4V-8000-YX.impact"
+msgstr "Loss of services provided by the device\ninstances associated with this fault\n"
+msgid "SUN4V-8000-YX.action"
+msgstr "Schedule a repair procedure to replace the affected\ndevice if necessary, or contact Sun for support.\n"
+#
+# code: SUN4V-8001-02
+# keys: fault.io.n2.dmu
+#
+msgid "SUN4V-8001-02.type"
+msgstr "Fault"
+msgid "SUN4V-8001-02.severity"
+msgstr "Critical"
+msgid "SUN4V-8001-02.description"
+msgstr "A problem was detected in the DMU subsystem of the N2's SOC\n  Refer to %s for more information."
+msgid "SUN4V-8001-02.response"
+msgstr "One or more device instances may be disabled\n"
+msgid "SUN4V-8001-02.impact"
+msgstr "Loss of services provided by the device\ninstances associated with this fault\n"
+msgid "SUN4V-8001-02.action"
+msgstr "Schedule a repair procedure to replace the affected\ndevice if necessary, or contact Sun for support.\n"
+#
+# code: SUN4V-8001-1X
+# keys: fault.io.n2.niu
+#
+msgid "SUN4V-8001-1X.type"
+msgstr "Fault"
+msgid "SUN4V-8001-1X.severity"
+msgstr "Critical"
+msgid "SUN4V-8001-1X.description"
+msgstr "A problem was detected in the NIU subsystem of the N2's SOC\n  Refer to %s for more information."
+msgid "SUN4V-8001-1X.response"
+msgstr "One or more device instances may be disabled\n"
+msgid "SUN4V-8001-1X.impact"
+msgstr "Loss of services provided by the device\ninstances associated with this fault\n"
+msgid "SUN4V-8001-1X.action"
+msgstr "Schedule a repair procedure to replace the affected\ndevice if necessary, or contact Sun for support.\n"
+#
+# code: SUN4V-8001-2E
+# keys: fault.io.n2.siu
+#
+msgid "SUN4V-8001-2E.type"
+msgstr "Fault"
+msgid "SUN4V-8001-2E.severity"
+msgstr "Critical"
+msgid "SUN4V-8001-2E.description"
+msgstr "A problem was detected in the SIU subsystem of the N2's SOC\n  Refer to %s for more information."
+msgid "SUN4V-8001-2E.response"
+msgstr "One or more device instances may be disabled\n"
+msgid "SUN4V-8001-2E.impact"
+msgstr "Loss of services provided by the device\ninstances associated with this fault\n"
+msgid "SUN4V-8001-2E.action"
+msgstr "Schedule a repair procedure to replace the affected\ndevice if necessary, or contact Sun for support.\n"
+#
+# code: SUN4V-8001-3J
+# keys: fault.io.n2.soc
+#
+msgid "SUN4V-8001-3J.type"
+msgstr "Fault"
+msgid "SUN4V-8001-3J.severity"
+msgstr "Critical"
+msgid "SUN4V-8001-3J.description"
+msgstr "A problem was detected in N2's SOC\n  Refer to %s for more information."
+msgid "SUN4V-8001-3J.response"
+msgstr "One or more device instances may be disabled\n"
+msgid "SUN4V-8001-3J.impact"
+msgstr "Loss of services provided by the device\ninstances associated with this fault\n"
+msgid "SUN4V-8001-3J.action"
+msgstr "Schedule a repair procedure to replace the affected\ndevice if necessary, or contact Sun for support.\n"
+#
+# code: SUN4V-8001-4C
+# keys: fault.io.n2.crossbar
+#
+msgid "SUN4V-8001-4C.type"
+msgstr "Fault"
+msgid "SUN4V-8001-4C.severity"
+msgstr "Critical"
+msgid "SUN4V-8001-4C.description"
+msgstr "A problem was detected in the crossbar of the N2's SOC\n  Refer to %s for more information."
+msgid "SUN4V-8001-4C.response"
+msgstr "One or more device instances may be disabled\n"
+msgid "SUN4V-8001-4C.impact"
+msgstr "Loss of services provided by the device\ninstances associated with this fault\n"
+msgid "SUN4V-8001-4C.action"
+msgstr "Schedule a repair procedure to replace the affected\ndevice if necessary, or contact Sun for support.\n"
--- a/usr/src/cmd/fm/eversholt/files/sparc/sun4/fire.esc	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/eversholt/files/sparc/sun4/fire.esc	Fri Dec 22 12:42:28 2006 -0800
@@ -18,10 +18,10 @@
  *
  * CDDL HEADER END
  */
-/*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
+/* 
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved. 
+ * Use is subject to license terms. 
+ */ 
  
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
@@ -31,8 +31,9 @@
  * Eversholt rules for the Fire nexus driver
  */
  
-#define HB_FIT			1000 
-#define HBUS_FIT		1000 
+#define HB_FIT			400 
+#define HBUS_FIT		400 
+#define CPU_FIT			500 
 #define PCI_DEV_FIT		1000 
 #define PCIEX_DEV_FIT		1000 
 #define EBUS_FIT		1000 
@@ -40,9 +41,7 @@
 #define LINK_EVENTS_TIME	1h
 #define	CE_EVENTS_COUNT		10
 #define	CE_EVENTS_TIME		1h
-
-#define PROP_PLAT_FRU		"PLAT-FRU"
-
+ 
 /*
  * Macros for CE Fabric ereports
  */
@@ -56,136 +55,107 @@
 #define IS_SECONDARY (! payloadprop("primary"))
 
 /*
- * payload: imu-rds or imu-scs
- *
- * Extract the request id, the BDF, value in the IMU RDS/SCS log register
+ * payload: imu-rds
  *
- * PRM 2.0, pg 227-228
- *    REQ_ID field: bits [47:32]
- *
+ * Extract the request id, the BDF, value in the IMU RDS log register
  * Example:
  *   0x7766554433221100
  *         ^^^^
  */
-#define IMU_REQ_ID_BIT_OFFSET	32
-#define IMU_REQ_ID_BIT_MODULO	(1 << 16)
-#define IMU_MATCH_BDF(imu_rds_scs, b, d, f) \
-	( (payloadprop("primary")) && \
-	  ((((imu_rds_scs) >> IMU_REQ_ID_BIT_OFFSET) % IMU_REQ_ID_BIT_MODULO) \
-        	 == ((b << 8) | (d << 3) | f)) \
-	)
-
+#define IMU_MATCH_BDF(b, d, f) \
+	( IS_PRIMARY && ((payloadprop("imu-rds") >> 32) & 0xFFFF) == \
+		((b << 8) | (d << 3) | f))
 
-/*
- * payload: mmu-tfsr
- *
- * Extract the request id, the BDF value, in the MMU TFSR register
- *
- * PRM 2.0, pg 243
- *    Request ID: bits 15:0
- *
- * Example:
- *   0x7766554433221100
- *                 ^^^^
- */
-#define MMU_REQ_ID_BIT_MODULO (1 << 16)
-#define MMU_MATCH_BDF(mmu_tfsr, b, d, f) \
-	( (payloadprop("primary")) && \
-	  (((mmu_tfsr) % MMU_REQ_ID_BIT_MODULO) == ((b << 8) | (d << 3) | f)) \
-	)
-
-
-event error.io.fire.dmc.bad_op@hostbridge/pciexrc; 
-event error.io.fire.dmc.bad_parity@hostbridge/pciexrc; 
-event error.io.fire.pec.i-e-buffer-parity@hostbridge/pciexrc;
-event error.io.fire.pec.misc-egress@hostbridge/pciexrc ; 
-event error.io.fire.pec.adjacentnode@hostbridge/pciexrc ; 
-event error.io.fire.pec.secondary@hostbridge/pciexrc ; 
-event error.io.fire.pec.fabric_error@hostbridge/pciexrc ; 
-
-/*
- * Fatal JBC ereport: (mb_pea, cpe, ape, pio_cpe, jtceew, jtceei, jtceer)
- * ebus_to   ereport:
- *   The fmri of the ereport is ioboard0/hostbridge0
- *
- * Other ereports:
- *   The fmri is ioboard0/hostbridge0/pciexrc[0-1]
- *
- */
+/***************
+ * JBC ereports
+ ***************/
+event ereport.io.fire.jbc.ape@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.fire.jbc.bjc@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.fire.jbc.ce_asyn@hostbridge/pciexrc{within(5s)};
+event ereport.io.fire.jbc.cpe@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.fire.jbc.ebus_to@hostbridge/pciexrc{within(5s)};
+event ereport.io.fire.jbc.ebus_to@hostbridge{within(5s)};
+event ereport.io.fire.jbc.icise@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.fire.jbc.ijp@hostbridge/pciexrc{within(5s)}; 
 event ereport.io.fire.jbc.ill_acc@hostbridge/pciexrc{within(5s)};
 event ereport.io.fire.jbc.ill_acc_rd@hostbridge/pciexrc{within(5s)};
-
-event ereport.io.fire.jbc.mb_pea@hostbridge{within(5s)};
+event ereport.io.fire.jbc.ill_bmr@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.fire.jbc.ill_bmw@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.fire.jbc.jbe@hostbridge/pciexrc{within(5s)};
+event ereport.io.fire.jbc.jtceei@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.fire.jbc.jtceer@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.fire.jbc.jtceew@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.fire.jbc.jte@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.fire.jbc.jue@hostbridge/pciexrc{within(5s)};
+event ereport.io.fire.jbc.mb_pea@hostbridge/pciexrc{within(5s)};
 event ereport.io.fire.jbc.mb_per@hostbridge/pciexrc{within(5s)}; 
 event ereport.io.fire.jbc.mb_pew@hostbridge/pciexrc{within(5s)}; 
-event ereport.io.fire.jbc.ebus_to@hostbridge{within(5s)};
-event ereport.io.fire.jbc.ebus_to@hostbridge/pciexrc{within(5s)};
-
-
-/*
- * Do not diagnose or silently consume the next 15 ereports.
- * There will be a no-subscriber fmd message.
- */
- /*
-event ereport.io.fire.jbc.jue@hostbridge/pciexrc{within(5s)};
+event ereport.io.fire.jbc.pio_cpe@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.fire.jbc.pio_dpe@hostbridge/pciexrc{within(5s)}; 
 event ereport.io.fire.jbc.pio_unmap@hostbridge/pciexrc{within(5s)};  
 event ereport.io.fire.jbc.pio_unmap_rd@hostbridge/pciexrc{within(5s)};  
-event ereport.io.fire.jbc.jte@hostbridge/pciexrc{within(5s)}; 
-event ereport.io.fire.jbc.jbe@hostbridge/pciexrc{within(5s)}; 
-event ereport.io.fire.jbc.jtceew@hostbridge{within(5s)}; 
-event ereport.io.fire.jbc.jtceer@hostbridge{within(5s)}; 
-event ereport.io.fire.jbc.jtceei@hostbridge{within(5s)}; 
-event ereport.io.fire.jbc.icise@hostbridge/pciexrc{within(5s)}; 
-event ereport.io.fire.jbc.ijp@hostbridge/pciexrc{within(5s)}; 
-event ereport.io.fire.jbc.ill_bmw@hostbridge/pciexrc{within(5s)} ; 
-event ereport.io.fire.jbc.ill_bmr@hostbridge/pciexrc{within(5s)} ; 
+event ereport.io.fire.jbc.rd_dpe@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.fire.jbc.ue_asyn@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.fire.jbc.unsol_intr@hostbridge/pciexrc{within(5s)};
 event ereport.io.fire.jbc.unsol_rd@hostbridge/pciexrc{within(5s)};
-event ereport.io.fire.jbc.unsol_intr@hostbridge/pciexrc{within(5s)};
-event ereport.io.fire.jbc.bjc@hostbridge/pciexrc{within(5s)}; 
- */
+event ereport.io.fire.jbc.wr_dpe@hostbridge/pciexrc{within(5s)}; 
 
-/*
+/***************
  * DMC ereports
- *
- */
+ ***************/
 event ereport.io.fire.dmc.byp_err@hostbridge/pciexrc{within(5s)}; 
 event ereport.io.fire.dmc.byp_oor@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.fire.dmc.cor_not_en@hostbridge/pciexrc{within(5s)};
+event ereport.io.fire.dmc.eq_not_en@hostbridge/pciexrc{within(5s)};
+event ereport.io.fire.dmc.eq_over@hostbridge/pciexrc{within(5s)};
+event ereport.io.fire.dmc.fatal_not_en@hostbridge/pciexrc{within(5s)};
+event ereport.io.fire.dmc.msi_mal_err@hostbridge/pciexrc{within(5s)};
+event ereport.io.fire.dmc.msi_not_en@hostbridge/pciexrc{within(5s)};
+event ereport.io.fire.dmc.msi_par_err@hostbridge/pciexrc{within(5s)};
+event ereport.io.fire.dmc.nonfatal_not_en@hostbridge/pciexrc{within(5s)};
+event ereport.io.fire.dmc.pmeack_not_en@hostbridge/pciexrc{within(5s)};
+event ereport.io.fire.dmc.pmpme_not_en@hostbridge/pciexrc{within(5s)};
+event ereport.io.fire.dmc.tbw_dme@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.fire.dmc.tbw_dpe@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.fire.dmc.tbw_err@hostbridge/pciexrc{within(5s)};
+event ereport.io.fire.dmc.tbw_ude@hostbridge/pciexrc{within(5s)}; 
 event ereport.io.fire.dmc.trn_err@hostbridge/pciexrc{within(5s)}; 
 event ereport.io.fire.dmc.trn_oor@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.fire.dmc.ttc_cae@hostbridge/pciexrc{within(5s)};
+event ereport.io.fire.dmc.ttc_dpe@hostbridge/pciexrc{within(5s)}; 
 event ereport.io.fire.dmc.tte_inv@hostbridge/pciexrc{within(5s)}; 
 event ereport.io.fire.dmc.tte_prt@hostbridge/pciexrc{within(5s)}; 
-event ereport.io.fire.dmc.ttc_dpe@hostbridge/pciexrc{within(5s)}; 
-event ereport.io.fire.dmc.tbw_dme@hostbridge/pciexrc{within(5s)}; 
-event ereport.io.fire.dmc.tbw_ude@hostbridge/pciexrc{within(5s)}; 
-event ereport.io.fire.dmc.tbw_err@hostbridge/pciexrc{within(5s)}; 
-event ereport.io.fire.dmc.tbw_dpe@hostbridge/pciexrc{within(5s)}; 
-event ereport.io.fire.dmc.ttc_cae@hostbridge/pciexrc{within(5s)};
-event ereport.io.fire.dmc.eq_over@hostbridge/pciexrc{within(5s)};
 
-/*
+/***************
  * TLU Other Event ereports
- *
- */
+ ***************/
+event ereport.io.fire.pec.crs@hostbridge/pciexrc{within(5s)};
+event ereport.io.fire.pec.edp@hostbridge/pciexrc{within(5s)};
+event ereport.io.fire.pec.ehp@hostbridge/pciexrc{within(5s)};
+event ereport.io.fire.pec.eip@hostbridge/pciexrc{within(5s)};
+event ereport.io.fire.pec.emp@hostbridge/pciexrc{within(5s)};
+event ereport.io.fire.pec.epe@hostbridge/pciexrc{within(5s)};
+event ereport.io.fire.pec.ero@hostbridge/pciexrc{within(5s)};
+event ereport.io.fire.pec.erp@hostbridge/pciexrc{within(5s)};
+event ereport.io.fire.pec.eru@hostbridge/pciexrc{within(5s)};
 event ereport.io.fire.pec.ihb_pe@hostbridge/pciexrc{within(5s)};
 event ereport.io.fire.pec.iip@hostbridge/pciexrc{within(5s)};
-event ereport.io.fire.pec.edp@hostbridge/pciexrc{within(5s)};
-event ereport.io.fire.pec.ehp@hostbridge/pciexrc{within(5s)};
-event ereport.io.fire.pec.eru@hostbridge/pciexrc{within(5s)};
-event ereport.io.fire.pec.ero@hostbridge/pciexrc{within(5s)};
-event ereport.io.fire.pec.emp@hostbridge/pciexrc{within(5s)};
-event ereport.io.fire.pec.epe@hostbridge/pciexrc{within(5s)};
-event ereport.io.fire.pec.erp@hostbridge/pciexrc{within(5s)};
-event ereport.io.fire.pec.eip@hostbridge/pciexrc{within(5s)};
+event ereport.io.fire.pec.ldn@hostbridge/pciexrc{within(5s)};
+event ereport.io.fire.pec.lin@hostbridge/pciexrc{within(5s)};
+event ereport.io.fire.pec.lrs@hostbridge/pciexrc{within(5s)};
+event ereport.io.fire.pec.lup@hostbridge/pciexrc{within(5s)};
+event ereport.io.fire.pec.mrc@hostbridge/pciexrc{within(5s)};
+event ereport.io.fire.pec.ruc@hostbridge/pciexrc{within(5s)};
+event ereport.io.fire.pec.wuc@hostbridge/pciexrc{within(5s)};
 
-event ereport.io.fire.link-events-trip@hostbridge/pciexrc ; 
-
-/* 
+/***************
  * TLU Uncorrectable and Correctable ereports
- */
+ ***************/
 event ereport.io.fire.pec.ur@hostbridge/pciexrc {within(5s)};
 event ereport.io.fire.pec.uc@hostbridge/pciexrc {within(5s)};
 event ereport.io.fire.pec.cto@hostbridge/pciexrc {within(5s)};
 event ereport.io.fire.pec.rof@hostbridge/pciexrc {within(5s)};
+event ereport.io.fire.pec.mfc@hostbridge/pciexrc {within(5s)};
 event ereport.io.fire.pec.mfp@hostbridge/pciexrc {within(5s)};
 event ereport.io.fire.pec.pois@hostbridge/pciexrc {within(5s)};
 event ereport.io.fire.pec.fcp@hostbridge/pciexrc {within(5s)};
@@ -197,117 +167,73 @@
 event ereport.io.fire.pec.rnr@hostbridge/pciexrc {within(5s)};
 event ereport.io.fire.pec.rto@hostbridge/pciexrc {within(5s)};
 
-/* 
+/***************
  * Fire Fabric ereport
+ * -------------
  * Whenever a leaf device sends an error message (fatal, non-fatal, or CE) to 
  * root complex, the nexus driver publishes this ereport to log the ereport.
- */
+ ***************/
 event ereport.io.fire.fabric@pciexbus/pciexdev/pciexfn {within(1s)};
 event ereport.io.fire.fabric@pcibus/pcidev/pcifn {within(1s)};
+event error.io.fire.fabric-sib@hostbridge/pciexrc;
+event error.io.fire.fabric@pciexbus/pciexdev/pciexfn;
+event error.io.fire.fabric@pcibus/pcidev/pcifn;
 
-/* 
- * A faulty Fire hostbridge may cause (* may cause PCI-E abort): 
- * 
- *  - merge buffer errors mb_pea,w,r 
- *  - mmu data parity errors ttc_dpe*, tbw_dpe*
- *  - ingress/egress buffer parity errors ihb_pe, iip, edp, ehp
- *  - misc egress eru, ero, emp, epe, erp, eip
- *  - too many link down/reset events
- *  - EQ overflow
- */ 
+/***************
+ * sun4v unknown error packets
+ * -------------
+ * In a sun4v system, if HV sends an epkt to the guest the following wrong
+ * things can happen.
+ * o HV sends malformed epkt
+ * o Guest has coding error and doesn't understand epkt
+ * o HV and Guest are out of sync.
+ ***************/
+event ereport.io.fire.epkt@hostbridge/pciexrc {within(5s)};
 
+/******************************
+ * Generic Rules Begin Here   *
+ ******************************/
+
+/***************
+ * Fire Asic HW error
+ * -------------
+ * Errors caused by parity or unexpected behaviors in the asic.
+ ***************/
 fru hostbridge/pciexrc; 
 asru hostbridge/pciexrc; 
- 
 event fault.io.fire.asic@hostbridge/pciexrc, 
-    FITrate=HB_FIT, FRU=hostbridge/pciexrc, ASRU=hostbridge/pciexrc; 
- 
-prop fault.io.fire.asic@hostbridge/pciexrc (0)-> 
-    ereport.io.fire.jbc.mb_pea@hostbridge,
-    ereport.io.fire.jbc.mb_per@hostbridge/pciexrc,
-    ereport.io.fire.jbc.mb_pew@hostbridge/pciexrc,
-    ereport.io.fire.dmc.eq_over@hostbridge/pciexrc,
-    error.io.fire.dmc.bad_parity@hostbridge/pciexrc,
-    error.io.fire.pec.i-e-buffer-parity@hostbridge/pciexrc,
-    error.io.fire.pec.misc-egress@hostbridge/pciexrc,
-    error.io.fire.pec.adjacentnode@hostbridge/pciexrc; 
-
-prop error.io.fire.dmc.bad_parity@hostbridge/pciexrc (1)-> 
-    ereport.io.fire.dmc.ttc_dpe@hostbridge/pciexrc,
-    ereport.io.fire.dmc.tbw_dpe@hostbridge/pciexrc; 
+    FITrate=HB_FIT,
+    ASRU=hostbridge/pciexrc,
+    FRU=hostbridge/pciexrc;
 
-prop error.io.fire.pec.i-e-buffer-parity@hostbridge/pciexrc (1) ->
-    ereport.io.fire.pec.ihb_pe@hostbridge/pciexrc,
-    ereport.io.fire.pec.iip@hostbridge/pciexrc,
-    ereport.io.fire.pec.ehp@hostbridge/pciexrc,
-    ereport.io.fire.pec.edp@hostbridge/pciexrc;
+event error.io.fire.jbc.asic@hostbridge/pciexrc;
+event error.io.fire.dmc.asic@hostbridge/pciexrc;
+event error.io.fire.pec.asic@hostbridge/pciexrc;
 
-prop error.io.fire.pec.misc-egress@hostbridge/pciexrc (1) ->
-    ereport.io.fire.pec.eru@hostbridge/pciexrc,
-    ereport.io.fire.pec.ero@hostbridge/pciexrc,
-    ereport.io.fire.pec.emp@hostbridge/pciexrc,
-    ereport.io.fire.pec.epe@hostbridge/pciexrc,
-    ereport.io.fire.pec.erp@hostbridge/pciexrc,
-    ereport.io.fire.pec.eip@hostbridge/pciexrc;
-
-
-/*
- * EBUS fault
- */
-event fault.io.ebus@hostbridge/pciexrc,
-    FITrate=EBUS_FIT, FRU=hostbridge/pciexrc, ASRU=hostbridge/pciexrc;
+prop fault.io.fire.asic@hostbridge/pciexrc (0)->
+    error.io.fire.jbc.asic@hostbridge/pciexrc,
+    error.io.fire.dmc.asic@hostbridge/pciexrc,
+    error.io.fire.pec.asic@hostbridge/pciexrc;
 
-/*
- * A faulty ebus can cause ebus timeout ebus_to
- */
-prop fault.io.ebus@hostbridge/pciexrc (0)->
-    ereport.io.fire.jbc.ebus_to@hostbridge,
-    ereport.io.fire.jbc.ebus_to@hostbridge/pciexrc;
-
-
-/*
- * hostbus
- */
-event fault.io.fire.hbus@hostbridge/pciexrc, 
-    FITrate=HBUS_FIT, FRU=hostbridge/pciexrc, ASRU=hostbridge/pciexrc; 
- 
-event error.io.fire.jbc.pio_dpe@hostbridge/pciexrc;
+/***************
+ * Fire PX SW error
+ * -------------
+ * Errors caused by bad SW
+ ***************/
+event defect.io.fire.pciex.driver@hostbridge/pciexrc;
+event error.io.fire.jbc.driver@hostbridge/pciexrc;
+event error.io.fire.dmc.driver@hostbridge/pciexrc;
+event error.io.fire.dmc.bad_state@hostbridge/pciexrc;
 
-event ereport.io.fire.jbc.ape@hostbridge{within(5s)}; 
-event ereport.io.fire.jbc.pio_dpe@hostbridge/pciexrc{within(5s)}; 
-event ereport.io.fire.jbc.rd_dpe@hostbridge/pciexrc{within(5s)}; 
-event ereport.io.fire.jbc.wr_dpe@hostbridge/pciexrc{within(5s)}; 
-event ereport.io.fire.jbc.cpe@hostbridge{within(5s)}; 
-event ereport.io.fire.jbc.pio_cpe@hostbridge{within(5s)}; 
- 
-/* A faulty host bus may cause: 
- * 
- *  - ape:      jbus address parity error. 
- *  - pio_dpe*: jbus PIO write parity error. 
- *  - rd_dpe :  jbus DMA read parity error 
- *  - wr_dpe:   jbus DMA write parity error. 
- *  - cpe:      jbus control parity error. 
- *  - pio_cpe:  jbus PIO control parity error. 
- */ 
-prop fault.io.fire.hbus@hostbridge/pciexrc (0)-> 
-    ereport.io.fire.jbc.ape@hostbridge, 
-    error.io.fire.jbc.pio_dpe@hostbridge/pciexrc, 
-    ereport.io.fire.jbc.rd_dpe@hostbridge/pciexrc, 
-    ereport.io.fire.jbc.wr_dpe@hostbridge/pciexrc, 
-    ereport.io.fire.jbc.cpe@hostbridge, 
-    ereport.io.fire.jbc.pio_cpe@hostbridge; 
+prop defect.io.fire.pciex.driver@hostbridge/pciexrc (0)->
+    error.io.fire.jbc.driver@hostbridge/pciexrc,
+    error.io.fire.dmc.driver@hostbridge/pciexrc,
+    error.io.fire.dmc.bad_state@hostbridge/pciexrc,
+    ereport.io.fire.epkt@hostbridge/pciexrc;
 
-prop error.io.fire.jbc.pio_dpe@hostbridge/pciexrc (1)->
-    ereport.io.fire.jbc.pio_dpe@hostbridge/pciexrc ;
-    
-event ereport.io.fire.dmc.msi_par_err@hostbridge/pciexrc{within(5s)};
-event ereport.io.fire.dmc.msi_mal_err@hostbridge/pciexrc{within(5s)};
-
-/*
- *
- * PCI-E device fault
- *
- */
+/***************
+ * PCI-E/PCI device fault and SW defects
+ ***************/
 fru pciexbus/pciexdev;
 asru pciexbus/pciexdev/pciexfn;
 event fault.io.fire.pciex.device@pciexbus/pciexdev/pciexfn,
@@ -315,49 +241,6 @@
     ASRU=pciexbus/pciexdev/pciexfn,
     FITrate=PCIEX_DEV_FIT;
 
-/*
- * A faulty PCI-E device can cause (chip specific ereports):
- *
- *    MSI malformed or parity error
- *
- * Extract the request id in the RDS/SCS log register. It 's the BDF
- * value of the device.
- */
-prop fault.io.fire.pciex.device@pciexbus[b]/pciexdev[d]/pciexfn[f] (0) ->
-    ereport.io.fire.dmc.msi_mal_err@hostbridge/pciexrc
-        {
-            IMU_MATCH_BDF(payloadprop("imu-rds"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pciexbus[b]/pciexdev[d]/pciexfn[f])
-        },
-    ereport.io.fire.dmc.msi_par_err@hostbridge/pciexrc
-        { 
-            IMU_MATCH_BDF(payloadprop("imu-rds"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pciexbus[b]/pciexdev[d]/pciexfn[f])
-        };
- 
-/*
- *  Event queue overflow
- */
-prop fault.io.fire.pciex.device@pciexbus[b]/pciexdev[d]/pciexfn[0] (0) ->
-    ereport.io.fire.dmc.eq_over@hostbridge/pciexrc
-        {  
-            /*
-             * Indict PCI-E FRU(s) under this root complex excluding the 
-             * one that the Fire ASIC resides on. 
-             */
-            is_under(hostbridge/pciexrc, pciexbus[b]/pciexdev[d]/pciexfn[0])
-	    &&
-	    (confprop(asru(pciexbus[b]/pciexdev[d]/pciexfn[0]), PROP_PLAT_FRU)
-	        != 
-	     confprop(asru(hostbridge/pciexrc), PROP_PLAT_FRU))
-        };
-
-
-/*
- * PCI devices
- * Similar to the above rules.
- */
-
 fru pcibus/pcidev;
 asru pcibus/pcidev/pcifn;
 event fault.io.fire.pci.device@pcibus/pcidev/pcifn,
@@ -365,16 +248,262 @@
     FRU=pcibus/pcidev,
     ASRU=pcibus/pcidev/pcifn;
 
+event defect.io.fire.pciex.driver@pciexbus/pciexdev/pciexfn;
+
+/******************************
+ * JBC Rules Begin Here       *
+ ******************************/
+
+/***************
+ * EBUS fault
+ * -------------
+ * Errors involving the ebus
+ ***************/
+fru hostbridge/pciexrc;
+asru hostbridge/pciexrc;
+event fault.io.ebus@hostbridge/pciexrc,
+    FITrate=EBUS_FIT,
+    FRU=hostbridge/pciexrc,
+    ASRU=hostbridge/pciexrc;
+
+/*
+ * A faulty ebus can cause ebus timeout ebus_to
+ * ebus_to   ereport:
+ *   sun4v: The fmri of the ereport is ioboard/hostbridge
+ *   sun4u: The fmri of the ereport is pciexrc
+ */
+prop fault.io.ebus@hostbridge/pciexrc (1)->
+    ereport.io.fire.jbc.ebus_to@hostbridge,
+    ereport.io.fire.jbc.ebus_to@hostbridge/pciexrc;
+
+/***************
+ * Fire Asic HW error
+ * -------------
+ * Errors caused by parity or unexpected behaviors in the asic.
+ ***************/
+prop error.io.fire.jbc.asic@hostbridge/pciexrc (1)->
+    ereport.io.fire.jbc.cpe@hostbridge/pciexrc, 
+    ereport.io.fire.jbc.mb_pea@hostbridge/pciexrc,
+    ereport.io.fire.jbc.mb_per@hostbridge/pciexrc,
+    ereport.io.fire.jbc.mb_pew@hostbridge/pciexrc,
+    ereport.io.fire.jbc.pio_cpe@hostbridge/pciexrc,
+    ereport.io.fire.jbc.pio_dpe@hostbridge/pciexrc; 
+
+/***************
+ * JBC Hostbus Link Errors
+ * -------------
+ * Possible Parity Errors caused by bad links traces or cables.
+ * For instance on Ontarios there is a flex cable.  For Chicagos
+ * it could be the link trace between the CPU and Fire.
+ ***************/
+event error.io.fire.jbc.bad_link@hostbridge/pciexrc;
+
+prop error.io.fire.jbc.bad_link@hostbridge/pciexrc (1)-> 
+    ereport.io.fire.jbc.ape@hostbridge/pciexrc,
+    ereport.io.fire.jbc.bjc@hostbridge/pciexrc,
+    ereport.io.fire.jbc.rd_dpe@hostbridge/pciexrc,
+    ereport.io.fire.jbc.wr_dpe@hostbridge/pciexrc;
+
+/***************
+ * JBC Hostbus Errors
+ * -------------
+ * Errors being returned from the hostbus side and detected by fire asic.
+ ***************/
+fru hostbridge/pciexrc;
+asru hostbridge/pciexrc;
+event fault.io.fire.hbus@hostbridge/pciexrc, 
+    FITrate=HBUS_FIT,
+    FRU=hostbridge/pciexrc, 
+    ASRU=hostbridge/pciexrc;
+ 
+prop fault.io.fire.hbus@hostbridge/pciexrc (0)-> 
+    error.io.fire.jbc.bad_link@hostbridge/pciexrc,
+    ereport.io.fire.jbc.icise@hostbridge/pciexrc,
+    ereport.io.fire.jbc.ill_bmr@hostbridge/pciexrc,
+    ereport.io.fire.jbc.jtceei@hostbridge/pciexrc,
+    ereport.io.fire.jbc.jtceer@hostbridge/pciexrc,
+    ereport.io.fire.jbc.jtceew@hostbridge/pciexrc;
+
+/***************
+ * JBC Datapath Errors
+ * -------------
+ * Errors resulting from the datapath of the hostbus and detected by fire asic.
+ ***************/
+fru cmp;
+asru cmp;
+event fault.io.fire.datapath@cmp,
+    FITrate=CPU_FIT,
+    FRU=cmp,
+    ASRU=cmp;
+
+prop fault.io.fire.datapath@cmp (0)->
+    error.io.fire.jbc.bad_link@hostbridge/pciexrc;
+
+/* Duplicate the above fault prop for cpumodule */
+fru cpumodule/cpu;
+asru cpumodule/cpu;
+event fault.io.fire.datapath@cpumodule/cpu,
+    FITrate=CPU_FIT, 
+    FRU=cpumodule/cpu,
+    ASRU=cpumodule/cpu;
+
+prop fault.io.fire.datapath@cpumodule/cpu (0)->
+    error.io.fire.jbc.bad_link@hostbridge/pciexrc,
+    ereport.io.fire.jbc.wr_dpe@hostbridge/pciexrc;
+
+/***************
+ * Fire driver is at fault.
+ * -------------
+ * The px driver should not have been in this state.  Defect the px driver.
+ ***************/
+prop error.io.fire.jbc.driver@hostbridge/pciexrc (1)->
+    ereport.io.fire.jbc.ijp@hostbridge/pciexrc,
+    ereport.io.fire.jbc.ill_acc@hostbridge/pciexrc,
+    ereport.io.fire.jbc.ill_acc_rd@hostbridge/pciexrc,
+    ereport.io.fire.jbc.ill_bmw@hostbridge/pciexrc,
+    ereport.io.fire.jbc.jue@hostbridge/pciexrc,
+    ereport.io.fire.jbc.pio_unmap@hostbridge/pciexrc,
+    ereport.io.fire.jbc.pio_unmap_rd@hostbridge/pciexrc;
+
+
+/******************************
+ * DMC Rules Begin Here       *
+ ******************************/
+
+/***************
+ * Fire PX SW error
+ * -------------
+ * Errors caused by bad SW
+ ***************/
+prop error.io.fire.dmc.driver@hostbridge/pciexrc (1)->
+    ereport.io.fire.dmc.ttc_cae@hostbridge/pciexrc;
+ 
+/***************
+ * Unexpected Fire State
+ * -------------
+ * The px driver should not have been in this state.  Defect the px driver.
+ ***************/
+event error.io.fire.dmc.bad_state-mmu@hostbridge/pciexrc;
+event error.io.fire.dmc.bad_state-no_fab@hostbridge/pciexrc;
+
+prop error.io.fire.dmc.bad_state@hostbridge/pciexrc (1)->
+    ereport.io.fire.dmc.cor_not_en@hostbridge/pciexrc,
+    ereport.io.fire.dmc.eq_not_en@hostbridge/pciexrc,
+    ereport.io.fire.dmc.fatal_not_en@hostbridge/pciexrc,
+    ereport.io.fire.dmc.msi_not_en@hostbridge/pciexrc,
+    ereport.io.fire.dmc.nonfatal_not_en@hostbridge/pciexrc,
+    ereport.io.fire.dmc.pmeack_not_en@hostbridge/pciexrc,
+    ereport.io.fire.dmc.pmpme_not_en@hostbridge/pciexrc,
+    error.io.fire.dmc.bad_state-no_fab@hostbridge/pciexrc;
+
+prop error.io.fire.dmc.bad_state-no_fab@hostbridge/pciexrc (1)->
+    error.io.fire.dmc.bad_state-mmu@hostbridge/pciexrc;
+
+prop error.io.fire.dmc.bad_state-no_fab@hostbridge/pciexrc (1)->
+    error.io.fire.fabric-sib@hostbridge/pciexrc;
+
+prop error.io.fire.dmc.bad_state-mmu@hostbridge/pciexrc (1)->
+    ereport.io.fire.dmc.tbw_dme@hostbridge/pciexrc,
+    ereport.io.fire.dmc.trn_err@hostbridge/pciexrc;
+
+/***************
+ * Fire Asic HW error
+ * -------------
+ * Errors caused by parity or unexpected behaviors in the asic.
+ ***************/
+event error.io.fire.dmc.bad_parity@hostbridge/pciexrc; 
+
+prop error.io.fire.dmc.asic@hostbridge/pciexrc (1)->
+    error.io.fire.dmc.bad_parity@hostbridge/pciexrc,
+    ereport.io.fire.dmc.eq_over@hostbridge/pciexrc;
+
+/***************
+ * Parity errors caused by dmc
+ * -------------
+ * Fire asic error.
+ ***************/
+event error.io.fire.dmc.bad_parity-no_fab@hostbridge/pciexrc;
+event error.io.fire.dmc.bad_parity-mmu@hostbridge/pciexrc;
+
+prop error.io.fire.dmc.bad_parity@hostbridge/pciexrc (1)-> 
+    ereport.io.fire.dmc.msi_par_err@hostbridge/pciexrc,
+    error.io.fire.dmc.bad_parity-no_fab@hostbridge/pciexrc;
+
+prop error.io.fire.dmc.bad_parity-no_fab@hostbridge/pciexrc (1)->
+    error.io.fire.dmc.bad_parity-mmu@hostbridge/pciexrc;
+
+prop error.io.fire.dmc.bad_parity-no_fab@hostbridge/pciexrc (1)->
+    error.io.fire.fabric-sib@hostbridge/pciexrc;
+
+prop error.io.fire.dmc.bad_parity-mmu@hostbridge/pciexrc (1)->
+    ereport.io.fire.dmc.tbw_dpe@hostbridge/pciexrc,
+    ereport.io.fire.dmc.tbw_ude@hostbridge/pciexrc,
+    ereport.io.fire.dmc.ttc_dpe@hostbridge/pciexrc;
+	
+
+/***************
+ * Bad DMA requests
+ * -------------
+ * Errors caused by bad leaf drivers, which will end up sending fire.fabric
+ * ereport, which will be diagnosed in itself.  Do not diagnose the bad DMA
+ * requests and rely on the fire.fabric error being there.  Propagate to a
+ * fault.io.fire.pciex.device.
+ *
+ * Atleast 1 PCIe device will be faulted.  PCI devices will also be if the
+ * DMA came from a PCI device.
+ ***************/
+event error.io.fire.dmc.fabric_diag@hostbridge/pciexrc;
+
+prop error.io.fire.dmc.fabric_diag@hostbridge/pciexrc(0) ->
+    ereport.io.fire.dmc.byp_err@hostbridge/pciexrc{ IS_PRIMARY },
+    ereport.io.fire.dmc.byp_oor@hostbridge/pciexrc{ IS_PRIMARY },
+    ereport.io.fire.dmc.trn_oor@hostbridge/pciexrc{ IS_PRIMARY },
+    ereport.io.fire.dmc.tte_inv@hostbridge/pciexrc{ IS_PRIMARY },
+    ereport.io.fire.dmc.tte_prt@hostbridge/pciexrc{ IS_PRIMARY };
+
+prop error.io.fire.fabric@pciexbus/pciexdev/pciexfn (0) ->
+	error.io.fire.dmc.fabric_diag@hostbridge/pciexrc {
+		is_under(hostbridge/pciexrc, pciexbus/pciexdev/pciexfn)
+	};
+
+/***************
+ * Malformed MSI
+ * -------------
+ * A non-compliant PCIe/PCI device sent a malformed MSI.
+ ***************/
+prop fault.io.fire.pciex.device@pciexbus[b]/pciexdev[d]/pciexfn[f] (0) ->
+    ereport.io.fire.dmc.msi_mal_err@hostbridge/pciexrc
+        {
+            IMU_MATCH_BDF(b, d, f) &&
+            is_under(hostbridge/pciexrc, pciexbus[b]/pciexdev[d]/pciexfn[f])
+        };
 prop fault.io.fire.pci.device@pcibus[b]/pcidev[d]/pcifn[f] (0) ->
     ereport.io.fire.dmc.msi_mal_err@hostbridge/pciexrc
         { 
-            IMU_MATCH_BDF(payloadprop("imu-rds"), b, d, f) &&
+            IMU_MATCH_BDF(b, d, f) &&
             is_under(hostbridge/pciexrc, pcibus[b]/pcidev[d]/pcifn[f])
-        },
-    ereport.io.fire.dmc.msi_par_err@hostbridge/pciexrc
-        { 
-            IMU_MATCH_BDF(payloadprop("imu-rds"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pcibus[b]/pcidev[d]/pcifn[f])
+        };
+
+/***************
+ * Event queue overflow
+ * -------------
+ * Since we don't know which devices are sending too many EQ's, we must
+ * indict Fire asic and all PCIe/PCI devices
+ ***************/
+#define PROP_PLAT_FRU "FRU"
+#define GET_HB_FRU (confprop(asru(hostbridge/pciexrc), PROP_PLAT_FRU))
+#define GET_PCIE_FRU (confprop(asru(pciexbus[b]/pciexdev[d]/pciexfn[0]), PROP_PLAT_FRU))
+#define GET_PCI_FRU (confprop(asru(pcibus[b]/pcidev[d]/pcifn[0]), PROP_PLAT_FRU))
+
+prop fault.io.fire.pciex.device@pciexbus[b]/pciexdev[d]/pciexfn[0] (0) ->
+    ereport.io.fire.dmc.eq_over@hostbridge/pciexrc
+        {  
+            /*
+             * Indict PCI-E FRU(s) under this root complex excluding the 
+             * one that the Fire ASIC resides on. 
+             */
+            is_under(hostbridge/pciexrc, pciexbus[b]/pciexdev[d]/pciexfn[0]) &&
+	    (GET_HB_FRU != GET_PCIE_FRU)
         };
 
 prop fault.io.fire.pci.device@pcibus[b]/pcidev[d]/pcifn[0] (0) ->
@@ -384,267 +513,117 @@
              * Indict PCI FRU(s) under this root complex excluding the 
              * one that the Fire ASIC resides on. 
              */
-            is_under(hostbridge/pciexrc, pcibus[b]/pcidev[d]/pcifn[0])
-	    &&
-	    (confprop(asru(pcibus[b]/pcidev[d]/pcifn[0]), PROP_PLAT_FRU)
-	        != 
-	     confprop(asru(hostbridge/pciexrc), PROP_PLAT_FRU))
+            is_under(hostbridge/pciexrc, pcibus[b]/pcidev[d]/pcifn[0]) &&
+	    (GET_HB_FRU != GET_PCI_FRU)
         };
 
+/***************
+ * Secondary errors
+ * -------------
+ * These are errors that require logs to be diagnosable.  Secondary errors
+ * do not have logs so, just propagate them to no-diag.
+ ***************/
+event error.io.fire.dmc.secondary@hostbridge/pciexrc; 
 
-event ereport.io.fire.dmc.msi_not_en@hostbridge/pciexrc{within(5s)};
-event ereport.io.fire.dmc.cor_not_en@hostbridge/pciexrc{within(5s)};
-event ereport.io.fire.dmc.nonfatal_not_en@hostbridge/pciexrc{within(5s)};
-event ereport.io.fire.dmc.fatal_not_en@hostbridge/pciexrc{within(5s)};
-event ereport.io.fire.dmc.pmpme_not_en@hostbridge/pciexrc{within(5s)};
-event ereport.io.fire.dmc.pmeack_not_en@hostbridge/pciexrc{within(5s)};
-event ereport.io.fire.dmc.eq_not_en@hostbridge/pciexrc{within(5s)};
+prop error.io.fire.dmc.secondary@hostbridge/pciexrc (0) ->
+    ereport.io.fire.dmc.byp_err@hostbridge/pciexrc{ IS_SECONDARY },
+    ereport.io.fire.dmc.byp_oor@hostbridge/pciexrc{ IS_SECONDARY },
+    ereport.io.fire.dmc.msi_mal_err@hostbridge/pciexrc{ IS_SECONDARY },
+    ereport.io.fire.dmc.trn_oor@hostbridge/pciexrc{ IS_SECONDARY },
+    ereport.io.fire.dmc.tte_inv@hostbridge/pciexrc{ IS_SECONDARY },
+    ereport.io.fire.dmc.tte_prt@hostbridge/pciexrc{ IS_SECONDARY };
+
+/******************************
+ * PEC Rules Begin Here       *
+ ******************************/
+
+event error.io.fire.pec.buffer-parity@hostbridge/pciexrc;
+event error.io.fire.pec.misc-egress@hostbridge/pciexrc ; 
+event error.io.fire.pec.adjacentnode@hostbridge/pciexrc ; 
+event error.io.fire.pec.fabric_error@hostbridge/pciexrc ; 
 
-event error.io.fire.dmc.msg_not_en@hostbridge/pciexrc ;
+/***************
+ * Fire PX SW error
+ * -------------
+ * Errors caused by bad SW
+ ***************/
+prop defect.io.fire.pciex.driver@hostbridge/pciexrc (0) ->
+    ereport.io.fire.pec.crs@hostbridge/pciexrc,
+    ereport.io.fire.pec.mrc@hostbridge/pciexrc;
 
-event defect.io.fire.pci.driver@pcibus/pcidev/pcifn;
-event defect.io.fire.pciex.driver@pciexbus/pciexdev/pciexfn;
+/***************
+ * Fire Asic HW error
+ * -------------
+ * Errors caused by parity or unexpected behaviors in the asic.
+ ***************/
+prop error.io.fire.pec.asic@hostbridge/pciexrc (1)->
+    error.io.fire.pec.buffer-parity@hostbridge/pciexrc,
+    error.io.fire.pec.misc-egress@hostbridge/pciexrc,
+    error.io.fire.pec.adjacentnode@hostbridge/pciexrc; 
 
-/*
- * A faulty bridge or leaf device driver can cause
- * - mmu invalid, out of range, protection etc. all except data parity
- * - invalid pio r/w
- * - msg received to unenabled queue
- * - unsupported request
+prop error.io.fire.pec.buffer-parity@hostbridge/pciexrc (1) ->
+    ereport.io.fire.pec.edp@hostbridge/pciexrc,
+    ereport.io.fire.pec.ehp@hostbridge/pciexrc,
+    ereport.io.fire.pec.eip@hostbridge/pciexrc,
+    ereport.io.fire.pec.erp@hostbridge/pciexrc,
+    ereport.io.fire.pec.ihb_pe@hostbridge/pciexrc,
+    ereport.io.fire.pec.iip@hostbridge/pciexrc;
+
+prop error.io.fire.pec.misc-egress@hostbridge/pciexrc (1) ->
+    ereport.io.fire.pec.emp@hostbridge/pciexrc,
+    ereport.io.fire.pec.epe@hostbridge/pciexrc,
+    ereport.io.fire.pec.ero@hostbridge/pciexrc,
+    ereport.io.fire.pec.eru@hostbridge/pciexrc;
+
+/***************
+ * Bad IO requests
+ * -------------
+ * Errors caused by bad leaf drivers, which will end up sending fire.fabric
+ * ereport, which will be diagnosed in itself.  Do not diagnose the bad IO
+ * requests and rely on the fire.fabric error being there.  Propagate to a
+ * fault.io.fire.pciex.device.
  *
- * Need to break into multiple prop to avoid the "line to long" runtime error
- */
-prop defect.io.fire.pciex.driver@pciexbus[b]/pciexdev[d]/pciexfn[f] (0) ->
-    /* msg not enable */
-    ereport.io.fire.dmc.msi_not_en@hostbridge/pciexrc
-        {
-            IMU_MATCH_BDF(payloadprop("imu-rds"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pciexbus[b]/pciexdev[d]/pciexfn[f])
-        },
-    ereport.io.fire.dmc.cor_not_en@hostbridge/pciexrc
-        {
-            IMU_MATCH_BDF(payloadprop("imu-rds"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pciexbus[b]/pciexdev[d]/pciexfn[f])
-        },
-    ereport.io.fire.dmc.nonfatal_not_en@hostbridge/pciexrc
-        {
-            IMU_MATCH_BDF(payloadprop("imu-rds"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pciexbus[b]/pciexdev[d]/pciexfn[f])
-        },
-    ereport.io.fire.dmc.fatal_not_en@hostbridge/pciexrc
-        {
-            IMU_MATCH_BDF(payloadprop("imu-rds"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pciexbus[b]/pciexdev[d]/pciexfn[f])
-        },
-    ereport.io.fire.dmc.pmpme_not_en@hostbridge/pciexrc
-        {
-            IMU_MATCH_BDF(payloadprop("imu-rds"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pciexbus[b]/pciexdev[d]/pciexfn[f])
-        },
-    ereport.io.fire.dmc.pmeack_not_en@hostbridge/pciexrc
-        {
-            IMU_MATCH_BDF(payloadprop("imu-rds"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pciexbus[b]/pciexdev[d]/pciexfn[f])
-        },
-    ereport.io.fire.dmc.eq_not_en@hostbridge/pciexrc
-        {
-            IMU_MATCH_BDF(payloadprop("imu-scs"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pciexbus[b]/pciexdev[d]/pciexfn[f])
-        };
-
+ * Atleast 1 PCIe device will be fauled.  PCI will be fault as well if the
+ * DMA came from a PCI device.
+ ***************/
+event error.io.fire.pec.fabric_diag@hostbridge/pciexrc;
 
-prop defect.io.fire.pciex.driver@pciexbus[b]/pciexdev[d]/pciexfn[f] (0) ->
-    /* bad_op */
-    ereport.io.fire.dmc.byp_err@hostbridge/pciexrc
-        { 
-            MMU_MATCH_BDF(payloadprop("mmu-tfsr"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pciexbus[b]/pciexdev[d]/pciexfn[f])
-        },
-    ereport.io.fire.dmc.byp_oor@hostbridge/pciexrc
-        { 
-            MMU_MATCH_BDF(payloadprop("mmu-tfsr"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pciexbus[b]/pciexdev[d]/pciexfn[f])
-        },
-    ereport.io.fire.dmc.trn_err@hostbridge/pciexrc
-        { 
-            MMU_MATCH_BDF(payloadprop("mmu-tfsr"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pciexbus[b]/pciexdev[d]/pciexfn[f])
-        },
-    ereport.io.fire.dmc.trn_oor@hostbridge/pciexrc
-        { 
-            MMU_MATCH_BDF(payloadprop("mmu-tfsr"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pciexbus[b]/pciexdev[d]/pciexfn[f])
-        },
-    ereport.io.fire.dmc.tte_inv@hostbridge/pciexrc
-        { 
-            MMU_MATCH_BDF(payloadprop("mmu-tfsr"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pciexbus[b]/pciexdev[d]/pciexfn[f])
-        },
-    ereport.io.fire.dmc.tte_prt@hostbridge/pciexrc
-        { 
-            MMU_MATCH_BDF(payloadprop("mmu-tfsr"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pciexbus[b]/pciexdev[d]/pciexfn[f])
-        },
-    ereport.io.fire.dmc.tbw_dme@hostbridge/pciexrc
-        { 
-            MMU_MATCH_BDF(payloadprop("mmu-tfsr"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pciexbus[b]/pciexdev[d]/pciexfn[f])
-        },
-    ereport.io.fire.dmc.tbw_ude@hostbridge/pciexrc
-        { 
-            MMU_MATCH_BDF(payloadprop("mmu-tfsr"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pciexbus[b]/pciexdev[d]/pciexfn[f])
-        },
-    ereport.io.fire.dmc.tbw_err@hostbridge/pciexrc
-        { 
-            MMU_MATCH_BDF(payloadprop("mmu-tfsr"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pciexbus[b]/pciexdev[d]/pciexfn[f])
-        };
+prop error.io.fire.pec.fabric_diag@hostbridge/pciexrc(1) ->
+    ereport.io.fire.pec.wuc@hostbridge/pciexrc{ IS_PRIMARY },
+    ereport.io.fire.pec.ruc@hostbridge/pciexrc{ IS_PRIMARY },
+    ereport.io.fire.pec.pois@hostbridge/pciexrc{ IS_PRIMARY },
+    ereport.io.fire.pec.ur@hostbridge/pciexrc{ IS_PRIMARY };
 
 
-/* repeat the above prop for PCI devices */ 
-prop defect.io.fire.pci.driver@pcibus[b]/pcidev[d]/pcifn[f] (0) ->
-    /* msg not enable */
-    ereport.io.fire.dmc.msi_not_en@hostbridge/pciexrc
-        {
-            IMU_MATCH_BDF(payloadprop("imu-rds"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pcibus[b]/pcidev[d]/pcifn[f])
-        },
-    ereport.io.fire.dmc.cor_not_en@hostbridge/pciexrc
-        {
-            IMU_MATCH_BDF(payloadprop("imu-rds"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pcibus[b]/pcidev[d]/pcifn[f])
-        },
-    ereport.io.fire.dmc.nonfatal_not_en@hostbridge/pciexrc
-        {
-            IMU_MATCH_BDF(payloadprop("imu-rds"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pcibus[b]/pcidev[d]/pcifn[f])
-        },
-    ereport.io.fire.dmc.fatal_not_en@hostbridge/pciexrc
-        {
-            IMU_MATCH_BDF(payloadprop("imu-rds"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pcibus[b]/pcidev[d]/pcifn[f])
-        },
-    ereport.io.fire.dmc.pmpme_not_en@hostbridge/pciexrc
-        {
-            IMU_MATCH_BDF(payloadprop("imu-rds"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pcibus[b]/pcidev[d]/pcifn[f])
-        },
-    ereport.io.fire.dmc.pmeack_not_en@hostbridge/pciexrc
-        {
-            IMU_MATCH_BDF(payloadprop("imu-rds"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pcibus[b]/pcidev[d]/pcifn[f])
-        },
-    ereport.io.fire.dmc.eq_not_en@hostbridge/pciexrc
-        {
-            IMU_MATCH_BDF(payloadprop("imu-scs"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pcibus[b]/pcidev[d]/pcifn[f])
-        };
+prop error.io.fire.fabric@pciexbus/pciexdev/pciexfn (0) ->
+	error.io.fire.pec.fabric_diag@hostbridge/pciexrc {
+		is_under(hostbridge/pciexrc, pciexbus/pciexdev/pciexfn)
+	};
 
-prop defect.io.fire.pci.driver@pcibus[b]/pcidev[d]/pcifn[f] (0) ->
-    /* bad_op */
-    ereport.io.fire.dmc.byp_err@hostbridge/pciexrc
-        { 
-            MMU_MATCH_BDF(payloadprop("mmu-tfsr"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pcibus[b]/pcidev[d]/pcifn[f])
-        },
-    ereport.io.fire.dmc.byp_oor@hostbridge/pciexrc
-        { 
-            MMU_MATCH_BDF(payloadprop("mmu-tfsr"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pcibus[b]/pcidev[d]/pcifn[f])
-        },
-    ereport.io.fire.dmc.trn_err@hostbridge/pciexrc
-        { 
-            MMU_MATCH_BDF(payloadprop("mmu-tfsr"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pcibus[b]/pcidev[d]/pcifn[f])
-        },
-    ereport.io.fire.dmc.trn_oor@hostbridge/pciexrc
-        { 
-            MMU_MATCH_BDF(payloadprop("mmu-tfsr"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pcibus[b]/pcidev[d]/pcifn[f])
-        },
-    ereport.io.fire.dmc.tte_inv@hostbridge/pciexrc
-        { 
-            MMU_MATCH_BDF(payloadprop("mmu-tfsr"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pcibus[b]/pcidev[d]/pcifn[f])
-        },
-    ereport.io.fire.dmc.tte_prt@hostbridge/pciexrc
-        { 
-            MMU_MATCH_BDF(payloadprop("mmu-tfsr"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pcibus[b]/pcidev[d]/pcifn[f])
-        },
-    ereport.io.fire.dmc.tbw_dme@hostbridge/pciexrc
-        { 
-            MMU_MATCH_BDF(payloadprop("mmu-tfsr"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pcibus[b]/pcidev[d]/pcifn[f])
-        },
-    ereport.io.fire.dmc.tbw_ude@hostbridge/pciexrc
-        { 
-            MMU_MATCH_BDF(payloadprop("mmu-tfsr"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pcibus[b]/pcidev[d]/pcifn[f])
-        },
-    ereport.io.fire.dmc.tbw_err@hostbridge/pciexrc
-        { 
-            MMU_MATCH_BDF(payloadprop("mmu-tfsr"), b, d, f) &&
-            is_under(hostbridge/pciexrc, pcibus[b]/pcidev[d]/pcifn[f])
-        };
-    
- 
-event defect.io.fire.pciex.driver@hostbridge/pciexrc;
-
-/*
- * A faulty Fire nexus driver can cause
- * - Jbus unmapped error
- * - mmu invalid, out of range, protection etc. all except data parity
- * - invalid pio r/w
- * - msg received to unenabled queue
- */
- 
-prop defect.io.fire.pciex.driver@hostbridge/pciexrc (0)-> 
-    error.io.fire.dmc.bad_op@hostbridge/pciexrc,
-    error.io.fire.dmc.msg_not_en@hostbridge/pciexrc; 
- 
-prop error.io.fire.dmc.bad_op@hostbridge/pciexrc (1)-> 
-    ereport.io.fire.dmc.byp_err@hostbridge/pciexrc,
-    ereport.io.fire.dmc.byp_oor@hostbridge/pciexrc,
-    ereport.io.fire.dmc.trn_err@hostbridge/pciexrc,
-    ereport.io.fire.dmc.trn_oor@hostbridge/pciexrc,
-    ereport.io.fire.dmc.tte_inv@hostbridge/pciexrc,
-    ereport.io.fire.dmc.tte_prt@hostbridge/pciexrc,
-    ereport.io.fire.dmc.tbw_dme@hostbridge/pciexrc,
-    ereport.io.fire.dmc.tbw_ude@hostbridge/pciexrc,
-    ereport.io.fire.dmc.tbw_err@hostbridge/pciexrc;
- 
-prop error.io.fire.dmc.msg_not_en@hostbridge/pciexrc (1)->
-    ereport.io.fire.dmc.msi_not_en@hostbridge/pciexrc,
-    ereport.io.fire.dmc.cor_not_en@hostbridge/pciexrc,
-    ereport.io.fire.dmc.nonfatal_not_en@hostbridge/pciexrc,
-    ereport.io.fire.dmc.fatal_not_en@hostbridge/pciexrc,
-    ereport.io.fire.dmc.pmpme_not_en@hostbridge/pciexrc,
-    ereport.io.fire.dmc.pmeack_not_en@hostbridge/pciexrc,
-    ereport.io.fire.dmc.eq_not_en@hostbridge/pciexrc;
-
+/***************
+ * Failed Links
+ * -------------
+ * They will cause the fabric to be scanned and a fire.fabric ereport
+ * for the suspected devices will be sent.  Do no diagnose these
+ * ereports and let the fire.fabric ereport be diagnosed.
+ ***************/
+event ereport.io.fire.link-events-trip@hostbridge/pciexrc ; 
 
 engine serd.io.fire.link-events@hostbridge/pciexrc,
     N=LINK_EVENTS_COUNT, T=LINK_EVENTS_TIME, method=persistent, 
     trip=ereport.io.fire.link-events-trip@hostbridge/pciexrc ;
 
-event upset.io.fire.link-events@hostbridge/pciexrc ,
+event upset.io.fire.link-events@hostbridge/pciexrc,
     engine=serd.io.fire.link-events@hostbridge/pciexrc ;
 
-event error.io.fire.link-events@hostbridge/pciexrc ;
-
-event ereport.io.fire.pec.lin@hostbridge/pciexrc{within(5s)};
-event ereport.io.fire.pec.lrs@hostbridge/pciexrc{within(5s)};
-event ereport.io.fire.pec.ldn@hostbridge/pciexrc{within(5s)};
-event ereport.io.fire.pec.lup@hostbridge/pciexrc{within(5s)};
+event error.io.fire.link-events@hostbridge/pciexrc;
 
 prop upset.io.fire.link-events@hostbridge/pciexrc (0)->
-    error.io.fire.link-events@hostbridge/pciexrc ;
+    error.io.fire.link-events@hostbridge/pciexrc;
   
 prop error.io.fire.link-events@hostbridge/pciexrc (1)->
-    ereport.io.fire.pec.lrs@hostbridge/pciexrc ,
-    ereport.io.fire.pec.ldn@hostbridge/pciexrc ;
+    ereport.io.fire.pec.lrs@hostbridge/pciexrc,
+    ereport.io.fire.pec.ldn@hostbridge/pciexrc;
 
 
 /*
@@ -656,10 +635,9 @@
     FITrate=HB_FIT, FRU=hostbridge/pciexrc/pciexbus/pciexdev,
     ASRU=hostbridge/pciexrc/pciexbus/pciexdev/pciexfn; 
 
-/*
- * Faulty adjacent node may cause
- *    too many link down/reset events
- */
+prop fault.io.fire.asic@hostbridge/pciexrc (0) ->
+    error.io.fire.pec.adjacentnode@hostbridge/pciexrc;
+
 prop fault.io.fire.pciex.device@hostbridge/pciexrc/pciexbus/pciexdev/pciexfn 
 (0) ->
     error.io.fire.pec.adjacentnode@hostbridge/pciexrc 
@@ -671,97 +649,79 @@
 prop error.io.fire.pec.adjacentnode@hostbridge/pciexrc (0) ->
     ereport.io.fire.link-events-trip@hostbridge/pciexrc;
 
-  
-/*
+/***************
+ * Undiagnosible Secondary Errors
+ * -------------
  * Secondary errors of the ereport that the device is at fault.
  * Undiagnosed the secondary errors since the payload is invalid.
- */
-prop error.io.fire.pec.secondary@hostbridge/pciexrc (0) ->
-    ereport.io.fire.dmc.msi_par_err@hostbridge/pciexrc{ IS_SECONDARY },
-    ereport.io.fire.dmc.msi_mal_err@hostbridge/pciexrc{ IS_SECONDARY },
-    ereport.io.fire.dmc.eq_over@hostbridge/pciexrc{ IS_SECONDARY };
+ ***************/
+event error.io.fire.pec.secondary@hostbridge/pciexrc; 
+
+prop error.io.fire.pec.secondary@hostbridge/pciexrc (1) ->
+    ereport.io.fire.pec.ruc@hostbridge/pciexrc{ IS_SECONDARY },
+    ereport.io.fire.pec.wuc@hostbridge/pciexrc{ IS_SECONDARY },
+    ereport.io.fire.pec.pois@hostbridge/pciexrc{ IS_SECONDARY },
+    ereport.io.fire.pec.ur@hostbridge/pciexrc{ IS_SECONDARY };
 
 /*
  * For logging purpose only.
  * The Fire nexus driver generates equivalent pciex ereports for the 
  * common pciex rules to diagnose.
  */
-prop error.io.fire.pec.fabric_error@hostbridge/pciexrc(0) ->
-    ereport.io.fire.pec.cto@hostbridge/pciexrc, 
-    ereport.io.fire.pec.ur@hostbridge/pciexrc,
-    ereport.io.fire.pec.uc@hostbridge/pciexrc,
-    ereport.io.fire.pec.cto@hostbridge/pciexrc,
-    ereport.io.fire.pec.rof@hostbridge/pciexrc,
-    ereport.io.fire.pec.mfp@hostbridge/pciexrc,
-    ereport.io.fire.pec.pois@hostbridge/pciexrc,
-    ereport.io.fire.pec.fcp@hostbridge/pciexrc,
-    ereport.io.fire.pec.dlp@hostbridge/pciexrc,
-    ereport.io.fire.pec.te@hostbridge/pciexrc,
-    ereport.io.fire.pec.re@hostbridge/pciexrc,
+prop error.io.fire.pec.fabric_error@hostbridge/pciexrc (0) ->
     ereport.io.fire.pec.bdp@hostbridge/pciexrc,
     ereport.io.fire.pec.btp@hostbridge/pciexrc,
+    ereport.io.fire.pec.cto@hostbridge/pciexrc, 
+    ereport.io.fire.pec.dlp@hostbridge/pciexrc,
+    ereport.io.fire.pec.fcp@hostbridge/pciexrc,
+    ereport.io.fire.pec.mfc@hostbridge/pciexrc,
+    ereport.io.fire.pec.mfp@hostbridge/pciexrc,
+    ereport.io.fire.pec.re@hostbridge/pciexrc,
     ereport.io.fire.pec.rnr@hostbridge/pciexrc,
-    ereport.io.fire.pec.rto@hostbridge/pciexrc;
-
-
-/* add memory async ereports */
-event ereport.io.fire.jbc.ce_asyn@hostbridge/pciexrc{within(5s)};
-event ereport.io.fire.jbc.ue_asyn@hostbridge/pciexrc{within(5s)}; 
-event ereport.io.fire.pec.mrc@hostbridge/pciexrc{within(5s)};
-event ereport.io.fire.pec.wuc@hostbridge/pciexrc{within(5s)};
-event ereport.io.fire.pec.ruc@hostbridge/pciexrc{within(5s)};
-event ereport.io.fire.pec.crs@hostbridge/pciexrc{within(5s)};
+    ereport.io.fire.pec.rof@hostbridge/pciexrc,
+    ereport.io.fire.pec.rto@hostbridge/pciexrc,
+    ereport.io.fire.pec.te@hostbridge/pciexrc,
+    ereport.io.fire.pec.uc@hostbridge/pciexrc;
 
-/* 
- * Upset used to hide ereports that are not currently diagnosed. 
- */ 
-event upset.io.fire.nodiag@hostbridge;
- 
-prop upset.io.fire.nodiag@hostbridge (0)-> 
-    ereport.io.fire.jbc.ue_asyn@hostbridge/pciexrc, 
-    ereport.io.fire.jbc.ce_asyn@hostbridge/pciexrc, 
-    ereport.io.fire.jbc.ill_acc@hostbridge/pciexrc, 
-    ereport.io.fire.jbc.ill_acc_rd@hostbridge/pciexrc, 
-    ereport.io.fire.dmc.ttc_cae@hostbridge/pciexrc,
-    ereport.io.fire.pec.mrc@hostbridge/pciexrc,
-    ereport.io.fire.pec.wuc@hostbridge/pciexrc,
-    ereport.io.fire.pec.ruc@hostbridge/pciexrc,
-    ereport.io.fire.pec.crs@hostbridge/pciexrc,
-    ereport.io.fire.pec.lin@hostbridge/pciexrc,
-    ereport.io.fire.pec.lup@hostbridge/pciexrc,
-    error.io.fire.pec.secondary@hostbridge/pciexrc,
-    error.io.fire.pec.fabric_error@hostbridge/pciexrc
-    ; 
+/******************************
+ * Fabric Rules Begin Here       *
+ ******************************/
 
-event error.io.fire.fabric@hostbridge/pciexrc;
+/***************
+ * fire.fabric rules
+ * -------------
+ * Below rules are so we get a single suspect list in 1 fault with percentage
+ * of indiction being equal among all the suspect FRUs
+ ***************/
+prop fault.io.fire.pciex.device@pciexbus/pciexdev/pciexfn (0) ->
+	error.io.fire.fabric@pciexbus/pciexdev/pciexfn;
 
-prop fault.io.fire.pciex.device@pciexbus/pciexdev/pciexfn (1) ->
+prop fault.io.fire.pci.device@pcibus/pcidev/pcifn (0) ->
+	error.io.fire.fabric@pcibus/pcidev/pcifn;
+
+prop error.io.fire.fabric@pciexbus/pciexdev/pciexfn (1) ->
 	ereport.io.fire.fabric@pciexbus/pciexdev/pciexfn { !MATCH_CE };
 
-prop fault.io.fire.pci.device@pcibus/pcidev/pcifn (1) ->
+prop error.io.fire.fabric@pcibus/pcidev/pcifn (1) ->
 	ereport.io.fire.fabric@pcibus/pcidev/pcifn;
 
-/*
- * Below rules are so we get a single suspect list in 1 fault with percentage
- * of indiction being equal among all the suspect FRUs
- */
-prop error.io.fire.fabric@hostbridge/pciexrc (0) ->
+prop error.io.fire.fabric-sib@hostbridge/pciexrc (0) ->
 	ereport.io.fire.fabric@pciexbus/pciexdev/pciexfn {
 		is_under(hostbridge/pciexrc, pciexbus/pciexdev/pciexfn) && !MATCH_CE
 	};
 
-prop error.io.fire.fabric@hostbridge/pciexrc (0) ->
+prop error.io.fire.fabric-sib@hostbridge/pciexrc (0) ->
 	ereport.io.fire.fabric@pcibus/pcidev/pcifn {
 		is_under(hostbridge/pciexrc, pcibus/pcidev/pcifn)
 	};
 
-prop fault.io.fire.pciex.device@pciexbus/pciexdev/pciexfn (1) ->
-	error.io.fire.fabric@hostbridge/pciexrc {
+prop error.io.fire.fabric@pciexbus/pciexdev/pciexfn (1) ->
+	error.io.fire.fabric-sib@hostbridge/pciexrc {
 		is_under(hostbridge/pciexrc, pciexbus/pciexdev/pciexfn)
 	};
 
-prop fault.io.fire.pci.device@pcibus/pcidev/pcifn (1) ->
-	error.io.fire.fabric@hostbridge/pciexrc {
+prop error.io.fire.fabric@pcibus/pcidev/pcifn (1) ->
+	error.io.fire.fabric-sib@hostbridge/pciexrc {
 		is_under(hostbridge/pciexrc, pcibus/pcidev/pcifn)
 	};
 
@@ -783,3 +743,32 @@
 prop fault.io.fire.pciex.device@pciexbus/pciexdev/pciexfn (0) ->
 	ereport.io.fire.pciex.ce@pciexbus/pciexdev/pciexfn;
 
+/***************
+ * Upsets
+ * ------------- 
+ * Used to hide ereports that are not currently diagnose or should not be
+ * diagnosed
+ ***************/ 
+event upset.io.fire.nodiag@hostbridge/pciexrc;
+event error.io.fire.dmc.nodiag@hostbridge/pciexrc;
+
+prop error.io.fire.dmc.nodiag@hostbridge/pciexrc (1)->
+    ereport.io.fire.dmc.tbw_err@hostbridge/pciexrc;
+
+prop error.io.fire.dmc.nodiag@hostbridge/pciexrc (1)->
+    error.io.fire.fabric-sib@hostbridge/pciexrc;
+
+prop upset.io.fire.nodiag@hostbridge/pciexrc (0)-> 
+    ereport.io.fire.jbc.ce_asyn@hostbridge/pciexrc, /* CPU */
+    ereport.io.fire.jbc.jbe@hostbridge/pciexrc, /* CPU */
+    ereport.io.fire.jbc.jte@hostbridge/pciexrc, /* CPU */
+    ereport.io.fire.jbc.ue_asyn@hostbridge/pciexrc, /* CPU */
+    ereport.io.fire.jbc.unsol_intr@hostbridge/pciexrc, /* CPU */
+    ereport.io.fire.jbc.unsol_rd@hostbridge/pciexrc, /* CPU */
+    ereport.io.fire.pec.lin@hostbridge/pciexrc,
+    ereport.io.fire.pec.lup@hostbridge/pciexrc,
+    error.io.fire.pec.fabric_error@hostbridge/pciexrc,
+    error.io.fire.pec.secondary@hostbridge/pciexrc,
+    error.io.fire.dmc.nodiag@hostbridge/pciexrc,
+    error.io.fire.dmc.fabric_diag@hostbridge/pciexrc,
+    error.io.fire.dmc.secondary@hostbridge/pciexrc; 
--- a/usr/src/cmd/fm/eversholt/files/sparc/sun4v/Makefile	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/eversholt/files/sparc/sun4v/Makefile	Fri Dec 22 12:42:28 2006 -0800
@@ -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.
 #
 #
@@ -29,7 +28,7 @@
 include ../sun4/Makefile.sun4
 
 EFT_PLAT= sun4v
-SUN4VEFTFILES= 
+SUN4VEFTFILES= n2piu.eft
 EFT_PLAT_FILES= $(SUN4VEFTFILES) $(SUN4EFTFILES)
 
 include ../../Makefile.com
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/eversholt/files/sparc/sun4v/n2piu.esc	Fri Dec 22 12:42:28 2006 -0800
@@ -0,0 +1,316 @@
+/*
+ * 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"
+
+#pragma dictionary "SUN4V" 
+
+/*
+ * Eversholt rules for the N2 PIU extention to Fire nexus driver
+ */
+#define HB_FIT			400 
+#define NONFATAL_COUNT		10
+#define NONFATAL_TIME		1hour
+#define PCIEX_DEV_FIT		1000 
+#define LINK_EVENTS_COUNT	10
+#define LINK_EVENTS_TIME	1h
+
+/*
+ * Test for primary or secondary ereports
+ */
+#define IS_PRIMARY (payloadprop("primary"))
+#define IS_SECONDARY (! payloadprop("primary"))
+
+/*
+ * payload: mmu-tfsr
+ *
+ * Extract the request id, the BDF value, in the MMU TFSR register
+ *
+ * PRM 2.0, pg 243
+ *    Request ID: bits 15:0
+ *
+ * Example:
+ *   0x7766554433221100
+ *                 ^^^^
+ */
+#define MMU_REQ_ID_BIT_MODULO (1 << 16)
+#define MMU_MATCH_BDF(mmu_tfsr, b, d, f) \
+	( IS_PRIMARY && \
+	  (((mmu_tfsr) % MMU_REQ_ID_BIT_MODULO) == ((b << 8) | (d << 3) | f)) \
+	)
+
+/*
+ * Faults, upsets and defects
+ */
+/* N2 Asic */
+fru hostbridge/pciexrc; 
+asru hostbridge/pciexrc; 
+event fault.io.fire.asic@hostbridge/pciexrc, 
+    FITrate=HB_FIT, FRU=hostbridge/pciexrc, ASRU=hostbridge/pciexrc; 
+event fault.io.n2.soc@hostbridge/pciexrc, 
+    FITrate=HB_FIT, FRU=hostbridge/pciexrc, ASRU=hostbridge/pciexrc; 
+event fault.io.n2.crossbar@hostbridge/pciexrc, 
+    FITrate=HB_FIT, FRU=hostbridge/pciexrc, ASRU=hostbridge/pciexrc; 
+event fault.io.n2.dmu@hostbridge/pciexrc, 
+    FITrate=HB_FIT, FRU=hostbridge/pciexrc, ASRU=hostbridge/pciexrc; 
+event fault.io.n2.ncu@hostbridge/pciexrc, 
+    FITrate=HB_FIT, FRU=hostbridge/pciexrc, ASRU=hostbridge/pciexrc; 
+event fault.io.n2.siu@hostbridge/pciexrc, 
+    FITrate=HB_FIT, FRU=hostbridge/pciexrc, ASRU=hostbridge/pciexrc; 
+event fault.io.n2.niu@hostbridge/pciexrc, 
+    FITrate=HB_FIT, FRU=hostbridge/pciexrc, ASRU=hostbridge/pciexrc; 
+
+/* PCI/PCIe SW driver defects */
+event defect.io.fire.pci.driver@pcibus/pcidev/pcifn;
+event defect.io.fire.pciex.driver@pciexbus/pciexdev/pciexfn;
+/* Fire/N2 driver defects */
+event defect.io.fire.pciex.driver@hostbridge/pciexrc;
+
+/* No diagnosis */
+event upset.io.fire.nodiag@hostbridge;
+
+/*
+ * Additional "DMC" errors to fire.
+ * Driver errors.
+ */
+event ereport.io.n2.dmu.sun4v_va_oor@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.n2.dmu.sun4v_adj_va_uf@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.n2.dmu.sun4v_inv_pg_sz@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.n2.dmu.sun4v_key_err@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.n2.dmu.iotsbdesc_inv@hostbridge/pciexrc{within(5s)}; 
+
+/*
+ * Additional "DMC" errors to fire.
+ * N2 asic parity error
+ */
+event ereport.io.n2.dmu.iotsbdesc_dpe@hostbridge/pciexrc{within(5s)}; 
+
+/*
+ * Additional "PEC" errors to fire.
+ */
+event ereport.io.n2.peu.err_sds_los@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.n2.peu.nfp@hostbridge/pciexrc{within(5s)}; 
+
+/*
+ * Unique SOC errors to N2
+ */
+/* fault.io.n2.soc */
+event ereport.io.n2.soc.ncumondotable@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.n2.soc.ncuctagce@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.n2.soc.ncuinttable@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.n2.soc.ncudataparity@hostbridge/pciexrc{within(5s)}; 
+
+/* fault.io.n2.crossbar */
+event ereport.io.n2.soc.ncupcxdata@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.n2.soc.ncudmucredit@hostbridge/pciexrc{within(5s)}; 
+
+/* fault.io.n2.dmu */
+event ereport.io.n2.soc.siidmuctague@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.n2.soc.siidmuctagce@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.n2.soc.siidmuaparity@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.n2.soc.siidmudparity@hostbridge/pciexrc{within(5s)}; 
+
+/* fault.io.n2.ncu */
+event ereport.io.n2.soc.ncupcxue@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.n2.soc.dmuncucredit@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.n2.soc.ncumondofifo@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.n2.soc.ncucpxue@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.n2.soc.ncudmuue@hostbridge/pciexrc{within(5s)}; 
+
+/* fault.io.n2.siu */
+event ereport.io.n2.soc.ncuctague@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.n2.soc.sioctague@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.n2.soc.dmusiicredit@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.n2.soc.dmudataparity@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.n2.soc.sioctagce@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.n2.soc.dmuctagce@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.n2.soc.dmuctague@hostbridge/pciexrc{within(5s)}; 
+
+/* fault.io.n2.niu */
+event ereport.io.n2.soc.siiniuctagce@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.n2.soc.siiniuctague@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.n2.soc.siiniuaparity@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.n2.soc.siiniudparity@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.n2.soc.niuctague@hostbridge/pciexrc{within(5s)}; 
+event ereport.io.n2.soc.niuctagce@hostbridge/pciexrc{within(5s)};
+event ereport.io.n2.soc.niudataparity@hostbridge/pciexrc{within(5s)}; 
+
+/* fault.io.niu/niufn */
+event ereport.io.device.inval_state@niu/niufn{within(5s)};
+event ereport.io.device.no_response@niu/niufn{within(5s)};
+event ereport.io.device.stall@niu/niufn{within(5s)};
+event ereport.io.device.badint_limit@niu/niufn{within(5s)};
+event ereport.io.device.nf-device@niu/niufn;
+
+
+/*
+ * Bad DMA requests
+ */
+event error.io.fire.dmc.fabric_diag@hostbridge/pciexrc;
+
+prop error.io.fire.dmc.fabric_diag@hostbridge/pciexrc(0) ->
+    ereport.io.n2.dmu.iotsbdesc_inv@hostbridge/pciexrc{ IS_PRIMARY },
+    ereport.io.n2.dmu.sun4v_adj_va_uf@hostbridge/pciexrc{ IS_PRIMARY },
+    ereport.io.n2.dmu.sun4v_inv_pg_sz@hostbridge/pciexrc{ IS_PRIMARY },
+    ereport.io.n2.dmu.sun4v_key_err@hostbridge/pciexrc{ IS_PRIMARY },
+    ereport.io.n2.dmu.sun4v_va_oor@hostbridge/pciexrc{ IS_PRIMARY };
+
+event error.io.fire.dmc.secondary@hostbridge/pciexrc; 
+
+prop error.io.fire.dmc.secondary@hostbridge/pciexrc (0) ->
+    ereport.io.n2.dmu.iotsbdesc_inv@hostbridge/pciexrc{ IS_SECONDARY },
+    ereport.io.n2.dmu.sun4v_adj_va_uf@hostbridge/pciexrc{ IS_SECONDARY },
+    ereport.io.n2.dmu.sun4v_inv_pg_sz@hostbridge/pciexrc{ IS_SECONDARY },
+    ereport.io.n2.dmu.sun4v_key_err@hostbridge/pciexrc{ IS_SECONDARY },
+    ereport.io.n2.dmu.sun4v_va_oor@hostbridge/pciexrc{ IS_SECONDARY };
+
+/*
+ * Fault at the adjacent node which is right below the Fire ASIC
+ */
+event error.io.fire.pec.adjacentnode@hostbridge/pciexrc; 
+
+prop error.io.fire.pec.adjacentnode@hostbridge/pciexrc (0) ->
+    ereport.io.n2.peu.nfp@hostbridge/pciexrc;
+
+/*
+ * DMU N2 asic parity error
+ */
+prop fault.io.fire.asic@hostbridge/pciexrc (0)-> 
+    ereport.io.n2.dmu.iotsbdesc_dpe@hostbridge/pciexrc;
+
+/*
+ * Surprise remove or serdes los, similar to fire ldn event,
+ * don't diag.
+ */
+prop upset.io.fire.nodiag@hostbridge (0)-> 
+    ereport.io.n2.peu.err_sds_los@hostbridge/pciexrc;
+
+/* SOC Errors */ 
+/* fault.io.n2.soc */
+prop fault.io.n2.soc@hostbridge/pciexrc (1)-> 
+	ereport.io.n2.soc.ncumondotable@hostbridge/pciexrc,
+	ereport.io.n2.soc.ncuctagce@hostbridge/pciexrc,
+	ereport.io.n2.soc.ncuinttable@hostbridge/pciexrc,
+	ereport.io.n2.soc.ncudataparity@hostbridge/pciexrc;
+
+/* fault.io.n2.crossbar */
+prop fault.io.n2.crossbar@hostbridge/pciexrc (1)-> 
+	ereport.io.n2.soc.ncudmucredit@hostbridge/pciexrc,
+	ereport.io.n2.soc.ncupcxdata@hostbridge/pciexrc;
+
+/* fault.io.n2.dmu */
+prop fault.io.n2.dmu@hostbridge/pciexrc (1)-> 
+	ereport.io.n2.soc.siidmuctague@hostbridge/pciexrc,
+	ereport.io.n2.soc.siidmuctagce@hostbridge/pciexrc,
+	ereport.io.n2.soc.siidmuaparity@hostbridge/pciexrc,
+	ereport.io.n2.soc.siidmudparity@hostbridge/pciexrc;
+
+/* fault.io.n2.ncu */
+prop fault.io.n2.ncu@hostbridge/pciexrc (1)-> 
+	ereport.io.n2.soc.ncupcxue@hostbridge/pciexrc,
+	ereport.io.n2.soc.dmuncucredit@hostbridge/pciexrc,
+	ereport.io.n2.soc.ncumondofifo@hostbridge/pciexrc,
+	ereport.io.n2.soc.ncucpxue@hostbridge/pciexrc,
+	ereport.io.n2.soc.ncudmuue@hostbridge/pciexrc;
+
+/* fault.io.n2.siu */
+prop fault.io.n2.siu@hostbridge/pciexrc (1)-> 
+	ereport.io.n2.soc.ncuctague@hostbridge/pciexrc,
+	ereport.io.n2.soc.sioctague@hostbridge/pciexrc,
+	ereport.io.n2.soc.dmusiicredit@hostbridge/pciexrc,
+	ereport.io.n2.soc.dmudataparity@hostbridge/pciexrc,
+	ereport.io.n2.soc.sioctagce@hostbridge/pciexrc,
+	ereport.io.n2.soc.dmuctagce@hostbridge/pciexrc,
+	ereport.io.n2.soc.dmuctague@hostbridge/pciexrc;
+
+/* fault.io.n2.niu */
+prop fault.io.n2.niu@hostbridge/pciexrc (0)-> 
+	ereport.io.n2.soc.siiniuctague@hostbridge/pciexrc,
+	ereport.io.n2.soc.siiniuaparity@hostbridge/pciexrc,
+	ereport.io.n2.soc.siiniudparity@hostbridge/pciexrc,
+	ereport.io.n2.soc.siiniuctagce@hostbridge/pciexrc,
+	ereport.io.n2.soc.niuctague@hostbridge/pciexrc,
+	ereport.io.n2.soc.niuctagce@hostbridge/pciexrc,
+	ereport.io.n2.soc.niudataparity@hostbridge/pciexrc;
+
+/* n2 niu/niufn */
+event error.io.device.f-device@niu/niufn;
+event error.io.device.nf-device@niu/niufn;
+event error.io.service.restored@niu/niufn;
+event ereport.io.service.lost@niu/niufn{within(5s)};
+event ereport.io.service.restored@niu/niufn{within(30s)};
+event ereport.io.service.degraded@niu/niufn{within(5s)};
+event ereport.io.service.unaffected@niu/niufn{within(5s)};
+
+/* fault error propogation */
+prop fault.io.n2.niu@hostbridge/pciexrc (0)->
+        error.io.device.f-device@niu/niufn,
+        error.io.device.nf-device@niu/niufn;
+
+/* fault.io.niu/niufn */
+prop error.io.service.restored@niu/niufn (1)->
+	ereport.io.service.lost@niu/niufn,
+	ereport.io.service.degraded@niu/niufn;
+
+prop error.io.service.restored@niu/niufn (1)->
+    ereport.io.service.restored@niu/niufn;
+
+prop error.io.device.f-device@niu/niufn (1)->
+    ereport.io.device.inval_state@niu/niufn,
+    ereport.io.device.no_response@niu/niufn,
+    ereport.io.device.stall@niu/niufn,
+    ereport.io.device.badint_limit@niu/niufn;
+
+prop error.io.device.f-device@niu/niufn (1)->
+    ereport.io.service.lost@niu/niufn,
+    ereport.io.service.degraded@niu/niufn;
+
+engine serd.io.device.nonfatal@niu/niufn,
+    N=NONFATAL_COUNT, T=NONFATAL_TIME, method=persistent,
+    trip=ereport.io.device.nf-device@niu/niufn;
+
+event upset.io.device.nonfatal@niu/niufn,
+    engine=serd.io.device.nonfatal@niu/niufn;
+
+prop error.io.device.nf-device@niu/niufn (1)->
+    ereport.io.device.nf-device@niu/niufn;
+
+prop error.io.device.nf-device@niu/niufn (0)->
+    ereport.io.device.inval_state@niu/niufn,
+    ereport.io.device.no_response@niu/niufn,
+    ereport.io.device.stall@niu/niufn,
+    ereport.io.device.badint_limit@niu/niufn,
+    ereport.io.service.unaffected@niu/niufn,
+    error.io.service.restored@niu/niufn;
+
+prop upset.io.device.nonfatal@niu/niufn (1)->
+    ereport.io.device.inval_state@niu/niufn,
+    ereport.io.device.no_response@niu/niufn,
+    ereport.io.device.stall@niu/niufn,
+    ereport.io.device.badint_limit@niu/niufn;
+
+prop upset.io.device.nonfatal@niu/niufn (1)->
+    ereport.io.service.unaffected@niu/niufn,
+    error.io.service.restored@niu/niufn;
--- a/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpu.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpu.c	Fri Dec 22 12:42:28 2006 -0800
@@ -57,8 +57,6 @@
 #endif /* sun4u */
 
 #define	CMD_CPU_UEC_INCR	10
-#define	CPU_FRU_FMRI		FM_FMRI_SCHEME_HC":///" \
-    FM_FMRI_LEGACY_HC"="
 
 /* Must be in sync with cmd_cpu_type_t */
 static const char *const cpu_names[] = {
@@ -157,6 +155,10 @@
 #define	UST1_CPU_CORE_STEP		1
 #define	UST1_CPUS_PER_CHIP		32
 #define	UST1_CPU_CHIP_STEP		1
+#define	UST2_CPUS_PER_CORE		8
+#define	UST2_CPU_CORE_STEP		1
+#define	UST2_CPUS_PER_CHIP		64
+#define	UST2_CPU_CHIP_STEP		1
 
 	case CPU_ULTRASPARC_T1:
 		switch (level) {
@@ -175,7 +177,24 @@
 			*cpustep = 1;
 			return;
 		}
-	/* core2cpus CPU_ULTRASPARC_T2 */
+	case CPU_ULTRASPARC_T2:
+		switch (level) {
+		case CMD_CPU_LEVEL_CORE:
+			*cpuinit = core * UST2_CPUS_PER_CORE;
+			*cpufinal = *cpuinit + UST2_CPUS_PER_CORE - 1;
+			*cpustep = UST2_CPU_CORE_STEP;
+			return;
+		case CMD_CPU_LEVEL_CHIP:
+			*cpuinit = core * UST2_CPUS_PER_CHIP;
+			*cpufinal = *cpuinit + UST2_CPUS_PER_CHIP - 1;
+			*cpustep = UST2_CPU_CHIP_STEP;
+			return;
+		default:
+			*cpuinit = *cpufinal = core;
+			*cpustep = 1;
+			return;
+		}
+
 #endif /* sun4u */
 	default:
 		*cpuinit = *cpufinal = core;
@@ -217,7 +236,16 @@
 		default:
 			return (cpuid);
 		}
-	/* cmd_cpu2core CPU_ULTRASPARC_T2 */
+	case CPU_ULTRASPARC_T2:
+		switch (level) {
+		case CMD_CPU_LEVEL_CORE:
+			return (cpuid/UST2_CPUS_PER_CORE);
+		case CMD_CPU_LEVEL_CHIP:
+			return (cpuid/UST2_CPUS_PER_CHIP);
+		default:
+			return (cpuid);
+		}
+
 #endif /* sun4u */
 	default:
 		return (cpuid);
@@ -1478,41 +1506,8 @@
 	return (NULL);
 }
 
-char *
-cpu_getfrustr(fmd_hdl_t *hdl, uint32_t cpuid)
-{
-	kstat_named_t *kn;
-	kstat_ctl_t *kc;
-	kstat_t *ksp;
-	int i;
-
-	if ((kc = kstat_open()) == NULL)
-		return (NULL); /* errno is set for us */
-
-	if ((ksp = kstat_lookup(kc, "cpu_info", cpuid, NULL)) == NULL ||
-	    kstat_read(kc, ksp, NULL) == -1) {
-		int oserr = errno;
-		(void) kstat_close(kc);
-		(void) cmd_set_errno(oserr);
-		return (NULL);
-	}
-
-	for (kn = ksp->ks_data, i = 0; i < ksp->ks_ndata; i++, kn++) {
-		if (strcmp(kn->name, "cpu_fru") == 0) {
-			char *str = fmd_hdl_strdup(hdl,
-			    KSTAT_NAMED_STR_PTR(kn), FMD_SLEEP);
-			(void) kstat_close(kc);
-			return (str);
-		}
-	}
-
-	(void) kstat_close(kc);
-	(void) cmd_set_errno(ENOENT);
-	return (NULL);
-}
-
 static nvlist_t *
-cpu_mkfru(char *frustr)
+cpu_mkfru(char *frustr, char *serialstr, char *partstr)
 {
 	char *comp;
 	nvlist_t *fru, *hcelem;
@@ -1538,8 +1533,12 @@
 	}
 
 	if (nvlist_add_uint8(fru, FM_VERSION, FM_HC_SCHEME_VERSION) != 0 ||
-	    nvlist_add_string(fru, FM_FMRI_SCHEME,
-	    FM_FMRI_SCHEME_HC) != 0 ||
+	    nvlist_add_string(fru, FM_FMRI_SCHEME, FM_FMRI_SCHEME_HC) != 0 ||
+	    (partstr != NULL &&
+		nvlist_add_string(fru, FM_FMRI_HC_PART, partstr) != 0) ||
+	    (serialstr != NULL &&
+		nvlist_add_string(fru, FM_FMRI_HC_SERIAL_ID,
+		serialstr) != 0) ||
 	    nvlist_add_string(fru, FM_FMRI_HC_ROOT, "") != 0 ||
 	    nvlist_add_uint32(fru, FM_FMRI_HC_LIST_SZ, 1) != 0 ||
 	    nvlist_add_nvlist_array(fru, FM_FMRI_HC_LIST, &hcelem, 1) != 0) {
@@ -1553,18 +1552,23 @@
 }
 
 static nvlist_t *
-cpu_getfru(fmd_hdl_t *hdl, uint32_t cpuid)
+cpu_getfru(fmd_hdl_t *hdl, cmd_cpu_t *cp)
 {
-	char *frustr;
+	char *frustr, *partstr, *serialstr;
 	nvlist_t *nvlp;
 
-	if ((frustr = cpu_getfrustr(hdl, cpuid)) == NULL) {
+	if ((frustr = cmd_cpu_getfrustr(hdl, cp)) == NULL) {
 		fmd_hdl_error(hdl, "failed to retrieve FRU string for CPU %d",
-		    cpuid);
+		    cp->cpu_cpuid);
 		return (NULL);
 	}
-	nvlp = cpu_mkfru(frustr);
+	partstr = cmd_cpu_getpartstr(hdl, cp);
+	serialstr = cmd_cpu_getserialstr(hdl, cp);
+	nvlp = cpu_mkfru(frustr, partstr, serialstr);
 	fmd_hdl_strfree(hdl, frustr);
+	fmd_hdl_strfree(hdl, partstr);
+	fmd_hdl_strfree(hdl, serialstr);
+
 	return (nvlp);
 }
 
@@ -1620,7 +1624,6 @@
 {
 	cmd_cpu_t *cpu;
 	nvlist_t *fru;
-	char *frustr;
 
 	/*
 	 * No CPU state matches the CPU described in the ereport.  Create a new
@@ -1652,34 +1655,7 @@
 
 	cmd_fmri_init(hdl, &cpu->cpu_asru, asru, "cpu_asru_%d", cpu->cpu_cpuid);
 
-	/*
-	 * If this ereport contains a 'cpufru' element, use it to construct
-	 * the FRU FMRI instead of going to kstats.
-	 *
-	 * Unfortunately, the string associated with 'cpufru' is
-	 * not in precisely the right form -- so the following code is
-	 * written to adjust.
-	 */
-	if (nvlist_lookup_string(asru, FM_FMRI_CPU_CPUFRU, &frustr) == 0) {
-		char *s1, *s2;
-		size_t frustrlen = strlen(frustr) + sizeof (CPU_FRU_FMRI) + 1;
-
-		s1 = fmd_hdl_zalloc(hdl, frustrlen, FMD_SLEEP);
-		s2 = strrchr(frustr, '/') + 1;
-		if (s2 == NULL)
-			s2 = "MB";
-
-		(void) snprintf(s1, frustrlen, "%s%s",
-		    CPU_FRU_FMRI, s2);
-
-		if ((fru = cpu_mkfru(s1)) != NULL) {
-			cmd_fmri_init(hdl, &cpu->cpu_fru, fru, "cpu_fru_%d",
-			    cpu->cpu_cpuid);
-			nvlist_free(fru);
-		}
-		fmd_hdl_free(hdl, s1, frustrlen);
-
-	} else if ((fru = cpu_getfru(hdl, cpuid)) != NULL) {
+	if ((fru = cpu_getfru(hdl, cpu)) != NULL) {
 		cmd_fmri_init(hdl, &cpu->cpu_fru, fru, "cpu_fru_%d",
 		    cpu->cpu_cpuid);
 		nvlist_free(fru);
@@ -2057,6 +2033,10 @@
 	case CMD_PTR_CPU_L2CTL:
 		cpu_case_restore(hdl, cpu, &cpu->cpu_l2ctl, cp, "l2ctl");
 		break;
+	case CMD_PTR_CPU_MISC_REGS:
+		cpu_case_restore(hdl, cpu, &cpu->cpu_misc_regs, cp,
+		    "misc_regs");
+		break;
 	default:
 		fmd_hdl_abort(hdl, "invalid %s subtype %d\n",
 		    ptr->ptr_name, ptr->ptr_subtype);
--- a/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpu.h	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpu.h	Fri Dec 22 12:42:28 2006 -0800
@@ -86,6 +86,9 @@
 extern "C" {
 #endif
 
+#define	CPU_FRU_FMRI		FM_FMRI_SCHEME_HC":///" \
+    FM_FMRI_LEGACY_HC"="
+
 typedef struct cmd_cpu cmd_cpu_t;
 
 typedef enum cmd_cpu_type {
@@ -115,6 +118,10 @@
 	cmd_case_t cpuc_freg;		/* Floatpnt reg errors (frc, fru) */
 	cmd_case_t cpuc_mau;		/* Modular arith errors (MAU) */
 	cmd_case_t cpuc_l2ctl;		/* L2$ directory, VUAD parity */
+	cmd_case_t cpuc_misc_regs;	/* Scratchpad array (SCA) */
+					/* Tick compare (TC) */
+					/* Store buffer (SBD) */
+					/* Trap stack array errors (TSA) */
 #ifdef sun4u
 	cmd_case_t cpuc_opl_invsfsr;	/* Olympus-C cpu inv-sfsr errors */
 	cmd_case_t cpuc_oplue_detcpu;	/* Olympus-C cpu det. ue (eid=CPU) */
@@ -416,6 +423,7 @@
 #define	cpu_freg		cpu_cases.cpuc_freg
 #define	cpu_mau			cpu_cases.cpuc_mau
 #define	cpu_l2ctl		cpu_cases.cpuc_l2ctl
+#define	cpu_misc_regs		cpu_cases.cpuc_misc_regs
 #ifdef sun4u
 #define	cpu_opl_invsfsr		cpu_cases.cpuc_opl_invsfsr
 #define	cpu_oplue_detcpu	cpu_cases.cpuc_oplue_detcpu
@@ -612,6 +620,30 @@
     const char *, cmd_errcl_t);
 
 /*
+ * SBD (Storage Buffer Data) errors
+ * SCA (Scratchpath Array) erros
+ * TC (Tick compare) errors
+ * TSA (Trap stack Array) errors
+ *
+ *         SERD name
+ *   Type  (if any)   Fault
+ *  ------ --------- -------------------------------
+ *   SBDC     misc_regs    fault.cpu.<cputype>.misc_regs
+ *   SBDU
+ *   SCAC, SCAU
+ *   TCC, TCU
+ *   TSAC, TSAU
+ *
+ * The expected resolution of misc_regs faults is the repair of
+ * the indicated CPU.
+ */
+extern cmd_evdisp_t cmd_miscregs_ce(fmd_hdl_t *, fmd_event_t *, nvlist_t *,
+    const char *, cmd_errcl_t);
+extern cmd_evdisp_t cmd_miscregs_ue(fmd_hdl_t *, fmd_event_t *, nvlist_t *,
+    const char *, cmd_errcl_t);
+
+
+/*
  * CPUs are described by FMRIs.  This routine will retrieve the CPU state
  * structure (creating a new one if necessary) described by the detector
  * FMRI in the passed ereport.
@@ -619,7 +651,11 @@
 extern cmd_cpu_t *cmd_cpu_lookup_from_detector(fmd_hdl_t *, nvlist_t *,
     const char *, uint8_t);
 
-extern char *cpu_getfrustr(fmd_hdl_t *, uint32_t);
+extern char *cmd_cpu_getfrustr(fmd_hdl_t *, cmd_cpu_t *);
+extern char *cmd_cpu_getpartstr(fmd_hdl_t *, cmd_cpu_t *);
+
+extern char *cmd_cpu_getserialstr(fmd_hdl_t *, cmd_cpu_t *);
+
 extern cmd_cpu_t *cmd_cpu_lookup(fmd_hdl_t *, nvlist_t *, const char *,
     uint8_t);
 
--- a/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpuerr.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpuerr.c	Fri Dec 22 12:42:28 2006 -0800
@@ -127,11 +127,15 @@
 CMD_CPU_SIMPLEHANDLER(irc, ireg, CMD_PTR_CPU_IREG, "ireg", "ireg")
 CMD_CPU_SIMPLEHANDLER(frc, freg, CMD_PTR_CPU_FREG, "freg", "freg")
 CMD_CPU_SIMPLEHANDLER(mau, mau, CMD_PTR_CPU_MAU, "mau", "mau")
+CMD_CPU_SIMPLEHANDLER(miscregs_ce, misc_regs, CMD_PTR_CPU_MISC_REGS,
+	"misc_regs", "misc_regs")
 
 CMD_CPU_SIMPLEHANDLER(fpu, fpu, CMD_PTR_CPU_FPU, "", "fpu")
 CMD_CPU_SIMPLEHANDLER(l2ctl, l2ctl, CMD_PTR_CPU_L2CTL, "", "l2ctl")
 CMD_CPU_SIMPLEHANDLER(iru, ireg, CMD_PTR_CPU_IREG, "", "ireg")
 CMD_CPU_SIMPLEHANDLER(fru, freg, CMD_PTR_CPU_FREG, "", "freg")
+CMD_CPU_SIMPLEHANDLER(miscregs_ue, misc_regs, CMD_PTR_CPU_MISC_REGS,
+	"", "misc_regs")
 
 
 #ifdef sun4u
--- a/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_dimm.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_dimm.c	Fri Dec 22 12:42:28 2006 -0800
@@ -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.
  */
 
@@ -78,8 +77,13 @@
 cmd_dimm_create_fault(fmd_hdl_t *hdl, cmd_dimm_t *dimm, const char *fltnm,
     uint_t cert)
 {
+#ifdef sun4v
+	return (fmd_nvl_create_fault(hdl, fltnm, cert, dimm->dimm_asru_nvl,
+	    cmd_mem2hc(hdl, dimm->dimm_asru_nvl), NULL));
+#else
 	return (fmd_nvl_create_fault(hdl, fltnm, cert, dimm->dimm_asru_nvl,
 	    dimm->dimm_asru_nvl, NULL));
+#endif /* sun4v */
 }
 
 static void
@@ -111,6 +115,16 @@
 void
 cmd_dimm_destroy(fmd_hdl_t *hdl, cmd_dimm_t *dimm)
 {
+	int i;
+	cmd_mq_t *q;
+
+	for (i = 0; i < CMD_MAX_CKWDS; i++) {
+		while ((q = cmd_list_next(&dimm->mq_root[i])) != NULL) {
+			cmd_list_delete(&dimm->mq_root[i], q);
+			fmd_hdl_free(hdl, q, sizeof (cmd_mq_t));
+		}
+	}
+
 	fmd_stat_destroy(hdl, 1, &(dimm->dimm_retstat));
 	cmd_dimm_free(hdl, dimm, FMD_B_TRUE);
 }
--- a/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_dimm.h	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_dimm.h	Fri Dec 22 12:42:28 2006 -0800
@@ -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.
  */
 
@@ -64,6 +63,13 @@
 #endif
 
 /*
+ * CMD_MAX_CKWDS denotes the highest number, across all covered
+ * SPARC architectures, of checkwords per cache line.
+ */
+
+#define	CMD_MAX_CKWDS	4
+
+/*
  * The DIMM structure started life without a version number.  Making things more
  * complicated, the version number in the new struct occupies the space used for
  * the case pointer in the non-versioned struct.  We therefore have to use
@@ -98,12 +104,30 @@
 	uint_t dimmp_nretired;		/* # ret'd pages for CEs in DIMM */
 } cmd_dimm_pers_t;
 
+/*
+ * Index block for MQSC rules 4A and 4B correlation of memory CEs
+ * on a single DIMM. "Unit Position" refers to bit or nibble depending
+ * on the memory ECC.  This structure is not persisted.
+ */
+
+typedef struct cmd_mq {
+	cmd_list_t mq_l;		/* pointers to prev and next */
+	uint64_t mq_tstamp;		/* timestamp of ereport in secs */
+	uint16_t mq_ckwd;		/* phys addr mod 64 */
+	uint64_t mq_phys_addr;		/* from ereport */
+	uint16_t mq_unit_position;	/* bit for sun4u, nibble for sun4v */
+	uint16_t mq_dram;		/* by table lookup from unit pos */
+	fmd_event_t *mq_ep;		/* ereport - for potential fault */
+} cmd_mq_t;
+
 struct cmd_dimm {
 	cmd_dimm_pers_t dimm_pers;
 	cmd_bank_t *dimm_bank;		/* This DIMM's bank (if discovered) */
 	const char *dimm_unum;		/* This DIMM's name */
 	cmd_case_t dimm_case;		/* Open CE case against this DIMM */
-	fmd_stat_t dimm_retstat;
+	fmd_stat_t dimm_retstat;	/* retirement statistics, this DIMM */
+	cmd_list_t
+	    mq_root[CMD_MAX_CKWDS];	/* per-checkword CEs to correlate */
 };
 
 #define	CMD_DIMM_MAXSIZE \
@@ -126,6 +150,9 @@
 extern nvlist_t *cmd_dimm_fru(cmd_dimm_t *);
 extern nvlist_t *cmd_dimm_create_fault(fmd_hdl_t *, cmd_dimm_t *, const char *,
     uint_t);
+#ifdef sun4v
+extern nvlist_t *cmd_mem2hc(fmd_hdl_t *, nvlist_t *);
+#endif /* sun4v */
 
 extern nvlist_t *cmd_dimm_fmri_derive(fmd_hdl_t *, uint64_t, uint16_t,
     uint64_t);
--- a/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_main.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_main.c	Fri Dec 22 12:42:28 2006 -0800
@@ -231,11 +231,69 @@
 	{ "ereport.cpu.*.idc",		cmd_icache,	CMD_CPU_LEVEL_CORE },
 	{ "ereport.cpu.*.dtc",		cmd_dcache,	CMD_CPU_LEVEL_CORE },
 	{ "ereport.cpu.*.ddc",		cmd_dcache,	CMD_CPU_LEVEL_CORE },
-	/* cmd_subscribers CPU_ULTRASPARC_T2 */
+	{ "ereport.cpu.*.irfc",		cmd_irc },
+	{ "ereport.cpu.*.irfu",		cmd_iru },
+	{ "ereport.cpu.*.frfc",		cmd_frc },
+	{ "ereport.cpu.*.frfu",		cmd_fru },
+
+
+
+
+
+	{ "ereport.cpu.*.mamu",		cmd_mau,	CMD_CPU_LEVEL_CORE },
+	{ "ereport.cpu.*.mrau",		cmd_mau,	CMD_CPU_LEVEL_CORE },
+	{ "ereport.cpu.*.ittm",		cmd_itlb,	CMD_CPU_LEVEL_CORE },
+	{ "ereport.cpu.*.ittp",		cmd_itlb,	CMD_CPU_LEVEL_CORE },
+	{ "ereport.cpu.*.itdp",		cmd_itlb,	CMD_CPU_LEVEL_CORE },
+	{ "ereport.cpu.*.itmu",		cmd_itlb,	CMD_CPU_LEVEL_CORE },
+	{ "ereport.cpu.*.dttm",		cmd_dtlb,	CMD_CPU_LEVEL_CORE },
+	{ "ereport.cpu.*.dttp",		cmd_dtlb,	CMD_CPU_LEVEL_CORE },
+	{ "ereport.cpu.*.dtdp",		cmd_dtlb,	CMD_CPU_LEVEL_CORE },
+	{ "ereport.cpu.*.dtmu",		cmd_dtlb,	CMD_CPU_LEVEL_CORE },
+	{ "ereport.cpu.*.icvp",		cmd_icache,	CMD_CPU_LEVEL_CORE },
+	{ "ereport.cpu.*.ictp",		cmd_icache,	CMD_CPU_LEVEL_CORE },
+	{ "ereport.cpu.*.ictm",		cmd_icache,	CMD_CPU_LEVEL_CORE },
+	{ "ereport.cpu.*.icdp",		cmd_icache,	CMD_CPU_LEVEL_CORE },
+	{ "ereport.cpu.*.dcvp",		cmd_dcache,	CMD_CPU_LEVEL_CORE },
+	{ "ereport.cpu.*.dctp",		cmd_dcache,	CMD_CPU_LEVEL_CORE },
+	{ "ereport.cpu.*.dctm",		cmd_dcache,	CMD_CPU_LEVEL_CORE },
+	{ "ereport.cpu.*.dcdp",		cmd_dcache,	CMD_CPU_LEVEL_CORE },
+	{ "ereport.cpu.*.itl2c",	cmd_xxc,	CMD_ERRCL_LDAC |
+		CMD_CPU_LEVEL_CHIP },
+	{ "ereport.cpu.*.dtl2c",	cmd_xxc,	CMD_ERRCL_LDAC |
+		CMD_CPU_LEVEL_CHIP },
+	{ "ereport.cpu.*.icl2c",	cmd_xxc,	CMD_ERRCL_LDAC |
+		CMD_CPU_LEVEL_CHIP },
+	{ "ereport.cpu.*.dcl2c",	cmd_xxc,	CMD_ERRCL_LDAC |
+		CMD_CPU_LEVEL_CHIP },
+	{ "ereport.cpu.*.mal2c",	cmd_xxc,	CMD_ERRCL_LDAC |
+		CMD_CPU_LEVEL_CHIP },
+	{ "ereport.cpu.*.cwql2c",	cmd_xxc,	CMD_ERRCL_LDAC |
+		CMD_CPU_LEVEL_CHIP },
+	{ "ereport.cpu.*.lvc",		cmd_txce,	CMD_CPU_LEVEL_CHIP },
+	{ "ereport.cpu.*.itl2u",	cmd_xxu,	CMD_ERRCL_LDAU |
+		CMD_CPU_LEVEL_CHIP },
+	{ "ereport.cpu.*.dtl2u",	cmd_xxu,	CMD_ERRCL_LDAU |
+		CMD_CPU_LEVEL_CHIP },
+	{ "ereport.cpu.*.icl2u",	cmd_xxu,	CMD_ERRCL_LDAU |
+		CMD_CPU_LEVEL_CHIP },
+	{ "ereport.cpu.*.dcl2u",	cmd_xxu,	CMD_ERRCL_LDAU |
+		CMD_CPU_LEVEL_CHIP },
+	{ "ereport.cpu.*.mal2u",	cmd_xxu,	CMD_ERRCL_LDAU |
+		CMD_CPU_LEVEL_CHIP },
+	{ "ereport.cpu.*.cwql2u",	cmd_xxu,	CMD_ERRCL_LDAU |
+		CMD_CPU_LEVEL_CHIP },
+	{ "ereport.cpu.*.lvf",		cmd_l2ctl },
+	{ "ereport.cpu.*.lrf",		cmd_l2ctl },
+	{ "ereport.cpu.*.itl2nd",	cmd_nop },
+	{ "ereport.cpu.*.dtl2nd",	cmd_nop },
+	{ "ereport.cpu.*.icl2nd",	cmd_nop },
+	{ "ereport.cpu.*.l2nd",		cmd_nop },
+	{ "ereport.cpu.*.mal2nd",	cmd_nop },
+	{ "ereport.cpu.*.cwql2nd",	cmd_nop },
 	{ "ereport.cpu.*.ldac",		cmd_xxc, 	CMD_ERRCL_LDAC |
 	    CMD_CPU_LEVEL_CHIP },
-	{ "ereport.cpu.*.ldwc",		cmd_xxc,	CMD_ERRCL_LDWC |
-	    CMD_CPU_LEVEL_CHIP },
+	{ "ereport.cpu.*.ldwc",		cmd_nop },
 	{ "ereport.cpu.*.ldrc",		cmd_xxc,	CMD_ERRCL_LDRC |
 	    CMD_CPU_LEVEL_CHIP },
 	{ "ereport.cpu.*.ldsc", 	cmd_xxc,	CMD_ERRCL_LDSC |
@@ -243,18 +301,47 @@
 	{ "ereport.cpu.*.ltc",		cmd_txce },
 	{ "ereport.cpu.*.ldau",		cmd_xxu, 	CMD_ERRCL_LDAU |
 	    CMD_CPU_LEVEL_CHIP },
-	{ "ereport.cpu.*.ldwu",		cmd_xxu,	CMD_ERRCL_LDWU |
-	    CMD_CPU_LEVEL_CHIP },
+	{ "ereport.cpu.*.ldwu",		cmd_nop },
 	{ "ereport.cpu.*.ldru",		cmd_xxu,	CMD_ERRCL_LDRU |
 	    CMD_CPU_LEVEL_CHIP },
 	{ "ereport.cpu.*.ldsu",		cmd_xxu,	CMD_ERRCL_LDSU |
 	    CMD_CPU_LEVEL_CHIP },
 	{ "ereport.cpu.*.lvu",		cmd_l2ctl },
 	{ "ereport.cpu.*.lru",		cmd_l2ctl },
+	{ "ereport.cpu.*.fbr",		cmd_ce,		CMD_ERRCL_DAC },
+	{ "ereport.cpu.*.fbu",		cmd_ue,		CMD_ERRCL_DAU },
 	{ "ereport.cpu.*.dac",		cmd_ce,		CMD_ERRCL_DAC },
 	{ "ereport.cpu.*.dsc",		cmd_ce,		CMD_ERRCL_DSC },
 	{ "ereport.cpu.*.dau",		cmd_ue,		CMD_ERRCL_DAU },
 	{ "ereport.cpu.*.dsu",		cmd_ue,		CMD_ERRCL_DSU },
+	{ "ereport.cpu.*.sbdpc",	cmd_miscregs_ce,
+	    CMD_CPU_LEVEL_THREAD },
+	{ "ereport.cpu.*.sbdlc",	cmd_miscregs_ce,
+	    CMD_CPU_LEVEL_THREAD },
+	{ "ereport.cpu.*.sbdpu",	cmd_miscregs_ue,
+	    CMD_CPU_LEVEL_THREAD },
+	{ "ereport.cpu.*.sbdlu",	cmd_miscregs_ue,
+	    CMD_CPU_LEVEL_THREAD },
+	{ "ereport.cpu.*.sbdio",	cmd_miscregs_ue,
+	    CMD_CPU_LEVEL_THREAD },
+	{ "ereport.cpu.*.sbapp",	cmd_miscregs_ue,
+	    CMD_CPU_LEVEL_THREAD },
+	{ "ereport.cpu.*.scac",		cmd_miscregs_ce,
+	    CMD_CPU_LEVEL_THREAD },
+	{ "ereport.cpu.*.scau",		cmd_miscregs_ue,
+	    CMD_CPU_LEVEL_THREAD },
+	{ "ereport.cpu.*.tccp",		cmd_miscregs_ce,
+	    CMD_CPU_LEVEL_THREAD },
+	{ "ereport.cpu.*.tccd",		cmd_miscregs_ce,
+	    CMD_CPU_LEVEL_THREAD },
+	{ "ereport.cpu.*.tcup",		cmd_miscregs_ue,
+	    CMD_CPU_LEVEL_THREAD },
+	{ "ereport.cpu.*.tcud",		cmd_miscregs_ue,
+	    CMD_CPU_LEVEL_THREAD },
+	{ "ereport.cpu.*.tsac",		cmd_miscregs_ce,
+	    CMD_CPU_LEVEL_THREAD },
+	{ "ereport.cpu.*.tsau",		cmd_miscregs_ue,
+	    CMD_CPU_LEVEL_THREAD },
 #endif /* sun4u */
 	{ "ereport.cpu.*.fpu.hwcopy",	cmd_fpu },
 	{ NULL, NULL }
@@ -378,6 +465,7 @@
 	{ "dcache_t", FMD_TYPE_TIME, "168h" },
 	{ "pcache_n", FMD_TYPE_UINT32, "2" },
 	{ "pcache_t", FMD_TYPE_TIME, "168h" },
+#ifdef sun4u
 	{ "itlb_n", FMD_TYPE_UINT32, "2" },
 	{ "itlb_t", FMD_TYPE_TIME, "168h" },
 	{ "dtlb_n", FMD_TYPE_UINT32, "2" },
@@ -386,18 +474,30 @@
 	{ "l2tag_t", FMD_TYPE_TIME, "1h" },
 	{ "l2data_n", FMD_TYPE_UINT32, "12" },
 	{ "l2data_t", FMD_TYPE_TIME, "1h" },
+#else
+	{ "itlb_n", FMD_TYPE_UINT32, "8" },
+	{ "itlb_t", FMD_TYPE_TIME, "168h" },
+	{ "dtlb_n", FMD_TYPE_UINT32, "8" },
+	{ "dtlb_t", FMD_TYPE_TIME, "168h" },
+	{ "l2tag_n", FMD_TYPE_UINT32, "8" },
+	{ "l2tag_t", FMD_TYPE_TIME, "20h" },
+	{ "l2data_n", FMD_TYPE_UINT32, "8" },
+	{ "l2data_t", FMD_TYPE_TIME, "2h" },
+#endif
 	{ "l3tag_n", FMD_TYPE_UINT32, "4" },
 	{ "l3tag_t", FMD_TYPE_TIME, "1h" },
 	{ "l3data_n", FMD_TYPE_UINT32, "12" },
 	{ "l3data_t", FMD_TYPE_TIME, "1h" },
 	{ "ce_n", FMD_TYPE_UINT32, "2" },
 	{ "ce_t", FMD_TYPE_TIME, "72h" },
-	{ "ireg_n", FMD_TYPE_UINT32, "2" },
+	{ "ireg_n", FMD_TYPE_UINT32, "8" },
 	{ "ireg_t", FMD_TYPE_TIME, "168h" },
-	{ "freg_n", FMD_TYPE_UINT32, "2" },
+	{ "freg_n", FMD_TYPE_UINT32, "8" },
 	{ "freg_t", FMD_TYPE_TIME, "168h" },
-	{ "mau_n", FMD_TYPE_UINT32, "2" },
+	{ "mau_n", FMD_TYPE_UINT32, "0" },
 	{ "mau_t", FMD_TYPE_TIME, "168h" },
+	{ "misc_regs_n", FMD_TYPE_UINT32, "8"},
+	{ "misc_regs_t", FMD_TYPE_TIME, "168h" },
 	{ "iorxefrx_window", FMD_TYPE_TIME, "3s" },
 	{ "xxcu_trdelay", FMD_TYPE_TIME, "200ms" },
 	{ "xxcu_restart_delay", FMD_TYPE_TIME, "1s" },
@@ -406,6 +506,8 @@
 	{ "thresh_abs_sysmem", FMD_TYPE_UINT64, "0" },
 	{ "thresh_abs_badrw", FMD_TYPE_UINT64, "128" },
 	{ "max_perm_ce_dimm", FMD_TYPE_UINT32, "128" },
+	{ "int_ce_n", FMD_TYPE_UINT32, "10" },
+	{ "int_ce_t", FMD_TYPE_TIME, "1h" },
 	{ NULL, 0, NULL }
 };
 
@@ -486,6 +588,7 @@
 	fmd_hdl_subscribe(hdl, "ereport.cpu.ultraSPARC-IIIiplus.*");
 	fmd_hdl_subscribe(hdl, "ereport.cpu.ultraSPARC-IV.*");
 	fmd_hdl_subscribe(hdl, "ereport.cpu.ultraSPARC-IVplus.*");
+	fmd_hdl_subscribe(hdl, "ereport.cpu.ultraSPARC-T2.*");
 	fmd_hdl_subscribe(hdl, "ereport.cpu.ultraSPARC-T1.*");
 
 	fmd_hdl_subscribe(hdl, "ereport.io.tom.ecc.drce");
--- a/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_mem.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_mem.c	Fri Dec 22 12:42:28 2006 -0800
@@ -75,6 +75,18 @@
 	return (nm);
 }
 
+char *
+cmd_page_serdnm_create(fmd_hdl_t *hdl, const char *serdbase,
+    uint64_t phys_addr)
+{
+	const char *fmt = "%s_%llXserd";
+	size_t sz = snprintf(NULL, 0, fmt, serdbase, phys_addr) + 1;
+	char *nm = fmd_hdl_alloc(hdl, sz, FMD_SLEEP);
+	(void) snprintf(nm, sz, fmt, serdbase, phys_addr);
+
+	return (nm);
+}
+
 void
 cmd_mem_case_restore(fmd_hdl_t *hdl, cmd_case_t *cc, fmd_case_t *cp,
     const char *serdbase, const char *unum)
--- a/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_mem.h	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_mem.h	Fri Dec 22 12:42:28 2006 -0800
@@ -113,6 +113,8 @@
     nvlist_t *);
 
 extern ce_dispact_t cmd_mem_name2type(const char *, int);
+extern int cmd_synd2upos(uint16_t);
+extern int cmd_upos2dram(uint16_t);
 extern cmd_evdisp_t cmd_ce(fmd_hdl_t *, fmd_event_t *, nvlist_t *,
     const char *, cmd_errcl_t);
 extern cmd_evdisp_t cmd_ue(fmd_hdl_t *, fmd_event_t *, nvlist_t *,
@@ -168,6 +170,7 @@
 extern void cmd_mem_case_restore(fmd_hdl_t *, cmd_case_t *, fmd_case_t *,
     const char *, const char *);
 extern char *cmd_mem_serdnm_create(fmd_hdl_t *, const char *, const char *);
+extern char *cmd_page_serdnm_create(fmd_hdl_t *, const char *, uint64_t);
 extern void cmd_mem_retirestat_create(fmd_hdl_t *, fmd_stat_t *, const char *,
     uint64_t);
 extern int cmd_mem_thresh_check(fmd_hdl_t *, uint_t);
--- a/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_memerr.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_memerr.c	Fri Dec 22 12:42:28 2006 -0800
@@ -166,13 +166,220 @@
 	fmd_case_solve(hdl, cp);
 }
 
+/* Create a fresh index block for MQSC CE correlation. */
+
+cmd_mq_t *
+mq_create(fmd_hdl_t *hdl, fmd_event_t *ep,
+    uint64_t afar, uint16_t upos, uint64_t now)
+{
+	cmd_mq_t *cp;
+	cp = fmd_hdl_zalloc(hdl, sizeof (cmd_mq_t), FMD_SLEEP);
+	cp->mq_tstamp = now;
+	cp->mq_ckwd = (afar >> 4) & 0x3;
+	cp->mq_phys_addr = afar;
+	cp->mq_unit_position = upos;
+	cp->mq_dram = cmd_upos2dram(upos);
+	cp->mq_ep = ep;
+
+	return (cp);
+}
+
+/*
+ * Add an index block for a new CE, sorted
+ * a) by ascending unit position
+ * b) order of arrival (~= time order)
+ */
+
+void
+mq_add(fmd_hdl_t *hdl, cmd_dimm_t *dimm, fmd_event_t *ep,
+    uint64_t afar, uint16_t synd, uint64_t now)
+{
+	cmd_mq_t *ip, *jp;
+	int cw, unit_position;
+
+	cw = (afar & 0x30) >> 4;		/* 0:3 */
+	if ((unit_position = cmd_synd2upos(synd)) < 0)
+		return;				/* not a CE */
+
+	for (ip = cmd_list_next(&dimm->mq_root[cw]); ip != NULL; ) {
+		if (ip->mq_unit_position > unit_position) break;
+		else if (ip->mq_unit_position == unit_position &&
+		    ip->mq_phys_addr == afar) {
+			/*
+			 * Found a duplicate cw, unit_position, and afar.
+			 * Delete this node, to be superseded by the new
+			 * node added below.
+			 */
+			jp = cmd_list_next(ip);
+			cmd_list_delete(&dimm->mq_root[cw], &ip->mq_l);
+			fmd_hdl_free(hdl, ip, sizeof (cmd_mq_t));
+			ip = jp;
+		} else ip = cmd_list_next(ip);
+	}
+	jp = mq_create(hdl, ep, afar, unit_position, now);
+	if (ip == NULL)
+		cmd_list_append(&dimm->mq_root[cw], jp);
+	else
+		cmd_list_insert_before(&dimm->mq_root[cw], ip, jp);
+}
+
+/*
+ * Prune the MQSC index lists (one for each checkword), by deleting
+ * outdated index blocks from each list.
+ */
+
+void
+mq_prune(fmd_hdl_t *hdl, cmd_dimm_t *dimm, uint64_t now)
+{
+	cmd_mq_t *ip, *jp;
+	int cw;
+
+	for (cw = 0; cw < CMD_MAX_CKWDS; cw++) {
+		for (ip = cmd_list_next(&dimm->mq_root[cw]); ip != NULL; ) {
+			if (ip->mq_tstamp < now - (72*60*60)) {
+				jp = cmd_list_next(ip);
+				cmd_list_delete(&dimm->mq_root[cw], ip);
+				fmd_hdl_free(hdl, ip, sizeof (cmd_mq_t));
+				ip = jp;
+			} /* tstamp < now - ce_t */
+			else ip = cmd_list_next(ip);
+		} /* per checkword */
+	} /* cw = 0...3 */
+}
+
+/*
+ * Check the MQSC index lists (one for each checkword) by making a
+ * complete pass through each list, checking if the criteria for either
+ * Rule 4A or 4B have been met.  Rule 4A checking is done for each checkword;
+ * 4B check is done at end.
+ *
+ * Rule 4A: fault a DIMM  "whenever Solaris reports two or more CEs from
+ * two or more different physical addresses on each of two or more different
+ * bit positions from the same DIMM within 72 hours of each other, and all
+ * the addresses are in the same relative checkword (that is, the AFARs
+ * are all the same modulo 64).  [Note: This means at least 4 CEs; two
+ * from one bit position, with unique addresses, and two from another,
+ * also with unique addresses, and the lower 6 bits of all the addresses
+ * are the same."
+ *
+ * Rule 4B: fault a DIMM "whenever Solaris reports two or more CEs from
+ * two or more different physical addresses on each of three or more
+ * different outputs from the same DRAM within 72 hours of each other, as
+ * long as the three outputs do not all correspond to the same relative
+ * bit position in their respective checkwords.  [Note: This means at least
+ * 6 CEs; two from one DRAM output signal, with unique addresses, two from
+ * another output from the same DRAM, also with unique addresses, and two
+ * more from yet another output from the same DRAM, again with unique
+ * addresses, as long as the three outputs do not all correspond to the
+ * same relative bit position in their respective checkwords.]"
+ */
+
+void
+mq_check(fmd_hdl_t *hdl, cmd_dimm_t *dimm)
+{
+	int upos_pairs, curr_upos, cw, i, j, k;
+	nvlist_t *flt;
+	typedef struct upos_pair {
+		int upos;
+		int dram;
+		cmd_mq_t *mq1;
+		cmd_mq_t *mq2;
+	} upos_pair_t;
+	upos_pair_t upos_array[8]; /* max per cw = 2, * 4 cw's */
+	cmd_mq_t *ip;
+
+	upos_pairs = 0;
+	upos_array[0].mq1 = NULL;
+	for (cw = 0; cw < CMD_MAX_CKWDS; cw++) {
+		i = upos_pairs;
+		curr_upos = -1;
+		for (ip = cmd_list_next(&dimm->mq_root[cw]); ip != NULL;
+		    ip = cmd_list_next(ip)) {
+			if (curr_upos != ip->mq_unit_position)
+				curr_upos = ip->mq_unit_position;
+			else if (i > upos_pairs &&
+			    curr_upos == upos_array[i-1].upos)
+				continue; /* skip triples, quads, etc. */
+			else if (upos_array[i].mq1 == NULL) {
+				/* we have a pair */
+				upos_array[i].upos = curr_upos;
+				upos_array[i].dram = ip->mq_dram;
+				upos_array[i].mq1 = cmd_list_prev(ip);
+				upos_array[i].mq2 = ip;
+				upos_array[++i].mq1 = NULL;
+			}
+		}
+		if (i - upos_pairs >= 2) {
+			flt = cmd_dimm_create_fault(hdl,
+			    dimm, "fault.memory.dimm", CMD_FLTMAXCONF);
+			for (j = upos_pairs; j < i; j++) {
+				fmd_case_add_ereport(hdl,
+				    dimm->dimm_case.cc_cp,
+				    upos_array[j].mq1->mq_ep);
+				fmd_case_add_ereport(hdl,
+				    dimm->dimm_case.cc_cp,
+				    upos_array[j].mq2->mq_ep);
+			}
+			fmd_case_add_suspect(hdl, dimm->dimm_case.cc_cp, flt);
+			fmd_case_solve(hdl, dimm->dimm_case.cc_cp);
+			return;
+		}
+		upos_pairs += i;
+	}
+
+	if (upos_pairs  < 3)
+		return; /* 4B violation needs at least 3 pairs */
+
+	for (i = 0; i < upos_pairs; i++) {
+		for (j = i+1; j < upos_pairs; j++) {
+			if (upos_array[i].dram != upos_array[j].dram)
+				continue;
+			for (k = j+1; k < upos_pairs; k++) {
+				if (upos_array[j].dram != upos_array[k].dram)
+					continue;
+				if ((upos_array[i].upos !=
+				    upos_array[j].upos) ||
+				    (upos_array[j].upos !=
+				    upos_array[k].upos)) {
+					flt = cmd_dimm_create_fault(hdl,
+					    dimm, "fault.memory.dimm",
+					    CMD_FLTMAXCONF);
+					fmd_case_add_ereport(hdl,
+					    dimm->dimm_case.cc_cp,
+					    upos_array[i].mq1->mq_ep);
+					fmd_case_add_ereport(hdl,
+					    dimm->dimm_case.cc_cp,
+					    upos_array[i].mq2->mq_ep);
+					fmd_case_add_ereport(hdl,
+					    dimm->dimm_case.cc_cp,
+					    upos_array[j].mq1->mq_ep);
+					fmd_case_add_ereport(hdl,
+					    dimm->dimm_case.cc_cp,
+					    upos_array[j].mq2->mq_ep);
+					fmd_case_add_ereport(hdl,
+					    dimm->dimm_case.cc_cp,
+					    upos_array[k].mq1->mq_ep);
+					fmd_case_add_ereport(hdl,
+					    dimm->dimm_case.cc_cp,
+					    upos_array[k].mq2->mq_ep);
+					fmd_case_add_suspect(hdl,
+					    dimm->dimm_case.cc_cp, flt);
+					fmd_case_solve(hdl,
+					    dimm->dimm_case.cc_cp);
+					return;
+				}
+			}
+		}
+	}
+}
+
 /*ARGSUSED*/
 cmd_evdisp_t
 cmd_ce_common(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl,
     const char *class, uint64_t afar, uint8_t afar_status, uint16_t synd,
     uint8_t synd_status, ce_dispact_t type, uint64_t disp, nvlist_t *asru)
 {
-	cmd_dimm_t *dimm;
+	cmd_dimm_t *dimm, *d;
 	cmd_page_t *page;
 	const char *uuid;
 
@@ -180,8 +387,9 @@
 	    synd_status != AFLT_STAT_VALID)
 		return (CMD_EVD_UNUSED);
 
-	if ((page = cmd_page_lookup(afar)) != NULL && page->page_case != NULL &&
-	    fmd_case_solved(hdl, page->page_case))
+	if ((page = cmd_page_lookup(afar)) != NULL &&
+	    page->page_case.cc_cp != NULL &&
+	    fmd_case_solved(hdl, page->page_case.cc_cp))
 		return (CMD_EVD_REDUND);
 
 #ifdef sun4u
@@ -200,13 +408,72 @@
 	    (dimm = cmd_dimm_create(hdl, asru)) == NULL)
 		return (CMD_EVD_UNUSED);
 
+	if (dimm->dimm_case.cc_cp == NULL) {
+		dimm->dimm_case.cc_cp = cmd_case_create(hdl,
+		    &dimm->dimm_header, CMD_PTR_DIMM_CASE, &uuid);
+	}
+
+	/*
+	 * Add to MQSC correlation lists all CEs which pass validity
+	 * checks above.
+	 */
+	{
+		uint64_t *now;
+		uint_t nelem;
+		if (nvlist_lookup_uint64_array(nvl,
+		    "__tod", &now, &nelem) == 0) {
+
+			mq_add(hdl, dimm, ep, afar, synd, *now);
+			mq_prune(hdl, dimm, *now);
+			mq_check(hdl, dimm);
+		}
+	}
+
 	switch (type) {
 	case CE_DISP_UNKNOWN:
 		CMD_STAT_BUMP(ce_unknown);
-		return (CMD_EVD_UNUSED);
+		break;
 	case CE_DISP_INTERMITTENT:
 		CMD_STAT_BUMP(ce_interm);
-		return (CMD_EVD_UNUSED);
+		fmd_hdl_debug(hdl,
+		    "adding intermittent event to CE serd engine\n");
+
+		if (dimm->dimm_case.cc_serdnm == NULL) {
+			dimm->dimm_case.cc_serdnm = cmd_mem_serdnm_create(hdl,
+			    "dimm", dimm->dimm_unum);
+
+			fmd_serd_create(hdl, dimm->dimm_case.cc_serdnm,
+			    fmd_prop_get_int32(hdl, "int_ce_n"),
+			    fmd_prop_get_int64(hdl, "int_ce_t"));
+		}
+
+		/*
+		 * At most one such SERD engine for intermittent events is
+		 * allowed at any time.  Destroy SERD engines on other DIMMs.
+		 */
+
+		for (d = cmd_list_next(&cmd.cmd_dimms); d != NULL;
+		    d = cmd_list_next(d)) {
+			if (d == dimm) continue; /* skip current dimm */
+			else if (d->dimm_case.cc_serdnm != NULL) {
+				fmd_serd_destroy(hdl, d->dimm_case.cc_serdnm);
+				d->dimm_case.cc_serdnm = NULL;
+			}
+		}
+
+		if (fmd_serd_record(hdl, dimm->dimm_case.cc_serdnm, ep) ==
+		    FMD_B_FALSE)
+			return (CMD_EVD_OK); /* engine hasn't fired */
+
+		fmd_hdl_debug(hdl, "ce int serd fired\n");
+		fmd_case_add_serd(hdl, dimm->dimm_case.cc_cp,
+		    dimm->dimm_case.cc_serdnm);
+		fmd_case_add_suspect(hdl, dimm->dimm_case.cc_cp,
+		    cmd_dimm_create_fault(hdl, dimm, "fault.memory.dimm", 100));
+		fmd_case_solve(hdl, dimm->dimm_case.cc_cp);
+		dimm->dimm_flags |= CMD_MEM_F_FAULTING;
+		fmd_serd_reset(hdl, dimm->dimm_case.cc_serdnm);
+		return (CMD_EVD_OK);
 	case CE_DISP_POSS_PERS:
 		CMD_STAT_BUMP(ce_ppersis);
 		break;
@@ -246,9 +513,12 @@
 		return (CMD_EVD_BAD);
 	}
 
-	if (dimm->dimm_case.cc_cp == NULL) {
-		dimm->dimm_case.cc_cp = cmd_case_create(hdl,
-		    &dimm->dimm_header, CMD_PTR_DIMM_CASE, &uuid);
+	if (page == NULL)
+		page = cmd_page_create(hdl, asru, afar);
+
+	if (page->page_case.cc_cp == NULL) {
+		page->page_case.cc_cp = cmd_case_create(hdl,
+		    &page->page_header, CMD_PTR_PAGE_CASE, &uuid);
 	}
 
 	switch (type) {
@@ -257,28 +527,28 @@
 		fmd_hdl_debug(hdl, "adding %sPersistent event to CE serd "
 		    "engine\n", type == CE_DISP_POSS_PERS ? "Possible-" : "");
 
-		if (dimm->dimm_case.cc_serdnm == NULL) {
-			dimm->dimm_case.cc_serdnm = cmd_mem_serdnm_create(hdl,
-			    "dimm", dimm->dimm_unum);
+		if (page->page_case.cc_serdnm == NULL) {
+			page->page_case.cc_serdnm = cmd_page_serdnm_create(hdl,
+			    "page", page->page_physbase);
 
-			fmd_serd_create(hdl, dimm->dimm_case.cc_serdnm,
+			fmd_serd_create(hdl, page->page_case.cc_serdnm,
 			    fmd_prop_get_int32(hdl, "ce_n"),
 			    fmd_prop_get_int64(hdl, "ce_t"));
 		}
 
-		if (fmd_serd_record(hdl, dimm->dimm_case.cc_serdnm, ep) ==
+		if (fmd_serd_record(hdl, page->page_case.cc_serdnm, ep) ==
 		    FMD_B_FALSE)
 				return (CMD_EVD_OK); /* engine hasn't fired */
 
-		fmd_hdl_debug(hdl, "ce serd fired\n");
-		fmd_case_add_serd(hdl, dimm->dimm_case.cc_cp,
-		    dimm->dimm_case.cc_serdnm);
-		fmd_serd_reset(hdl, dimm->dimm_case.cc_serdnm);
+		fmd_hdl_debug(hdl, "ce page serd fired\n");
+		fmd_case_add_serd(hdl, page->page_case.cc_cp,
+		    page->page_case.cc_serdnm);
+		fmd_serd_reset(hdl, page->page_case.cc_serdnm);
 		break;	/* to retire */
 
 	case CE_DISP_LEAKY:
 	case CE_DISP_STICKY:
-		fmd_case_add_ereport(hdl, dimm->dimm_case.cc_cp, ep);
+		fmd_case_add_ereport(hdl, page->page_case.cc_cp, ep);
 		break;	/* to retire */
 	}
 
@@ -309,9 +579,70 @@
 	bank->bank_flags |= CMD_MEM_F_FAULTING;
 	cmd_bank_dirty(hdl, bank);
 
+#ifdef	sun4u
 	flt = cmd_bank_create_fault(hdl, bank, "fault.memory.bank",
 	    CMD_FLTMAXCONF);
 	fmd_case_add_suspect(hdl, cp, flt);
+#else /* sun4v */
+	{
+		/*
+		 * Break up the bank's unum into separate unums for each dimm.
+		 * Create an asru from each unum.
+		 */
+
+		cmd_bank_memb_t *d;
+		char dimm_unum_string[MAXPATHLEN];
+		const char *q, *r;
+		nvlist_t *fmri;
+		size_t baselen;
+
+		q = strchr(bank->bank_unum, ' ');
+		baselen = q - bank->bank_unum + 1;
+		(void) strncpy(dimm_unum_string, bank->bank_unum, baselen);
+
+		/*
+		 * This method of breaking apart the bank unum works for
+		 * sun4v bank unums, until such time as a dimm enumerator
+		 * is written for libtopo.
+		 */
+
+		while (*q == ' ') {
+			r = strchr(q+1, ' ');
+			if (r == NULL)
+			    r = bank->bank_unum +
+			    strlen(bank->bank_unum) + 1; /* null@end */
+			(void) strncpy(dimm_unum_string+baselen,
+			    q+1, r-q-1);
+			dimm_unum_string[baselen+(r-q-1)] = 0;
+			fmri = cmd_mem_fmri_create(dimm_unum_string);
+			if (fmd_nvl_fmri_expand(hdl, fmri) < 0) {
+				nvlist_free(fmri);
+				fmd_hdl_abort(hdl,
+				    "failed to expand dimm FMRI from "
+				    "previously validated bank\n");
+			}
+
+			/*
+			 * If dimm structure doesn't already exist for
+			 * each dimm, create and link to bank.
+			 */
+
+			if (cmd_dimm_lookup(hdl, fmri) == NULL)
+			    (void) cmd_dimm_create(hdl, fmri);
+			nvlist_free(fmri);
+			q = r;
+		}
+
+		/* create separate fault for each dimm in bank */
+
+		for (d = cmd_list_next(&bank->bank_dimms);
+		    d != NULL; d = cmd_list_next(d)) {
+			flt = cmd_dimm_create_fault(hdl, d->bm_dimm,
+			    "fault.memory.bank", CMD_FLTMAXCONF);
+			fmd_case_add_suspect(hdl, cp, flt);
+		}
+	}
+#endif /* sun4u */
 	fmd_case_solve(hdl, cp);
 }
 
@@ -369,8 +700,9 @@
 	if (afar_status != AFLT_STAT_VALID)
 		return (CMD_EVD_UNUSED);
 
-	if ((page = cmd_page_lookup(afar)) != NULL && page->page_case != NULL &&
-	    fmd_case_solved(hdl, page->page_case))
+	if ((page = cmd_page_lookup(afar)) != NULL &&
+	    page->page_case.cc_cp != NULL &&
+	    fmd_case_solved(hdl, page->page_case.cc_cp))
 		return (CMD_EVD_REDUND);
 
 	if (fmd_nvl_fmri_expand(hdl, asru) < 0) {
--- a/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_page.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_page.c	Fri Dec 22 12:42:28 2006 -0800
@@ -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.
@@ -31,27 +30,37 @@
  */
 
 #include <cmd_page.h>
+#include <cmd_mem.h>
 #include <cmd.h>
 #ifdef sun4u
 #include <cmd_dp_page.h>
 #endif
 
 #include <errno.h>
-#include <string.h>
+#include <strings.h>
 #include <fm/fmd_api.h>
 #include <sys/fm/protocol.h>
 
 static void
 page_write(fmd_hdl_t *hdl, cmd_page_t *page)
 {
-	fmd_buf_write(hdl, NULL, page->page_bufname, page, sizeof (cmd_page_t));
+	fmd_buf_write(hdl, NULL, page->page_bufname, page,
+	    sizeof (cmd_page_pers_t));
 }
 
 static void
 cmd_page_free(fmd_hdl_t *hdl, cmd_page_t *page, int destroy)
 {
-	if (page->page_case != NULL)
-		cmd_case_fini(hdl, page->page_case, destroy);
+	cmd_case_t *cc = &page->page_case;
+
+	if (cc->cc_cp != NULL)
+		cmd_case_fini(hdl, cc->cc_cp, destroy);
+
+	if (cc->cc_serdnm != NULL) {
+		if (fmd_serd_exists(hdl, cc->cc_serdnm) && destroy)
+			fmd_serd_destroy(hdl, cc->cc_serdnm);
+		fmd_hdl_strfree(hdl, cc->cc_serdnm);
+	}
 
 	if (destroy)
 		fmd_buf_destroy(hdl, NULL, page->page_bufname);
@@ -96,6 +105,7 @@
 
 	page = fmd_hdl_zalloc(hdl, sizeof (cmd_page_t), FMD_SLEEP);
 	page->page_nodetype = CMD_NT_PAGE;
+	page->page_version = CMD_PAGE_VERSION;
 	page->page_physbase = pa;
 
 	cmd_bufname(page->page_bufname, sizeof (page->page_bufname),
@@ -103,7 +113,8 @@
 
 	if ((errno = nvlist_dup(modasru, &asru, 0)) != 0 ||
 	    (errno = nvlist_add_uint64(asru, FM_FMRI_MEM_PHYSADDR,
-	    page->page_physbase)) != 0)
+	    page->page_physbase)) != 0 ||
+	    (errno = fmd_nvl_fmri_expand(hdl, asru)) != 0)
 		fmd_hdl_abort(hdl, "failed to build page fmri");
 
 	cmd_fmri_init(hdl, &page->page_asru, asru, "page_asru_%llx",
@@ -125,6 +136,41 @@
 	return (page_lookup_by_physaddr(pa));
 }
 
+static cmd_page_t *
+page_v0tov1(fmd_hdl_t *hdl, cmd_page_0_t *old, size_t oldsz)
+{
+	cmd_page_t *new;
+
+	if (oldsz != sizeof (cmd_page_0_t)) {
+		fmd_hdl_abort(hdl, "size of state doesn't match size of "
+		    "version 0 state (%u bytes).\n", sizeof (cmd_page_0_t));
+	}
+
+	new = fmd_hdl_zalloc(hdl, sizeof (cmd_page_t), FMD_SLEEP);
+	new->page_header = old->page0_header;
+	new->page_version = CMD_PAGE_VERSION;
+	new->page_asru = old->page0_asru;
+
+	fmd_hdl_free(hdl, old, oldsz);
+	return (new);
+}
+
+static cmd_page_t *
+page_wrapv1(fmd_hdl_t *hdl, cmd_page_pers_t *pers, size_t psz)
+{
+	cmd_page_t *page;
+
+	if (psz != sizeof (cmd_page_pers_t)) {
+		fmd_hdl_abort(hdl, "size of state doesn't match size of "
+		    "version 1 state (%u bytes).\n", sizeof (cmd_page_pers_t));
+	}
+
+	page = fmd_hdl_zalloc(hdl, sizeof (cmd_page_t), FMD_SLEEP);
+	bcopy(pers, page, sizeof (cmd_page_pers_t));
+	fmd_hdl_free(hdl, pers, psz);
+	return (page);
+}
+
 void *
 cmd_page_restore(fmd_hdl_t *hdl, fmd_case_t *cp, cmd_case_ptr_t *ptr)
 {
@@ -137,17 +183,56 @@
 	}
 
 	if (page == NULL) {
+		int migrated = 0;
+		size_t pagesz;
+
 		fmd_hdl_debug(hdl, "restoring page from %s\n", ptr->ptr_name);
 
+		if ((pagesz = fmd_buf_size(hdl, NULL, ptr->ptr_name)) == 0) {
+			fmd_hdl_abort(hdl, "page referenced by case %s does "
+			    "not exist in saved state\n",
+			    fmd_case_uuid(hdl, cp));
+		} else if (pagesz > CMD_PAGE_MAXSIZE ||
+		    pagesz < CMD_PAGE_MINSIZE) {
+			fmd_hdl_abort(hdl, "page buffer referenced by case %s "
+			    "is out of bounds (is %u bytes, max %u, min %u)\n",
+			    fmd_case_uuid(hdl, cp), pagesz,
+			    CMD_PAGE_MAXSIZE, CMD_PAGE_MINSIZE);
+		}
+
 		if ((page = cmd_buf_read(hdl, NULL, ptr->ptr_name,
-		    sizeof (cmd_page_t))) == NULL) {
-			fmd_hdl_abort(hdl, "failed to read buf %s",
+		    pagesz)) == NULL) {
+			fmd_hdl_abort(hdl, "failed to read page buf %s",
 			    ptr->ptr_name);
 		}
 
+		fmd_hdl_debug(hdl, "found %d in version field\n",
+		    page->page_version);
+
+		if (CMD_PAGE_VERSIONED(page)) {
+			switch (page->page_version) {
+			case CMD_PAGE_VERSION_1:
+				page = page_wrapv1(hdl, (cmd_page_pers_t *)page,
+				    pagesz);
+				break;
+			default:
+				fmd_hdl_abort(hdl, "unknown version (found %d) "
+				    "for page state referenced by case %s.\n",
+				    page->page_version, fmd_case_uuid(hdl, cp));
+				break;
+			}
+		} else {
+			page = page_v0tov1(hdl, (cmd_page_0_t *)page, pagesz);
+			migrated = 1;
+		}
+
+		if (migrated) {
+/*			CMD_STAT_BUMP(page_migrat);	*/
+			cmd_page_dirty(hdl, page);
+		}
+
 		cmd_fmri_restore(hdl, &page->page_asru);
 
-		page->page_case = NULL;
 		cmd_list_append(&cmd.cmd_pages, page);
 	}
 
@@ -157,12 +242,13 @@
 		cmd_case_redirect(hdl, cp, CMD_PTR_PAGE_CASE);
 		/*FALLTHROUGH*/
 	case CMD_PTR_PAGE_CASE:
-		page->page_case = cp;
+		cmd_case_restore(hdl, &page->page_case, cp,
+		    cmd_page_serdnm_create(hdl, "page", page->page_physbase));
 		break;
 
 #ifdef sun4u
 	case CMD_PTR_DP_PAGE_DEFER:
-		page->page_case = cp;
+		page->page_case.cc_cp = cp;
 		cmd_dp_page_restore(hdl, page);
 		break;
 #endif
@@ -174,6 +260,7 @@
 	return (page);
 }
 
+
 /*ARGSUSED*/
 void
 cmd_page_validate(fmd_hdl_t *hdl)
@@ -195,6 +282,18 @@
 }
 
 void
+cmd_page_dirty(fmd_hdl_t *hdl, cmd_page_t *page)
+{
+	if (fmd_buf_size(hdl, NULL, page->page_bufname) !=
+	    sizeof (cmd_page_pers_t))
+		fmd_buf_destroy(hdl, NULL, page->page_bufname);
+
+	/* No need to rewrite the FMRIs in the page - they don't change */
+	fmd_buf_write(hdl, NULL, page->page_bufname, &page->page_pers,
+	    sizeof (cmd_page_pers_t));
+}
+
+void
 cmd_page_fini(fmd_hdl_t *hdl)
 {
 	cmd_page_t *page;
--- a/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_page.h	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_page.h	Fri Dec 22 12:42:28 2006 -0800
@@ -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.
  */
 
@@ -44,17 +43,47 @@
 extern "C" {
 #endif
 
+#define	PAGE_MKVERSION(version)	((version) << 4 | 1)
+
+#define	CMD_PAGE_VERSION_1	PAGE_MKVERSION(1)	/* 17 */
+#define	CMD_PAGE_VERSION	CMD_PAGE_VERSION_1
+
+#define	CMD_PAGE_VERSIONED(page)	((page)->page_version & 1)
+
+typedef struct cmd_page_0 {
+	cmd_header_t page0_header;	/* Nodetype must be CMD_NT_PAGE */
+	fmd_case_t *page0_case;		/* Open ret. case against this page */
+	cmd_fmri_t page0_asru;		/* ASRU for this page */
+	uint64_t page0_physbase;	/* Base phys addr for this page */
+} cmd_page_0_t;
+
+typedef struct cmd_page_pers {
+	cmd_header_t pagep_header;	/* Nodetype must be CMD_NT_PAGE */
+	uint_t pagep_version;
+	cmd_fmri_t pagep_asru;		/* ASRU for this DIMM */
+	uint64_t pagep_physbase;	/* base phys addr for page */
+	uint_t pagep_flags;		/* CMD_MEM_F_* */
+} cmd_page_pers_t;
+
 typedef struct cmd_page {
-	cmd_header_t page_header;	/* Nodetype must be CMD_NT_PAGE */
-	fmd_case_t *page_case;		/* Open ret. case against this page */
-	cmd_fmri_t page_asru;		/* ASRU for this page */
-	uint64_t page_physbase;		/* Base phys addr for this page */
+	cmd_page_pers_t page_pers;
+	cmd_case_t page_case;		/* Open CE case against this page */
 } cmd_page_t;
 
+#define	CMD_PAGE_MAXSIZE \
+	MAX(sizeof (cmd_page_0_t), sizeof (cmd_page_pers_t))
+#define	CMD_PAGE_MINSIZE \
+	MIN(sizeof (cmd_page_0_t), sizeof (cmd_page_pers_t))
+
+#define	page_header		page_pers.pagep_header
+#define	page_nodetype		page_pers.pagep_header.hdr_nodetype
+#define	page_bufname		page_pers.pagep_header.hdr_bufname
+#define	page_version		page_pers.pagep_version
+#define	page_asru		page_pers.pagep_asru
+#define	page_asru_nvl		page_pers.pagep_asru.fmri_nvl
+#define	page_flags		page_pers.pagep_flags
+#define	page_physbase		page_pers.pagep_physbase
 #define	page_list		page_header.hdr_list
-#define	page_nodetype		page_header.hdr_nodetype
-#define	page_bufname		page_header.hdr_bufname
-#define	page_asru_nvl		page_asru.fmri_nvl
 
 /*
  * Page retirement
@@ -69,6 +98,7 @@
 extern cmd_page_t *cmd_page_create(fmd_hdl_t *, nvlist_t *, uint64_t);
 extern cmd_page_t *cmd_page_lookup(uint64_t);
 
+extern void cmd_page_dirty(fmd_hdl_t *, cmd_page_t *);
 extern void *cmd_page_restore(fmd_hdl_t *, fmd_case_t *, cmd_case_ptr_t *);
 extern void cmd_page_validate(fmd_hdl_t *);
 extern void cmd_page_destroy(fmd_hdl_t *, cmd_page_t *);
--- a/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_pageerr.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_pageerr.c	Fri Dec 22 12:42:28 2006 -0800
@@ -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.
  */
 
@@ -32,6 +31,7 @@
 
 #include <cmd_page.h>
 #include <cmd.h>
+#include <cmd_mem.h>
 
 #include <errno.h>
 #include <string.h>
@@ -49,7 +49,7 @@
 	if (page == NULL)
 		page = cmd_page_create(hdl, modasru, afar);
 
-	if (page->page_case != NULL) {
+	if (page->page_flags & CMD_MEM_F_FAULTING) {
 		/*
 		 * We've already faulted this page.  No need to kick it while
 		 * it's down -- don't fault it again.
@@ -57,7 +57,8 @@
 		return;
 	}
 
-	page->page_case = cmd_case_create(hdl, &page->page_header,
+	if (page->page_case.cc_cp == NULL)
+	    page->page_case.cc_cp = cmd_case_create(hdl, &page->page_header,
 	    CMD_PTR_PAGE_CASE, &uuid);
 
 	flt = fmd_nvl_create_fault(hdl, "fault.memory.page", 100,
@@ -66,9 +67,9 @@
 	if (nvlist_add_boolean_value(flt, FM_SUSPECT_MESSAGE, B_FALSE) != 0)
 		fmd_hdl_abort(hdl, "failed to add no-message member to fault");
 
-	fmd_case_add_ereport(hdl, page->page_case, ep);
-	fmd_case_add_suspect(hdl, page->page_case, flt);
-	fmd_case_solve(hdl, page->page_case);
+	fmd_case_add_ereport(hdl, page->page_case.cc_cp, ep);
+	fmd_case_add_suspect(hdl, page->page_case.cc_cp, flt);
+	fmd_case_solve(hdl, page->page_case.cc_cp);
 }
 
 void
--- a/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_state.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_state.c	Fri Dec 22 12:42:28 2006 -0800
@@ -97,7 +97,8 @@
 	cmd_cpuerr_close,	/* CMD_PTR_CPU_UGESR_CORE_ERR */
 	cmd_cpuerr_close,	/* CMD_PTR_CPU_UGESR_DAE */
 	cmd_cpuerr_close,	/* CMD_PTR_CPU_UGESR_IAE */
-	cmd_cpuerr_close	/* CMD_PTR_CPU_UGESR_UGE */
+	cmd_cpuerr_close,	/* CMD_PTR_CPU_UGESR_UGE */
+	cmd_cpuerr_close	/* CMD_PTR_CPU_MISC_REGS */
 };
 
 fmd_case_t *
--- a/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_state.h	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_state.h	Fri Dec 22 12:42:28 2006 -0800
@@ -122,7 +122,8 @@
 	CMD_PTR_CPU_UGESR_CORE_ERR,
 	CMD_PTR_CPU_UGESR_DAE,
 	CMD_PTR_CPU_UGESR_IAE,
-	CMD_PTR_CPU_UGESR_UGE
+	CMD_PTR_CPU_UGESR_UGE,
+	CMD_PTR_CPU_MISC_REGS
 } cmd_ptrsubtype_t;
 
 /*
--- a/usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_cpu_arch.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_cpu_arch.c	Fri Dec 22 12:42:28 2006 -0800
@@ -93,6 +93,57 @@
 			return (0);
 		} else
 			return (-1);
+	} else
+		return (-1);
+}
+
+char *
+cmd_cpu_getfrustr_by_id(fmd_hdl_t *hdl, uint32_t cpuid)
+{
+	kstat_named_t *kn;
+	kstat_ctl_t *kc;
+	kstat_t *ksp;
+	int i;
+
+	if ((kc = kstat_open()) == NULL)
+		return (NULL); /* errno is set for us */
+
+	if ((ksp = kstat_lookup(kc, "cpu_info", cpuid, NULL)) == NULL ||
+	    kstat_read(kc, ksp, NULL) == -1) {
+		int oserr = errno;
+		(void) kstat_close(kc);
+		(void) cmd_set_errno(oserr);
+		return (NULL);
 	}
-	return (-1);
+
+	for (kn = ksp->ks_data, i = 0; i < ksp->ks_ndata; i++, kn++) {
+		if (strcmp(kn->name, "cpu_fru") == 0) {
+			char *str = fmd_hdl_strdup(hdl,
+			    KSTAT_NAMED_STR_PTR(kn), FMD_SLEEP);
+			(void) kstat_close(kc);
+			return (str);
+		}
+	}
+
+	(void) kstat_close(kc);
+	(void) cmd_set_errno(ENOENT);
+	return (NULL);
 }
+
+char *
+cmd_cpu_getfrustr(fmd_hdl_t *hdl, cmd_cpu_t *cp)
+{
+	return (cmd_cpu_getfrustr_by_id(hdl, cp->cpu_cpuid));
+}
+
+/*ARGSUSED*/
+char *
+cmd_cpu_getpartstr(fmd_hdl_t *hdl, cmd_cpu_t *cp) {
+	return (NULL);
+}
+
+/*ARGSUSED*/
+char *
+cmd_cpu_getserialstr(fmd_hdl_t *hdl, cmd_cpu_t *cp) {
+	return (NULL);
+}
--- a/usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_dp_page.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_dp_page.c	Fri Dec 22 12:42:28 2006 -0800
@@ -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.
@@ -60,14 +59,14 @@
 static void
 dp_page_defer_data_write(fmd_hdl_t *hdl, cmd_dp_defer_t *dpage)
 {
-	fmd_buf_write(hdl, dpage->dp_defer_page->page_case, "mcids",
+	fmd_buf_write(hdl, dpage->dp_defer_page->page_case.cc_cp, "mcids",
 	    &dpage->dp_defer_mcids, sizeof (dpage->dp_defer_mcids));
 }
 
 static void
 dp_page_defer_data_restore(fmd_hdl_t *hdl, cmd_dp_defer_t *dpage)
 {
-	fmd_buf_read(hdl, dpage->dp_defer_page->page_case, "mcids",
+	fmd_buf_read(hdl, dpage->dp_defer_page->page_case.cc_cp, "mcids",
 	    &dpage->dp_defer_mcids, sizeof (dpage->dp_defer_mcids));
 }
 
@@ -140,14 +139,14 @@
 	if (page == NULL) {
 		page = cmd_page_create(hdl, modasru, afar);
 		dpage = dp_page_defer_create(hdl, page, afar);
-		page->page_case = cmd_case_create(hdl, &page->page_header,
+		page->page_case.cc_cp = cmd_case_create(hdl, &page->page_header,
 		    CMD_PTR_DP_PAGE_DEFER, &uuid);
-		fmd_case_setprincipal(hdl, page->page_case, ep);
+		fmd_case_setprincipal(hdl, page->page_case.cc_cp, ep);
 	} else {
 		dpage = dp_page_defer_lookup(page);
 		if (dpage == NULL)
 			fmd_hdl_abort(hdl, "deferred page with no defer data");
-		fmd_case_add_ereport(hdl, page->page_case, ep);
+		fmd_case_add_ereport(hdl, page->page_case.cc_cp, ep);
 	}
 
 	dp_page_defer_add_data(hdl, dpage, afar);
@@ -192,7 +191,7 @@
 			fmd_hdl_debug(hdl, "deferred memory UE  overtaken by "
 			    "dp fault");
 			CMD_STAT_BUMP(dp_ignored_ue);
-			fmd_case_close(hdl, page->page_case);
+			fmd_case_close(hdl, page->page_case.cc_cp);
 			cmd_list_delete(&cmd.cmd_deferred_pages, dpage);
 			fmd_hdl_free(hdl, dpage, sizeof (cmd_dp_defer_t));
 			cmd_page_destroy(hdl, page);
@@ -203,17 +202,17 @@
 
 		bank = cmd_bank_lookup(hdl, nvl);
 
-		ep = fmd_case_getprincipal(hdl, page->page_case);
+		ep = fmd_case_getprincipal(hdl, page->page_case.cc_cp);
 		fmd_case_add_ereport(hdl, bank->bank_case.cc_cp, ep);
 
 		bank->bank_nretired++;
 		bank->bank_retstat.fmds_value.ui64++;
 		cmd_bank_dirty(hdl, bank);
 
-		fmd_case_reset(hdl, page->page_case);
-		cmd_case_fini(hdl, page->page_case, FMD_B_TRUE);
+		fmd_case_reset(hdl, page->page_case.cc_cp);
+		cmd_case_fini(hdl, page->page_case.cc_cp, FMD_B_TRUE);
 
-		page->page_case = NULL;
+		page->page_case.cc_cp = NULL;
 		cmd_page_fault(hdl, nvl, nvl, ep, page->page_physbase);
 		cmd_bank_fault(hdl, bank);
 
--- a/usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_memerr_arch.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_memerr_arch.c	Fri Dec 22 12:42:28 2006 -0800
@@ -541,3 +541,251 @@
 {
 	return (sysconf(_SC_PHYS_PAGES));
 }
+
+/*
+ * DRAM by bit.  Note that this is independent of check-word or DIMM side.
+ * Actual DRAM pin *is* dependent on both check-word and DIMM side.
+ * DRAMs are numbered D0 to D35, but that doesn't tell us what DIMM
+ * they're on!
+ *
+ *  Corrected version of the table that came from bugid 6346507
+ *  bit 2 dram was correct in the original, dram 2 dimm was not.
+ *
+ * Data bits are numbers, 0 - 127.
+ * ECC bits C0 - C8 => 128-136
+ * MTAG bits MT0 - MT2 => 137-139
+ * MTAG ECC bits MTC0 - MTC3 => 140-143
+ *
+ * This is for Uniboard systems.  Other systems may be different.
+ * Awk code edited for "C" declaration.
+ */
+
+int uni_upos2dram[] = {
+	/* 0 */ 3, /* 1 */ 3, /* 2 */ 3, /* 3 */ 1,
+	/* 4 */ 2, /* 5 */ 0, /* 6 */ 1, /* 7 */ 2,
+	/* 8 */ 4, /* 9 */ 4, /* 10 */ 4, /* 11 */ 4,
+	/* 12 */ 5, /* 13 */ 5, /* 14 */ 5, /* 15 */ 5,
+	/* 16 */ 6, /* 17 */ 6, /* 18 */ 6, /* 19 */ 6,
+	/* 20 */ 7, /* 21 */ 7, /* 22 */ 7, /* 23 */ 7,
+	/* 24 */ 8, /* 25 */ 8, /* 26 */ 8, /* 27 */ 8,
+	/* 28 */ 9, /* 29 */ 9, /* 30 */ 9, /* 31 */ 9,
+	/* 32 */ 10, /* 33 */ 10, /* 34 */ 10, /* 35 */ 10,
+	/* 36 */ 11, /* 37 */ 11, /* 38 */ 11, /* 39 */ 11,
+	/* 40 */ 12, /* 41 */ 12, /* 42 */ 12, /* 43 */ 12,
+	/* 44 */ 13, /* 45 */ 13, /* 46 */ 13, /* 47 */ 13,
+	/* 48 */ 14, /* 49 */ 14, /* 50 */ 14, /* 51 */ 15,
+	/* 52 */ 15, /* 53 */ 15, /* 54 */ 16, /* 55 */ 16,
+	/* 56 */ 17, /* 57 */ 17, /* 58 */ 17, /* 59 */ 17,
+	/* 60 */ 18, /* 61 */ 18, /* 62 */ 18, /* 63 */ 18,
+	/* 64 */ 19, /* 65 */ 19, /* 66 */ 19, /* 67 */ 19,
+	/* 68 */ 20, /* 69 */ 20, /* 70 */ 20, /* 71 */ 20,
+	/* 72 */ 21, /* 73 */ 21, /* 74 */ 22, /* 75 */ 22,
+	/* 76 */ 22, /* 77 */ 23, /* 78 */ 23, /* 79 */ 23,
+	/* 80 */ 24, /* 81 */ 24, /* 82 */ 24, /* 83 */ 24,
+	/* 84 */ 25, /* 85 */ 25, /* 86 */ 25, /* 87 */ 25,
+	/* 88 */ 26, /* 89 */ 26, /* 90 */ 26, /* 91 */ 26,
+	/* 92 */ 27, /* 93 */ 27, /* 94 */ 27, /* 95 */ 27,
+	/* 96 */ 28, /* 97 */ 28, /* 98 */ 28, /* 99 */ 28,
+	/* 100 */ 29, /* 101 */ 29, /* 102 */ 29, /* 103 */ 29,
+	/* 104 */ 30, /* 105 */ 30, /* 106 */ 30, /* 107 */ 30,
+	/* 108 */ 31, /* 109 */ 31, /* 110 */ 31, /* 111 */ 31,
+	/* 112 */ 32, /* 113 */ 32, /* 114 */ 32, /* 115 */ 32,
+	/* 116 */ 33, /* 117 */ 33, /* 118 */ 33, /* 119 */ 33,
+	/* 120 */ 34, /* 121 */ 34, /* 122 */ 34, /* 123 */ 34,
+	/* 124 */ 35, /* 125 */ 35, /* 126 */ 35, /* 127 */ 35,
+	/* 128 */ 16, /* 129 */ 15, /* 130 */ 14, /* 131 */ 16,
+	/* 132 */ 0, /* 133 */ 21, /* 134 */ 23, /* 135 */ 22,
+	/* 136 */ 21, /* 137 */ 0, /* 138 */ 1, /* 139 */ 2,
+	/* 140 */ 0, /* 141 */ 1, /* 142 */ 2, /* 143 */ 3
+};
+
+/*
+ * This is for daktari systems and should apply to all 480 490 880 890
+ */
+
+int dak_upos2dram[] = {
+	/* 0 */ 5, /* 1 */ 5, /* 2 */ 5, /* 3 */ 5,
+	/* 4 */ 7, /* 5 */ 7, /* 6 */ 7, /* 7 */ 7,
+	/* 8 */ 6, /* 9 */ 6, /* 10 */ 6, /* 11 */ 6,
+	/* 12 */ 8, /* 13 */ 8, /* 14 */ 8, /* 15 */ 8,
+	/* 16 */ 4, /* 17 */ 4, /* 18 */ 4, /* 19 */ 4,
+	/* 20 */ 0, /* 21 */ 0, /* 22 */ 0, /* 23 */ 0,
+	/* 24 */ 3, /* 25 */ 3, /* 26 */ 3, /* 27 */ 3,
+	/* 28 */ 2, /* 29 */ 2, /* 30 */ 2, /* 31 */ 2,
+	/* 32 */ 1, /* 33 */ 1, /* 34 */ 1, /* 35 */ 1,
+	/* 36 */ 14, /* 37 */ 14, /* 38 */ 14, /* 39 */ 14,
+	/* 40 */ 16, /* 41 */ 16, /* 42 */ 16, /* 43 */ 16,
+	/* 44 */ 17, /* 45 */ 17, /* 46 */ 15, /* 47 */ 15,
+	/* 48 */ 13, /* 49 */ 13, /* 50 */ 13, /* 51 */ 9,
+	/* 52 */ 9, /* 53 */ 9, /* 54 */ 12, /* 55 */ 12,
+	/* 56 */ 11, /* 57 */ 11, /* 58 */ 11, /* 59 */ 11,
+	/* 60 */ 10, /* 61 */ 10, /* 62 */ 10, /* 63 */ 10,
+	/* 64 */ 23, /* 65 */ 23, /* 66 */ 23, /* 67 */ 23,
+	/* 68 */ 25, /* 69 */ 25, /* 70 */ 25, /* 71 */ 25,
+	/* 72 */ 24, /* 73 */ 24, /* 74 */ 26, /* 75 */ 26,
+	/* 76 */ 26, /* 77 */ 22, /* 78 */ 22, /* 79 */ 22,
+	/* 80 */ 18, /* 81 */ 21, /* 82 */ 21, /* 83 */ 21,
+	/* 84 */ 20, /* 85 */ 20, /* 86 */ 20, /* 87 */ 20,
+	/* 88 */ 19, /* 89 */ 19, /* 90 */ 19, /* 91 */ 19,
+	/* 92 */ 32, /* 93 */ 32, /* 94 */ 32, /* 95 */ 32,
+	/* 96 */ 34, /* 97 */ 34, /* 98 */ 34, /* 99 */ 34,
+	/* 100 */ 33, /* 101 */ 33, /* 102 */ 33, /* 103 */ 33,
+	/* 104 */ 35, /* 105 */ 35, /* 106 */ 35, /* 107 */ 35,
+	/* 108 */ 31, /* 109 */ 31, /* 110 */ 31, /* 111 */ 31,
+	/* 112 */ 27, /* 113 */ 27, /* 114 */ 27, /* 115 */ 27,
+	/* 116 */ 30, /* 117 */ 30, /* 118 */ 30, /* 119 */ 30,
+	/* 120 */ 29, /* 121 */ 29, /* 122 */ 29, /* 123 */ 29,
+	/* 124 */ 28, /* 125 */ 28, /* 126 */ 28, /* 127 */ 28,
+	/* 128 */ 12, /* 129 */ 9, /* 130 */ 13, /* 131 */ 12,
+	/* 132 */  18, /* 133 */ 24, /* 134 */ 22, /* 135 */ 26,
+	/* 136 */ 24, /* 137 */ 21, /* 138 */ 18, /* 139 */ 18,
+	/* 140 */ 15, /* 141 */ 15, /* 142 */ 17, /* 143 */ 17
+};
+
+/*
+ * This is for Excalibur based systems and should apply to
+ * SunBlade 1000/2000 280R and Netra 20s
+ */
+
+int exc_upos2dram[] = {
+	/* 0 */ 18, /* 1 */ 0, /* 2 */ 0, /* 3 */ 0,
+	/* 4 */ 9, /* 5 */ 18, /* 6 */ 27, /* 7 */ 9,
+	/* 8 */ 28, /* 9 */ 28, /* 10 */ 28, /* 11 */ 28,
+	/* 12 */ 29, /* 13 */ 29, /* 14 */ 29, /* 15 */ 29,
+	/* 16 */ 30, /* 17 */ 30, /* 18 */ 30, /* 19 */ 30,
+	/* 20 */ 21, /* 21 */ 21, /* 22 */ 21, /* 23 */ 21,
+	/* 24 */ 12, /* 25 */ 12, /* 26 */ 12, /* 27 */ 12,
+	/* 28 */ 22, /* 29 */ 22, /* 30 */ 22, /* 31 */ 22,
+	/* 32 */ 31, /* 33 */ 31, /* 34 */ 31, /* 35 */ 31,
+	/* 36 */ 32, /* 37 */ 32, /* 38 */ 32, /* 39 */ 32,
+	/* 40 */ 33, /* 41 */ 33, /* 42 */ 33, /* 43 */ 33,
+	/* 44 */ 24, /* 45 */ 24, /* 46 */ 24, /* 47 */ 24,
+	/* 48 */ 15, /* 49 */ 15, /* 50 */ 15, /* 51 */ 25,
+	/* 52 */ 25, /* 53 */ 25, /* 54 */ 34, /* 55 */ 34,
+	/* 56 */ 35, /* 57 */ 35, /* 58 */ 35, /* 59 */ 35,
+	/* 60 */ 19, /* 61 */ 19, /* 62 */ 19, /* 63 */ 19,
+	/* 64 */ 10, /* 65 */ 10, /* 66 */ 10, /* 67 */ 10,
+	/* 68 */ 1, /* 69 */ 1, /* 70 */ 1, /* 71 */ 1,
+	/* 72 */ 20, /* 73 */ 20, /* 74 */ 11, /* 75 */ 11,
+	/* 76 */ 11, /* 77 */ 2, /* 78 */ 2, /* 79 */ 2,
+	/* 80 */ 3, /* 81 */ 3, /* 82 */ 3, /* 83 */ 3,
+	/* 84 */ 4, /* 85 */ 4, /* 86 */ 4, /* 87 */ 4,
+	/* 88 */ 13, /* 89 */ 13, /* 90 */ 13, /* 91 */ 13,
+	/* 92 */ 23, /* 93 */ 23, /* 94 */ 23, /* 95 */ 23,
+	/* 96 */ 14, /* 97 */ 14, /* 98 */ 14, /* 99 */ 14,
+	/* 100 */ 5, /* 101 */ 5, /* 102 */ 5, /* 103 */ 5,
+	/* 104 */ 6, /* 105 */ 6, /* 106 */ 6, /* 107 */ 6,
+	/* 108 */ 7, /* 109 */ 7, /* 110 */ 7, /* 111 */ 7,
+	/* 112 */ 16, /* 113 */ 16, /* 114 */ 16, /* 115 */ 16,
+	/* 116 */ 26, /* 117 */ 26, /* 118 */ 26, /* 119 */ 26,
+	/* 120 */ 17, /* 121 */ 17, /* 122 */ 17, /* 123 */ 17,
+	/* 124 */ 8, /* 125 */ 8, /* 126 */ 8, /* 127 */ 8,
+	/* 128 */ 34, /* 129 */ 25, /* 130 */ 15, /* 131 */ 34,
+	/* 132 */  27, /* 133 */ 20, /* 134 */ 2, /* 135 */ 11,
+	/* 136 */ 20, /* 137 */ 9, /* 138 */ 18, /* 139 */ 27,
+	/* 140 */ 0, /* 141 */ 9, /* 142 */ 18, /* 143 */ 27
+};
+
+/*
+ * sun4u bit position as function of e_synd,
+ * from JPS1 Implementation Supplement table P-7
+ * Encode bit positions as follows:
+ * 0-127 data bits 0-127
+ * 128-136 check bits 0-8 (Cn = 128+n)
+ * no error or multibit error = -1 (not valid CE)
+ */
+
+int esynd2bit [] = {
+	-1, 128, 129, -1, 130, -1, -1, 47,
+	131, -1, -1, 53, -1, 41, 29, -1, /* 000-00F */
+	132, -1, -1, 50, -1, 38, 25, -1,
+	-1, 33, 24, -1, 11, -1, -1, 16, /* 010-01F */
+	133, -1, -1, 46, -1, 37, 19, -1,
+	-1, 31, 32, -1,  7, -1, -1, 10, /* 020-02F */
+	-1, 40, 13, -1, 59, -1, -1, 66,
+	-1, -1, -1,  0, -1, 67, 71, -1, /* 030-03F */
+	134, -1, -1, 43, -1, 36, 18, -1,
+	-1, 49, 15, -1, 63, -1, -1,  6, /* 040-04F */
+	-1, 44, 28, -1, -1, -1, -1, 52,
+	68, -1, -1, 62, -1, -1, -1, -1, /* 050-05F */
+	-1, 26, 106, -1, 64, -1, -1,  2,
+	120, -1, -1, -1, -1, -1, -1, -1, /* 060-06F */
+	116, -1, -1, -1, -1, -1, -1, -1,
+	-1, 58, 54, -1, -1, -1, -1, -1, /* 070-07F */
+	135, -1, -1, 42, -1, 35, 17, -1,
+	-1, 45, 14, -1, 21, -1, -1,  5, /* 080-08F */
+	-1, 27, -1, -1, 99, -1, -1,  3,
+	114, -1, -1, 20, -1, -1, -1, -1, /* 090-09F */
+	-1, 23, 113, -1, 112, -1, -1, 51,
+	95, -1, -1, -1, -1, -1, -1, -1, /* 0A0-0AF */
+	103, -1, -1, -1, -1, -1, -1, -1,
+	-1, 48, -1, -1, 73, -1, -1, -1, /* 0B0-0BF */
+	-1, 22, 110, -1, 109, -1, -1,  9,
+	108, -1, -1, -1, -1, -1, -1, -1, /* 0C0-0CF */
+	102, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1, /* 0D0-0DF */
+	98, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1, /* 0E0-0EF */
+	-1, -1, -1, -1, -1, -1, -1, -1,
+	56, -1, -1, -1, -1, -1, -1, -1, /* 0F0-0FF */
+	136, -1, -1, 39, -1, 34, 105, -1,
+	-1, 30, 104, -1, 101, -1, -1,  4, /* 100-10F */
+	-1, -1, 100, -1, 83, -1, -1, 12,
+	87, -1, -1, 57, -1, -1, -1, -1, /* 110-11F */
+	-1, 97, 82, -1, 78, -1, -1,  1,
+	96, -1, -1, -1, -1, -1, -1, -1, /* 120-12F */
+	94, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, 79, -1, 69, -1, -1, -1, /* 130-13F */
+	-1, 93, 92, -1, 91, -1, -1,  8,
+	90, -1, -1, -1, -1, -1, -1, -1, /* 140-14F */
+	89, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1, /* 150-15F */
+	86, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1, /* 160-16F */
+	-1, -1, -1, -1, -1, -1, -1, -1,
+	60, -1, -1, -1, -1, -1, -1, -1, /* 170-17F */
+	-1, 88, 85, -1, 84, -1, -1, 55,
+	81, -1, -1, -1, -1, -1, -1, -1, /* 180-18F */
+	77, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1, /* 190-19F */
+	74, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1, /* 1A0-1AF */
+	-1, 70, 107, -1, 65, -1, -1, -1,
+	127, -1, -1, -1, -1, -1, -1, -1, /* 1B0-1BF */
+	80, -1, -1, 72, -1, 119, 118, -1,
+	-1, 126, 76, -1, 125, -1, -1, -1, /* 1C0-1CF */
+	-1, 115, 124, -1, 75, -1, -1, -1,
+	61, -1, -1, -1, -1, -1, -1, -1, /* 1D0-1DF */
+	-1, 123, 122, -1, 121, -1, -1, -1,
+	117, -1, -1, -1, -1, -1, -1, -1, /* 1E0-1EF */
+	111, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1  /* 1F0-1FF */
+};
+
+int msynd2bit [] = {  /* msynd 0-F */
+	-1, 140, 141,  -1,
+	142, -1,  -1, 137,
+	143, -1,  -1, 138,
+	-1, 139,  -1,  -1
+};
+
+int
+cmd_synd2upos(uint16_t syndrome) {
+	return (esynd2bit[syndrome]);
+}
+
+const char *fmd_fmri_get_platform();
+
+int
+cmd_upos2dram(uint16_t unit_position) {
+
+	const char *plat_name = fmd_fmri_get_platform();
+
+	if (strcmp(plat_name, "SUNW,SunFire") == 0)
+		return (uni_upos2dram[unit_position]);
+	else if (strcmp(plat_name, "SUNW,V880") == 0)
+		return (dak_upos2dram[unit_position]);
+	else if (strcmp(plat_name, "SUNW,SunBlade") == 0)
+		return (exc_upos2dram[unit_position]);
+	else return (-1);
+}
--- a/usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_opl.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_opl.c	Fri Dec 22 12:42:28 2006 -0800
@@ -148,7 +148,7 @@
 	if ((errno = nvlist_alloc(&fmri, NV_UNIQUE_NAME, 0)) != 0)
 		return (NULL);
 
-	if ((frustr = cpu_getfrustr(hdl, cpuid)) == NULL) {
+	if ((frustr = cmd_cpu_getfrustr_by_id(hdl, cpuid)) == NULL) {
 		nvlist_free(fmri);
 		return (NULL);
 	}
--- a/usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_opl.h	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_opl.h	Fri Dec 22 12:42:28 2006 -0800
@@ -93,6 +93,7 @@
     const char *, cmd_errcl_t);
 
 extern nvlist_t *opl_cpursrc_create(fmd_hdl_t *, uint32_t);
+extern char *cmd_cpu_getfrustr_by_id(fmd_hdl_t *, uint32_t);
 extern cmd_list_t *opl_cpulist_insert(fmd_hdl_t *, uint32_t, int);
 extern void opl_cpulist_free(fmd_hdl_t *, cmd_list_t *);
 extern uint8_t opl_avg(uint_t, uint_t);
--- a/usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_oplerr.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_oplerr.c	Fri Dec 22 12:42:28 2006 -0800
@@ -93,8 +93,8 @@
 	}
 
 	if ((page = cmd_page_lookup(pa)) != NULL &&
-	    page->page_case != NULL &&
-	    fmd_case_solved(hdl, page->page_case))
+	    page->page_case.cc_cp != NULL &&
+	    fmd_case_solved(hdl, page->page_case.cc_cp))
 		return (CMD_EVD_REDUND);
 
 	if (nvlist_dup(rsrc, &asru, 0) != 0) {
@@ -333,7 +333,8 @@
 		return (CMD_EVD_BAD);
 
 	if ((page = cmd_page_lookup(pa)) != NULL &&
-	    page->page_case != NULL && fmd_case_solved(hdl, page->page_case))
+	    page->page_case.cc_cp != NULL &&
+	    fmd_case_solved(hdl, page->page_case.cc_cp))
 		return (CMD_EVD_REDUND);
 
 	if (nvlist_dup(rsrc, &asru, 0) != 0) {
--- a/usr/src/cmd/fm/modules/sun4v/cpumem-diagnosis/cmd_cpu_arch.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/modules/sun4v/cpumem-diagnosis/cmd_cpu_arch.c	Fri Dec 22 12:42:28 2006 -0800
@@ -52,14 +52,20 @@
 	uint64_t niagara_l2_afsr = 0;
 
 	if (nvlist_lookup_uint64(nvl, FM_EREPORT_PAYLOAD_NAME_L2_AFSR,
+	    &niagara_l2_afsr) != 0 &&
+	    nvlist_lookup_uint64(nvl, FM_EREPORT_PAYLOAD_NAME_L2_ESR,
 	    &niagara_l2_afsr) != 0)
 		return (-1);
-	if (nvlist_lookup_uint64(nvl, FM_EREPORT_PAYLOAD_NAME_L2_REAL_AFAR,
+	if (nvlist_lookup_uint64(nvl, FM_EREPORT_PAYLOAD_NAME_L2_AFAR,
+	    &xr->xr_afar) != 0 &&
+	    nvlist_lookup_uint64(nvl, FM_EREPORT_PAYLOAD_NAME_L2_EAR,
 	    &xr->xr_afar) != 0)
 		return (-1);
 	if (nvlist_lookup_uint32(nvl, FM_EREPORT_PAYLOAD_NAME_L2_SYND,
-	    &xr->xr_synd) != 0)
-		return (-1);
+	    &xr->xr_synd) != 0) {
+		/* Niagara-2 doesn't provide separate (redundant) l2-synd */
+		xr->xr_synd = niagara_l2_afsr & NI2_L2AFSR_SYND;
+	}
 
 	if (cmd_afsr_check(hdl, niagara_l2_afsr, clcode,
 	    &xr->xr_synd_status) != 0)
@@ -123,17 +129,17 @@
 	case CMD_ERRCL_LDAC:
 	case CMD_ERRCL_LDSC:
 		*stat_val =
-			((afsr & NI_L2AFSR_P07) == 0) ?
+			((afsr & NI_L2AFSR_P08) == 0) ?
 			AFLT_STAT_VALID : AFLT_STAT_INVALID;
 		break;
 	case CMD_ERRCL_LDWC:
 		*stat_val =
-			((afsr & NI_L2AFSR_P08) == 0) ?
+			((afsr & NI_L2AFSR_P09) == 0) ?
 			AFLT_STAT_VALID : AFLT_STAT_INVALID;
 		break;
 	case CMD_ERRCL_LDRC:
 		*stat_val =
-			((afsr & NI_L2AFSR_P09) == 0) ?
+			((afsr & NI_L2AFSR_P10) == 0) ?
 			AFLT_STAT_VALID : AFLT_STAT_INVALID;
 		break;
 	default:
@@ -150,7 +156,17 @@
 {
 	uint64_t niagara_l2_afsr = 0;
 	uint8_t stat_val;
+
+	/*
+	 * In Niagara-1, we carried forward the register names afsr and afar
+	 * in ereports from sun4u, even though the hardware registers were
+	 * named esr and ear respectively.  In Niagara-2 we decided to conform
+	 * to the hardware names.
+	 */
+
 	if (nvlist_lookup_uint64(nvl, FM_EREPORT_PAYLOAD_NAME_L2_AFSR,
+	    &niagara_l2_afsr) != 0 &&
+	    nvlist_lookup_uint64(nvl, FM_EREPORT_PAYLOAD_NAME_L2_ESR,
 	    &niagara_l2_afsr) != 0)
 		return (-1);
 
@@ -159,8 +175,67 @@
 
 	if (stat_val == AFLT_STAT_VALID) {
 		if (nvlist_lookup_uint64(nvl,
-		    FM_EREPORT_PAYLOAD_NAME_L2_REAL_AFAR, afar) == 0)
+		    FM_EREPORT_PAYLOAD_NAME_L2_AFAR, afar) == 0 ||
+		    nvlist_lookup_uint64(nvl,
+		    FM_EREPORT_PAYLOAD_NAME_L2_EAR, afar) == 0)
 			return (0);
 	}
 	return (-1);
 }
+
+/*
+ * sun4v cmd_cpu_get_frustr expects a 'cpufru' element in 'detector' FMRI
+ * of ereport (which is stored as 'asru' of cmd_cpu_t).  For early sun4v,
+ * this was mistakenly spec'ed as "hc://MB" instead of "hc:///component=MB",
+ * so this situation must be remediated when found.
+ */
+
+char *
+cmd_cpu_getfrustr(fmd_hdl_t *hdl, cmd_cpu_t *cp)
+{
+	char *frustr;
+	nvlist_t *asru = cp->cpu_asru_nvl;
+
+	if (nvlist_lookup_string(asru, FM_FMRI_CPU_CPUFRU, &frustr) == 0) {
+		if (strncmp(frustr, CPU_FRU_FMRI,
+		    sizeof (CPU_FRU_FMRI) -1) == 0)
+			return (fmd_hdl_strdup(hdl, frustr, FMD_SLEEP));
+		else {
+			char *s1, *s2;
+			size_t frustrlen;
+
+			s2 = strrchr(frustr, '/') + 1;
+			if (s2 == NULL)
+				s2 = "MB";
+			frustrlen = strlen(s2) + sizeof (CPU_FRU_FMRI);
+			s1 = fmd_hdl_alloc(hdl, frustrlen, FMD_SLEEP);
+			s1 = strcpy(s1, CPU_FRU_FMRI);
+			s1 = strcat(s1, s2);
+			return (s1);
+		}
+	}
+	(void) cmd_set_errno(ENOENT);
+	return (NULL);
+}
+
+char *
+cmd_cpu_getpartstr(fmd_hdl_t *hdl, cmd_cpu_t *cp) {
+	char *partstr;
+	nvlist_t *asru = cp->cpu_asru_nvl;
+
+	if (nvlist_lookup_string(asru, FM_FMRI_HC_PART, &partstr) == 0)
+		return (fmd_hdl_strdup(hdl, partstr, FMD_SLEEP));
+	else
+		return (NULL);
+}
+
+char *
+cmd_cpu_getserialstr(fmd_hdl_t *hdl, cmd_cpu_t *cp) {
+	char *serialstr;
+	nvlist_t *asru = cp->cpu_asru_nvl;
+
+	if (nvlist_lookup_string(asru, FM_FMRI_HC_SERIAL_ID, &serialstr) == 0)
+		return (fmd_hdl_strdup(hdl, serialstr, FMD_SLEEP));
+	else
+		return (NULL);
+}
--- a/usr/src/cmd/fm/modules/sun4v/cpumem-diagnosis/cmd_memerr_arch.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/modules/sun4v/cpumem-diagnosis/cmd_memerr_arch.c	Fri Dec 22 12:42:28 2006 -0800
@@ -51,6 +51,7 @@
 #include <sys/errclassify.h>
 #include <sys/niagararegs.h>
 #include <sys/fm/ldom.h>
+#include <ctype.h>
 
 extern ldom_hdl_t *cpumem_diagnosis_lhp;
 
@@ -113,13 +114,31 @@
 	uint64_t disp;
 	int minorvers = 1;
 
+	if (nvlist_lookup_uint64(nvl,
+	    FM_EREPORT_PAYLOAD_NAME_L2_AFSR, &l2_afsr) != 0 &&
+	    nvlist_lookup_uint64(nvl,
+	    FM_EREPORT_PAYLOAD_NAME_L2_ESR, &l2_afsr) != 0)
+		return (CMD_EVD_BAD);
+
+	if (nvlist_lookup_uint64(nvl,
+	    FM_EREPORT_PAYLOAD_NAME_DRAM_AFSR, &dram_afsr) != 0 &&
+	    nvlist_lookup_uint64(nvl,
+	    FM_EREPORT_PAYLOAD_NAME_DRAM_ESR, &dram_afsr) != 0)
+		return (CMD_EVD_BAD);
+
+	if (nvlist_lookup_uint64(nvl,
+	    FM_EREPORT_PAYLOAD_NAME_L2_AFAR, &l2_afar) != 0 &&
+	    nvlist_lookup_uint64(nvl,
+	    FM_EREPORT_PAYLOAD_NAME_L2_EAR, &l2_afar) != 0)
+		return (CMD_EVD_BAD);
+
+	if (nvlist_lookup_uint64(nvl,
+	    FM_EREPORT_PAYLOAD_NAME_DRAM_AFAR, &dram_afar) != 0 &&
+	    nvlist_lookup_uint64(nvl,
+	    FM_EREPORT_PAYLOAD_NAME_DRAM_EAR, &dram_afar) != 0)
+		return (CMD_EVD_BAD);
+
 	if (nvlist_lookup_pairs(nvl, 0,
-	    FM_EREPORT_PAYLOAD_NAME_L2_AFSR, DATA_TYPE_UINT64, &l2_afsr,
-	    FM_EREPORT_PAYLOAD_NAME_DRAM_AFSR, DATA_TYPE_UINT64, &dram_afsr,
-	    FM_EREPORT_PAYLOAD_NAME_L2_AFAR, DATA_TYPE_UINT64,
-	    &l2_afar,
-	    FM_EREPORT_PAYLOAD_NAME_DRAM_AFAR, DATA_TYPE_UINT64,
-	    &dram_afar,
 	    FM_EREPORT_PAYLOAD_NAME_ERR_TYPE, DATA_TYPE_STRING, &typenm,
 	    FM_EREPORT_PAYLOAD_NAME_RESOURCE, DATA_TYPE_NVLIST, &rsrc,
 	    NULL) != 0)
@@ -254,3 +273,252 @@
 
 	return (npage);
 }
+
+static int galois_mul[16][16] = {
+/* 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F */
+{  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}, /* 0 */
+{  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15}, /* 1 */
+{  0,  2,  4,  6,  8, 10, 12, 14,  3,  1,  7,  5, 11,  9, 15, 13}, /* 2 */
+{  0,  3,  6,  5, 12, 15, 10,  9, 11,  8, 13, 14,  7,  4,  1,  2}, /* 3 */
+{  0,  4,  8, 12,  3,  7, 11, 15,  6,  2, 14, 10,  5,  1, 13,  9}, /* 4 */
+{  0,  5, 10, 15,  7,  2, 13,  8, 14, 11,  4,  1,  9, 12,  3,  6}, /* 5 */
+{  0,  6, 12, 10, 11, 13,  7,  1,  5,  3,  9, 15, 14,  8,  2,  4}, /* 6 */
+{  0,  7, 14,  9, 15,  8,  1,  6, 13, 10,  3,  4,  2,  5, 12, 11}, /* 7 */
+{  0,  8,  3, 11,  6, 14,  5, 13, 12,  4, 15,  7, 10,  2,  9,  1}, /* 8 */
+{  0,  9,  1,  8,  2, 11,  3, 10,  4, 13,  5, 12,  6, 15,  7, 14}, /* 9 */
+{  0, 10,  7, 13, 14,  4,  9,  3, 15,  5,  8,  2,  1, 11,  6, 12}, /* A */
+{  0, 11,  5, 14, 10,  1, 15,  4,  7, 12,  2,  9, 13,  6,  8,  3}, /* B */
+{  0, 12, 11,  7,  5,  9, 14,  2, 10,  6,  1, 13, 15,  3,  4,  8}, /* C */
+{  0, 13,  9,  4,  1, 12,  8,  5,  2, 15, 11,  6,  3, 14, 10,  7}, /* D */
+{  0, 14, 15,  1, 13,  3,  2, 12,  9,  7,  6,  8,  4, 10, 11,  5}, /* E */
+{  0, 15, 13,  2,  9,  6,  4, 11,  1, 14, 12,  3,  8,  7,  5, 10}  /* F */
+};
+
+static int
+galois_div(int num, int denom) {
+	int i;
+
+	for (i = 0; i < 16; i++) {
+		if (galois_mul[denom][i] == num)
+		    return (i);
+	}
+	return (-1);
+}
+
+/*
+ * Data nibbles N0-N31 => 0-31
+ * check nibbles C0-3 => 32-35
+ */
+
+int
+cmd_synd2upos(uint16_t syndrome) {
+
+	uint16_t s0, s1, s2, s3;
+
+	if (syndrome == 0)
+		return (-1); /* clean syndrome, not a CE */
+
+	s0 = syndrome & 0xF;
+	s1 = (syndrome >> 4) & 0xF;
+	s2 = (syndrome >> 8) & 0xF;
+	s3 = (syndrome >> 12) & 0xF;
+
+	if (s3 == 0) {
+		if (s2 == 0 && s1 == 0)
+			return (32); /* 0 0 0 e => C0 */
+		if (s2 == 0 && s0 == 0)
+			return (33); /* 0 0 e 0 => C1 */
+		if (s1 == 0 && s0 == 0)
+			return (34); /* 0 e 0 0 => C2 */
+		if (s2 == s1 && s1 == s0)
+			return (31); /* 0 d d d => N31 */
+		return (-1); /* multibit error */
+	} else if (s2 == 0) {
+		if (s1 == 0 && s0 == 0)
+			return (35); /* e 0 0 0 => C4 */
+		if (s1 == 0 || s0 == 0)
+			return (-1); /* not a 0 b c */
+		if (s3 != galois_div(galois_mul[s1][s1], s0))
+			return (-1); /* check nibble not valid */
+		return (galois_div(s0, s1) - 1); /* N0 - N14 */
+	} else if (s1 == 0) {
+		if (s2 == 0 || s0 == 0)
+			return (-1); /* not a b 0 c */
+		if (s3 != galois_div(galois_mul[s2][s2], s0))
+			return (-1); /* check nibble not valid */
+		return (galois_div(s0, s2) + 14); /* N15 - N29 */
+	} else if (s0 == 0) {
+		if (s3 == s2 && s2 == s1)
+			return (30); /* d d d 0 => N30 */
+		return (-1);
+	} else return (-1);
+}
+
+int
+cmd_upos2dram(uint16_t upos) {
+
+	/*
+	 * If and/or when x8 DIMMs are used on sun4v systems, this
+	 * function will become more complicated.
+	 */
+
+	return ((int)upos);
+
+}
+
+typedef struct tr_ent {
+	const char *nac_component;
+	const char *hc_component;
+} tr_ent_t;
+
+static tr_ent_t tr_tbl[] = {
+	{ "MB",		"motherboard" },
+	{ "CMP",	"chip" },
+	{ "BR",		"branch" },
+	{ "CH",		"dram-channel" },
+	{ "R",		"rank" },
+	{ "D",		"dimm" }
+};
+
+#define	tr_tbl_n	sizeof (tr_tbl) / sizeof (tr_ent_t)
+
+static int
+map_name(const char *p) {
+	int i;
+
+	for (i = 0; i < tr_tbl_n; i++) {
+		if (strncmp(p, tr_tbl[i].nac_component,
+		    strlen(tr_tbl[i].nac_component)) == 0)
+			return (i);
+	}
+	return (-1);
+}
+
+static int
+count_components(const char *str, char sep)
+{
+	int num = 0;
+	const char *cptr = str;
+
+	if (*cptr == sep) cptr++;		/* skip initial sep */
+	if (strlen(cptr) > 0) num = 1;
+	while ((cptr = strchr(cptr, sep)) != NULL) {
+		cptr++;
+		if (cptr == NULL || strcmp(cptr, "") == 0) break;
+		if (map_name(cptr) >= 0) num++;
+	}
+	return (num);
+}
+
+/*
+ * This version of breakup_components assumes that all component names which
+ * it sees are of the form:  <nonnumeric piece><numeric piece>
+ * i.e. no embedded numerals in component name which have to be spelled out.
+ */
+
+static int
+breakup_components(char *str, char *sep, nvlist_t **hc_nvl)
+{
+	char namebuf[64], instbuf[64];
+	char *token, *tokbuf;
+	int i, j, namelen, instlen;
+
+	i = 0;
+	for (token = strtok_r(str, sep, &tokbuf);
+	    token != NULL;
+	    token = strtok_r(NULL, sep, &tokbuf)) {
+		namelen = strcspn(token, "0123456789");
+		instlen = strspn(token+namelen, "0123456789");
+		(void) strncpy(namebuf, token, namelen);
+		namebuf[namelen] = '\0';
+
+		if ((j = map_name(namebuf) < 0))
+		    continue; /* skip names that don't map */
+
+		if (instlen == 0) {
+			(void) strncpy(instbuf, "0", 2);
+		} else {
+			(void) strncpy(instbuf, token+namelen, instlen);
+			instbuf[instlen] = '\0';
+		}
+		if (nvlist_add_string(hc_nvl[i], FM_FMRI_HC_NAME,
+		    tr_tbl[j].hc_component) != 0 ||
+		    nvlist_add_string(hc_nvl[i], FM_FMRI_HC_ID, instbuf) != 0)
+			return (-1);
+		i++;
+	}
+	return (1);
+}
+
+nvlist_t *
+cmd_mem2hc(fmd_hdl_t *hdl, nvlist_t *mem_fmri) {
+
+	char *nac_name, *s, *p, **sa;
+	const char *unum = cmd_fmri_get_unum(mem_fmri);
+	nvlist_t *fp, **hc_list;
+	int i, n;
+	unsigned int usi;
+
+	nac_name = fmd_hdl_zalloc(hdl, strlen(unum)+1, FMD_SLEEP);
+	if ((s = strstr(unum, ": ")) != NULL) {
+		(void) strncpy(nac_name, unum, s-unum); /* up to ": " */
+		(void) strncpy(nac_name+(s-unum), "/", 2); /* add "/" and \0 */
+		(void) strncat(nac_name, s+2, strlen(unum)-(s+2-unum)+1);
+	} else {
+		(void) strcpy(nac_name, unum);
+	}
+
+	n = count_components(nac_name, '/');
+	hc_list = fmd_hdl_zalloc(hdl, sizeof (nvlist_t *)*n, FMD_SLEEP);
+
+	for (i = 0; i < n; i++) {
+		(void) nvlist_alloc(&hc_list[i],
+		    NV_UNIQUE_NAME|NV_UNIQUE_NAME_TYPE, 0);
+	}
+
+	if (breakup_components(nac_name, "/", hc_list) < 0) {
+		fmd_hdl_error(hdl, "cannot allocate components for hc-list\n");
+		for (i = 0; i < n; n++) {
+			if (hc_list[i] != NULL)
+			    nvlist_free(hc_list[i]);
+		}
+		fmd_hdl_free(hdl, hc_list, sizeof (nvlist_t *)*n);
+		fmd_hdl_free(hdl, nac_name, strlen(unum)+1);
+		return (NULL);
+	}
+	(void) nvlist_alloc(&fp, NV_UNIQUE_NAME|NV_UNIQUE_NAME_TYPE, 0);
+	if ((nvlist_add_uint8(fp, FM_VERSION,
+	    FM_HC_VERS0) != 0) ||
+	    (nvlist_add_string(fp, FM_FMRI_SCHEME, FM_FMRI_SCHEME_HC) != 0) ||
+	    (nvlist_add_string(fp, FM_FMRI_HC_ROOT, "/") != 0) ||
+	    (nvlist_add_uint32(fp, FM_FMRI_HC_LIST_SZ, n) != 0) ||
+	    (nvlist_add_nvlist_array(fp, FM_FMRI_HC_LIST, hc_list, n) != 0)) {
+		for (i = 0; i < n; n++) {
+			nvlist_free(hc_list[i]);
+		}
+		fmd_hdl_free(hdl, hc_list, sizeof (nvlist_t *)*n);
+		fmd_hdl_free(hdl, nac_name, strlen(unum)+1);
+		nvlist_free(fp);
+		return (NULL);
+	}
+	/*
+	 * if the nvlist_add_nvlist_array succeeds, then it frees
+	 * the hc_list[i]'s.
+	 */
+	fmd_hdl_free(hdl, hc_list, sizeof (nvlist_t *)*n);
+	fmd_hdl_free(hdl, nac_name, strlen(unum)+1);
+	if (nvlist_lookup_string_array(mem_fmri, FM_FMRI_HC_SERIAL_ID,
+	    &sa, &usi) == 0) {
+		if (nvlist_add_string(fp, FM_FMRI_HC_SERIAL_ID, *sa) != 0) {
+			nvlist_free(fp);
+			return (NULL);
+		}
+	}
+	if (nvlist_lookup_string(mem_fmri, FM_FMRI_HC_PART, &p) == 0) {
+		if (nvlist_add_string(fp, FM_FMRI_HC_PART, p) != 0) {
+			nvlist_free(fp);
+			return (NULL);
+		}
+	}
+	return (fp);
+}
--- a/usr/src/cmd/fm/modules/sun4v/cpumem-retire/cma_main.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/modules/sun4v/cpumem-retire/cma_main.c	Fri Dec 22 12:42:28 2006 -0800
@@ -80,19 +80,17 @@
 	    NULL },
 
 	/*
-	 * The following ultraSPARC-T1 faults do NOT retire a cpu thread,
+	 * The following ultraSPARC-T1/T2 faults do NOT retire a cpu thread,
 	 * and therefore must be intercepted before
 	 * the default "fault.cpu.*" dispatch to cma_cpu_retire.
 	 */
-	{ "fault.cpu.ultraSPARC-T1.freg", FM_FMRI_SCHEME_CPU,
+	{ "fault.cpu.*.l2cachedata", FM_FMRI_SCHEME_CPU,
 	    FM_CPU_SCHEME_VERSION, NULL },
-	{ "fault.cpu.ultraSPARC-T1.l2cachedata", FM_FMRI_SCHEME_CPU,
+	{ "fault.cpu.*.l2cachetag", FM_FMRI_SCHEME_CPU,
 	    FM_CPU_SCHEME_VERSION, NULL },
-	{ "fault.cpu.ultraSPARC-T1.l2cachetag", FM_FMRI_SCHEME_CPU,
+	{ "fault.cpu.*.l2cachectl", FM_FMRI_SCHEME_CPU,
 	    FM_CPU_SCHEME_VERSION, NULL },
-	{ "fault.cpu.ultraSPARC-T1.l2cachectl", FM_FMRI_SCHEME_CPU,
-	    FM_CPU_SCHEME_VERSION, NULL },
-	{ "fault.cpu.ultraSPARC-T1.mau", FM_FMRI_SCHEME_CPU,
+	{ "fault.cpu.*.mau", FM_FMRI_SCHEME_CPU,
 	    FM_CPU_SCHEME_VERSION, NULL },
 	{ "fault.cpu.*", FM_FMRI_SCHEME_CPU, FM_CPU_SCHEME_VERSION,
 	    cma_cpu_retire },
--- a/usr/src/cmd/fm/modules/sun4v/cpumem-retire/cma_page.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/modules/sun4v/cpumem-retire/cma_page.c	Fri Dec 22 12:42:28 2006 -0800
@@ -99,6 +99,12 @@
 		return (CMA_RA_FAILURE);
 	}
 
+	if (!fmd_nvl_fmri_present(hdl, asru)) {
+		fmd_hdl_debug(hdl, "page retire overtaken by events\n");
+		cma_stats.page_nonent.fmds_value.ui64++;
+		return (CMA_RA_SUCCESS);
+	}
+
 	if (nvlist_lookup_uint64(asru, FM_FMRI_MEM_PHYSADDR, &pageaddr) != 0) {
 		fmd_hdl_debug(hdl, "mem fault missing '%s'\n",
 		    FM_FMRI_MEM_PHYSADDR);
@@ -113,12 +119,6 @@
 		return (CMA_RA_FAILURE);
 	}
 
-	if (!fmd_nvl_fmri_present(hdl, asru)) {
-		fmd_hdl_debug(hdl, "page retire overtaken by events\n");
-		cma_stats.page_nonent.fmds_value.ui64++;
-		return (CMA_RA_SUCCESS);
-	}
-
 	/*
 	 * If the unum is an hc fmri string expand it to an fmri and include
 	 * that in a modified asru nvlist.
--- a/usr/src/cmd/fm/schemes/cpu/cpu.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/schemes/cpu/cpu.c	Fri Dec 22 12:42:28 2006 -0800
@@ -181,6 +181,18 @@
 			if ((rc = nvlist_add_uint64(nvl, FM_FMRI_CPU_SERIAL_ID,
 			    serialid)) != 0)
 				return (fmd_fmri_set_errno(rc));
+#ifdef sparc
+			if (cpu.cpu_mdesc_cpus != NULL) {
+				md_cpumap_t *mcmp = cpu_find_cpumap(cpuid);
+				(void) nvlist_add_string(nvl,
+				    FM_FMRI_CPU_CPUFRU, mcmp->cpumap_cpufru);
+				(void) nvlist_add_string(nvl,
+				    FM_FMRI_HC_PART, mcmp->cpumap_cpufrupn);
+				(void) nvlist_add_string(nvl,
+				    FM_FMRI_HC_SERIAL_ID,
+				    mcmp->cpumap_cpufrusn);
+			}
+#endif	/* sparc */
 		}
 	} else if (version == CPU_SCHEME_VERSION1) {
 		if ((rc = nvlist_lookup_string(nvl, FM_FMRI_CPU_SERIAL_ID,
--- a/usr/src/cmd/fm/schemes/cpu/sparc/cpu_mdesc.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/schemes/cpu/sparc/cpu_mdesc.c	Fri Dec 22 12:42:28 2006 -0800
@@ -34,20 +34,28 @@
 #include <errno.h>
 #include <cpu_mdesc.h>
 
-int
-cpu_get_serialid_mdesc(uint32_t cpuid, uint64_t *serialidp)
-{
+md_cpumap_t *
+cpu_find_cpumap(uint32_t cpuid) {
 	int i;
 	md_cpumap_t *mcmp;
 
 	for (i = 0, mcmp = cpu.cpu_mdesc_cpus;
 	    i < cpu.cpu_mdesc_ncpus; i++, mcmp++) {
 		if (cpuid == mcmp->cpumap_pid) {
-			*serialidp = mcmp->cpumap_serialno;
-			return (0);
+			return (mcmp);
 		}
 	}
+	return (NULL);
+}
 
+int
+cpu_get_serialid_mdesc(uint32_t cpuid, uint64_t *serialidp)
+{
+	md_cpumap_t *mcmp;
+	if ((mcmp = cpu_find_cpumap(cpuid)) != NULL) {
+		*serialidp = mcmp->cpumap_serialno;
+		return (0);
+	}
 	return (fmd_fmri_set_errno(ENOENT));
 }
 
@@ -87,6 +95,7 @@
 	    idx < cpu.cpu_mdesc_ncpus;
 	    idx++, mcmp++) {
 		uint64_t tl;
+		char *cpufru, *cpufrusn, *cpufrupn;
 
 		if (md_get_prop_val(mdp, listp[idx], "id", &tl) < 0)
 			tl = (uint64_t)-1; /* invalid value */
@@ -99,6 +108,21 @@
 		if (md_get_prop_val(mdp, listp[idx], "serial#",
 		    &mcmp->cpumap_serialno) < 0)
 			mcmp->cpumap_serialno = 0;
+
+		if (md_get_prop_str(mdp, listp[idx], "cpufru",
+		    &cpufru) < 0)
+			cpufru = "mb";
+		mcmp->cpumap_cpufru = fmd_fmri_strdup(cpufru);
+
+		if (md_get_prop_str(mdp, listp[idx], "cpufru-serial#",
+		    &cpufrusn) < 0)
+			cpufrusn = "CPU FRU serial number not available";
+		mcmp->cpumap_cpufrusn = fmd_fmri_strdup(cpufrusn);
+
+		if (md_get_prop_str(mdp, listp[idx], "cpufru-part#",
+		    &cpufrupn) < 0)
+			cpufrupn = "CPU FRU part number not available";
+		mcmp->cpumap_cpufrupn = fmd_fmri_strdup(cpufrupn);
 	}
 
 	fmd_fmri_free(listp, sizeof (mde_cookie_t) * num_nodes);
@@ -112,6 +136,15 @@
 cpu_mdesc_fini(void)
 {
 	if (cpu.cpu_mdesc_cpus != NULL) {
+		int idx;
+		md_cpumap_t *mcmp;
+		for (idx = 0, mcmp = cpu.cpu_mdesc_cpus;
+		    idx < cpu.cpu_mdesc_ncpus;
+		    idx++, mcmp++) {
+			fmd_fmri_strfree(mcmp->cpumap_cpufru);
+			fmd_fmri_strfree(mcmp->cpumap_cpufrusn);
+			fmd_fmri_strfree(mcmp->cpumap_cpufrupn);
+		}
 		fmd_fmri_free(cpu.cpu_mdesc_cpus,
 		    cpu.cpu_mdesc_ncpus * sizeof (md_cpumap_t));
 	}
--- a/usr/src/cmd/fm/schemes/cpu/sparc/cpu_mdesc.h	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/schemes/cpu/sparc/cpu_mdesc.h	Fri Dec 22 12:42:28 2006 -0800
@@ -41,16 +41,20 @@
 	uint32_t cpumap_id;
 	uint32_t cpumap_pid;
 	uint64_t cpumap_serialno;
+	char *cpumap_cpufru;
+	char *cpumap_cpufrusn;
+	char *cpumap_cpufrupn;
 } md_cpumap_t;
 
 typedef struct cpu {
-	md_cpumap_t *cpu_mdesc_cpus;	/* head of ptr list for cpu maps */
+	md_cpumap_t *cpu_mdesc_cpus;	/* ptr to array of cpu maps */
 	uint32_t cpu_mdesc_ncpus;	/* number of cpu maps */
 } cpu_t;
 
 extern cpu_t cpu;
 
 extern int cpu_get_serialid_mdesc(uint32_t, uint64_t *);
+extern md_cpumap_t *cpu_find_cpumap(uint32_t);
 extern int cpu_mdesc_init(ldom_hdl_t *lhp);
 extern void cpu_mdesc_fini(void);
 
--- a/usr/src/cmd/fm/schemes/mem/mem.h	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/schemes/mem/mem.h	Fri Dec 22 12:42:28 2006 -0800
@@ -113,12 +113,16 @@
 	char *dm_label;			/* The UNUM for this DIMM */
 	char *dm_device;		/* Path to I2C device for DIMM */
 	char dm_serid[MEM_SERID_MAXLEN]; /* Cached serial number */
+	char *dm_part;			/* DIMM part number */
 	uint64_t dm_drgen;		/* DR gen count for cached S/N */
 } mem_dimm_map_t;
 
 typedef struct mem {
 	mem_dimm_map_t *mem_dm;		/* List supported DIMMs */
 	uint64_t mem_memconfig;		/* HV memory-configuration-id# */
+	uint64_t mem_rank_mask;		/* "rank" bit */
+	int mem_ch_shift;		/* # bits for "CH" */
+	const char *mem_rank_str;	/* string denoting "rank" */
 } mem_t;
 
 extern int mem_discover(void);
--- a/usr/src/cmd/fm/schemes/mem/mem_unum.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/schemes/mem/mem_unum.c	Fri Dec 22 12:42:28 2006 -0800
@@ -94,6 +94,8 @@
 	{ "/MBU_A/MEMB%*d/%n%nMEM%*d%*1c%n",	" MEM%*d%*1c%n" },
 	{ "/MBU_B/MEMB%*d/%n%nMEM%*d%*1c%n",	" MEM%*d%*1c%n" },
 	{ "/CMU%*2d/%n%nMEM%*2d%*1c%n",		" MEM%*2d%*1c%n" },
+	{ "MB/CMP%*d/BR%*d%n:%n%n",		" BR%*d/D%*d/J%*4d%n",	"/" },
+	{ "MB/CMP%*d/BR%*d%n%n%n",		"/BR%*d/D%*d/J%*4d%n" },
 	{ NULL }
 };
 
--- a/usr/src/cmd/fm/schemes/mem/sparc/mem_disc.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/cmd/fm/schemes/mem/sparc/mem_disc.c	Fri Dec 22 12:42:28 2006 -0800
@@ -348,8 +348,10 @@
 mem_discover_mdesc(md_t *mdp, size_t mdbufsz)
 {
 	mde_cookie_t *listp;
-	int num_nodes, idx, mdesc_dimm_count;
+	int num_nodes, idx, mdesc_dimm_count, unique_ch;
 	mem_dimm_map_t *dm;
+	uint64_t sysmem_size, i, drgen = fmd_fmri_get_drgen();
+	char curr_ch;
 
 	num_nodes = md_node_count(mdp);
 	listp = fmd_fmri_alloc(sizeof (mde_cookie_t) * num_nodes);
@@ -371,21 +373,62 @@
 	    md_find_name(mdp, "fwd"), listp);
 
 	for (idx = 0; idx < mdesc_dimm_count; idx++) {
-		char *unum, *serial;
+		char *unum, *serial, *part;
 
 		if (md_get_prop_str(mdp, listp[idx], "nac", &unum) < 0)
 			unum = "";
 		if (md_get_prop_str(mdp, listp[idx], "serial#", &serial) < 0)
 			serial = "";
+		if (md_get_prop_str(mdp, listp[idx], "part#", &part) < 0)
+			part = "DIMM PART # not available";
 
 		dm = fmd_fmri_zalloc(sizeof (mem_dimm_map_t));
 		dm->dm_label = fmd_fmri_strdup(unum);
 		(void) strncpy(dm->dm_serid, serial, MEM_SERID_MAXLEN - 1);
+		dm->dm_part = fmd_fmri_strdup(part);
+		dm->dm_drgen = drgen;
 
 		dm->dm_next = mem.mem_dm;
 		mem.mem_dm = dm;
 	}
 
+	if (strstr(mem.mem_dm->dm_label, "BR") != NULL) { /* N2 */
+		mem.mem_rank_str = "CH";
+	} else  { /* Niagara-1 */
+		mem.mem_rank_str = "/R";
+	}
+
+	curr_ch = '\0';
+	unique_ch = 0;
+	for (dm = mem.mem_dm; dm != NULL; dm = dm->dm_next) {
+		char my_ch;
+		if (mem.mem_rank_str == "CH")
+			my_ch = *(strstr(dm->dm_label, "BR") + 2);
+		else my_ch = *(strstr(dm->dm_label, "CH") + 2);
+		if (curr_ch != my_ch) {
+			unique_ch++;
+			curr_ch = my_ch;
+		}
+	}
+
+	if (unique_ch == 1) mem.mem_ch_shift = 0;
+	else if (unique_ch == 2) mem.mem_ch_shift = 1;
+	else mem.mem_ch_shift = 2;
+
+	mdesc_dimm_count = md_scan_dag(mdp,
+	    MDE_INVAL_ELEM_COOKIE, md_find_name(mdp, "mblock"),
+	    md_find_name(mdp, "fwd"), listp);
+
+	sysmem_size = 0;
+	for (idx = 0; idx < mdesc_dimm_count; idx++) {
+		uint64_t size = 0;
+		if (md_get_prop_val(mdp, listp[idx], "size", &size) == 0)
+			sysmem_size += size;
+	}
+
+	for (i = 1 << 30; i < sysmem_size; i <<= 1); /* round up to 2^i */
+	mem.mem_rank_mask = i >> 1; /* PA high order bit */
+
 	fmd_fmri_free(listp, sizeof (mde_cookie_t) * num_nodes);
 	fmd_fmri_free(*mdp, mdbufsz);
 
--- a/usr/src/lib/fm/Makefile	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/lib/fm/Makefile	Fri Dec 22 12:42:28 2006 -0800
@@ -44,4 +44,6 @@
 
 libldom: libmdesc
 
+topo: $($(MACH)_SUBDIRS)
+
 include ./Makefile.subdirs
--- a/usr/src/lib/fm/topo/libtopo/common/cpu.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/lib/fm/topo/libtopo/common/cpu.c	Fri Dec 22 12:42:28 2006 -0800
@@ -30,12 +30,19 @@
 #include <limits.h>
 #include <strings.h>
 #include <unistd.h>
+#include <topo_error.h>
 #include <fm/topo_mod.h>
 #include <sys/fm/protocol.h>
 
 #include <topo_method.h>
 #include <cpu.h>
 
+/*
+ * platform specific cpu module
+ */
+#define	PLATFORM_CPU_VERSION	CPU_VERSION
+#define	PLATFORM_CPU_NAME	"platform-cpu"
+
 static int cpu_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t,
     topo_instance_t, void *, void *);
 static void cpu_release(topo_mod_t *, tnode_t *);
@@ -185,19 +192,50 @@
 cpu_enum(topo_mod_t *mod, tnode_t *pnode, const char *name,
     topo_instance_t min, topo_instance_t max, void *arg, void *notused2)
 {
+	topo_mod_t *nmp;
 	cpu_node_t *cpuip = (cpu_node_t *)arg;
 
-	if (topo_node_range_create(mod, pnode, "cpu", 0,
-	    cpuip->cn_ncpustats + 1) < 0) {
-		topo_mod_dprintf(mod, "cpu enumeration failed to create cpu "
-		    "range [0-%d]: %s\n", cpuip->cn_ncpustats + 1,
-		    topo_mod_errmsg(mod));
-		return (-1); /* mod_errno set */
+	if ((nmp = topo_mod_load(mod, PLATFORM_CPU_NAME,
+				PLATFORM_CPU_VERSION)) == NULL) {
+		if (topo_mod_errno(mod) == ETOPO_MOD_NOENT) {
+			/*
+			 * There is no platform specific cpu module, so use
+			 * the default enumeration with kstats of this builtin
+			 * cpu module.
+			 */
+			if (topo_node_range_create(mod, pnode, name, 0,
+						cpuip->cn_ncpustats + 1) < 0) {
+				topo_mod_dprintf(mod,
+					"cpu enumeration failed to create "
+					"cpu range [0-%d]: %s\n",
+					cpuip->cn_ncpustats + 1,
+					topo_mod_errmsg(mod));
+				return (-1); /* mod_errno set */
+			}
+			(void) topo_method_register(mod, pnode, cpu_methods);
+			return (cpu_create(mod, pnode, name, min, max, cpuip));
+
+		} else {
+			/* Fail to load the module */
+			topo_mod_dprintf(mod,
+					"Failed to load module %s: %s",
+					PLATFORM_CPU_NAME,
+					topo_mod_errmsg(mod));
+			return (-1);
+		}
 	}
 
+	if (topo_mod_enumerate(nmp, pnode, PLATFORM_CPU_NAME, name,
+				min, max, NULL) < 0) {
+		topo_mod_dprintf(mod,
+				"%s failed to enumerate: %s",
+				PLATFORM_CPU_NAME,
+				topo_mod_errmsg(mod));
+		return (-1);
+	}
 	(void) topo_method_register(mod, pnode, cpu_methods);
 
-	return (cpu_create(mod, pnode, name, min, max, cpuip));
+	return (0);
 }
 
 static void
--- a/usr/src/lib/fm/topo/libtopo/common/hc.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/lib/fm/topo/libtopo/common/hc.c	Fri Dec 22 12:42:28 2006 -0800
@@ -81,6 +81,7 @@
 	{ HC, FM_FMRI_SCHEME_HC, HC_VERSION, &hc_ops };
 
 static const hcc_t hc_canon[] = {
+	{ BRANCH, TOPO_STABILITY_PRIVATE },
 	{ CMP, TOPO_STABILITY_PRIVATE },
 	{ CENTERPLANE, TOPO_STABILITY_PRIVATE },
 	{ CHASSIS, TOPO_STABILITY_PRIVATE },
@@ -95,6 +96,8 @@
 	{ IOBOARD, TOPO_STABILITY_PRIVATE },
 	{ MEMORYCONTROL, TOPO_STABILITY_PRIVATE },
 	{ MOTHERBOARD, TOPO_STABILITY_PRIVATE },
+	{ NIU, TOPO_STABILITY_PRIVATE },
+	{ NIUFN, TOPO_STABILITY_PRIVATE },
 	{ PCI_BUS, TOPO_STABILITY_PRIVATE },
 	{ PCI_DEVICE, TOPO_STABILITY_PRIVATE },
 	{ PCI_FUNCTION, TOPO_STABILITY_PRIVATE },
@@ -106,7 +109,9 @@
 	{ PCIEX_SWDWN, TOPO_STABILITY_PRIVATE },
 	{ RANK, TOPO_STABILITY_PRIVATE },
 	{ SATA_PORT, TOPO_STABILITY_PRIVATE },
-	{ SYSTEMBOARD, TOPO_STABILITY_PRIVATE }
+	{ SYSTEMBOARD, TOPO_STABILITY_PRIVATE },
+	{ XAUI, TOPO_STABILITY_PRIVATE },
+	{ XFP, TOPO_STABILITY_PRIVATE }
 };
 
 static int hc_ncanon = sizeof (hc_canon) / sizeof (hcc_t);
@@ -684,16 +689,16 @@
 		 * Return possible serial, part and revision
 		 */
 		if (strcmp(aname, FM_FMRI_HC_SERIAL_ID) == 0) {
-			*serial = aid;
+			*serial = topo_mod_strdup(mod, aid);
 		} else if (strcmp(aname, FM_FMRI_HC_PART) == 0) {
-			*part = aid;
+			*part = topo_mod_strdup(mod, aid);
 		} else if (strcmp(aname, FM_FMRI_HC_REVISION) == 0) {
-			*rev = aid;
+			*rev = topo_mod_strdup(mod, aid);
 		} else {
 			if (na == NULL) {
 				if (topo_mod_nvalloc(mod, &na,
 				    NV_UNIQUE_NAME) == 0) {
-					nvlist_add_string(na, aname, aid);
+				    (void) nvlist_add_string(na, aname, aid);
 				}
 			} else {
 				(void) nvlist_add_string(na, aname, aid);
--- a/usr/src/lib/fm/topo/libtopo/common/topo_hc.h	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/lib/fm/topo/libtopo/common/topo_hc.h	Fri Dec 22 12:42:28 2006 -0800
@@ -36,6 +36,7 @@
 /*
  * Allowable hardware component names for hc FMRIs
  */
+#define	BRANCH		"branch"
 #define	CMP		"CMP"
 #define	CENTERPLANE	"centerplane"
 #define	CHASSIS		"chassis"
@@ -50,6 +51,8 @@
 #define	IOBOARD		"ioboard"
 #define	MEMORYCONTROL	"memory-controller"
 #define	MOTHERBOARD	"motherboard"
+#define	NIU		"niu"
+#define	NIUFN		"niufn"
 #define	PCI_BUS		"pcibus"
 #define	PCI_DEVICE	"pcidev"
 #define	PCI_FUNCTION    "pcifn"
@@ -62,6 +65,8 @@
 #define	RANK		"rank"
 #define	SATA_PORT	"sata-port"
 #define	SYSTEMBOARD	"systemboard"
+#define	XAUI		"xaui"
+#define	XFP		"xfp"
 
 /*
  * Allowable hc node property group and property names
--- a/usr/src/lib/fm/topo/libtopo/sparc/Makefile	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/lib/fm/topo/libtopo/sparc/Makefile	Fri Dec 22 12:42:28 2006 -0800
@@ -27,4 +27,8 @@
 
 include ../Makefile.com
 
+CPPFLAGS += -I $(ROOT)/usr/platform/sun4v/include
+LDLIBS += -L$(ROOTLIBDIR) -lmdesc -lldom
+DYNFLAGS += -R/usr/lib/fm
+
 install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT)
--- a/usr/src/lib/fm/topo/libtopo/sparcv9/Makefile	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/lib/fm/topo/libtopo/sparcv9/Makefile	Fri Dec 22 12:42:28 2006 -0800
@@ -28,4 +28,8 @@
 include ../Makefile.com
 include ../../../../Makefile.lib.64
 
+CPPFLAGS += -I $(ROOT)/usr/platform/sun4v/include
+LDLIBS += -L$(ROOTLIBDIR64) -lmdesc -lldom
+DYNFLAGS += -R/usr/lib/fm/$(MACH64)
+
 install: all $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTLINT64)
--- a/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/Makefile	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/Makefile	Fri Dec 22 12:42:28 2006 -0800
@@ -31,7 +31,9 @@
 TOPOFILE = Sun-Fire-T200-hc-topology.xml	\
 	Sun-Fire-T1000-hc-topology.xml	\
 	SPARC-Enterprise-T1000-hc-topology.xml \
-	Sun-Blade-T6300-hc-topology.xml
+	Sun-Blade-T6300-hc-topology.xml \
+	SPARC-Enterprise-T5120-hc-topology.xml \
+	SPARC-Enterprise-T5220-hc-topology.xml
 
 SRCDIR = ../SUNW,Sun-Fire-T200
 
--- a/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/SPARC-Enterprise-T1000-hc-topology.xml	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/SPARC-Enterprise-T1000-hc-topology.xml	Fri Dec 22 12:42:28 2006 -0800
@@ -38,6 +38,9 @@
       </propgroup>
     </node>
     <dependents grouping='children'>
+     <range name='chip' min='0' max='0'>
+       <enum-method name='chip' version='1' />
+     </range>
      <range name='hostbridge' min='0' max='254'>
        <enum-method name='hostbridge' version='1' />
      </range>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/SPARC-Enterprise-T5120-hc-topology.xml	Fri Dec 22 12:42:28 2006 -0800
@@ -0,0 +1,54 @@
+<?xml version="1.0"?>
+<!DOCTYPE topology SYSTEM "/usr/share/lib/xml/dtd/topology.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"
+-->
+
+<topology name='SUNW,SPARC-Enterprise-T5120' scheme='hc'>
+  <range name='motherboard' min='0' max='0'>
+   <enum-method name='motherboard' version='1'/>
+ 
+     <dependents grouping='children'>
+       <range name='chip' min='0' max='0'>
+         <enum-method name='chip' version='1'/>
+ 
+         <dependents grouping='children'>
+           <range name='hostbridge' min='0' max='254'>
+             <enum-method name='hostbridge' version='1'/>
+ 
+             <dependents grouping='children'>
+               <range name='niu' min='0' max='0'>
+                <enum-method name='niu' version='1'/>
+               </range>
+             </dependents>
+
+           </range>
+         </dependents>
+
+       </range>
+     </dependents>
+
+   </range>
+</topology>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/SPARC-Enterprise-T5220-hc-topology.xml	Fri Dec 22 12:42:28 2006 -0800
@@ -0,0 +1,54 @@
+<?xml version="1.0"?>
+<!DOCTYPE topology SYSTEM "/usr/share/lib/xml/dtd/topology.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"
+-->
+
+<topology name='SUNW,SPARC-Enterprise-T5220' scheme='hc'>
+  <range name='motherboard' min='0' max='0'>
+   <enum-method name='motherboard' version='1'/>
+ 
+     <dependents grouping='children'>
+       <range name='chip' min='0' max='0'>
+         <enum-method name='chip' version='1'/>
+ 
+         <dependents grouping='children'>
+           <range name='hostbridge' min='0' max='254'>
+             <enum-method name='hostbridge' version='1' />
+ 
+             <dependents grouping='children'>
+               <range name='niu' min='0' max='0'>
+                <enum-method name='niu' version='1'/>
+               </range>
+             </dependents>
+
+           </range>
+         </dependents>
+       </range>
+
+     </dependents>
+ 
+   </range>
+</topology>
--- a/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/Sun-Blade-T6300-hc-topology.xml	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/Sun-Blade-T6300-hc-topology.xml	Fri Dec 22 12:42:28 2006 -0800
@@ -38,6 +38,9 @@
       </propgroup>
     </node>
     <dependents grouping='children'>
+     <range name='chip' min='0' max='0'>
+       <enum-method name='chip' version='1' />
+     </range>
      <range name='hostbridge' min='0' max='254'>
        <enum-method name='hostbridge' version='1' />
      </range>
--- a/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/Sun-Fire-T1000-hc-topology.xml	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/Sun-Fire-T1000-hc-topology.xml	Fri Dec 22 12:42:28 2006 -0800
@@ -38,6 +38,9 @@
       </propgroup>
     </node>
     <dependents grouping='children'>
+     <range name='chip' min='0' max='0'>
+       <enum-method name='chip' version='1' />
+     </range>
      <range name='hostbridge' min='0' max='254'>
        <enum-method name='hostbridge' version='1' />
      </range>
--- a/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/Sun-Fire-T200-hc-topology.xml	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/Sun-Fire-T200-hc-topology.xml	Fri Dec 22 12:42:28 2006 -0800
@@ -37,21 +37,26 @@
           value='MB' />
       </propgroup>
     </node>
+    <dependents grouping='children'>
+      <range name='chip' min='0' max='0'>
+        <enum-method name='chip' version='1' />
+      </range>
+    </dependents>
   </range>
   <range name='ioboard' min='0' max='0'>
     <node instance='0'>
-     <propgroup name='protocol' version='1'
+      <propgroup name='protocol' version='1'
         name-stability='Private' data-stability='Private' >
         <propval name='FRU' type='fmri'
           value='hc:///component=IOBD' />
         <propval name='label' type='string'
           value='IOBD' />
       </propgroup>
-      </node>
-      <dependents grouping='children'>
-        <range name='hostbridge' min='0' max='254'>
-          <enum-method name='hostbridge' version='1' />
-        </range>
-      </dependents>
-    </range>
+    </node>
+    <dependents grouping='children'>
+      <range name='hostbridge' min='0' max='254'>
+        <enum-method name='hostbridge' version='1' />
+      </range>
+    </dependents>
+  </range>
 </topology>
--- a/usr/src/lib/fm/topo/maps/sun4v/sun4v-hc-topology.xml	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/lib/fm/topo/maps/sun4v/sun4v-hc-topology.xml	Fri Dec 22 12:42:28 2006 -0800
@@ -38,6 +38,9 @@
       </propgroup>
     </node>
     <dependents grouping='children'>
+     <range name='chip' min='0' max='32'>
+       <enum-method name='chip' version='1' />
+     </range>
      <range name='hostbridge' min='0' max='254'>
        <enum-method name='hostbridge' version='1' />
      </range>
--- a/usr/src/lib/fm/topo/modules/common/pcibus/did_props.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/lib/fm/topo/modules/common/pcibus/did_props.c	Fri Dec 22 12:42:28 2006 -0800
@@ -38,11 +38,12 @@
 #include <fm/topo_mod.h>
 #include <fm/topo_hc.h>
 #include <libdevinfo.h>
-
 #include <hostbridge.h>
 #include <pcibus.h>
 #include <did.h>
 #include <did_props.h>
+#include "topo_tree.h"
+#include <fm/libtopo.h>
 
 static int ASRU_set(tnode_t *, did_t *,
     const char *, const char *, const char *);
@@ -415,15 +416,24 @@
 static int
 FRU_fmri_hack(topo_mod_t *mp, tnode_t *tn, const char *label)
 {
-	char buf[PATH_MAX];
 	nvlist_t *fmri;
 	int err, e;
-
+	tnode_t *pnode, *cnode = tn;
+	char *plabel;
 
-	(void) snprintf(buf, PATH_MAX, "hc:///component=%s", label);
-	if (topo_mod_str2nvl(mp, buf, &fmri) < 0)
-		return (-1);
+	pnode = tn->tn_parent;
+	while (pnode != NULL) {
+		if (topo_node_label(pnode, &plabel, &err) < 0)
+			break;
+		if (strcmp(plabel, label) != 0)
+			break;
+		cnode = pnode;
+		pnode = pnode->tn_parent;
+	}
 
+	if (topo_node_resource(cnode, &fmri, &err) < 0 ||
+	    fmri == NULL)
+		return (topo_mod_seterrno(mp, err));
 	e = topo_node_fru_set(tn, fmri, 0, &err);
 	nvlist_free(fmri);
 	if (e < 0)
--- a/usr/src/lib/fm/topo/modules/common/pcibus/util.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/lib/fm/topo/modules/common/pcibus/util.c	Fri Dec 22 12:42:28 2006 -0800
@@ -27,6 +27,8 @@
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 #include <stdlib.h>
+#include <string.h>
+#include <strings.h>
 #include <sys/fm/protocol.h>
 #include <fm/topo_mod.h>
 #include <fm/topo_hc.h>
@@ -64,6 +66,30 @@
 	return (r);
 }
 
+static int
+get_pci_vpd_sn_pn(topo_mod_t *mp, di_node_t dn, char **serial, char **part)
+{
+	char *s = NULL, *p = NULL;
+	di_prom_handle_t promtree = DI_PROM_HANDLE_NIL;
+
+	if ((promtree = topo_mod_prominfo(mp)) == DI_PROM_HANDLE_NIL) {
+		topo_mod_dprintf(mp,
+			"get vpd data: di_prom_handle_init failed.\n");
+		return (-1);
+	}
+
+	/* Get Serial Number and Part Number */
+	if ((di_prom_prop_lookup_bytes(promtree, dn, "vpd-serial-number",
+		(uchar_t **)&s) > 0) && (s != NULL))
+		*serial = topo_mod_strdup(mp, s);
+
+	if ((di_prom_prop_lookup_bytes(promtree, dn, "vpd-part-number",
+		(uchar_t **)&p) > 0) && (p != NULL))
+		*part = topo_mod_strdup(mp, p);
+
+	return (0);
+}
+
 tnode_t *
 tnode_create(topo_mod_t *mp, tnode_t *parent,
     const char *name, topo_instance_t i, void *priv)
@@ -71,11 +97,23 @@
 	nvlist_t *fmri;
 	tnode_t *ntn;
 	nvlist_t *auth;
+	char *serial = NULL, *part = NULL;
 
 	auth = topo_mod_auth(mp, parent);
+	/*
+	 * Get PCI/PCIEX Device Serial Number and Part Number
+	 * from PCI VPD
+	 */
+	if ((strcmp(name, PCI_DEVICE) == 0) ||
+	    (strcmp(name, PCIEX_DEVICE) == 0))
+		(void) get_pci_vpd_sn_pn(mp, priv, &serial, &part);
+
 	fmri = topo_mod_hcfmri(mp, parent, FM_HC_SCHEME_VERSION, name, i, NULL,
-	    auth, NULL, NULL, NULL);
+		auth, part, NULL, serial);
 	nvlist_free(auth);
+	topo_mod_strfree(mp, serial);
+	topo_mod_strfree(mp, part);
+
 	if (fmri == NULL) {
 		topo_mod_dprintf(mp,
 		    "Unable to make nvlist for %s bind.\n", name);
--- a/usr/src/lib/fm/topo/modules/sun4/chip/Makefile.chip	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/lib/fm/topo/modules/sun4/chip/Makefile.chip	Fri Dec 22 12:42:28 2006 -0800
@@ -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.
@@ -28,11 +27,13 @@
 MODULE = chip
 CLASS = arch
 SUN4DIR = ../../sun4/$(MODULE)
-MODULESRCS = chip.c
+MODULESRCS = chip_$(ARCH).c
 
 include ../../Makefile.plugin
 
-LDLIBS += -lkstat
+INCDIRS += $(SUN4DIR)
+
+CPPFLAGS += $(INCDIRS:%=-I%)
 
 %.o: $(SUN4DIR)/%.c
 	$(COMPILE.c) -o $@ $<
--- a/usr/src/lib/fm/topo/modules/sun4/chip/chip.c	Fri Dec 22 11:52:51 2006 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,277 +0,0 @@
-/*
- * 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 <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <limits.h>
-#include <alloca.h>
-#include <kstat.h>
-#include <errno.h>
-#include <libnvpair.h>
-#include <sys/types.h>
-#include <sys/bitmap.h>
-#include <sys/processor.h>
-#include <sys/param.h>
-#include <sys/fm/protocol.h>
-#include <sys/systeminfo.h>
-#include <fm/topo_mod.h>
-
-/*
- * Enumerates the processing chips, or sockets, (as distinct from cores) in a
- * system.  For each chip found, the necessary nodes (one or more cores, and
- * possibly a memory controller) are constructed underneath.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define	CHIP_VERSION	TOPO_VERSION
-#define	CPU_NODE_NAME	"cpu"
-#define	CHIP_NODE_NAME	"chip"
-
-typedef struct chip {
-	kstat_ctl_t *chip_kc;
-	kstat_t **chip_cpustats;
-	uint_t chip_ncpustats;
-} chip_t;
-
-static int chip_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t,
-    topo_instance_t, void *, void *);
-
-static const topo_modops_t chip_ops =
-	{ chip_enum, NULL};
-static const topo_modinfo_t chip_info =
-	{ "chip", FM_FMRI_SCHEME_HC, CHIP_VERSION, &chip_ops };
-
-int
-_topo_init(topo_mod_t *mod)
-{
-	chip_t *chip;
-
-	if (getenv("TOPOCHIPDBG"))
-		topo_mod_setdebug(mod);
-	topo_mod_dprintf(mod, "initializing chip enumerator\n");
-
-	if ((chip = topo_mod_zalloc(mod, sizeof (chip_t))) == NULL)
-		return (-1);
-
-	if ((chip->chip_kc = kstat_open()) == NULL) {
-		topo_mod_dprintf(mod, "kstat_open failed: %s\n",
-		    strerror(errno));
-		topo_mod_free(mod, chip, sizeof (chip_t));
-		return (-1);
-	}
-
-	chip->chip_ncpustats = sysconf(_SC_CPUID_MAX);
-	if ((chip->chip_cpustats = topo_mod_zalloc(mod, (
-	    chip->chip_ncpustats + 1) * sizeof (kstat_t *))) == NULL) {
-		(void) kstat_close(chip->chip_kc);
-		topo_mod_free(mod, chip, sizeof (chip_t));
-		return (-1);
-	}
-
-	if (topo_mod_register(mod, &chip_info, TOPO_VERSION) != 0) {
-		topo_mod_dprintf(mod, "failed to register hc: "
-		    "%s\n", topo_mod_errmsg(mod));
-		topo_mod_free(mod, chip->chip_cpustats,
-		    (chip->chip_ncpustats + 1) * sizeof (kstat_t *));
-		(void) kstat_close(chip->chip_kc);
-		topo_mod_free(mod, chip, sizeof (chip_t));
-		return (-1);
-	}
-	topo_mod_setspecific(mod, (void *)chip);
-
-	return (0);
-}
-
-void
-_topo_fini(topo_mod_t *mod)
-{
-	chip_t *chip;
-
-	chip = topo_mod_getspecific(mod);
-
-	if (chip->chip_cpustats != NULL)
-		topo_mod_free(mod, chip->chip_cpustats,
-		    (chip->chip_ncpustats + 1) * sizeof (kstat_t *));
-
-	(void) kstat_close(chip->chip_kc);
-	topo_mod_free(mod, chip, sizeof (chip_t));
-
-	topo_mod_unregister(mod);
-}
-
-static int
-cpu_kstat_init(chip_t *chip, int i)
-{
-	kstat_t *ksp;
-
-	if (chip->chip_cpustats[i] == NULL) {
-		if ((ksp = kstat_lookup(chip->chip_kc, "cpu_info", i, NULL)) ==
-		    NULL || kstat_read(chip->chip_kc, ksp, NULL) < 0)
-			return (-1);
-
-		chip->chip_cpustats[i] = ksp;
-	} else {
-		ksp = chip->chip_cpustats[i];
-	}
-
-	return (ksp->ks_instance);
-}
-
-static nvlist_t *
-cpu_fmri_create(topo_mod_t *mod, uint32_t cpuid, char *s, uint8_t cpumask)
-{
-	int err;
-	nvlist_t *asru;
-
-	if (topo_mod_nvalloc(mod, &asru, NV_UNIQUE_NAME) != 0)
-		return (NULL);
-
-	err = nvlist_add_uint8(asru, FM_VERSION, FM_CPU_SCHEME_VERSION);
-	err |= nvlist_add_string(asru, FM_FMRI_SCHEME, FM_FMRI_SCHEME_CPU);
-	err |= nvlist_add_uint32(asru, FM_FMRI_CPU_ID, cpuid);
-	err |= nvlist_add_uint8(asru, FM_FMRI_CPU_MASK, cpumask);
-	if (s != NULL)
-		err |= nvlist_add_string(asru, FM_FMRI_CPU_SERIAL_ID, s);
-	if (err != 0) {
-		nvlist_free(asru);
-		(void) topo_mod_seterrno(mod, EMOD_FMRI_NVL);
-		return (NULL);
-	}
-
-	return (asru);
-}
-
-/*ARGSUSED*/
-static int
-cpu_create(topo_mod_t *mod, tnode_t *rnode, const char *name,
-    topo_instance_t min, topo_instance_t max, chip_t *chip)
-{
-	int i, err, chip_id, nerr = 0;
-	char *s, sbuf[21];
-	tnode_t *cnode;
-	kstat_named_t *ks, *kf;
-	nvlist_t *fmri, *asru;
-	nvlist_t *auth = topo_mod_auth(mod, rnode);
-
-	/*
-	 * Override what was created for us
-	 */
-	topo_node_range_destroy(rnode, name);
-	if (topo_node_range_create(mod, rnode, name, 0, chip->chip_ncpustats)
-	    < 0)
-		return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM));
-
-	for (i = 0; i <= chip->chip_ncpustats; i++) {
-
-		if ((chip_id = cpu_kstat_init(chip, i)) < 0)
-			continue;
-
-		if ((ks = kstat_data_lookup(chip->chip_cpustats[i],
-		    "device_ID")) != NULL) {
-			(void) snprintf(sbuf, 21, "%llX", ks->value.ui64);
-			s = sbuf;
-		} else {
-			s = NULL;
-		}
-
-		fmri = topo_mod_hcfmri(mod, rnode, FM_HC_SCHEME_VERSION, name,
-		    (topo_instance_t)chip_id, NULL, auth, NULL, NULL, s);
-		if (fmri == NULL || (cnode = topo_node_bind(mod,
-		    rnode, name, i, fmri)) == NULL) {
-			++nerr;
-			nvlist_free(fmri);
-			continue;
-		}
-		nvlist_free(fmri);
-
-		if ((asru = cpu_fmri_create(mod, i, s, 0)) != NULL) {
-			(void) topo_node_asru_set(cnode, asru, 0, &err);
-			nvlist_free(asru);
-		} else {
-			++nerr;
-		}
-
-		/*
-		 * We look for a cpu_fru kstat.  If one is available and
-		 * it contains something useful, use it as the label and
-		 * and the FRU.
-		 *
-		 * This is a problem for platforms that do not properly
-		 * support the cpu_fru kstat like Ontario or if
-		 * we start exporting a different type of FRU label
-		 */
-		if ((kf = kstat_data_lookup(chip->chip_cpustats[i], "cpu_fru"))
-		    != NULL && strcmp(KSTAT_NAMED_STR_PTR(kf),
-		    "hc:///component=") != 0) {
-			nvlist_t *fru;
-			char *lp;
-
-			if (topo_mod_str2nvl(mod, KSTAT_NAMED_STR_PTR(kf),
-			    &fru) == 0) {
-				(void) topo_node_fru_set(cnode, fru, 0, &err);
-				nvlist_free(fru);
-			}
-
-			if ((lp = strchr(KSTAT_NAMED_STR_PTR(kf), '='))
-			    == NULL) {
-				(void) topo_node_label_set(cnode, NULL, &err);
-			} else {
-				++lp;
-				(void) topo_node_label_set(cnode, lp, &err);
-			}
-		} else {
-			(void) topo_node_label_set(cnode, NULL, &err);
-		}
-	}
-
-	nvlist_free(auth);
-
-	if (nerr != 0)
-		return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM));
-	else
-		return (0);
-}
-
-/*ARGSUSED*/
-static int
-chip_enum(topo_mod_t *mod, tnode_t *rnode, const char *name,
-    topo_instance_t min, topo_instance_t max, void *arg, void *notused)
-{
-	chip_t *chip = (chip_t *)arg;
-
-	if (strcmp(name, CPU_NODE_NAME) == 0)
-		return (cpu_create(mod, rnode, name, min, max, chip));
-
-	return (0);
-}
--- a/usr/src/lib/fm/topo/modules/sun4u/chip/Makefile	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/lib/fm/topo/modules/sun4u/chip/Makefile	Fri Dec 22 12:42:28 2006 -0800
@@ -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.
@@ -28,3 +27,5 @@
 ARCH = sun4u
 
 include ../../sun4/chip/Makefile.chip
+
+LDLIBS += -lkstat
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/topo/modules/sun4u/chip/chip_sun4u.c	Fri Dec 22 12:42:28 2006 -0800
@@ -0,0 +1,277 @@
+/*
+ * 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 <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <limits.h>
+#include <alloca.h>
+#include <kstat.h>
+#include <errno.h>
+#include <libnvpair.h>
+#include <sys/types.h>
+#include <sys/bitmap.h>
+#include <sys/processor.h>
+#include <sys/param.h>
+#include <sys/fm/protocol.h>
+#include <sys/systeminfo.h>
+#include <fm/topo_mod.h>
+
+/*
+ * Enumerates the processing chips, or sockets, (as distinct from cores) in a
+ * system.  For each chip found, the necessary nodes (one or more cores, and
+ * possibly a memory controller) are constructed underneath.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define	CHIP_VERSION	TOPO_VERSION
+#define	CPU_NODE_NAME	"cpu"
+#define	CHIP_NODE_NAME	"chip"
+
+typedef struct chip {
+	kstat_ctl_t *chip_kc;
+	kstat_t **chip_cpustats;
+	uint_t chip_ncpustats;
+} chip_t;
+
+static int chip_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t,
+    topo_instance_t, void *, void *);
+
+static const topo_modops_t chip_ops =
+	{ chip_enum, NULL};
+static const topo_modinfo_t chip_info =
+	{ "chip", FM_FMRI_SCHEME_HC, CHIP_VERSION, &chip_ops };
+
+int
+_topo_init(topo_mod_t *mod)
+{
+	chip_t *chip;
+
+	if (getenv("TOPOCHIPDBG"))
+		topo_mod_setdebug(mod);
+	topo_mod_dprintf(mod, "initializing chip enumerator\n");
+
+	if ((chip = topo_mod_zalloc(mod, sizeof (chip_t))) == NULL)
+		return (-1);
+
+	if ((chip->chip_kc = kstat_open()) == NULL) {
+		topo_mod_dprintf(mod, "kstat_open failed: %s\n",
+		    strerror(errno));
+		topo_mod_free(mod, chip, sizeof (chip_t));
+		return (-1);
+	}
+
+	chip->chip_ncpustats = sysconf(_SC_CPUID_MAX);
+	if ((chip->chip_cpustats = topo_mod_zalloc(mod, (
+	    chip->chip_ncpustats + 1) * sizeof (kstat_t *))) == NULL) {
+		(void) kstat_close(chip->chip_kc);
+		topo_mod_free(mod, chip, sizeof (chip_t));
+		return (-1);
+	}
+
+	if (topo_mod_register(mod, &chip_info, TOPO_VERSION) != 0) {
+		topo_mod_dprintf(mod, "failed to register hc: "
+		    "%s\n", topo_mod_errmsg(mod));
+		topo_mod_free(mod, chip->chip_cpustats,
+		    (chip->chip_ncpustats + 1) * sizeof (kstat_t *));
+		(void) kstat_close(chip->chip_kc);
+		topo_mod_free(mod, chip, sizeof (chip_t));
+		return (-1);
+	}
+	topo_mod_setspecific(mod, (void *)chip);
+
+	return (0);
+}
+
+void
+_topo_fini(topo_mod_t *mod)
+{
+	chip_t *chip;
+
+	chip = topo_mod_getspecific(mod);
+
+	if (chip->chip_cpustats != NULL)
+		topo_mod_free(mod, chip->chip_cpustats,
+		    (chip->chip_ncpustats + 1) * sizeof (kstat_t *));
+
+	(void) kstat_close(chip->chip_kc);
+	topo_mod_free(mod, chip, sizeof (chip_t));
+
+	topo_mod_unregister(mod);
+}
+
+static int
+cpu_kstat_init(chip_t *chip, int i)
+{
+	kstat_t *ksp;
+
+	if (chip->chip_cpustats[i] == NULL) {
+		if ((ksp = kstat_lookup(chip->chip_kc, "cpu_info", i, NULL)) ==
+		    NULL || kstat_read(chip->chip_kc, ksp, NULL) < 0)
+			return (-1);
+
+		chip->chip_cpustats[i] = ksp;
+	} else {
+		ksp = chip->chip_cpustats[i];
+	}
+
+	return (ksp->ks_instance);
+}
+
+static nvlist_t *
+cpu_fmri_create(topo_mod_t *mod, uint32_t cpuid, char *s, uint8_t cpumask)
+{
+	int err;
+	nvlist_t *asru;
+
+	if (topo_mod_nvalloc(mod, &asru, NV_UNIQUE_NAME) != 0)
+		return (NULL);
+
+	err = nvlist_add_uint8(asru, FM_VERSION, FM_CPU_SCHEME_VERSION);
+	err |= nvlist_add_string(asru, FM_FMRI_SCHEME, FM_FMRI_SCHEME_CPU);
+	err |= nvlist_add_uint32(asru, FM_FMRI_CPU_ID, cpuid);
+	err |= nvlist_add_uint8(asru, FM_FMRI_CPU_MASK, cpumask);
+	if (s != NULL)
+		err |= nvlist_add_string(asru, FM_FMRI_CPU_SERIAL_ID, s);
+	if (err != 0) {
+		nvlist_free(asru);
+		(void) topo_mod_seterrno(mod, EMOD_FMRI_NVL);
+		return (NULL);
+	}
+
+	return (asru);
+}
+
+/*ARGSUSED*/
+static int
+cpu_create(topo_mod_t *mod, tnode_t *rnode, const char *name,
+    topo_instance_t min, topo_instance_t max, chip_t *chip)
+{
+	int i, err, chip_id, nerr = 0;
+	char *s, sbuf[21];
+	tnode_t *cnode;
+	kstat_named_t *ks, *kf;
+	nvlist_t *fmri, *asru;
+	nvlist_t *auth = topo_mod_auth(mod, rnode);
+
+	/*
+	 * Override what was created for us
+	 */
+	topo_node_range_destroy(rnode, name);
+	if (topo_node_range_create(mod, rnode, name, 0, chip->chip_ncpustats)
+	    < 0)
+		return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM));
+
+	for (i = 0; i <= chip->chip_ncpustats; i++) {
+
+		if ((chip_id = cpu_kstat_init(chip, i)) < 0)
+			continue;
+
+		if ((ks = kstat_data_lookup(chip->chip_cpustats[i],
+		    "device_ID")) != NULL) {
+			(void) snprintf(sbuf, 21, "%llX", ks->value.ui64);
+			s = sbuf;
+		} else {
+			s = NULL;
+		}
+
+		fmri = topo_mod_hcfmri(mod, rnode, FM_HC_SCHEME_VERSION, name,
+		    (topo_instance_t)chip_id, NULL, auth, NULL, NULL, s);
+		if (fmri == NULL || (cnode = topo_node_bind(mod,
+		    rnode, name, i, fmri)) == NULL) {
+			++nerr;
+			nvlist_free(fmri);
+			continue;
+		}
+		nvlist_free(fmri);
+
+		if ((asru = cpu_fmri_create(mod, i, s, 0)) != NULL) {
+			(void) topo_node_asru_set(cnode, asru, 0, &err);
+			nvlist_free(asru);
+		} else {
+			++nerr;
+		}
+
+		/*
+		 * We look for a cpu_fru kstat.  If one is available and
+		 * it contains something useful, use it as the label and
+		 * and the FRU.
+		 *
+		 * This is a problem for platforms that do not properly
+		 * support the cpu_fru kstat like Ontario or if
+		 * we start exporting a different type of FRU label
+		 */
+		if ((kf = kstat_data_lookup(chip->chip_cpustats[i], "cpu_fru"))
+		    != NULL && strcmp(KSTAT_NAMED_STR_PTR(kf),
+		    "hc:///component=") != 0) {
+			nvlist_t *fru;
+			char *lp;
+
+			if (topo_mod_str2nvl(mod, KSTAT_NAMED_STR_PTR(kf),
+			    &fru) == 0) {
+				(void) topo_node_fru_set(cnode, fru, 0, &err);
+				nvlist_free(fru);
+			}
+
+			if ((lp = strchr(KSTAT_NAMED_STR_PTR(kf), '='))
+			    == NULL) {
+				(void) topo_node_label_set(cnode, NULL, &err);
+			} else {
+				++lp;
+				(void) topo_node_label_set(cnode, lp, &err);
+			}
+		} else {
+			(void) topo_node_label_set(cnode, NULL, &err);
+		}
+	}
+
+	nvlist_free(auth);
+
+	if (nerr != 0)
+		return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM));
+	else
+		return (0);
+}
+
+/*ARGSUSED*/
+static int
+chip_enum(topo_mod_t *mod, tnode_t *rnode, const char *name,
+    topo_instance_t min, topo_instance_t max, void *arg, void *notused)
+{
+	chip_t *chip = (chip_t *)arg;
+
+	if (strcmp(name, CPU_NODE_NAME) == 0)
+		return (cpu_create(mod, rnode, name, min, max, chip));
+
+	return (0);
+}
--- a/usr/src/lib/fm/topo/modules/sun4v/Makefile	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/lib/fm/topo/modules/sun4v/Makefile	Fri Dec 22 12:42:28 2006 -0800
@@ -25,6 +25,7 @@
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
 
-SUBDIRS = chip hostbridge pcibus
+SUBDIRS = chip hostbridge pcibus motherboard niu platform-cpu
+
 
 include ../../../Makefile.subdirs
--- a/usr/src/lib/fm/topo/modules/sun4v/chip/Makefile	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/lib/fm/topo/modules/sun4v/chip/Makefile	Fri Dec 22 12:42:28 2006 -0800
@@ -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.
@@ -27,4 +26,8 @@
 
 ARCH = sun4v
 
+INCDIRS = $(ROOT)/usr/platform/sun4v/include
+
 include ../../sun4/chip/Makefile.chip
+
+LDLIBS += -lumem -lmdesc -lldom
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/topo/modules/sun4v/chip/chip_sun4v.c	Fri Dec 22 12:42:28 2006 -0800
@@ -0,0 +1,465 @@
+/*
+ * 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 <strings.h>
+#include <sys/types.h>
+#include <sys/mdesc.h>
+#include <sys/fm/ldom.h>
+#include <fm/topo_mod.h>
+#include <sys/fm/protocol.h>
+
+#include <unistd.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <umem.h>
+
+#include <stdlib.h>
+
+
+/*
+ * Enumerates the processing chips, or sockets, (as distinct from cores) in a
+ * system.  For each chip found, the necessary nodes (one or more cores, and
+ * possibly a memory controller) are constructed underneath.
+ */
+
+#define	CHIP_VERSION	TOPO_VERSION
+#define	CPU_NODE_NAME	"cpu"
+#define	CHIP_NODE_NAME	"chip"
+
+typedef struct md_cpumap {
+	uint32_t cpumap_id;		/* virtual cpuid */
+	uint32_t cpumap_pid;		/* physical cpuid */
+	uint64_t cpumap_serialno;	/* cpu serial number */
+} md_cpumap_t;
+
+typedef struct chip {
+	uint64_t *chip_serials;		/* list of cpu serial numbers */
+	md_cpumap_t *chip_cpus;		/* List of cpu maps */
+	uint32_t chip_ncpus;		/* size */
+} chip_t;
+
+
+/* Forward declaration */
+static int chip_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t,
+    topo_instance_t, void *, void *);
+static void chip_release(topo_mod_t *, tnode_t *);
+static int cpu_mdesc_init(topo_mod_t *mod, chip_t *chip);
+
+
+static const topo_modops_t chip_ops =
+	{ chip_enum, chip_release };
+static const topo_modinfo_t chip_info =
+	{ "chip", FM_FMRI_SCHEME_HC, CHIP_VERSION, &chip_ops };
+
+
+static const topo_pgroup_info_t chip_auth_pgroup = {
+	FM_FMRI_AUTHORITY,
+	TOPO_STABILITY_PRIVATE,
+	TOPO_STABILITY_PRIVATE,
+	1
+};
+
+static void *
+chip_alloc(size_t size)
+{
+	return (umem_alloc(size, UMEM_DEFAULT));
+}
+
+static void
+chip_free(void *data, size_t size)
+{
+	umem_free(data, size);
+}
+
+int
+_topo_init(topo_mod_t *mod)
+{
+	chip_t *chip;
+
+	if (getenv("TOPOCHIPDBG"))
+		topo_mod_setdebug(mod);
+	topo_mod_dprintf(mod, "initializing chip enumerator\n");
+
+	if ((chip = topo_mod_zalloc(mod, sizeof (chip_t))) == NULL)
+		return (-1);
+
+	if (cpu_mdesc_init(mod, chip) != 0) {
+		topo_mod_dprintf(mod, "failed to get cpus from the PRI/MD\n");
+		topo_mod_free(mod, chip, sizeof (chip_t));
+		return (-1);
+	}
+
+	if (topo_mod_register(mod, &chip_info, TOPO_VERSION) != 0) {
+		topo_mod_dprintf(mod, "failed to register hc: "
+		    "%s\n", topo_mod_errmsg(mod));
+		topo_mod_free(mod, chip, sizeof (chip_t));
+		return (-1);
+	}
+	topo_mod_setspecific(mod, (void *)chip);
+
+	topo_mod_dprintf(mod, "chip enumerator inited\n");
+
+	return (0);
+}
+
+void
+_topo_fini(topo_mod_t *mod)
+{
+	chip_t *chip;
+
+	chip = (chip_t *)topo_mod_getspecific(mod);
+
+	if (chip->chip_serials != NULL)
+		topo_mod_free(mod, chip->chip_serials,
+			chip->chip_ncpus * sizeof (uint64_t));
+
+	if (chip->chip_cpus != NULL)
+		topo_mod_free(mod, chip->chip_cpus,
+			chip->chip_ncpus * sizeof (md_cpumap_t));
+
+	topo_mod_free(mod, chip, sizeof (chip_t));
+
+	topo_mod_unregister(mod);
+
+}
+
+static tnode_t *
+chip_tnode_create(topo_mod_t *mod, tnode_t *parent,
+    const char *name, topo_instance_t i, char *serial, void *priv)
+{
+	int err;
+	nvlist_t *fmri;
+	tnode_t *ntn;
+	char *prod = NULL, *csn = NULL, *server = NULL;
+	nvlist_t *auth = NULL;
+
+	if (topo_mod_nvalloc(mod, &auth, NV_UNIQUE_NAME) == 0) {
+		if (topo_prop_get_string(parent, FM_FMRI_AUTHORITY,
+		    FM_FMRI_AUTH_PRODUCT, &prod, &err) == 0)
+		    (void) nvlist_add_string(auth, FM_FMRI_AUTH_PRODUCT,
+			    prod);
+		if (topo_prop_get_string(parent, FM_FMRI_AUTHORITY,
+			FM_FMRI_AUTH_SERVER, &server, &err) == 0)
+			(void) nvlist_add_string(auth, FM_FMRI_AUTH_SERVER,
+			    server);
+		if (topo_prop_get_string(parent, FM_FMRI_AUTHORITY,
+		    FM_FMRI_AUTH_CHASSIS, &csn, &err) == 0)
+			(void) nvlist_add_string(auth, FM_FMRI_AUTH_CHASSIS,
+			    csn);
+	}
+
+
+	fmri = topo_mod_hcfmri(mod, parent, FM_HC_SCHEME_VERSION, name, i,
+	    NULL, auth, NULL, NULL, serial);
+	nvlist_free(auth);
+	if (fmri == NULL) {
+		topo_mod_dprintf(mod,
+		    "Unable to make nvlist for %s bind: %s.\n",
+		    name, topo_mod_errmsg(mod));
+		return (NULL);
+	}
+
+	ntn = topo_node_bind(mod, parent, name, i, fmri);
+	if (ntn == NULL) {
+		topo_mod_dprintf(mod,
+		    "topo_node_bind (%s%d/%s%d) failed: %s\n",
+		    topo_node_name(parent), topo_node_instance(parent),
+		    name, i,
+		    topo_strerror(topo_mod_errno(mod)));
+		nvlist_free(fmri);
+		return (NULL);
+	}
+	nvlist_free(fmri);
+	topo_node_setspecific(ntn, priv);
+
+	if (topo_pgroup_create(ntn, &chip_auth_pgroup, &err) == 0) {
+		(void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY,
+		    FM_FMRI_AUTH_PRODUCT, &err);
+		(void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY,
+		    FM_FMRI_AUTH_CHASSIS, &err);
+		(void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY,
+		    FM_FMRI_AUTH_SERVER, &err);
+	}
+
+	/* Inherit the Label FRU fields from the parent */
+	(void) topo_node_label_set(ntn, NULL, &err);
+	(void) topo_node_fru_set(ntn, NULL, 0, &err);
+
+	return (ntn);
+}
+
+static int
+cpu_mdesc_init(topo_mod_t *mod, chip_t *chip)
+{
+	md_t *mdp;
+	mde_cookie_t *listp;
+	md_cpumap_t *mcmp;
+	int i, num_nodes, idx;
+	ssize_t bufsiz = 0;
+	uint64_t *bufp;
+	ldom_hdl_t *lhp;
+
+	lhp = ldom_init(chip_alloc, chip_free);
+	if ((bufsiz = ldom_get_core_md(lhp, &bufp)) <= 0) {
+		return (-1);
+	}
+
+	if ((mdp = md_init_intern(bufp, chip_alloc, chip_free)) == NULL ||
+	    (num_nodes = md_node_count(mdp)) <= 0) {
+		chip_free(bufp, (size_t)bufsiz);
+		return (-1);
+	}
+
+	listp = topo_mod_zalloc(mod, sizeof (mde_cookie_t) * num_nodes);
+
+	chip->chip_ncpus = md_scan_dag(mdp,
+					MDE_INVAL_ELEM_COOKIE,
+					md_find_name(mdp, "cpu"),
+					md_find_name(mdp, "fwd"),
+					listp);
+	topo_mod_dprintf(mod, "Found %d cpus\n", chip->chip_ncpus);
+
+	chip->chip_cpus = topo_mod_zalloc(mod, chip->chip_ncpus *
+	    sizeof (md_cpumap_t));
+	chip->chip_serials = topo_mod_zalloc(mod, chip->chip_ncpus *
+	    sizeof (uint64_t));
+
+	for (idx = 0, mcmp = chip->chip_cpus;
+	    idx < chip->chip_ncpus;
+	    idx++, mcmp++) {
+		uint64_t tl;
+
+		if (md_get_prop_val(mdp, listp[idx], "id", &tl) < 0)
+			tl = (uint64_t)-1; /* invalid value */
+		mcmp->cpumap_id = tl;
+
+		if (md_get_prop_val(mdp, listp[idx], "pid", &tl) < 0)
+			tl = mcmp->cpumap_id;
+		mcmp->cpumap_pid = tl;
+
+		if (md_get_prop_val(mdp, listp[idx], "serial#",
+		    &mcmp->cpumap_serialno) < 0)
+			mcmp->cpumap_serialno = 0;
+
+		/* unique serial number */
+		for (i = 0; i < chip->chip_ncpus &&
+		    chip->chip_serials[i] != 0; i++) {
+			if (mcmp->cpumap_serialno == chip->chip_serials[i]) {
+				break;
+			}
+		}
+		if (i < chip->chip_ncpus && chip->chip_serials[i] == 0) {
+			chip->chip_serials[i] = mcmp->cpumap_serialno;
+			topo_mod_dprintf(mod, "chip[%d] serial is %llx\n", i,
+				chip->chip_serials[i]);
+		}
+	}
+
+	topo_mod_free(mod, listp, sizeof (mde_cookie_t) * num_nodes);
+	topo_mod_free(mod, *mdp, bufsiz);
+	(void) md_fini(mdp);
+
+	return (0);
+}
+
+static nvlist_t *
+cpu_fmri_create(topo_mod_t *mod, uint32_t cpuid, char *serial, uint8_t cpumask)
+{
+	int err;
+	nvlist_t *fmri;
+
+	if (topo_mod_nvalloc(mod, &fmri, NV_UNIQUE_NAME) != 0)
+		return (NULL);
+	err = nvlist_add_uint8(fmri, FM_VERSION, FM_CPU_SCHEME_VERSION);
+	err |= nvlist_add_string(fmri, FM_FMRI_SCHEME, FM_FMRI_SCHEME_CPU);
+	err |= nvlist_add_uint32(fmri, FM_FMRI_CPU_ID, cpuid);
+	err |= nvlist_add_uint8(fmri, FM_FMRI_CPU_MASK, cpumask);
+	if (serial != NULL)
+		err |= nvlist_add_string(fmri, FM_FMRI_CPU_SERIAL_ID, serial);
+	if (err != 0) {
+		nvlist_free(fmri);
+		(void) topo_mod_seterrno(mod, EMOD_FMRI_NVL);
+		return (NULL);
+	}
+
+	return (fmri);
+}
+
+/*ARGSUSED*/
+static int
+cpu_create(topo_mod_t *mod, tnode_t *rnode, const char *name, chip_t *chip,
+		int chipidx)
+{
+	int i;
+	int min = -1;
+	int max = -1;
+	int err;
+	int nerr = 0;
+	int pid;
+	char sbuf[32];
+	tnode_t *cnode;
+	nvlist_t *asru;
+
+	topo_mod_dprintf(mod, "enumerating cpus\n");
+
+	/*
+	 * find the min/max id of cpus per this cmp and create a cpu range
+	 */
+	for (i = 0; i < chip->chip_ncpus; i++) {
+		if (chip->chip_cpus[i].cpumap_serialno !=
+		    chip->chip_serials[chipidx])
+			continue;
+		if ((min < 0) || (chip->chip_cpus[i].cpumap_pid < min))
+			min = chip->chip_cpus[i].cpumap_pid;
+		if ((max < 0) || (chip->chip_cpus[i].cpumap_pid > max))
+			max = chip->chip_cpus[i].cpumap_pid;
+	}
+	if (min < 0 || max < 0)
+		return (-1);
+	topo_node_range_destroy(rnode, name);
+	if (topo_node_range_create(mod, rnode, name, 0, max+1) < 0) {
+		topo_mod_dprintf(mod, "failed to create cpu range[0,%d]: %s\n",
+					max, topo_mod_errmsg(mod));
+		return (-1);
+	}
+
+	(void) snprintf(sbuf, sizeof (sbuf), "%llx",
+			chip->chip_serials[chipidx]);
+
+	/*
+	 * Create the cpu[i] nodes of a given cmp chipidx
+	 */
+	for (i = 0; i < chip->chip_ncpus; i++) {
+
+		if (chip->chip_cpus[i].cpumap_serialno !=
+		    chip->chip_serials[chipidx]) {
+			continue;
+		}
+
+		/* physical cpuid */
+		pid = chip->chip_cpus[i].cpumap_pid;
+		cnode = chip_tnode_create(mod, rnode, name,
+					(topo_instance_t)pid, sbuf, NULL);
+		if (cnode == NULL) {
+			topo_mod_dprintf(mod,
+					"failed to create a cpu=%d node: %s\n",
+					pid, topo_mod_errmsg(mod));
+			nerr++;
+			continue;
+		}
+
+		if ((asru = cpu_fmri_create(mod, pid, sbuf, 0)) != NULL) {
+			(void) topo_node_asru_set(cnode, asru, 0, &err);
+			nvlist_free(asru);
+		} else {
+			nerr++;
+		}
+	}
+
+	if (nerr != 0)
+		(void) topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM);
+
+	return (0);
+}
+
+/*ARGSUSED*/
+static int
+chip_create(topo_mod_t *mod, tnode_t *rnode, const char *name,
+    topo_instance_t min, topo_instance_t max, chip_t *chip)
+{
+	int nerr = 0;
+	int err;
+	int chipidx;
+	char sbuf[32];
+	tnode_t *cnode;
+
+	topo_mod_dprintf(mod, "enumerating cmp chip\n");
+
+	for (chipidx = 0; chipidx < chip->chip_ncpus &&
+			chip->chip_serials[chipidx] != 0; chipidx++);
+	topo_node_range_destroy(rnode, name);
+	if (topo_node_range_create(mod, rnode, name, 0, chipidx+1) < 0) {
+		topo_mod_dprintf(mod, "failed to create chip range[0,%d]: %s\n",
+					chipidx, topo_mod_errmsg(mod));
+		return (-1);
+	}
+
+	/*
+	 * Create the chip[i] nodes, one for each CMP chip uniquely identified
+	 * by the serial number.
+	 */
+	for (chipidx = 0; chipidx < chip->chip_ncpus &&
+			chip->chip_serials[chipidx] != 0; chipidx++) {
+
+		(void) snprintf(sbuf, sizeof (sbuf), "%llx",
+				chip->chip_serials[chipidx]);
+
+		topo_mod_dprintf(mod, "enumerating chip [%s]\n", sbuf);
+
+		cnode = chip_tnode_create(mod, rnode, name,
+					(topo_instance_t)chipidx, sbuf, NULL);
+		if (cnode == NULL) {
+			topo_mod_dprintf(mod, "failed to create a chip node: "
+						"%s\n", topo_mod_errmsg(mod));
+			nerr++;
+			continue;
+		}
+
+		/* Enumerate all cpu strands of this CMP chip */
+		err = cpu_create(mod, cnode, CPU_NODE_NAME, chip, chipidx);
+		if (err != 0) {
+			nerr++;
+		}
+	}
+
+	if (nerr != 0)
+		(void) topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM);
+
+	return (0);
+}
+
+/*ARGSUSED*/
+static int
+chip_enum(topo_mod_t *mod, tnode_t *rnode, const char *name,
+    topo_instance_t min, topo_instance_t max, void *arg, void *notused)
+{
+	chip_t *chip = (chip_t *)arg;
+
+	if (strcmp(name, CHIP_NODE_NAME) == 0)
+		return (chip_create(mod, rnode, name, min, max, chip));
+
+	return (0);
+}
+
+/*ARGSUSED*/
+static void
+chip_release(topo_mod_t *mp, tnode_t *node)
+{
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/topo/modules/sun4v/motherboard/Makefile	Fri Dec 22 12:42:28 2006 -0800
@@ -0,0 +1,39 @@
+#
+# 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"
+#
+
+MODULE = motherboard
+ARCH = sun4v
+CLASS = arch
+MBSRCS =  motherboard.c
+
+MODULESRCS = $(MBSRCS)
+
+include ../../Makefile.plugin
+
+CPPFLAGS += -I. -I$(ROOT)/usr/platform/sun4v/include
+LDLIBS += -ldevinfo -lmdesc -lldom -lumem
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/topo/modules/sun4v/motherboard/motherboard.c	Fri Dec 22 12:42:28 2006 -0800
@@ -0,0 +1,352 @@
+/*
+ * 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 <string.h>
+#include <strings.h>
+#include <fm/topo_mod.h>
+#include <fm/topo_hc.h>
+#include <libdevinfo.h>
+#include <limits.h>
+#include <sys/fm/protocol.h>
+#include <sys/param.h>
+#include <sys/systeminfo.h>
+#include <assert.h>
+#include <sys/utsname.h>
+#include <sys/systeminfo.h>
+#include <fm/fmd_fmri.h>
+#include <sys/types.h>
+#include <sys/mdesc.h>
+#include <sys/fm/ldom.h>
+
+
+#include "topo_prop.h"
+#include "topo_error.h"
+
+
+/*
+ * motherboard.c
+ *	sun4v specific motherboard enumerators
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define	MB_VERSION	TOPO_VERSION
+
+static int mb_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t,
+		topo_instance_t, void *, void *);
+
+static const topo_modops_t Mb_ops =
+	{ mb_enum, NULL};
+static const topo_modinfo_t mb_info =
+	{ MOTHERBOARD, FM_FMRI_SCHEME_HC, MB_VERSION, &Mb_ops};
+
+static const topo_pgroup_info_t mb_auth_pgroup = {
+	FM_FMRI_AUTHORITY,
+	TOPO_STABILITY_PRIVATE,
+	TOPO_STABILITY_PRIVATE,
+	1
+};
+
+static const topo_pgroup_info_t mb_sys_pgroup = {
+	TOPO_PGROUP_SYSTEM,
+	TOPO_STABILITY_PRIVATE,
+	TOPO_STABILITY_PRIVATE,
+	1
+};
+
+static topo_mod_t *mb_mod_hdl = NULL;
+
+/*ARGSUSED*/
+void
+_topo_init(topo_mod_t *mod, topo_version_t version)
+{
+	/*
+	 * Turn on module debugging output
+	 */
+	if (getenv("TOPOMBDBG") != NULL)
+		topo_mod_setdebug(mod);
+	topo_mod_dprintf(mod, "initializing motherboard enumerator\n");
+
+	if (topo_mod_register(mod, &mb_info, TOPO_VERSION) < 0) {
+		topo_mod_dprintf(mod, "motherboard registration failed: %s\n",
+			topo_mod_errmsg(mod));
+		return; /* mod errno already set */
+	}
+	topo_mod_dprintf(mod, "MB enumr initd\n");
+}
+
+void
+_topo_fini(topo_mod_t *mod)
+{
+	topo_mod_unregister(mod);
+}
+
+static void *
+mb_topo_alloc(size_t size)
+{
+	assert(mb_mod_hdl != NULL);
+	return (topo_mod_alloc(mb_mod_hdl, size));
+}
+
+static void
+mb_topo_free(void *data, size_t size)
+{
+	assert(mb_mod_hdl != NULL);
+	topo_mod_free(mb_mod_hdl, data, size);
+}
+
+static int
+mb_get_pri_serial_part(topo_mod_t *mod, ldom_hdl_t *lhp, const char *name,
+	char **serialp, char **partp)
+{
+	char isa[MAXNAMELEN];
+	md_t *mdp;
+	mde_cookie_t *listp;
+	uint64_t *bufp;
+	ssize_t bufsize = 0;
+	int  nfrus, num_nodes, i;
+	char *pstr = NULL;
+	char *sn, *pn, *dn;
+
+	topo_mod_dprintf(mod, "entering mb_get_pri_fru\n");
+
+	(void) sysinfo(SI_MACHINE, isa, MAXNAMELEN);
+
+	if (strcmp(isa, "sun4v") != 0) {
+		topo_mod_dprintf(mod, "not sun4v architecture%s\n",
+			isa);
+		return (-1);
+	}
+
+	if ((bufsize = ldom_get_core_md(lhp, &bufp)) < 1) {
+		topo_mod_dprintf(mod, "ldom_get_core_md error, bufsize=%d\n",
+			bufsize);
+		return (-1);
+	}
+	topo_mod_dprintf(mod, "pri bufsize=%d\n", bufsize);
+
+	if ((mdp = md_init_intern(bufp, mb_topo_alloc, mb_topo_free)) == NULL ||
+	    (num_nodes = md_node_count(mdp)) < 1) {
+		mb_topo_free(bufp, bufsize);
+		topo_mod_dprintf(mod, "md_init_intern error\n");
+		return (-1);
+	}
+	topo_mod_dprintf(mod, "num_nodes=%d\n", num_nodes);
+
+	if ((listp = (mde_cookie_t *)mb_topo_alloc(
+		sizeof (mde_cookie_t) * num_nodes)) == NULL) {
+		topo_mod_dprintf(mod, "alloc listp error\n");
+		return (-1);
+	}
+
+	nfrus = md_scan_dag(mdp, MDE_INVAL_ELEM_COOKIE,
+			md_find_name(mdp, "fru"),
+			md_find_name(mdp, "fwd"), listp);
+	if (nfrus <= 0) {
+		topo_mod_dprintf(mod, "error: nfrus=%d\n", nfrus);
+		return (-1);
+	}
+	topo_mod_dprintf(mod, "nfrus=%d\n", nfrus);
+	for (i = 0; i < nfrus; i++) {
+		if (md_get_prop_str(mdp, listp[i], "name", &pstr) == 0 &&
+		    strcmp(name, pstr) == 0) {
+			topo_mod_dprintf(mod, "found motherboard\n");
+			if (md_get_prop_str(mdp, listp[i], "serial_number",
+					    &sn) < 0)
+				sn = NULL;
+			if (md_get_prop_str(mdp, listp[i], "part_number",
+					    &pn) < 0)
+				pn = NULL;
+			if (md_get_prop_str(mdp, listp[i], "dash_number",
+					    &dn) < 0)
+				dn = NULL;
+			break;
+		}
+	}
+
+	*serialp = topo_mod_strdup(mod, sn);
+	*partp = topo_mod_alloc(mod, (strlen(dn)
+			+ strlen(pn) + 1));
+	(void) strcpy(*partp, pn);
+	if (dn != NULL)
+		(void) strcat(*partp, dn);
+
+	mb_topo_free(listp, sizeof (mde_cookie_t) * num_nodes);
+	mb_topo_free(bufp, (size_t)bufsize);
+	(void) md_fini(mdp);
+
+	return (0);
+}
+
+static void
+mb_prop_set(tnode_t *node, nvlist_t *auth)
+{
+	int err;
+	char isa[MAXNAMELEN];
+	struct utsname uts;
+	char *prod, *csn, *server;
+
+	if ((topo_pgroup_create(node, &mb_auth_pgroup, &err) != 0) &&
+	    (err != ETOPO_PROP_DEFD))
+		return;
+
+	if (nvlist_lookup_string(auth, FM_FMRI_AUTH_PRODUCT, &prod) == 0)
+		(void) topo_prop_set_string(node, FM_FMRI_AUTHORITY,
+		    FM_FMRI_AUTH_PRODUCT, TOPO_PROP_IMMUTABLE, prod, &err);
+	if (nvlist_lookup_string(auth, FM_FMRI_AUTH_CHASSIS, &csn) == 0)
+		(void) topo_prop_set_string(node, FM_FMRI_AUTHORITY,
+		    FM_FMRI_AUTH_CHASSIS, TOPO_PROP_IMMUTABLE, csn, &err);
+	if (nvlist_lookup_string(auth, FM_FMRI_AUTH_SERVER, &server) == 0)
+		(void) topo_prop_set_string(node, FM_FMRI_AUTHORITY,
+		    FM_FMRI_AUTH_SERVER, TOPO_PROP_IMMUTABLE, server, &err);
+
+	if (topo_pgroup_create(node, &mb_sys_pgroup, &err) != 0)
+		return;
+
+	isa[0] = '\0';
+	(void) sysinfo(SI_ARCHITECTURE, isa, sizeof (isa));
+	(void) uname(&uts);
+	(void) topo_prop_set_string(node, TOPO_PGROUP_SYSTEM, TOPO_PROP_ISA,
+	    TOPO_PROP_IMMUTABLE, isa, &err);
+	(void) topo_prop_set_string(node, TOPO_PGROUP_SYSTEM, TOPO_PROP_MACHINE,
+	    TOPO_PROP_IMMUTABLE, uts.machine, &err);
+}
+
+static tnode_t *
+mb_tnode_create(topo_mod_t *mod, tnode_t *parent,
+    const char *name, topo_instance_t i, void *priv)
+{
+	nvlist_t *fmri;
+	tnode_t *ntn;
+	char *serial = NULL, *part = NULL;
+	nvlist_t *auth = topo_mod_auth(mod, parent);
+	ldom_hdl_t *motherboard_lhp;
+
+	motherboard_lhp = ldom_init(mb_topo_alloc, mb_topo_free);
+
+	/* Get MB Serial Number and Part Number from PRI */
+	(void) mb_get_pri_serial_part(mod, motherboard_lhp, name,
+		&serial, &part);
+
+	fmri = topo_mod_hcfmri(mod, NULL, FM_HC_SCHEME_VERSION, name, i,
+	    NULL, auth, part, NULL, serial);
+
+	topo_mod_strfree(mod, serial);
+	topo_mod_strfree(mod, part);
+	ldom_fini(motherboard_lhp);
+
+	if (fmri == NULL) {
+		topo_mod_dprintf(mod,
+		    "Unable to make nvlist for %s bind: %s.\n",
+		    name, topo_mod_errmsg(mod));
+		return (NULL);
+	}
+
+	ntn = topo_node_bind(mod, parent, name, i, fmri);
+	if (ntn == NULL) {
+		topo_mod_dprintf(mod,
+		    "topo_node_bind (%s%d/%s%d) failed: %s\n",
+		    topo_node_name(parent), topo_node_instance(parent),
+		    name, i,
+		    topo_strerror(topo_mod_errno(mod)));
+		nvlist_free(fmri);
+		return (NULL);
+	}
+
+	mb_prop_set(ntn, auth);
+
+	nvlist_free(auth);
+	nvlist_free(fmri);
+
+	topo_node_setspecific(ntn, priv);
+
+	return (ntn);
+}
+
+/*ARGSUSED*/
+static tnode_t *
+mb_declare(tnode_t *parent, const char *name, topo_instance_t i,
+	void *priv, topo_mod_t *mp)
+{
+	tnode_t *ntn;
+	nvlist_t *fmri;
+	char *label = "MB";
+	int err;
+
+	if ((ntn = mb_tnode_create(mp, parent, name, 0, NULL)) == NULL)
+		return (NULL);
+
+	/* Set FRU */
+	if (topo_node_resource(ntn, &fmri, &err) < 0) {
+		(void) topo_mod_seterrno(mp, err);
+		topo_node_unbind(ntn);
+		return (NULL);
+	}
+	if (topo_node_fru_set(ntn, fmri, 0, &err) < 0)
+		(void) topo_mod_seterrno(mp, err);
+	nvlist_free(fmri);
+
+	/* Label is MB */
+	if (topo_prop_set_string(ntn, TOPO_PGROUP_PROTOCOL,
+		TOPO_PROP_LABEL,  TOPO_PROP_IMMUTABLE, label, &err) < 0) {
+		(void) topo_mod_seterrno(mp, err);
+	}
+
+	return (ntn);
+}
+
+/*ARGSUSED*/
+static int
+mb_enum(topo_mod_t *mod, tnode_t *pn, const char *name,
+	topo_instance_t min, topo_instance_t max, void *arg, void *notused)
+{
+	tnode_t *mbn;
+
+	if (strcmp(name, MOTHERBOARD) != 0) {
+		topo_mod_dprintf(mod,
+		    "Currently only know how to enumerate %s components.\n",
+		    MOTHERBOARD);
+		return (0);
+	}
+
+	mb_mod_hdl = mod;
+
+	mbn = mb_declare(pn, name, 0, NULL, mod);
+
+	if (mbn == NULL) {
+		topo_mod_dprintf(mod, "Enumeration of motherboard "
+			"failed: %s\n",
+			topo_strerror(topo_mod_errno(mod)));
+		return (-1); /* mod_errno already set */
+	}
+
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/topo/modules/sun4v/niu/Makefile	Fri Dec 22 12:42:28 2006 -0800
@@ -0,0 +1,39 @@
+#
+# 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"
+#
+
+MODULE = niu
+ARCH = sun4v
+CLASS = arch
+NIUSRCS = niu.c
+
+MODULESRCS = $(NIUSRCS)
+
+include ../../Makefile.plugin
+
+LDLIBS += -ldevinfo
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/topo/modules/sun4v/niu/niu.c	Fri Dec 22 12:42:28 2006 -0800
@@ -0,0 +1,255 @@
+/*
+ * 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 <string.h>
+#include <fm/topo_mod.h>
+#include <fm/topo_hc.h>
+#include <libdevinfo.h>
+#include <limits.h>
+#include <sys/fm/protocol.h>
+#include <sys/param.h>
+#include <sys/systeminfo.h>
+#include <assert.h>
+
+/*
+ * niu.c
+ *	sun4v specific niu enumerators
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define	NIU_VERSION	TOPO_VERSION
+#define	NIUFN_MAX	2
+
+static int niu_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t,
+		    topo_instance_t, void *, void *);
+
+static const topo_modops_t niu_ops =
+	{ niu_enum, NULL };
+
+const topo_modinfo_t niu_info =
+	{NIU, FM_FMRI_SCHEME_HC, NIU_VERSION, &niu_ops};
+
+static const topo_pgroup_info_t niu_auth_pgroup = {
+	FM_FMRI_AUTHORITY,
+	TOPO_STABILITY_PRIVATE,
+	TOPO_STABILITY_PRIVATE,
+	1
+};
+
+/*ARGSUSED*/
+void
+_topo_init(topo_mod_t *mod, topo_version_t version)
+{
+	/*
+	 * Turn on module debugging output
+	 */
+	if (getenv("TOPONIUDBG") != NULL)
+		topo_mod_setdebug(mod);
+	topo_mod_dprintf(mod, "initializing niu enumerator\n");
+
+	if (topo_mod_register(mod, &niu_info, TOPO_VERSION) < 0) {
+		topo_mod_dprintf(mod, "niu registration failed: %s\n",
+			topo_mod_errmsg(mod));
+		return; /* mod errno already set */
+	}
+	topo_mod_dprintf(mod, "NIU enumr initd\n");
+}
+
+void
+_topo_fini(topo_mod_t *mod)
+{
+	topo_mod_unregister(mod);
+}
+
+static tnode_t *
+niu_tnode_create(topo_mod_t *mod, tnode_t *parent,
+    const char *name, topo_instance_t i, void *priv)
+{
+	int err;
+	nvlist_t *fmri;
+	tnode_t *ntn;
+	nvlist_t *auth = topo_mod_auth(mod, parent);
+
+	fmri = topo_mod_hcfmri(mod, parent, FM_HC_SCHEME_VERSION, name, i,
+		NULL, auth, NULL, NULL, NULL);
+	nvlist_free(auth);
+
+	if (fmri == NULL) {
+		topo_mod_dprintf(mod,
+		    "Unable to make nvlist for %s bind: %s.\n",
+		    name, topo_mod_errmsg(mod));
+		return (NULL);
+	}
+
+	ntn = topo_node_bind(mod, parent, name, i, fmri);
+	if (ntn == NULL) {
+		topo_mod_dprintf(mod,
+		    "topo_node_bind (%s%d/%s%d) failed: %s\n",
+		    topo_node_name(parent), topo_node_instance(parent),
+		    name, i,
+		    topo_strerror(topo_mod_errno(mod)));
+		nvlist_free(fmri);
+		return (NULL);
+	}
+	nvlist_free(fmri);
+	topo_node_setspecific(ntn, priv);
+
+	if (topo_pgroup_create(ntn, &niu_auth_pgroup, &err) == 0) {
+		(void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY,
+		    FM_FMRI_AUTH_PRODUCT, &err);
+		(void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY,
+		    FM_FMRI_AUTH_CHASSIS, &err);
+		(void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY,
+		    FM_FMRI_AUTH_SERVER, &err);
+	}
+	return (ntn);
+}
+
+/*ARGSUSED*/
+static tnode_t *
+niu_declare(tnode_t *parent, const char *name, topo_instance_t i,
+	void *priv, topo_mod_t *mod)
+{
+	tnode_t *ntn;
+	int err;
+
+	if ((ntn = niu_tnode_create(mod, parent, name, 0, NULL)) == NULL) {
+		topo_mod_dprintf(mod, "%s ntn = NULL\n", name);
+		return (NULL);
+	}
+
+	/* inherit FRU from parent */
+	(void) topo_node_fru_set(ntn, NULL, 0, &err);
+	/* inherit parent's label */
+	if (topo_node_label_set(ntn, NULL, &err) < 0) {
+		topo_mod_dprintf(mod, "niu label error %d\n", err);
+	}
+	return (ntn);
+}
+
+/*ARGSUSED*/
+static tnode_t *
+niufn_declare(tnode_t *parent, const char *name, topo_instance_t i,
+	void *priv, topo_mod_t *mod)
+{
+	tnode_t *ntn;
+	int err;
+
+	if ((ntn = niu_tnode_create(mod, parent, name, i, priv)) == NULL)
+		return (NULL);
+
+	/* inherit FRU from parent */
+	(void) topo_node_fru_set(ntn, NULL, 0, &err);
+	/* inherit parent's label */
+	(void) topo_node_label_set(ntn, NULL, &err);
+
+	return (ntn);
+}
+
+static int
+niufn_instantiate(tnode_t *parent, const char *name, di_node_t pnode,
+	topo_mod_t *mod)
+{
+	di_node_t sib;
+	int i = 0;
+
+	if (strcmp(name, NIUFN) != 0) {
+		topo_mod_dprintf(mod,
+		    "Currently only know how to enumerate %s components.\n",
+			NIUFN);
+		return (0);
+	}
+
+	sib = di_child_node(pnode);
+	while (sib != DI_NODE_NIL) {
+		topo_mod_dprintf(mod, "Found NIUFN node %d\n", i);
+		if (niufn_declare(parent, NIUFN, i, sib, mod) == NULL) {
+			topo_mod_dprintf(mod, "Enumeration of %s=%d "
+				"failed: %s\n", NIUFN, i,
+				topo_strerror(topo_mod_errno(mod)));
+			return (-1);
+		}
+		sib = di_sibling_node(sib);
+		i++;
+	}
+	return (0);
+}
+
+/*ARGSUSED*/
+static int
+niu_enum(topo_mod_t *mod, tnode_t *rnode, const char *name,
+	topo_instance_t min, topo_instance_t max, void *arg, void *notused)
+{
+	tnode_t *niun;
+	di_node_t devtree;
+	di_node_t dnode;
+
+	if (strcmp(name, NIU) != 0) {
+		topo_mod_dprintf(mod,
+		    "Currently only know how to enumerate %s components.\n",
+		    NIU);
+		return (0);
+	}
+
+	if ((devtree = topo_mod_devinfo(mod)) == DI_NODE_NIL) {
+		topo_mod_dprintf(mod, "devinfo init failed.");
+		return (-1);
+	}
+	dnode = di_drv_first_node("niumx", devtree);
+	if (dnode != DI_NODE_NIL) {
+		topo_mod_dprintf(mod, "Found NIU node.\n");
+		niun = niu_declare(rnode, name, 0, dnode, mod);
+		if (niun == NULL) {
+			topo_mod_dprintf(mod, "Enumeration of niu failed: %s\n",
+				topo_strerror(topo_mod_errno(mod)));
+			return (-1); /* mod_errno already set */
+		}
+		if (topo_node_range_create(mod, niun, NIUFN,
+			0, NIUFN_MAX) < 0) {
+			topo_node_unbind(niun);
+			topo_mod_dprintf(mod, "child_range_add of NIUFN"
+				"failed: %s\n",
+				topo_strerror(topo_mod_errno(mod)));
+			return (-1); /* mod_errno already set */
+		}
+		if (niufn_instantiate(niun, NIUFN, dnode, mod) < 0) {
+			topo_mod_dprintf(mod, "Enumeration of niufn "
+				"failed %s\n",
+				topo_strerror(topo_mod_errno(mod)));
+		}
+	}
+	if (di_drv_next_node(dnode) != DI_NODE_NIL)
+		topo_mod_dprintf(mod,
+			"Currently only know how to enumerate one niu "
+			"components.\n");
+
+	return (0);
+}
--- a/usr/src/lib/fm/topo/modules/sun4v/pcibus/pci_sun4v.h	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/lib/fm/topo/modules/sun4v/pcibus/pci_sun4v.h	Fri Dec 22 12:42:28 2006 -0800
@@ -42,14 +42,37 @@
 	{ 226, "PCIE2" }
 };
 
+physnm_t t5120_pnms[] = {
+	/* Slot #, Label */
+	{   1, "MB/RISER1/PCIE1" },
+	{   2, "MB/RISER2/PCIE2" },
+	{   3, "MB/RISER3/PCIE3" }
+};
+
+physnm_t t5220_pnms[] = {
+	/* Slot #, Label */
+	{   1, "MB/RISER1/PCIE1" },
+	{   2, "MB/RISER2/PCIE2" },
+	{   3, "MB/RISER3/PCIE3" },
+	{   4, "MB/RISER1/PCIE4" },
+	{   5, "MB/RISER2/PCIE5" },
+	{   6, "MB/RISER3/PCIE6" }
+};
+
 pphysnm_t plat_pnames[] = {
 	{ "Sun-Fire-T200",
 	    sizeof (t200_pnms) / sizeof (physnm_t),
-	    t200_pnms }
+	    t200_pnms },
+	{ "SPARC-Enterprise-T5120",
+	    sizeof (t5120_pnms) / sizeof (physnm_t),
+	    t5120_pnms },
+	{ "SPARC-Enterprise-T5220",
+	    sizeof (t5220_pnms) / sizeof (physnm_t),
+	    t5220_pnms }
 };
 
 physlot_names_t PhyslotNMs = {
-	1,
+	3,
 	plat_pnames
 };
 
@@ -62,11 +85,17 @@
 pdevlabs_t plats_missing[] = {
 	{ "Sun-Fire-T200",
 	    sizeof (t200_missing) / sizeof (devlab_t),
-	    t200_missing }
+	    t200_missing },
+	{ "SPARC-Enterprise-T5120",
+	    0,
+	    NULL },
+	{ "SPARC-Enterprise-T5220",
+	    0,
+	    NULL }
 };
 
 missing_names_t Missing = {
-	1,
+	3,
 	plats_missing
 };
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/topo/modules/sun4v/platform-cpu/Makefile	Fri Dec 22 12:42:28 2006 -0800
@@ -0,0 +1,36 @@
+#
+# 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"
+
+MODULE = platform-cpu
+ARCH = sun4v
+CLASS = arch
+
+MODULESRCS = cpu.c
+
+include ../../Makefile.plugin
+
+CPPFLAGS += -I$(ROOT)/usr/platform/sun4v/include
+LDLIBS += -lumem -lmdesc -lldom
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/topo/modules/sun4v/platform-cpu/cpu.c	Fri Dec 22 12:42:28 2006 -0800
@@ -0,0 +1,343 @@
+/*
+ * 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 <strings.h>
+#include <umem.h>
+#include <sys/types.h>
+#include <sys/mdesc.h>
+#include <sys/fm/ldom.h>
+#include <fm/topo_mod.h>
+#include <sys/fm/protocol.h>
+
+/*
+ * Enumerates the cpu strands in a system. For each strand found, the
+ * necessary cpu-schemed nodes are constructed underneath.
+ */
+
+#define	PLATFORM_CPU_NAME	"platform-cpu"
+#define	PLATFORM_CPU_VERSION	TOPO_VERSION
+#define	CPU_NODE_NAME		"cpu"
+
+typedef struct md_cpumap {
+	uint32_t cpumap_id;		/* virtual cpuid */
+	uint32_t cpumap_pid;		/* physical cpuid */
+	uint64_t cpumap_serialno;	/* cpu serial number */
+} md_cpumap_t;
+
+typedef struct chip {
+	uint64_t *chip_serials;		/* list of cpu serial numbers */
+	md_cpumap_t *chip_cpus;		/* List of cpu maps */
+	uint32_t chip_ncpus;		/* size */
+} chip_t;
+
+
+/* Forward declaration */
+static int cpu_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t,
+    topo_instance_t, void *, void *);
+static void cpu_release(topo_mod_t *, tnode_t *);
+static int cpu_mdesc_init(topo_mod_t *mod, chip_t *chip);
+
+
+static const topo_modops_t cpu_ops =
+	{ cpu_enum, cpu_release };
+static const topo_modinfo_t cpu_info =
+	{ PLATFORM_CPU_NAME, FM_FMRI_SCHEME_CPU, PLATFORM_CPU_VERSION,
+		&cpu_ops };
+
+
+static void *
+cpu_alloc(size_t size)
+{
+	return (umem_alloc(size, UMEM_DEFAULT));
+}
+
+static void
+cpu_free(void *data, size_t size)
+{
+	umem_free(data, size);
+}
+
+int
+_topo_init(topo_mod_t *mod)
+{
+	chip_t *chip;
+
+	if (getenv("TOPOPLATFORMCPUDBG"))
+		topo_mod_setdebug(mod);
+	topo_mod_dprintf(mod, "initializing %s enumerator\n",
+			PLATFORM_CPU_NAME);
+
+	if ((chip = topo_mod_zalloc(mod, sizeof (chip_t))) == NULL)
+		return (-1);
+
+	if (cpu_mdesc_init(mod, chip) != 0) {
+		topo_mod_dprintf(mod, "failed to get cpus from the PRI/MD\n");
+		topo_mod_free(mod, chip, sizeof (chip_t));
+		return (-1);
+	}
+
+	if (topo_mod_register(mod, &cpu_info, TOPO_VERSION) != 0) {
+		topo_mod_dprintf(mod, "failed to register hc: "
+		    "%s\n", topo_mod_errmsg(mod));
+		topo_mod_free(mod, chip, sizeof (chip_t));
+		return (-1);
+	}
+	topo_mod_setspecific(mod, (void *)chip);
+
+	topo_mod_dprintf(mod, "%s enumerator inited\n", PLATFORM_CPU_NAME);
+
+	return (0);
+}
+
+void
+_topo_fini(topo_mod_t *mod)
+{
+	chip_t *chip;
+
+	chip = (chip_t *)topo_mod_getspecific(mod);
+
+	if (chip->chip_serials != NULL)
+		topo_mod_free(mod, chip->chip_serials,
+			chip->chip_ncpus * sizeof (uint64_t));
+
+	if (chip->chip_cpus != NULL)
+		topo_mod_free(mod, chip->chip_cpus,
+			chip->chip_ncpus * sizeof (md_cpumap_t));
+
+	topo_mod_free(mod, chip, sizeof (chip_t));
+
+	topo_mod_unregister(mod);
+
+}
+
+static int
+cpu_mdesc_init(topo_mod_t *mod, chip_t *chip)
+{
+	md_t *mdp;
+	mde_cookie_t *listp;
+	md_cpumap_t *mcmp;
+	int i, num_nodes, idx;
+	ssize_t bufsiz = 0;
+	uint64_t *bufp;
+	ldom_hdl_t *lhp;
+
+	lhp = ldom_init(cpu_alloc, cpu_free);
+	if ((lhp == NULL) || (bufsiz = ldom_get_core_md(lhp, &bufp)) <= 0) {
+		return (-1);
+	}
+
+	if ((mdp = md_init_intern(bufp, cpu_alloc, cpu_free)) == NULL ||
+	    (num_nodes = md_node_count(mdp)) <= 0) {
+		cpu_free(bufp, (size_t)bufsiz);
+		return (-1);
+	}
+
+	listp = topo_mod_zalloc(mod, sizeof (mde_cookie_t) * num_nodes);
+
+	chip->chip_ncpus = md_scan_dag(mdp,
+					MDE_INVAL_ELEM_COOKIE,
+					md_find_name(mdp, "cpu"),
+					md_find_name(mdp, "fwd"),
+					listp);
+	topo_mod_dprintf(mod, "Found %d cpus\n", chip->chip_ncpus);
+
+	chip->chip_cpus = topo_mod_zalloc(mod, chip->chip_ncpus *
+	    sizeof (md_cpumap_t));
+	chip->chip_serials = topo_mod_zalloc(mod, chip->chip_ncpus *
+	    sizeof (uint64_t));
+
+	for (idx = 0, mcmp = chip->chip_cpus;
+	    idx < chip->chip_ncpus;
+	    idx++, mcmp++) {
+		uint64_t tl;
+
+		if (md_get_prop_val(mdp, listp[idx], "id", &tl) < 0)
+			tl = (uint64_t)-1; /* invalid value */
+		mcmp->cpumap_id = tl;
+
+		if (md_get_prop_val(mdp, listp[idx], "pid", &tl) < 0)
+			tl = mcmp->cpumap_id;
+		mcmp->cpumap_pid = tl;
+
+		if (md_get_prop_val(mdp, listp[idx], "serial#",
+		    &mcmp->cpumap_serialno) < 0)
+			mcmp->cpumap_serialno = 0;
+
+		/* unique serial number */
+		for (i = 0; i < chip->chip_ncpus &&
+		    chip->chip_serials[i] != 0; i++) {
+			if (mcmp->cpumap_serialno == chip->chip_serials[i]) {
+				break;
+			}
+		}
+		if (i < chip->chip_ncpus && chip->chip_serials[i] == 0) {
+			chip->chip_serials[i] = mcmp->cpumap_serialno;
+			topo_mod_dprintf(mod, "chip[%d] serial is %llx\n", i,
+				chip->chip_serials[i]);
+		}
+	}
+
+	topo_mod_free(mod, listp, sizeof (mde_cookie_t) * num_nodes);
+	topo_mod_free(mod, *mdp, bufsiz);
+	(void) md_fini(mdp);
+
+	return (0);
+}
+static nvlist_t *
+cpu_fmri_create(topo_mod_t *mod, uint32_t cpuid, char *serial, uint8_t cpumask)
+{
+	int err;
+	nvlist_t *fmri;
+
+	if (topo_mod_nvalloc(mod, &fmri, NV_UNIQUE_NAME) != 0)
+		return (NULL);
+	err = nvlist_add_uint8(fmri, FM_VERSION, FM_CPU_SCHEME_VERSION);
+	err |= nvlist_add_string(fmri, FM_FMRI_SCHEME, FM_FMRI_SCHEME_CPU);
+	err |= nvlist_add_uint32(fmri, FM_FMRI_CPU_ID, cpuid);
+	err |= nvlist_add_uint8(fmri, FM_FMRI_CPU_MASK, cpumask);
+	if (serial != NULL)
+		err |= nvlist_add_string(fmri, FM_FMRI_CPU_SERIAL_ID, serial);
+	if (err != 0) {
+		nvlist_free(fmri);
+		(void) topo_mod_seterrno(mod, EMOD_FMRI_NVL);
+		return (NULL);
+	}
+
+	return (fmri);
+}
+
+static tnode_t *
+cpu_tnode_create(topo_mod_t *mod, tnode_t *parent,
+    const char *name, topo_instance_t i, char *serial, void *priv)
+{
+	int cpu_mask = 0;
+	nvlist_t *fmri;
+	tnode_t *ntn;
+
+	fmri = cpu_fmri_create(mod, i, serial, cpu_mask);
+	if (fmri == NULL) {
+		topo_mod_dprintf(mod,
+		    "Unable to make nvlist for %s bind: %s.\n",
+		    name, topo_mod_errmsg(mod));
+		return (NULL);
+	}
+
+	ntn = topo_node_bind(mod, parent, name, i, fmri);
+	if (ntn == NULL) {
+		topo_mod_dprintf(mod,
+		    "topo_node_bind (%s%d/%s%d) failed: %s\n",
+		    topo_node_name(parent), topo_node_instance(parent),
+		    name, i,
+		    topo_strerror(topo_mod_errno(mod)));
+		nvlist_free(fmri);
+		return (NULL);
+	}
+	nvlist_free(fmri);
+	topo_node_setspecific(ntn, priv);
+
+	return (ntn);
+}
+
+/*ARGSUSED*/
+static int
+cpu_create(topo_mod_t *mod, tnode_t *rnode, const char *name, chip_t *chip)
+{
+	int i;
+	int min = -1;
+	int max = -1;
+	int nerr = 0;
+	int pid;
+	char sbuf[32];
+	tnode_t *cnode;
+
+	topo_mod_dprintf(mod, "enumerating cpus\n");
+
+	/*
+	 * find the min/max id of cpus per this cmp and create a cpu range
+	 */
+	for (i = 0; i < chip->chip_ncpus; i++) {
+		if ((min < 0) || (chip->chip_cpus[i].cpumap_pid < min))
+			min = chip->chip_cpus[i].cpumap_pid;
+		if ((max < 0) || (chip->chip_cpus[i].cpumap_pid > max))
+			max = chip->chip_cpus[i].cpumap_pid;
+	}
+	if (min < 0 || max < 0)
+		return (-1);
+	topo_node_range_destroy(rnode, name);
+	if (topo_node_range_create(mod, rnode, name, 0, max+1) < 0) {
+		topo_mod_dprintf(mod, "failed to create cpu range[0,%d]: %s\n",
+					max+1, topo_mod_errmsg(mod));
+		return (-1);
+	}
+
+	/*
+	 * Create the cpu nodes
+	 */
+	for (i = 0; i < chip->chip_ncpus; i++) {
+
+		(void) snprintf(sbuf, sizeof (sbuf), "%llx",
+			chip->chip_cpus[i].cpumap_serialno);
+
+		/* physical cpuid */
+		pid = chip->chip_cpus[i].cpumap_pid;
+		cnode = cpu_tnode_create(mod, rnode, name,
+					(topo_instance_t)pid, sbuf, NULL);
+		if (cnode == NULL) {
+			topo_mod_dprintf(mod,
+					"failed to create a cpu=%d node: %s\n",
+					pid, topo_mod_errmsg(mod));
+			nerr++;
+			continue;
+		}
+
+	}
+
+	if (nerr != 0)
+		(void) topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM);
+
+	return (0);
+}
+
+/*ARGSUSED*/
+static int
+cpu_enum(topo_mod_t *mod, tnode_t *rnode, const char *name,
+    topo_instance_t min, topo_instance_t max, void *arg, void *notused)
+{
+	topo_mod_dprintf(mod, "%s enumerating %s\n", PLATFORM_CPU_NAME, name);
+	if (strcmp(name, CPU_NODE_NAME) == 0)
+		return (cpu_create(mod, rnode, name, (chip_t *)arg));
+
+	return (0);
+}
+
+/*ARGSUSED*/
+static void
+cpu_release(topo_mod_t *mp, tnode_t *node)
+{
+}
--- a/usr/src/pkgdefs/SUNWfmd/prototype_sparc	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/pkgdefs/SUNWfmd/prototype_sparc	Fri Dec 22 12:42:28 2006 -0800
@@ -109,6 +109,7 @@
 d none usr/platform/sun4v/lib/fm 755 root bin
 d none usr/platform/sun4v/lib/fm/eft 755 root bin
 f none usr/platform/sun4v/lib/fm/eft/fire.eft 444 root bin
+f none usr/platform/sun4v/lib/fm/eft/n2piu.eft 444 root bin
 d none usr/platform/sun4v/lib/fm/fmd 755 root bin
 d none usr/platform/sun4v/lib/fm/fmd/plugins 755 root bin
 f none usr/platform/sun4v/lib/fm/fmd/plugins/cpumem-diagnosis.so 555 root bin
@@ -122,8 +123,11 @@
 f none usr/platform/sun4v/lib/fm/topo/maps/sun4v-hc-topology.xml 444 root bin
 d none usr/platform/sun4v/lib/fm/topo/plugins 755 root bin
 f none usr/platform/sun4v/lib/fm/topo/plugins/chip.so 555 root bin
+f none usr/platform/sun4v/lib/fm/topo/plugins/platform-cpu.so 555 root bin
 f none usr/platform/sun4v/lib/fm/topo/plugins/hostbridge.so 555 root bin
 f none usr/platform/sun4v/lib/fm/topo/plugins/pcibus.so 555 root bin
+f none usr/platform/sun4v/lib/fm/topo/plugins/motherboard.so 555 root bin
+f none usr/platform/sun4v/lib/fm/topo/plugins/niu.so 555 root bin
 d none usr/platform/SUNW,SPARC-Enterprise 755 root sys
 d none usr/platform/SUNW,SPARC-Enterprise/lib 755 root bin
 d none usr/platform/SUNW,SPARC-Enterprise/lib/fm 755 root bin
@@ -165,3 +169,5 @@
 f none usr/platform/SUNW,Sun-Fire-T200/lib/fm/topo/maps/Sun-Fire-T1000-hc-topology.xml 444 root bin
 f none usr/platform/SUNW,Sun-Fire-T200/lib/fm/topo/maps/SPARC-Enterprise-T1000-hc-topology.xml 444 root bin
 f none usr/platform/SUNW,Sun-Fire-T200/lib/fm/topo/maps/Sun-Blade-T6300-hc-topology.xml 444 root bin
+f none usr/platform/SUNW,Sun-Fire-T200/lib/fm/topo/maps/SPARC-Enterprise-T5120-hc-topology.xml 444 root bin
+f none usr/platform/SUNW,Sun-Fire-T200/lib/fm/topo/maps/SPARC-Enterprise-T5220-hc-topology.xml 444 root bin
--- a/usr/src/pkgdefs/SUNWonmtst.v/prototype_sparc	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/pkgdefs/SUNWonmtst.v/prototype_sparc	Fri Dec 22 12:42:28 2006 -0800
@@ -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.
 #
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
@@ -61,4 +60,5 @@
 f none usr/platform/sun4v/include/sys/memtestio.h 644 root bin
 f none usr/platform/sun4v/include/sys/memtestio_v.h 644 root bin
 f none usr/platform/sun4v/include/sys/memtestio_ni.h 644 root bin
+f none usr/platform/sun4v/include/sys/memtestio_n2.h 644 root bin
 f none usr/bin/mtst 555 root bin
--- a/usr/src/uts/sparc/sys/fm/cpu/UltraSPARC-T1.h	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sparc/sys/fm/cpu/UltraSPARC-T1.h	Fri Dec 22 12:42:28 2006 -0800
@@ -40,11 +40,15 @@
 #define	FM_EREPORT_PAYLOAD_NAME_L2_AFAR		"l2-afar"
 #define	FM_EREPORT_PAYLOAD_NAME_L2_REAL_AFAR	"l2-real-afar"
 #define	FM_EREPORT_PAYLOAD_NAME_L2_SYND		"l2-synd"
+#define	FM_EREPORT_PAYLOAD_NAME_L2_ESR		"l2-esr"
+#define	FM_EREPORT_PAYLOAD_NAME_L2_EAR		"l2-ear"
 
 #define	FM_EREPORT_PAYLOAD_NAME_DRAM_AFSR	"dram-afsr"
 #define	FM_EREPORT_PAYLOAD_NAME_DRAM_AFAR	"dram-afar"
 #define	FM_EREPORT_PAYLOAD_NAME_DRAM_REAL_AFAR	"dram-real-afar"
 #define	FM_EREPORT_PAYLOAD_NAME_DRAM_SYND	"dram-synd"
+#define	FM_EREPORT_PAYLOAD_NAME_DRAM_ESR	"dram-esr"
+#define	FM_EREPORT_PAYLOAD_NAME_DRAM_EAR	"dram-ear"
 
 #define	FM_EREPORT_CPU_UST1_DAU			"dau"
 #define	FM_EREPORT_CPU_UST1_DAC			"dac"
--- a/usr/src/uts/sun4/io/px/pcie_pwr.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4/io/px/pcie_pwr.c	Fri Dec 22 12:42:28 2006 -0800
@@ -898,8 +898,10 @@
 		if (is_pcie = pcie_is_pcie(config_handle))
 			pcie_disable_errors(cdip, config_handle);
 		(void) pci_restore_config_regs(cdip);
-		if (is_pcie)
+		if (is_pcie) {
 			pcie_enable_errors(cdip, config_handle);
+			(void) pcie_enable_ce(cdip, config_handle);
+		}
 		pci_config_teardown(&config_handle);
 
 		if (ndi_prop_remove(DDI_DEV_T_NONE, cdip,
@@ -1028,8 +1030,10 @@
 		if (is_pcie = pcie_is_pcie(config_handle))
 			pcie_disable_errors(cdip, config_handle);
 		(void) pci_save_config_regs(cdip);
-		if (is_pcie)
+		if (is_pcie) {
 			pcie_enable_errors(cdip, config_handle);
+			(void) pcie_enable_ce(cdip, config_handle);
+		}
 		pci_config_teardown(&config_handle);
 	}
 	return (DDI_SUCCESS);
--- a/usr/src/uts/sun4/io/px/px_var.h	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4/io/px/px_var.h	Fri Dec 22 12:42:28 2006 -0800
@@ -141,7 +141,6 @@
 	int		px_pm_flags;
 	msiqid_t	px_pm_msiq_id;	/* EQ id for PCIE_PME_ACK_MSG Message */
 	uint32_t	px_pmetoack_ignored; /* count of PME_To_ACKs ignored */
-	uint32_t	px_pme_ignored; /* count of PME ignored */
 
 	/* CPR callback id */
 	callb_id_t	px_cprcb_id;
--- a/usr/src/uts/sun4v/Makefile.files	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/Makefile.files	Fri Dec 22 12:42:28 2006 -0800
@@ -127,7 +127,8 @@
 #
 MEMTEST_OBJS	+= memtest.o memtest_asm.o \
 			memtest_v.o memtest_v_asm.o \
-			memtest_ni.o memtest_ni_asm.o
+			memtest_ni.o memtest_ni_asm.o \
+			memtest_n2.o memtest_n2_asm.o
 
 #
 #			sun4v virtual devices
--- a/usr/src/uts/sun4v/io/niumx/niumx.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/io/niumx/niumx.c	Fri Dec 22 12:42:28 2006 -0800
@@ -259,6 +259,12 @@
 		/* add interrupt redistribution callback */
 		intr_dist_add(niumx_intr_dist, &niumxds_p->niumx_mutex);
 
+		niumxds_p->niumx_fm_cap = DDI_FM_EREPORT_CAPABLE |
+			DDI_FM_ACCCHK_CAPABLE | DDI_FM_DMACHK_CAPABLE;
+
+		ddi_fm_init(niumxds_p->dip, &niumxds_p->niumx_fm_cap,
+			&niumxds_p->niumx_fm_ibc);
+
 		ret = DDI_SUCCESS;
 		goto prop_free;
 cleanup:
@@ -289,6 +295,7 @@
 		    ddi_get_soft_state(niumx_state, ddi_get_instance(dip));
 
 		intr_dist_rem(niumx_intr_dist, &niumxds_p->niumx_mutex);
+		ddi_fm_fini(dip);
 		mutex_destroy(&niumxds_p->niumx_mutex);
 		ddi_soft_state_free(niumx_state, ddi_get_instance(dip));
 		return (DDI_SUCCESS);
--- a/usr/src/uts/sun4v/io/niumx/niumx_var.h	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/io/niumx/niumx_var.h	Fri Dec 22 12:42:28 2006 -0800
@@ -79,6 +79,8 @@
 	dev_info_t *dip;
 	devhandle_t	niumx_dev_hdl;	/* device handle */
 	kmutex_t niumx_mutex;
+	int niumx_fm_cap;
+	ddi_iblock_cookie_t niumx_fm_ibc;
 } niumx_devstate_t;
 
 #define	NIUMX_FUNC_NUM_MASK	1
--- a/usr/src/uts/sun4v/io/nxge/npi/npi_mac.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/io/nxge/npi/npi_mac.c	Fri Dec 22 12:42:28 2006 -0800
@@ -1096,7 +1096,20 @@
 				}
 				BMAC_REG_RD(handle, portn, BMAC_MAX_REG, &val);
 				val &= ~BMAC_MAX_FRAME_MASK;
-				val |= max_fsize;
+				if (max_fsize <= 0x5EE)
+					val |= 0x5EE;
+				else if ((max_fsize > 0x5EE) &&
+					(max_fsize <= 0x5F6))
+					val |= 0x5F6;
+				else if ((max_fsize > 0x5F6) &&
+					(max_fsize <= 0x7D6))
+					val |= 0x7D6;
+				else if ((max_fsize > 0x7D6) &&
+					(max_fsize <= 0x232E))
+					val |= 0x232E;
+				else if ((max_fsize > 0x232E) &&
+					(max_fsize <= 0x2406))
+					val |= 0x2406;
 				BMAC_REG_WR(handle, portn, BMAC_MAX_REG, val);
 				BMAC_REG_WR(handle, portn, BMAC_MIN_REG,
 						min_fsize);
--- a/usr/src/uts/sun4v/io/nxge/nxge_classify.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/io/nxge/nxge_classify.c	Fri Dec 22 12:42:28 2006 -0800
@@ -162,6 +162,19 @@
 	return (NXGE_OK);
 }
 
+nxge_status_t
+nxge_classify_uninit(p_nxge_t nxgep)
+{
+	nxge_status_t	status = NXGE_OK;
+
+	status = nxge_classify_exit_sw(nxgep);
+	if (status != NXGE_OK) {
+		return (status);
+	}
+
+	return (NXGE_OK);
+}
+
 /* ARGSUSED */
 uint64_t
 nxge_classify_get_cfg_value(p_nxge_t nxgep, uint8_t cfg_type,
--- a/usr/src/uts/sun4v/io/nxge/nxge_espc.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/io/nxge/nxge_espc.c	Fri Dec 22 12:42:28 2006 -0800
@@ -179,7 +179,7 @@
 		break;
 	case ESC_PHY_NONE:
 		status = NXGE_ERROR;
-		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_espc_phy_type_get:"
+		NXGE_DEBUG_MSG((nxgep, CFG_CTL, "nxge_espc_phy_type_get:"
 				"No phy type set"));
 		break;
 	default:
--- a/usr/src/uts/sun4v/io/nxge/nxge_fflp.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/io/nxge/nxge_fflp.c	Fri Dec 22 12:42:28 2006 -0800
@@ -75,14 +75,12 @@
 nxge_status_t nxge_fflp_config_vlan_table(p_nxge_t, uint16_t);
 nxge_status_t nxge_fflp_ip_class_config_all(p_nxge_t);
 nxge_status_t nxge_add_flow(p_nxge_t, flow_resource_t *);
-void nxge_handle_tcam_fragment_bug(p_nxge_t);
+static nxge_status_t nxge_tcam_handle_ip_fragment(p_nxge_t);
 nxge_status_t nxge_add_tcam_entry(p_nxge_t, flow_resource_t *);
 nxge_status_t nxge_add_fcram_entry(p_nxge_t, flow_resource_t *);
 nxge_status_t nxge_flow_get_hash(p_nxge_t, flow_resource_t *,
 			    uint32_t *, uint16_t *);
 
-nxge_status_t nxge_classify_exit_sw(p_nxge_t);
-
 nxge_status_t
 nxge_tcam_dump_entry(p_nxge_t nxgep, uint32_t location)
 {
@@ -1521,30 +1519,32 @@
 }
 
 
-void
-nxge_handle_tcam_fragment_bug(p_nxge_t nxgep)
+static nxge_status_t
+nxge_tcam_handle_ip_fragment(p_nxge_t nxgep)
 {
 	tcam_entry_t tcam_ptr;
 	tcam_location_t location;
 	uint8_t class;
+	uint32_t class_config;
 	npi_handle_t handle;
 	npi_status_t rs = NPI_SUCCESS;
 	p_nxge_hw_list_t	hw_p;
+	nxge_status_t status = NXGE_OK;
 
 	handle = nxgep->npi_reg_handle;
 	class = 0;
 	bzero((void*)&tcam_ptr, sizeof (tcam_entry_t));
 	tcam_ptr.ip4_noport_key = 1;
 	tcam_ptr.ip4_noport_mask = 1;
-	location = nxge_get_tcam_location(nxgep, class);
+	location = nxgep->function_num;
 	nxgep->classifier.fragment_bug_location = location;
 
 	if ((hw_p = nxgep->nxge_hw_p) == NULL) {
 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
-			" nxge_handle_tcam_fragment_bug:"
+			" nxge_tcam_handle_ip_fragment:"
 			" common hardware not set",
 			nxgep->niu_type));
-		return;
+		return (NXGE_ERROR);
 	}
 
 	MUTEX_ENTER(&hw_p->nxge_tcam_lock);
@@ -1554,11 +1554,11 @@
 	if (rs & NPI_FFLP_ERROR) {
 		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
-				    " nxge_handle_tcam_fragment_bug "
+				    " nxge_tcam_handle_ip_fragment "
 				    " tcam_entry write"
 				    " failed for location %d",
 				    location));
-		return;
+		return (NXGE_ERROR);
 	}
 
 	tcam_ptr.match_action.bits.ldw.rdctbl = nxgep->class_config.mac_rdcgrp;
@@ -1574,17 +1574,44 @@
 		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
 		NXGE_DEBUG_MSG((nxgep,
 				    FFLP_CTL,
-				    " nxge_handle_tcam_fragment_bug "
+				    " nxge_tcam_handle_ip_fragment "
 				    " tcam_entry write"
 				    " failed for ASC RAM location %d",
 				    location));
-		return;
+		return (NXGE_ERROR);
 	}
 
 	bcopy((void *)&tcam_ptr,
 		    (void *)&nxgep->classifier.tcam_entries[location].tce,
 		    sizeof (tcam_entry_t));
+	for (class = TCAM_CLASS_TCP_IPV4;
+		    class <= TCAM_CLASS_SCTP_IPV6; class++) {
+		class_config = nxgep->class_config.class_cfg[class];
+		class_config |= NXGE_CLASS_TCAM_LOOKUP;
+		status = nxge_fflp_ip_class_config(nxgep, class, class_config);
+
+		if (status & NPI_FFLP_ERROR) {
+			MUTEX_EXIT(&hw_p->nxge_tcam_lock);
+			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
+					"nxge_tcam_handle_ip_fragment "
+					"nxge_fflp_ip_class_config failed "
+					" class %d config %x ",
+					class, class_config));
+			return (NXGE_ERROR);
+		}
+	}
+
+	rs = npi_fflp_cfg_tcam_enable(handle);
+	if (rs & NPI_FFLP_ERROR) {
+		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
+		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
+				"nxge_tcam_handle_ip_fragment "
+			    " nxge_fflp_config_tcam_enable failed"));
+		return (NXGE_ERROR);
+	}
+
 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
+	return (NXGE_OK);
 }
 
 #ifdef lint
@@ -2122,7 +2149,13 @@
 		    "nxge_multicast_mac_assign_rdc_table failed"));
 		return (NXGE_ERROR);
 	}
-/* If requested, attach RDC table to VLAN ID */
+
+	status = nxge_tcam_handle_ip_fragment(nxgep);
+	if (status != NXGE_OK) {
+		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
+				    "nxge_tcam_handle_ip_fragment failed"));
+		return (NXGE_ERROR);
+	}
 
 	nxgep->classifier.state |= NXGE_FFLP_HW_INIT;
 
--- a/usr/src/uts/sun4v/io/nxge/nxge_fflp_hash.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/io/nxge/nxge_fflp_hash.c	Fri Dec 22 12:42:28 2006 -0800
@@ -25,11 +25,6 @@
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 #include <sys/types.h>
-
-#ifdef LINUX
-#include <stdint.h>
-#endif
-
 #include <nxge_fflp_hash.h>
 
 static void nxge_crc32c_word(uint32_t *crcptr, const uint32_t *buf, int len);
--- a/usr/src/uts/sun4v/io/nxge/nxge_fm.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/io/nxge/nxge_fm.c	Fri Dec 22 12:42:28 2006 -0800
@@ -35,211 +35,297 @@
 *nxge_fm_get_ereport_attr(nxge_fm_ereport_id_t);
 
 nxge_fm_ereport_attr_t	nxge_fm_ereport_pcs[] = {
-	{NXGE_FM_EREPORT_XPCS_LINK_DOWN,	"10g.link_down",
+	{NXGE_FM_EREPORT_XPCS_LINK_DOWN,	"10g_link_down",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_LOST},
-	{NXGE_FM_EREPORT_XPCS_TX_LINK_FAULT,	"10g.tx_link_fault",
+	{NXGE_FM_EREPORT_XPCS_TX_LINK_FAULT,	"10g_tx_link_fault",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_DEGRADED},
-	{NXGE_FM_EREPORT_XPCS_RX_LINK_FAULT,	"10g.rx_link_fault",
+	{NXGE_FM_EREPORT_XPCS_RX_LINK_FAULT,	"10g_rx_link_fault",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_DEGRADED},
-	{NXGE_FM_EREPORT_PCS_LINK_DOWN,		"1g.link_down",
+	{NXGE_FM_EREPORT_PCS_LINK_DOWN,		"1g_link_down",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_LOST},
-	{NXGE_FM_EREPORT_PCS_REMOTE_FAULT,	"1g.remote_fault",
+	{NXGE_FM_EREPORT_PCS_REMOTE_FAULT,	"1g_remote_fault",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_DEGRADED},
 };
 
 nxge_fm_ereport_attr_t	nxge_fm_ereport_mif[] = {
-	{NXGE_FM_EREPORT_MIF_ACCESS_FAIL,	"transceiver.access_fail"}
+	{NXGE_FM_EREPORT_MIF_ACCESS_FAIL,	"transceiver_access_fail"}
 };
 
 nxge_fm_ereport_attr_t nxge_fm_ereport_fflp[] = {
-	{NXGE_FM_EREPORT_FFLP_TCAM_ERR,		"classifier.tcam_err",
+	{NXGE_FM_EREPORT_FFLP_TCAM_ERR,		"classifier_tcam_err",
+						DDI_FM_DEVICE_INTERN_UNCORR,
 						DDI_SERVICE_UNAFFECTED},
-	{NXGE_FM_EREPORT_FFLP_VLAN_PAR_ERR,	"classifier.vlan_par_err",
+	{NXGE_FM_EREPORT_FFLP_VLAN_PAR_ERR,	"classifier_vlan_par_err",
+						DDI_FM_DEVICE_INTERN_UNCORR,
 						DDI_SERVICE_UNAFFECTED},
-	{NXGE_FM_EREPORT_FFLP_HASHT_DATA_ERR,	"classifier.hasht_data_err",
+	{NXGE_FM_EREPORT_FFLP_HASHT_DATA_ERR,	"classifier_hasht_data_err",
+						DDI_FM_DEVICE_INTERN_UNCORR,
 						DDI_SERVICE_UNAFFECTED},
-	{NXGE_FM_EREPORT_FFLP_HASHT_LOOKUP_ERR,	"classifier.hasht_lookup_err",
+	{NXGE_FM_EREPORT_FFLP_HASHT_LOOKUP_ERR,	"classifier_hasht_lookup_err",
+						DDI_FM_DEVICE_INTERN_UNCORR,
 						DDI_SERVICE_UNAFFECTED},
-	{NXGE_FM_EREPORT_FFLP_ACCESS_FAIL,	"classifier.access_fail",
+	{NXGE_FM_EREPORT_FFLP_ACCESS_FAIL,	"classifier_access_fail",
+						DDI_FM_DEVICE_NO_RESPONSE,
 						DDI_SERVICE_DEGRADED}
 };
 
 nxge_fm_ereport_attr_t nxge_fm_ereport_ipp[] = {
-	{NXGE_FM_EREPORT_IPP_EOP_MISS,		"rx.eop_miss",
+	{NXGE_FM_EREPORT_IPP_EOP_MISS,		"rx_eop_miss",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_LOST},
-	{NXGE_FM_EREPORT_IPP_SOP_MISS,		"rx.sop_miss",
+	{NXGE_FM_EREPORT_IPP_SOP_MISS,		"rx_sop_miss",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_LOST},
-	{NXGE_FM_EREPORT_IPP_DFIFO_UE,		"rx.dfifo_ucorr_err",
+	{NXGE_FM_EREPORT_IPP_DFIFO_UE,		"rx_dfifo_ucorr_err",
+						DDI_FM_DEVICE_INTERN_UNCORR,
 						DDI_SERVICE_LOST},
-	{NXGE_FM_EREPORT_IPP_DFIFO_CE,		"rx.dfifo_corr_err",
+	{NXGE_FM_EREPORT_IPP_DFIFO_CE,		"rx_dfifo_corr_err",
+						DDI_FM_DEVICE_INTERN_CORR,
 						DDI_SERVICE_UNAFFECTED},
-	{NXGE_FM_EREPORT_IPP_PFIFO_PERR,	"rx.dfifo_parity_err",
+	{NXGE_FM_EREPORT_IPP_PFIFO_PERR,	"rx_dfifo_parity_err",
+						DDI_FM_DEVICE_INTERN_UNCORR,
 						DDI_SERVICE_LOST},
-	{NXGE_FM_EREPORT_IPP_ECC_ERR_MAX,	"rx.ecc_err_max",
+	{NXGE_FM_EREPORT_IPP_ECC_ERR_MAX,	"rx_ecc_err_max",
+						DDI_FM_DEVICE_INTERN_UNCORR,
 						DDI_SERVICE_UNAFFECTED},
-	{NXGE_FM_EREPORT_IPP_PFIFO_OVER,	"rx.pfifo_overflow",
+	{NXGE_FM_EREPORT_IPP_PFIFO_OVER,	"rx_pfifo_overflow",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_LOST},
-	{NXGE_FM_EREPORT_IPP_PFIFO_UND,		"rx.pfifo_underrun",
+	{NXGE_FM_EREPORT_IPP_PFIFO_UND,		"rx_pfifo_underrun",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_LOST},
-	{NXGE_FM_EREPORT_IPP_BAD_CS_MX,		"rx.bad_cksum_max",
+	{NXGE_FM_EREPORT_IPP_BAD_CS_MX,		"rx_bad_cksum_max",
+						DDI_FM_DEVICE_INTERN_UNCORR,
 						DDI_SERVICE_UNAFFECTED},
-	{NXGE_FM_EREPORT_IPP_PKT_DIS_MX,	"rx.pkt_discard_max",
+	{NXGE_FM_EREPORT_IPP_PKT_DIS_MX,	"rx_pkt_discard_max",
+						DDI_FM_DEVICE_INTERN_UNCORR,
 						DDI_SERVICE_UNAFFECTED},
-	{NXGE_FM_EREPORT_IPP_RESET_FAIL,	"rx.reset_fail",
+	{NXGE_FM_EREPORT_IPP_RESET_FAIL,	"rx_reset_fail",
+						DDI_FM_DEVICE_NO_RESPONSE,
 						DDI_SERVICE_LOST}
 };
 
 nxge_fm_ereport_attr_t nxge_fm_ereport_rdmc[] = {
-	{NXGE_FM_EREPORT_RDMC_DCF_ERR,		"rxdma.dcf_err",
+	{NXGE_FM_EREPORT_RDMC_DCF_ERR,		"rxdma_dcf_err",
+						DDI_FM_DEVICE_INTERN_UNCORR,
 						DDI_SERVICE_LOST},
-	{NXGE_FM_EREPORT_RDMC_RCR_ACK_ERR,	"rxdma.rcr_ack_err",
+	{NXGE_FM_EREPORT_RDMC_RCR_ACK_ERR,	"rxdma_rcr_ack_err",
+						DDI_FM_DEVICE_INTERN_UNCORR,
 						DDI_SERVICE_DEGRADED},
-	{NXGE_FM_EREPORT_RDMC_DC_FIFO_ERR,	"rxdma.dc_fifo_err",
+	{NXGE_FM_EREPORT_RDMC_DC_FIFO_ERR,	"rxdma_dc_fifo_err",
+						DDI_FM_DEVICE_INTERN_UNCORR,
 						DDI_SERVICE_LOST},
-	{NXGE_FM_EREPORT_RDMC_RCR_SHA_PAR,	"rxdma.rcr_sha_par_err",
+	{NXGE_FM_EREPORT_RDMC_RCR_SHA_PAR,	"rxdma_rcr_sha_par_err",
+						DDI_FM_DEVICE_INTERN_UNCORR,
 						DDI_SERVICE_DEGRADED},
-	{NXGE_FM_EREPORT_RDMC_RBR_PRE_PAR,	"rxdma.rbr_pre_par_err",
+	{NXGE_FM_EREPORT_RDMC_RBR_PRE_PAR,	"rxdma_rbr_pre_par_err",
+						DDI_FM_DEVICE_INTERN_UNCORR,
 						DDI_SERVICE_DEGRADED},
-	{NXGE_FM_EREPORT_RDMC_RBR_TMOUT,	"rxdma.rbr_tmout",
+	{NXGE_FM_EREPORT_RDMC_RBR_TMOUT,	"rxdma_rbr_tmout",
+						DDI_FM_DEVICE_NO_RESPONSE,
 						DDI_SERVICE_DEGRADED},
-	{NXGE_FM_EREPORT_RDMC_RSP_CNT_ERR,	"rxdma.rsp_cnt_err",
+	{NXGE_FM_EREPORT_RDMC_RSP_CNT_ERR,	"rxdma_rsp_cnt_err",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_DEGRADED},
-	{NXGE_FM_EREPORT_RDMC_BYTE_EN_BUS,	"rxdma.byte_en_bus",
+	{NXGE_FM_EREPORT_RDMC_BYTE_EN_BUS,	"rxdma_byte_en_bus",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_DEGRADED},
-	{NXGE_FM_EREPORT_RDMC_RSP_DAT_ERR,	"rxdma.rsp_dat_err",
+	{NXGE_FM_EREPORT_RDMC_RSP_DAT_ERR,	"rxdma_rsp_dat_err",
+						DDI_FM_DEVICE_INTERN_UNCORR,
 						DDI_SERVICE_DEGRADED},
-	{NXGE_FM_EREPORT_RDMC_ID_MISMATCH,	"rxdma.id_mismatch",
+	{NXGE_FM_EREPORT_RDMC_ID_MISMATCH,	"rxdma_id_mismatch",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_LOST},
-	{NXGE_FM_EREPORT_RDMC_ZCP_EOP_ERR,	"rxdma.zcp_eop_err",
+	{NXGE_FM_EREPORT_RDMC_ZCP_EOP_ERR,	"rxdma_zcp_eop_err",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_LOST},
-	{NXGE_FM_EREPORT_RDMC_IPP_EOP_ERR,	"rxdma.ipp_eop_err",
+	{NXGE_FM_EREPORT_RDMC_IPP_EOP_ERR,	"rxdma_ipp_eop_err",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_LOST},
-	{NXGE_FM_EREPORT_RDMC_COMPLETION_ERR,	"rxdma.completion_err",
+	{NXGE_FM_EREPORT_RDMC_COMPLETION_ERR,	"rxdma_completion_err",
+						DDI_FM_DEVICE_INTERN_UNCORR,
 						DDI_SERVICE_UNAFFECTED},
-	{NXGE_FM_EREPORT_RDMC_CONFIG_ERR,	"rxdma.config_err",
+	{NXGE_FM_EREPORT_RDMC_CONFIG_ERR,	"rxdma_config_err",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_DEGRADED},
-	{NXGE_FM_EREPORT_RDMC_RCRINCON,		"rxdma.rcrincon",
+	{NXGE_FM_EREPORT_RDMC_RCRINCON,		"rxdma_rcrincon",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_DEGRADED},
-	{NXGE_FM_EREPORT_RDMC_RCRFULL,		"rxdma.rcrfull",
+	{NXGE_FM_EREPORT_RDMC_RCRFULL,		"rxdma_rcrfull",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_DEGRADED},
-	{NXGE_FM_EREPORT_RDMC_RBRFULL,		"rxdma.rbrfull",
+	{NXGE_FM_EREPORT_RDMC_RBRFULL,		"rxdma_rbrfull",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_DEGRADED},
-	{NXGE_FM_EREPORT_RDMC_RBRLOGPAGE,	"rxdma.rbrlogpage",
+	{NXGE_FM_EREPORT_RDMC_RBRLOGPAGE,	"rxdma_rbrlogpage",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_DEGRADED},
-	{NXGE_FM_EREPORT_RDMC_CFIGLOGPAGE,	"rxdma.cfiglogpage",
+	{NXGE_FM_EREPORT_RDMC_CFIGLOGPAGE,	"rxdma_cfiglogpage",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_DEGRADED}
 };
 
 nxge_fm_ereport_attr_t nxge_fm_ereport_zcp[] = {
-	{NXGE_FM_EREPORT_ZCP_RRFIFO_UNDERRUN,	"rxzcopy.rrfifo_underrun",
+	{NXGE_FM_EREPORT_ZCP_RRFIFO_UNDERRUN,	"rxzcopy_rrfifo_underrun",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_UNAFFECTED},
 	{NXGE_FM_EREPORT_ZCP_RSPFIFO_UNCORR_ERR,
-						"rxzcopy.rspfifo_uncorr_err",
+						"rxzcopy_rspfifo_uncorr_err",
+						DDI_FM_DEVICE_INTERN_UNCORR,
 						DDI_SERVICE_UNAFFECTED},
-	{NXGE_FM_EREPORT_ZCP_STAT_TBL_PERR,	"rxzcopy.stat_tbl_perr",
+	{NXGE_FM_EREPORT_ZCP_STAT_TBL_PERR,	"rxzcopy_stat_tbl_perr",
+						DDI_FM_DEVICE_INTERN_UNCORR,
 						DDI_SERVICE_UNAFFECTED},
-	{NXGE_FM_EREPORT_ZCP_DYN_TBL_PERR,	"rxzcopy.dyn_tbl_perr",
+	{NXGE_FM_EREPORT_ZCP_DYN_TBL_PERR,	"rxzcopy_dyn_tbl_perr",
+						DDI_FM_DEVICE_INTERN_UNCORR,
 						DDI_SERVICE_UNAFFECTED},
-	{NXGE_FM_EREPORT_ZCP_BUF_TBL_PERR,	"rxzcopy.buf_tbl_perr",
+	{NXGE_FM_EREPORT_ZCP_BUF_TBL_PERR,	"rxzcopy_buf_tbl_perr",
+						DDI_FM_DEVICE_INTERN_UNCORR,
 						DDI_SERVICE_UNAFFECTED},
-	{NXGE_FM_EREPORT_ZCP_CFIFO_ECC,		"rxzcopy.cfifo_ecc",
+	{NXGE_FM_EREPORT_ZCP_CFIFO_ECC,		"rxzcopy_cfifo_ecc",
+						DDI_FM_DEVICE_INTERN_CORR,
 						DDI_SERVICE_UNAFFECTED},
-	{NXGE_FM_EREPORT_ZCP_RRFIFO_OVERRUN,	"rxzcopy.rrfifo_overrun",
+	{NXGE_FM_EREPORT_ZCP_RRFIFO_OVERRUN,	"rxzcopy_rrfifo_overrun",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_UNAFFECTED},
-	{NXGE_FM_EREPORT_ZCP_BUFFER_OVERFLOW,	"rxzcopy.buffer_overflow",
+	{NXGE_FM_EREPORT_ZCP_BUFFER_OVERFLOW,	"rxzcopy_buffer_overflow",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_LOST},
-	{NXGE_FM_EREPORT_ZCP_TT_PROGRAM_ERR,	"rxzcopy.tt_program_err",
+	{NXGE_FM_EREPORT_ZCP_TT_PROGRAM_ERR,	"rxzcopy_tt_program_err",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_UNAFFECTED},
-	{NXGE_FM_EREPORT_ZCP_RSP_TT_INDEX_ERR,	"rxzcopy.rsp_tt_index_err",
+	{NXGE_FM_EREPORT_ZCP_RSP_TT_INDEX_ERR,	"rxzcopy_rsp_tt_index_err",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_UNAFFECTED},
-	{NXGE_FM_EREPORT_ZCP_SLV_TT_INDEX_ERR,	"rxzcopy.slv_tt_index_err",
+	{NXGE_FM_EREPORT_ZCP_SLV_TT_INDEX_ERR,	"rxzcopy_slv_tt_index_err",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_UNAFFECTED},
-	{NXGE_FM_EREPORT_ZCP_TT_INDEX_ERR,	"rxzcopy.tt_index_err",
+	{NXGE_FM_EREPORT_ZCP_TT_INDEX_ERR,	"rxzcopy_tt_index_err",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_UNAFFECTED},
-	{NXGE_FM_EREPORT_ZCP_ACCESS_FAIL,	"rxzcopy.access_fail",
+	{NXGE_FM_EREPORT_ZCP_ACCESS_FAIL,	"rxzcopy_access_fail",
+						DDI_FM_DEVICE_NO_RESPONSE,
 						DDI_SERVICE_LOST},
 };
 
 nxge_fm_ereport_attr_t nxge_fm_ereport_rxmac[] = {
-	{NXGE_FM_EREPORT_RXMAC_UNDERFLOW,	"rxmac.underflow",
+	{NXGE_FM_EREPORT_RXMAC_UNDERFLOW,	"rxmac_underflow",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_UNAFFECTED},
-	{NXGE_FM_EREPORT_RXMAC_CRC_ERRCNT_EXP,	"rxmac.crc_errcnt_exp",
+	{NXGE_FM_EREPORT_RXMAC_CRC_ERRCNT_EXP,	"rxmac_crc_errcnt_exp",
+						DDI_FM_DEVICE_INTERN_UNCORR,
 						DDI_SERVICE_UNAFFECTED},
 	{NXGE_FM_EREPORT_RXMAC_LENGTH_ERRCNT_EXP,
-						"rxmac.length_errcnt_exp",
+						"rxmac_length_errcnt_exp",
+						DDI_FM_DEVICE_INTERN_UNCORR,
 						DDI_SERVICE_UNAFFECTED},
-	{NXGE_FM_EREPORT_RXMAC_VIOL_ERRCNT_EXP,	"rxmac.viol_errcnt_exp",
+	{NXGE_FM_EREPORT_RXMAC_VIOL_ERRCNT_EXP,	"rxmac_viol_errcnt_exp",
+						DDI_FM_DEVICE_INTERN_UNCORR,
 						DDI_SERVICE_UNAFFECTED},
-	{NXGE_FM_EREPORT_RXMAC_RXFRAG_CNT_EXP,	"rxmac.rxfrag_cnt_exp",
+	{NXGE_FM_EREPORT_RXMAC_RXFRAG_CNT_EXP,	"rxmac_rxfrag_cnt_exp",
+						DDI_FM_DEVICE_INTERN_UNCORR,
 						DDI_SERVICE_UNAFFECTED},
-	{NXGE_FM_EREPORT_RXMAC_ALIGN_ECNT_EXP,	"rxmac.align_ecnt_exp",
+	{NXGE_FM_EREPORT_RXMAC_ALIGN_ECNT_EXP,	"rxmac_align_ecnt_exp",
+						DDI_FM_DEVICE_INTERN_UNCORR,
 						DDI_SERVICE_UNAFFECTED},
 	{NXGE_FM_EREPORT_RXMAC_LINKFAULT_CNT_EXP,
-						"rxmac.linkfault_cnt_exp",
+						"rxmac_linkfault_cnt_exp",
+						DDI_FM_DEVICE_INTERN_UNCORR,
 						DDI_SERVICE_UNAFFECTED},
-	{NXGE_FM_EREPORT_RXMAC_RESET_FAIL,	"rxmac.reset_fail",
+	{NXGE_FM_EREPORT_RXMAC_RESET_FAIL,	"rxmac_reset_fail",
+						DDI_FM_DEVICE_NO_RESPONSE,
 						DDI_SERVICE_UNAFFECTED},
 };
 
 nxge_fm_ereport_attr_t nxge_fm_ereport_tdmc[] = {
-	{NXGE_FM_EREPORT_TDMC_PREF_BUF_PAR_ERR,	"txdma.pref_buf_par_err",
+	{NXGE_FM_EREPORT_TDMC_PREF_BUF_PAR_ERR,	"txdma_pref_buf_par_err",
+						DDI_FM_DEVICE_INTERN_UNCORR,
 						DDI_SERVICE_DEGRADED},
-	{NXGE_FM_EREPORT_TDMC_MBOX_ERR,		"txdma.mbox_err",
+	{NXGE_FM_EREPORT_TDMC_MBOX_ERR,		"txdma_mbox_err",
+						DDI_FM_DEVICE_NO_RESPONSE,
 						DDI_SERVICE_DEGRADED},
-	{NXGE_FM_EREPORT_TDMC_NACK_PREF,	"txdma.nack_pref",
+	{NXGE_FM_EREPORT_TDMC_NACK_PREF,	"txdma_nack_pref",
+						DDI_FM_DEVICE_NO_RESPONSE,
 						DDI_SERVICE_DEGRADED},
-	{NXGE_FM_EREPORT_TDMC_NACK_PKT_RD,	"txdma.nack_pkt_rd",
+	{NXGE_FM_EREPORT_TDMC_NACK_PKT_RD,	"txdma_nack_pkt_rd",
+						DDI_FM_DEVICE_NO_RESPONSE,
 						DDI_SERVICE_DEGRADED},
-	{NXGE_FM_EREPORT_TDMC_PKT_SIZE_ERR,	"txdma.pkt_size_err",
+	{NXGE_FM_EREPORT_TDMC_PKT_SIZE_ERR,	"txdma_pkt_size_err",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_DEGRADED},
-	{NXGE_FM_EREPORT_TDMC_TX_RING_OFLOW,	"txdma.tx_ring_oflow",
+	{NXGE_FM_EREPORT_TDMC_TX_RING_OFLOW,	"txdma_tx_ring_oflow",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_DEGRADED},
-	{NXGE_FM_EREPORT_TDMC_CONF_PART_ERR,	"txdma.conf_part_err",
+	{NXGE_FM_EREPORT_TDMC_CONF_PART_ERR,	"txdma_conf_part_err",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_DEGRADED},
-	{NXGE_FM_EREPORT_TDMC_PKT_PRT_ERR,	"txdma.pkt_prt_err",
+	{NXGE_FM_EREPORT_TDMC_PKT_PRT_ERR,	"txdma_pkt_prt_err",
+						DDI_FM_DEVICE_INTERN_UNCORR,
 						DDI_SERVICE_DEGRADED},
-	{NXGE_FM_EREPORT_TDMC_RESET_FAIL,	"txdma.reset_fail"}
+	{NXGE_FM_EREPORT_TDMC_RESET_FAIL,	"txdma_reset_fail",
+						DDI_FM_DEVICE_NO_RESPONSE,
+						DDI_SERVICE_LOST},
 };
 
 nxge_fm_ereport_attr_t nxge_fm_ereport_txc[] = {
-	{NXGE_FM_EREPORT_TXC_RO_CORRECT_ERR,	"tx.ro_correct_err",
+	{NXGE_FM_EREPORT_TXC_RO_CORRECT_ERR,	"tx_ro_correct_err",
+						DDI_FM_DEVICE_INTERN_CORR,
 						DDI_SERVICE_UNAFFECTED},
-	{NXGE_FM_EREPORT_TXC_RO_UNCORRECT_ERR,	"tx.ro_uncorrect_err",
+	{NXGE_FM_EREPORT_TXC_RO_UNCORRECT_ERR,	"tx_ro_uncorrect_err",
+						DDI_FM_DEVICE_INTERN_UNCORR,
 						DDI_SERVICE_UNAFFECTED},
-	{NXGE_FM_EREPORT_TXC_SF_CORRECT_ERR,	"tx.sf_correct_err",
+	{NXGE_FM_EREPORT_TXC_SF_CORRECT_ERR,	"tx_sf_correct_err",
+						DDI_FM_DEVICE_INTERN_CORR,
 						DDI_SERVICE_UNAFFECTED},
-	{NXGE_FM_EREPORT_TXC_SF_UNCORRECT_ERR,	"tx.sf_uncorrect_err",
+	{NXGE_FM_EREPORT_TXC_SF_UNCORRECT_ERR,	"tx_sf_uncorrect_err",
+						DDI_FM_DEVICE_INTERN_UNCORR,
 						DDI_SERVICE_UNAFFECTED},
-	{NXGE_FM_EREPORT_TXC_ASSY_DEAD,		"tx.assembly_uncorrect_err",
+	{NXGE_FM_EREPORT_TXC_ASSY_DEAD,		"tx_assembly_uncorrect_err",
+						DDI_FM_DEVICE_INTERN_UNCORR,
 						DDI_SERVICE_UNAFFECTED},
-	{NXGE_FM_EREPORT_TXC_REORDER_ERR,	"tx.reorder_err",
+	{NXGE_FM_EREPORT_TXC_REORDER_ERR,	"tx_reorder_err",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_LOST},
 };
 
 nxge_fm_ereport_attr_t nxge_fm_ereport_txmac[] = {
-	{NXGE_FM_EREPORT_TXMAC_UNDERFLOW,	"txmac.underflow",
+	{NXGE_FM_EREPORT_TXMAC_UNDERFLOW,	"txmac_underflow",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_UNAFFECTED},
-	{NXGE_FM_EREPORT_TXMAC_OVERFLOW,	"txmac.overflow",
+	{NXGE_FM_EREPORT_TXMAC_OVERFLOW,	"txmac_overflow",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_UNAFFECTED},
-	{NXGE_FM_EREPORT_TXMAC_TXFIFO_XFR_ERR,	"txmac.txfifo_xfr_err",
+	{NXGE_FM_EREPORT_TXMAC_TXFIFO_XFR_ERR,	"txmac_txfifo_xfr_err",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_UNAFFECTED},
-	{NXGE_FM_EREPORT_TXMAC_MAX_PKT_ERR,	"txmac.max_pkt_err",
+	{NXGE_FM_EREPORT_TXMAC_MAX_PKT_ERR,	"txmac_max_pkt_err",
+						DDI_FM_DEVICE_INTERN_UNCORR,
 						DDI_SERVICE_UNAFFECTED},
-	{NXGE_FM_EREPORT_TXMAC_RESET_FAIL,	"txmac.reset_fail",
+	{NXGE_FM_EREPORT_TXMAC_RESET_FAIL,	"txmac_reset_fail",
+						DDI_FM_DEVICE_NO_RESPONSE,
 						DDI_SERVICE_UNAFFECTED},
 };
 
 nxge_fm_ereport_attr_t nxge_fm_ereport_espc[] = {
-	{NXGE_FM_EREPORT_ESPC_ACCESS_FAIL,	"eprom.access_fail",
+	{NXGE_FM_EREPORT_ESPC_ACCESS_FAIL,	"eprom_access_fail",
+						DDI_FM_DEVICE_NO_RESPONSE,
 						DDI_SERVICE_LOST},
 };
 
 nxge_fm_ereport_attr_t nxge_fm_ereport_sw[] = {
 	{NXGE_FM_EREPORT_SW_INVALID_PORT_NUM,	"invalid_port_num",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_LOST},
 	{NXGE_FM_EREPORT_SW_INVALID_CHAN_NUM,	"invalid_chan_num",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_LOST},
 	{NXGE_FM_EREPORT_SW_INVALID_PARAM,	"invalid_param",
+						DDI_FM_DEVICE_INVAL_STATE,
 						DDI_SERVICE_LOST},
 };
 
@@ -250,7 +336,7 @@
 	ddi_iblock_cookie_t iblk;
 
 	nxgep->fm_capabilities = ddi_prop_get_int(DDI_DEV_T_ANY, nxgep->dip,
-			DDI_PROP_DONTPASS, "fm-capable", 0);
+			DDI_PROP_DONTPASS, "fm-capable", 1);
 	NXGE_DEBUG_MSG((nxgep, DDI_CTL,
 		"FM capable = %d\n", nxgep->fm_capabilities));
 
@@ -491,10 +577,13 @@
 					nxge_fm_ereport_attr_t *ereport)
 {
 	uint64_t		ena;
-	char			*eclass;
+	char			eclass[FM_MAX_CLASS];
+	char			*err_str;
 	p_nxge_stats_t		statsp;
 
-	eclass = ereport->eclass;
+	(void) snprintf(eclass, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE,
+			ereport->eclass);
+	err_str = ereport->str;
 	ena = fm_ena_generate(0, FM_ENA_FMT1);
 	statsp = nxgep->statsp;
 
@@ -774,6 +863,8 @@
 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
 				DDI_NOSLEEP,
 				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
+				ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING,
+					err_str,
 				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
 				ERNAME_TXC_RO_STATE0, DATA_TYPE_UINT32,
 					(uint32_t)statsp->
@@ -849,8 +940,27 @@
 
 	if (fm_ereport_attr != NULL) {
 		nxge_fm_ereport(nxgep, err_portn, err_chan, fm_ereport_attr);
-		cmn_err(CE_NOTE, "!service_impact = %d\n",
-			fm_ereport_attr->impact);
 		ddi_fm_service_impact(nxgep->dip, fm_ereport_attr->impact);
 	}
 }
+
+int
+fm_check_acc_handle(ddi_acc_handle_t handle)
+{
+	ddi_fm_error_t err;
+
+	ddi_fm_acc_err_get(handle, &err, DDI_FME_VERSION);
+#ifndef	NXGE_FM_S10
+	ddi_fm_acc_err_clear(handle, DDI_FME_VERSION);
+#endif
+	return (err.fme_status);
+}
+
+int
+fm_check_dma_handle(ddi_dma_handle_t handle)
+{
+	ddi_fm_error_t err;
+
+	ddi_fm_dma_err_get(handle, &err, DDI_FME_VERSION);
+	return (err.fme_status);
+}
--- a/usr/src/uts/sun4v/io/nxge/nxge_hcall.s	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/io/nxge/nxge_hcall.s	Fri Dec 22 12:42:28 2006 -0800
@@ -81,9 +81,9 @@
 	mov	%o3, %g2
 	mov	N2NIU_RX_LP_INFO, %o5
 	ta	FAST_TRAP
-	stx     %o1, [%g1]
+	stx	%o1, [%g1]
 	retl
-	stx     %o2, [%g2]
+	stx	%o2, [%g2]
 	SET_SIZE(hv_niu_rx_logical_page_info)
 
 	/*
@@ -106,9 +106,9 @@
 	mov	%o3, %g2
 	mov	N2NIU_TX_LP_INFO, %o5
 	ta	FAST_TRAP
-	stx     %o1, [%g1]
+	stx	%o1, [%g1]
 	retl
-	stx     %o2, [%g2]
+	stx	%o2, [%g2]
 	SET_SIZE(hv_niu_tx_logical_page_info)
 
 #endif	/* lint || __lint */
--- a/usr/src/uts/sun4v/io/nxge/nxge_hw.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/io/nxge/nxge_hw.c	Fri Dec 22 12:42:28 2006 -0800
@@ -100,17 +100,16 @@
 nxge_hw_id_init(p_nxge_t nxgep)
 {
 	NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_hw_id_init"));
-
 	/*
 	 * Set up initial hardware parameters required such as mac mtu size.
 	 */
 	nxgep->mac.is_jumbo = B_FALSE;
 	nxgep->mac.maxframesize = NXGE_MTU_DEFAULT_MAX; /* 1522 */
-	if (nxge_jumbo_enable) {
-		nxgep->mac.maxframesize = nxge_jumbo_mtu +
-			sizeof (ether_header_t) + ETHERFCSL;
+	if (nxgep->param_arr[param_accept_jumbo].value || nxge_jumbo_enable) {
+		nxgep->mac.maxframesize = (uint16_t)nxge_jumbo_mtu;
 		nxgep->mac.is_jumbo = B_TRUE;
 	}
+
 	NXGE_DEBUG_MSG((nxgep, DDI_CTL,
 		"==> nxge_hw_id_init: maxframesize %d",
 		nxgep->mac.maxframesize));
@@ -974,20 +973,32 @@
 
 	NXGE_DEBUG_MSG((nxgep, SYSERR_CTL, "==> nxge_check_hw_state"));
 
+	MUTEX_ENTER(nxgep->genlock);
+	nxgep->nxge_timerid = 0;
+	if (!(nxgep->drv_state & STATE_HW_INITIALIZED)) {
+		goto nxge_check_hw_state_exit;
+	}
+
 	nxge_check_tx_hang(nxgep);
 
 	ldgvp = nxgep->ldgvp;
 	if (ldgvp == NULL || (ldgvp->ldvp_syserr == NULL)) {
 		NXGE_ERROR_MSG((nxgep, SYSERR_CTL, "<== nxge_check_hw_state: "
 			"NULL ldgvp (interrupt not ready)."));
-		return;
+		goto nxge_check_hw_state_exit;
 	}
+
 	t_ldvp = ldgvp->ldvp_syserr;
 	if (!t_ldvp->use_timer) {
 		NXGE_DEBUG_MSG((nxgep, SYSERR_CTL, "<== nxge_check_hw_state: "
 			"ldgvp $%p t_ldvp $%p use_timer flag %d",
 			ldgvp, t_ldvp, t_ldvp->use_timer));
-		return;
+		goto nxge_check_hw_state_exit;
+	}
+
+	if (fm_check_acc_handle(nxgep->dev_regs->nxge_regh) != DDI_FM_OK) {
+		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
+			"port%d Bad register acc handle", nxgep->mac.portnum));
 	}
 
 	(void) nxge_syserr_intr((void *)t_ldvp, (void *)nxgep);
@@ -995,6 +1006,8 @@
 	nxgep->nxge_timerid = nxge_start_timer(nxgep, nxge_check_hw_state,
 		NXGE_CHECK_TIMER);
 
+nxge_check_hw_state_exit:
+	MUTEX_EXIT(nxgep->genlock);
 	NXGE_DEBUG_MSG((nxgep, SYSERR_CTL, "<== nxge_check_hw_state"));
 }
 
--- a/usr/src/uts/sun4v/io/nxge/nxge_ipp.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/io/nxge/nxge_ipp.c	Fri Dec 22 12:42:28 2006 -0800
@@ -28,6 +28,8 @@
 #include <nxge_impl.h>
 #include <nxge_ipp.h>
 
+#define	NXGE_IPP_FIFO_SYNC_TRY_COUNT 100
+
 nxge_status_t
 nxge_ipp_init(p_nxge_t nxgep)
 {
@@ -127,20 +129,46 @@
 	uint32_t	config;
 	npi_handle_t	handle;
 	npi_status_t	rs = NPI_SUCCESS;
+	uint16_t wr_ptr, rd_ptr;
+	uint32_t try_count;
 
 	handle = nxgep->npi_handle;
 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
 
 	NXGE_DEBUG_MSG((nxgep, IPP_CTL, "==> nxge_ipp_disable: port%d", portn));
+	(void) nxge_rx_mac_disable(nxgep);
+
+	/*
+	 * Wait until ip read and write fifo pointers
+	 * are equal
+	 */
+	(void) npi_ipp_get_dfifo_rd_ptr(handle, portn, &rd_ptr);
+	(void) npi_ipp_get_dfifo_wr_ptr(handle, portn, &wr_ptr);
+	try_count = NXGE_IPP_FIFO_SYNC_TRY_COUNT;
+
+	while ((try_count > 0) && (rd_ptr != wr_ptr)) {
+		(void) npi_ipp_get_dfifo_rd_ptr(handle, portn, &rd_ptr);
+		(void) npi_ipp_get_dfifo_wr_ptr(handle, portn, &wr_ptr);
+		try_count--;
+	}
+
+	if (try_count == 0) {
+		if ((rd_ptr != 0) && (wr_ptr != 1)) {
+			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
+				    " nxge_ipp_disable: port%d failed"
+				    " rd_fifo != wr_fifo", portn));
+			goto fail;
+		}
+	}
+
 
 	/* disable the IPP */
 	config = nxgep->ipp.config;
 	if ((rs = npi_ipp_config(handle, DISABLE, portn, config))
-							!= NPI_SUCCESS) {
+					!= NPI_SUCCESS) {
 		goto fail;
 	}
 
-/* add code to reset control FIFO */
 	/* IPP soft reset */
 	if ((rs = npi_ipp_reset(handle, portn)) != NPI_SUCCESS) {
 		goto fail;
@@ -183,7 +211,7 @@
 	 */
 	(void) npi_ipp_get_dfifo_rd_ptr(handle, portn, &rd_ptr);
 	(void) npi_ipp_get_dfifo_wr_ptr(handle, portn, &wr_ptr);
-	try_count = 10;
+	try_count = NXGE_IPP_FIFO_SYNC_TRY_COUNT;
 
 	while ((try_count > 0) && (rd_ptr != wr_ptr)) {
 		(void) npi_ipp_get_dfifo_rd_ptr(handle, portn, &rd_ptr);
@@ -192,10 +220,12 @@
 	}
 
 	if (try_count == 0) {
-		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
-				    " nxge_ipp_reset: port%d failed"
+		if ((rd_ptr != 0) && (wr_ptr != 1)) {
+			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
+				    " nxge_ipp_disable: port%d failed"
 				    " rd_fifo != wr_fifo", portn));
-		goto fail;
+			goto fail;
+		}
 	}
 
 	/* IPP soft reset */
@@ -321,25 +351,25 @@
 		rxport_fatal = B_TRUE;
 	}
 	if (istatus.bits.w0.dfifo_uncorr_ecc_err) {
-		statsp->dfifo_ue++;
-		if ((rs = npi_ipp_get_ecc_syndrome(handle, portn,
+		boolean_t ue_ecc_valid;
+
+		if ((status = nxge_ipp_eccue_valid_check(nxgep, &ue_ecc_valid))
+								!= NXGE_OK)
+
+			return (status);
+
+		if (ue_ecc_valid) {
+			statsp->dfifo_ue++;
+			if ((rs = npi_ipp_get_ecc_syndrome(handle, portn,
 					&errlogp->ecc_syndrome)) != NPI_SUCCESS)
-			return (NXGE_ERROR | rs);
-		NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
+				return (NXGE_ERROR | rs);
+			NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
 					NXGE_FM_EREPORT_IPP_DFIFO_UE);
-		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
+			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
 				"nxge_ipp_err_evnts: fatal error: dfifo_ue\n"));
-		rxport_fatal = B_TRUE;
+			rxport_fatal = B_TRUE;
+		}
 	}
-#ifdef IPP_ECC_CORR_ERR
-	if (istatus.bits.w0.dfifo_corr_ecc_err) {
-		/*
-		 * Do nothing here. ECC errors are collected from the
-		 * ECC counter.
-		 */
-		;
-	}
-#endif
 	if (istatus.bits.w0.pre_fifo_perr) {
 		statsp->pfifo_perr++;
 		NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
@@ -349,14 +379,6 @@
 			"nxge_ipp_err_evnts: fatal error: pre_pifo_perr\n"));
 		rxport_fatal = B_TRUE;
 	}
-	if (istatus.bits.w0.ecc_err_cnt_ovfl) {
-		statsp->ecc_err_cnt += IPP_ECC_CNT_MASK;
-		NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
-					NXGE_FM_EREPORT_IPP_ECC_ERR_MAX);
-		if (statsp->ecc_err_cnt < (IPP_MAX_ERR_SHOW * IPP_ECC_CNT_MASK))
-			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
-				"nxge_ipp_err_evnts: ecc_err_max\n"));
-	}
 	if (istatus.bits.w0.pre_fifo_overrun) {
 		statsp->pfifo_over++;
 		NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
@@ -406,11 +428,9 @@
 			    " fatal Error on  Port #%d\n",
 			    portn));
 		status = nxge_ipp_fatal_err_recover(nxgep);
-#ifdef	NXGE_FM
 		if (status == NXGE_OK) {
 			FM_SERVICE_RESTORED(nxgep);
 		}
-#endif
 	}
 
 	return (status);
@@ -604,3 +624,67 @@
 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "Recovery failed"));
 	return (status | rs);
 }
+
+
+nxge_status_t
+nxge_ipp_eccue_valid_check(p_nxge_t nxgep, boolean_t *valid)
+{
+	npi_handle_t handle;
+	npi_status_t rs = NPI_SUCCESS;
+	uint8_t portn;
+	uint16_t rd_ptr;
+	uint16_t wr_ptr;
+	uint16_t curr_rd_ptr;
+	uint16_t curr_wr_ptr;
+	uint32_t stall_cnt;
+	uint32_t d0, d1, d2, d3, d4;
+
+	handle = nxgep->npi_handle;
+	portn = nxgep->mac.portnum;
+	*valid = B_TRUE;
+
+	if ((rs = npi_ipp_get_dfifo_rd_ptr(handle, portn, &rd_ptr))
+							!= NPI_SUCCESS)
+		goto fail;
+	if ((rs = npi_ipp_get_dfifo_rd_ptr(handle, portn, &wr_ptr))
+							!= NPI_SUCCESS)
+		goto fail;
+
+	if (rd_ptr == wr_ptr) {
+		cmn_err(CE_NOTE,
+			"nxge_ipp_eccue_valid_check: rd_ptr = %d wr_ptr = %d\n",
+			rd_ptr, wr_ptr);
+		*valid = B_FALSE;	/* IPP not stuck */
+	} else {
+		stall_cnt = 0;
+		while (stall_cnt < 16) {
+			if ((rs = npi_ipp_get_dfifo_rd_ptr(handle, portn,
+								&curr_rd_ptr))
+							!= NPI_SUCCESS)
+				goto fail;
+			if ((rs = npi_ipp_get_dfifo_wr_ptr(handle, portn,
+								&curr_wr_ptr))
+							!= NPI_SUCCESS)
+				goto fail;
+
+			if ((rd_ptr == curr_rd_ptr) && (wr_ptr == curr_wr_ptr))
+				stall_cnt++;
+			else {
+				*valid = B_FALSE;
+				break;
+			}
+		}
+
+		if (valid) {	/* futher check to see if ECC UE is valid */
+			if ((rs = npi_ipp_read_dfifo(handle, portn, rd_ptr, &d0,
+					&d1, &d2, &d3, &d4)) != NPI_SUCCESS)
+				goto fail;
+			if ((d4 & 0x1) == 0)	/* Not the 1st line */
+				*valid = B_FALSE;
+		}
+	}
+
+	return (NXGE_OK);
+fail:
+	return (NXGE_ERROR | rs);
+}
--- a/usr/src/uts/sun4v/io/nxge/nxge_kstats.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/io/nxge/nxge_kstats.c	Fri Dec 22 12:42:28 2006 -0800
@@ -318,10 +318,12 @@
 	XMAC_STAT_TX_PAUSE_STATE,
 	XMAC_STAT_TX_NOPAUSE_STATE,
 	XMAC_STAT_XPCS_DESKEW_ERR_CNT,
+#ifdef	NXGE_DEBUG_SYMBOL_ERR
 	XMAC_STAT_XPCS_SYMBOL_L0_ERR_CNT,
 	XMAC_STAT_XPCS_SYMBOL_L1_ERR_CNT,
 	XMAC_STAT_XPCS_SYMBOL_L2_ERR_CNT,
 	XMAC_STAT_XPCS_SYMBOL_L3_ERR_CNT,
+#endif
 	XMAC_STAT_END
 } nxge_xmac_stat_index_t;
 
@@ -363,6 +365,7 @@
 	{XMAC_STAT_TX_NOPAUSE_STATE, KSTAT_DATA_ULONG,	"txmac_nopause_state"},
 	{XMAC_STAT_XPCS_DESKEW_ERR_CNT,
 				KSTAT_DATA_ULONG,	"xpcs_deskew_err_cnt"},
+#ifdef	NXGE_DEBUG_SYMBOL_ERR
 	{XMAC_STAT_XPCS_SYMBOL_L0_ERR_CNT,
 				KSTAT_DATA_ULONG, "xpcs_ln0_symbol_err_cnt"},
 	{XMAC_STAT_XPCS_SYMBOL_L1_ERR_CNT,
@@ -371,6 +374,7 @@
 				KSTAT_DATA_ULONG, "xpcs_ln2_symbol_err_cnt"},
 	{XMAC_STAT_XPCS_SYMBOL_L3_ERR_CNT,
 				KSTAT_DATA_ULONG, "xpcs_ln3_symbol_err_cnt"},
+#endif
 	{XMAC_STAT_END,		NULL,			NULL}
 };
 
@@ -857,6 +861,7 @@
 				xmac_kstatsp->rx_remote_fault_err_cnt.value.ul;
 		statsp->xpcs_deskew_err_cnt =
 				xmac_kstatsp->xpcs_deskew_err_cnt.value.ul;
+#ifdef	NXGE_DEBUG_SYMBOL_ERR
 		statsp->xpcs_ln0_symbol_err_cnt =
 				xmac_kstatsp->xpcs_ln0_symbol_err_cnt.value.ul;
 		statsp->xpcs_ln1_symbol_err_cnt =
@@ -865,6 +870,7 @@
 				xmac_kstatsp->xpcs_ln2_symbol_err_cnt.value.ul;
 		statsp->xpcs_ln3_symbol_err_cnt =
 				xmac_kstatsp->xpcs_ln3_symbol_err_cnt.value.ul;
+#endif
 	} else {
 		xmac_kstatsp->tx_frame_cnt.value.ul = statsp->tx_frame_cnt;
 		xmac_kstatsp->tx_underflow_err.value.ul =
@@ -903,6 +909,7 @@
 				statsp->rx_remotefault_err;
 		xmac_kstatsp->xpcs_deskew_err_cnt.value.ul =
 				statsp->xpcs_deskew_err_cnt;
+#ifdef	NXGE_DEBUG_SYMBOL_ERR
 		xmac_kstatsp->xpcs_ln0_symbol_err_cnt.value.ul =
 				statsp->xpcs_ln0_symbol_err_cnt;
 		xmac_kstatsp->xpcs_ln1_symbol_err_cnt.value.ul =
@@ -911,6 +918,7 @@
 				statsp->xpcs_ln2_symbol_err_cnt;
 		xmac_kstatsp->xpcs_ln3_symbol_err_cnt.value.ul =
 				statsp->xpcs_ln3_symbol_err_cnt;
+#endif
 	}
 	NXGE_DEBUG_MSG((nxgep, KST_CTL, "<== nxge_xmac_stat_update"));
 	return (0);
@@ -1670,6 +1678,7 @@
 
 	kstat_named_init(&nxgekp->xpcs_deskew_err_cnt,	"xpcs_deskew_err_cnt",
 			KSTAT_DATA_ULONG);
+#ifdef	NXGE_DEBUG_SYMBOL_ERR
 	kstat_named_init(&nxgekp->xpcs_ln0_symbol_err_cnt,
 						"xpcs_ln0_symbol_err_cnt",
 			KSTAT_DATA_ULONG);
@@ -1682,6 +1691,7 @@
 	kstat_named_init(&nxgekp->xpcs_ln3_symbol_err_cnt,
 						"xpcs_ln3_symbol_err_cnt",
 			KSTAT_DATA_ULONG);
+#endif
 }
 
 void
@@ -2325,7 +2335,6 @@
 nxge_save_cntrs(p_nxge_t nxgep)
 {
 	p_nxge_stats_t 		statsp;
-	ddi_devstate_t 		dev_stat;
 	uint64_t		val;
 	npi_handle_t		handle;
 	uint8_t			portn;
@@ -2335,11 +2344,6 @@
 
 	NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_save_cntrs"));
 
-	dev_stat = FM_GET_DEVSTATE(nxgep);
-	if (dev_stat < DDI_DEVSTATE_DEGRADED) {
-		goto nxge_save_cntrs_exit;
-	}
-
 	statsp = (p_nxge_stats_t)nxgep->statsp;
 	handle = nxgep->npi_handle;
 	portn = nxgep->mac.portnum;
@@ -2404,6 +2408,7 @@
 					XPCS_REG_DESCWERR_COUNTER, &cnt32);
 		statsp->xmac_stats.xpcs_deskew_err_cnt +=
 					(val & XMAC_XPCS_DESKEW_ERR_CNT_MASK);
+#ifdef	NXGE_DEBUG_SYMBOL_ERR
 		(void) npi_xmac_xpcs_read(handle, portn,
 				XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &cnt32);
 		statsp->xmac_stats.xpcs_ln0_symbol_err_cnt +=
@@ -2418,6 +2423,7 @@
 		statsp->xmac_stats.xpcs_ln3_symbol_err_cnt +=
 				((cnt32 & XMAC_XPCS_SYM_ERR_CNT_L3_MASK) >>
 					XMAC_XPCS_SYM_ERR_CNT_L3_SHIFT);
+#endif
 	} else if (nxgep->mac.porttype == PORT_TYPE_BMAC) {
 		/*
 		 * Transmit MAC statistics.
--- a/usr/src/uts/sun4v/io/nxge/nxge_mac.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/io/nxge/nxge_mac.c	Fri Dec 22 12:42:28 2006 -0800
@@ -853,9 +853,9 @@
 {
 	p_nxge_param_t		param_arr;
 	p_nxge_stats_t		statsp;
-	uint8_t			portn;
 	uint16_t		val;
 #ifdef	NXGE_DEBUG
+	uint8_t			portn;
 	uint16_t		val1;
 #endif
 	uint8_t			phy_port_addr;
@@ -866,8 +866,9 @@
 	uint32_t		delay = 0;
 	optics_dcntr_t		op_ctr;
 	nxge_status_t		status = NXGE_OK;
-
+#ifdef	NXGE_DEBUG
 	portn = nxgep->mac.portnum;
+#endif
 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>", portn));
 
 	param_arr = nxgep->param_arr;
@@ -1005,33 +1006,6 @@
 			goto fail;
 
 
-		if (((nxgep->board_ver < 4) && (portn == 1)) &&
-			((nxgep->niu_type == NEPTUNE) ||
-			(nxgep->niu_type == NEPTUNE_2))) {
-			/*
-			 * XAUI signals' polarity on Channel 0 to 2 are swapped
-			 * on port 1 due to routing.
-			 */
-			if ((status = nxge_mdio_write(nxgep,
-					phy_port_addr,
-					BCM8704_USER_DEV4_ADDR,
-					BCM8704_USER_RX2_CONTROL1_REG,
-					BCM8704_RXPOL_FLIP)) != NXGE_OK)
-				goto fail;
-			if ((status = nxge_mdio_write(nxgep,
-					phy_port_addr,
-					BCM8704_USER_DEV4_ADDR,
-					BCM8704_USER_RX1_CONTROL1_REG,
-					BCM8704_RXPOL_FLIP)) != NXGE_OK)
-				goto fail;
-			if ((status = nxge_mdio_write(nxgep,
-					phy_port_addr,
-					BCM8704_USER_DEV4_ADDR,
-					BCM8704_USER_RX0_CONTROL1_REG,
-					BCM8704_RXPOL_FLIP)) != NXGE_OK)
-				goto fail;
-		}
-
 		/* Enable Tx and Rx LEDs to be driven by traffic */
 		if ((status = nxge_mdio_read(nxgep,
 					phy_port_addr,
@@ -1188,7 +1162,7 @@
 			portn));
 
 	/* Set Max and Min Frame Size */
-	if (nxge_jumbo_enable) {
+	if (nxgep->param_arr[param_accept_jumbo].value || nxge_jumbo_enable) {
 		SET_MAC_ATTR2(handle, ap, portn,
 		    MAC_PORT_FRAME_SIZE, 64, 0x2400, rs);
 	} else {
@@ -1198,8 +1172,8 @@
 
 	if (rs != NPI_SUCCESS)
 		goto fail;
-	nxgep->mac.is_jumbo = B_FALSE;
-	if (nxgep->mac.is_jumbo == B_TRUE)
+	if (nxgep->param_arr[param_accept_jumbo].value ||
+		nxgep->mac.is_jumbo == B_TRUE)
 		nxgep->mac.maxframesize = 0x2400;
 	else
 		nxgep->mac.maxframesize = 0x5EE + 4;
@@ -2506,7 +2480,7 @@
 	mii_anlpar_t anlpar;
 	mii_gsr_t gsr;
 	p_mii_regs_t mii_regs;
-	ddi_devstate_t dev_stat;
+
 	nxge_status_t status = NXGE_OK;
 	uint8_t portn;
 
@@ -2519,11 +2493,6 @@
 
 	RW_ENTER_WRITER(&nxgep->filter_lock);
 
-	dev_stat = FM_GET_DEVSTATE(nxgep);
-
-	if (dev_stat < DDI_DEVSTATE_DEGRADED) {
-		goto nxge_check_mii_link_exit;
-	}
 	if (nxgep->statsp->port_stats.lb_mode > nxge_lb_ext10)
 		goto nxge_check_mii_link_exit;
 
@@ -2572,10 +2541,6 @@
 	nxgep->bmsr.value = bmsr_data.value;
 	if ((status = nxge_mii_check(nxgep, bmsr_data, bmsr_ints)) != NXGE_OK)
 		goto fail;
-	if (FM_CHECK_DEV_HANDLE(nxgep) != DDI_SUCCESS) {
-		FM_REPORT_FAULT(nxgep, SERVICE_LOST, DEVICE_FAULT,
-		"register access fault detected in nxge_check_mii_link");
-	}
 
 nxge_check_mii_link_exit:
 	RW_EXIT(&nxgep->filter_lock);
@@ -2602,7 +2567,7 @@
 nxge_check_10g_link(p_nxge_t nxgep)
 {
 	uint8_t		portn;
-	ddi_devstate_t	dev_stat;
+
 	nxge_status_t	status = NXGE_OK;
 	boolean_t	link_up;
 
@@ -2611,12 +2576,6 @@
 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_10g_link port<%d>",
 				portn));
 
-	dev_stat = FM_GET_DEVSTATE(nxgep);
-
-	if (dev_stat < DDI_DEVSTATE_DEGRADED) {
-		goto fail;
-	}
-
 	status = nxge_check_bcm8704_link(nxgep, &link_up);
 
 	if (status != NXGE_OK)
@@ -2647,11 +2606,6 @@
 		}
 	}
 
-	if (FM_CHECK_DEV_HANDLE(nxgep) != DDI_SUCCESS) {
-		FM_REPORT_FAULT(nxgep, SERVICE_LOST, DEVICE_FAULT,
-		"register access fault detected in nxge_check_mii_link");
-	}
-
 	(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_10g_link port<%d>",
 				portn));
@@ -2679,11 +2633,6 @@
 	(void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link down",
 			statsp->mac_stats.xcvr_portn);
 
-	if (nxge_no_msg == 0) {
-		FM_REPORT_FAULT(nxgep, SERVICE_DEGRADED, EXTERNAL_FAULT,
-				link_stat_msg);
-	}
-
 	mac_link_update(nxgep->mach, LINK_STATE_DOWN);
 
 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_down"));
@@ -2714,11 +2663,6 @@
 
 	(void) nxge_xif_init(nxgep);
 
-	if (nxge_no_msg == 0) {
-		FM_REPORT_FAULT(nxgep, SERVICE_RESTORED, EXTERNAL_FAULT,
-					link_stat_msg);
-	}
-
 	/* Clean up symbol errors incurred during link transition */
 	if (nxgep->mac.portmode == PORT_10G_FIBER) {
 		(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
--- a/usr/src/uts/sun4v/io/nxge/nxge_main.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/io/nxge/nxge_main.c	Fri Dec 22 12:42:28 2006 -0800
@@ -29,6 +29,7 @@
  * SunOs MT STREAMS NIU/Neptune 10Gb Ethernet Device Driver.
  */
 #include	<sys/nxge/nxge_impl.h>
+#include	<sys/pcie.h>
 
 uint32_t 	nxge_use_partition = 0;		/* debug partition flag */
 uint32_t 	nxge_dma_obp_props_only = 1;	/* use obp published props */
@@ -470,7 +471,7 @@
 	status = nxge_get_xcvr_type(nxgep);
 
 	if (status != NXGE_OK) {
-		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_attach: "
+		NXGE_DEBUG_MSG((nxgep, NXGE_DDI_CTL, "nxge_attach: "
 				    " Couldn't determine card type"
 				    " .... exit "));
 		goto nxge_attach_fail;
@@ -754,6 +755,10 @@
 #endif
 	off_t		regsize;
 	nxge_status_t	status = NXGE_OK;
+#if !defined(_BIG_ENDIAN)
+	off_t pci_offset;
+	uint16_t pcie_devctl;
+#endif
 
 	NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_map_regs"));
 	nxgep->dev_regs = NULL;
@@ -831,9 +836,15 @@
 			 * resulting, in DMA not synched properly
 			 */
 #if !defined(_BIG_ENDIAN)
-		/* workarounds */
-		pci_config_put16(dev_regs->nxge_pciregh, 0x88, 0x80f);
+		/* workarounds for x86 systems */
+		pci_offset = 0x80 + PCIE_DEVCTL;
+		pcie_devctl = 0x0;
+		pcie_devctl &= PCIE_DEVCTL_ENABLE_NO_SNOOP;
+		pcie_devctl |= PCIE_DEVCTL_RO_EN;
+		pci_config_put16(dev_regs->nxge_pciregh, pci_offset,
+				    pcie_devctl);
 #endif
+
 		(void) ddi_dev_regsize(nxgep->dip, 1, &regsize);
 		NXGE_DEBUG_MSG((nxgep, DDI_CTL,
 			"nxge_map_regs: pio size 0x%x", regsize));
@@ -1155,6 +1166,10 @@
 
 	NXGE_DEBUG_MSG((nxgep, STR_CTL, "==> nxge_init"));
 
+	if (nxgep->drv_state & STATE_HW_INITIALIZED) {
+		return (status);
+	}
+
 	/*
 	 * Allocate system memory for the receive/transmit buffer blocks
 	 * and receive/transmit descriptor rings.
@@ -1574,6 +1589,13 @@
 	}
 
 	status = nxge_link_init(nxgep);
+
+	if (fm_check_acc_handle(nxgep->dev_regs->nxge_regh) != DDI_FM_OK) {
+		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
+			"port%d Bad register acc handle", nxgep->mac.portnum));
+		status = NXGE_ERROR;
+	}
+
 	if (status != NXGE_OK) {
 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
 			    " nxge_setup_dev status "
@@ -2873,20 +2895,15 @@
 	NXGE_DEBUG_MSG((nxgep, NXGE_CTL, "==> nxge_m_start"));
 
 	MUTEX_ENTER(nxgep->genlock);
-	if (nxgep->drv_state & STATE_HW_INITIALIZED) {
-		NXGE_DEBUG_MSG((nxgep, NXGE_CTL,
-			"<== nxge_m_start: hardware already initialized"));
-		MUTEX_EXIT(nxgep->genlock);
-		return (EINVAL);
-	}
-
-	if (nxge_init(nxgep) != DDI_SUCCESS) {
+	if (nxge_init(nxgep) != NXGE_OK) {
 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
 			"<== nxge_m_start: initialization failed"));
 		MUTEX_EXIT(nxgep->genlock);
 		return (EIO);
 	}
 
+	if (nxgep->nxge_mac_state == NXGE_MAC_STARTED)
+		goto nxge_m_start_exit;
 	/*
 	 * Start timer to check the system error and tx hangs
 	 */
@@ -2895,9 +2912,9 @@
 
 	nxgep->nxge_mac_state = NXGE_MAC_STARTED;
 
+nxge_m_start_exit:
 	MUTEX_EXIT(nxgep->genlock);
 	NXGE_DEBUG_MSG((nxgep, NXGE_CTL, "<== nxge_m_start"));
-
 	return (0);
 }
 
@@ -3122,10 +3139,22 @@
 	p_rx_rcr_rings_t	rcr_rings;
 	p_rx_rcr_ring_t		*rcr_p;
 	uint32_t		i, ndmas;
+	nxge_status_t		status;
 
 	NXGE_DEBUG_MSG((nxgep, RX_CTL, "==> nxge_m_resources"));
 
 	MUTEX_ENTER(nxgep->genlock);
+
+	/*
+	 * CR 6492541 Check to see if the drv_state has been intialized,
+	 * if not * call nxge_init().
+	 */
+	if (!(nxgep->drv_state & STATE_HW_INITIALIZED)) {
+		status = nxge_init(nxgep);
+		if (status != NXGE_OK)
+			goto nxge_m_resources_exit;
+	}
+
 	mrf.mrf_type = MAC_RX_FIFO;
 	mrf.mrf_blank = nxge_rx_hw_blank;
 	mrf.mrf_arg = (void *)nxgep;
@@ -3136,6 +3165,9 @@
 	rcr_p = rcr_rings->rcr_rings;
 	ndmas = rcr_rings->ndmas;
 
+	/*
+	 * Export our receive resources to the MAC layer.
+	 */
 	for (i = 0; i < ndmas; i++) {
 		((p_rx_rcr_ring_t)rcr_p[i])->rcr_mac_handle =
 				mac_resource_add(nxgep->mach,
@@ -3149,8 +3181,8 @@
 			((p_rx_rcr_ring_t)rcr_p[i])->rcr_mac_handle));
 	}
 
+nxge_m_resources_exit:
 	MUTEX_EXIT(nxgep->genlock);
-
 	NXGE_DEBUG_MSG((nxgep, RX_CTL, "<== nxge_m_resources"));
 }
 
--- a/usr/src/uts/sun4v/io/nxge/nxge_ndd.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/io/nxge/nxge_ndd.c	Fri Dec 22 12:42:28 2006 -0800
@@ -359,12 +359,14 @@
 	"default-port-rdc",	"default_port_rdc"},
 
 {  nxge_param_get_generic,	nxge_param_rx_intr_time,
-	NXGE_PARAM_RXDMA_RW | NXGE_PARAM_PROP_ARR32,
-	0, 31,	0,	0,
+	NXGE_PARAM_RXDMA_RW,
+	NXGE_RDC_RCR_TIMEOUT_MIN, NXGE_RDC_RCR_TIMEOUT_MAX,
+    RXDMA_RCR_TO_DEFAULT,	0,
 	"rxdma-intr-time",	"rxdma_intr_time"},
 {  nxge_param_get_generic,	nxge_param_rx_intr_pkts,
-	NXGE_PARAM_RXDMA_RW | NXGE_PARAM_PROP_ARR32,
-	0, 31,	0,	0,
+	NXGE_PARAM_RXDMA_RW,
+	NXGE_RDC_RCR_THRESHOLD_MIN, NXGE_RDC_RCR_THRESHOLD_MAX,
+	RXDMA_RCR_PTHRES_DEFAULT,	0,
 	"rxdma-intr-pkts",	"rxdma_intr_pkts"},
 
 {  nxge_param_get_generic,	NULL, NXGE_PARAM_READ_PROP,
@@ -1240,86 +1242,28 @@
 
 /* ARGSUSED */
 static int
-nxge_param_rx_intr_set(p_nxge_t nxgep, uint16_t value,
-			    uint8_t channel, uint8_t type)
-{
-	int status = 0;
-	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_rx_intr_set"));
-
-		/* setup value */
-	switch (type) {
-		case SET_RX_INTR_TIME_DISABLE:
-			status = nxge_rxdma_cfg_rcr_timeout(nxgep, channel,
-								    value, 0);
-			break;
-		case SET_RX_INTR_TIME_ENABLE:
-			status = nxge_rxdma_cfg_rcr_timeout(nxgep, channel,
-								value, 1);
-			break;
-		case SET_RX_INTR_PKTS:
-			status = nxge_rxdma_cfg_rcr_threshold(nxgep, channel,
-								    value);
-			break;
-		default:
-			status = NXGE_ERROR;
-			break;
-	}
-
-	NXGE_DEBUG_MSG((nxgep, IOC_CTL, "<== nxge_param_rx_intr_set"));
-	return (status);
-}
-
-/* ARGSUSED */
-static int
 nxge_param_rx_intr_pkts(p_nxge_t nxgep, queue_t *q,
 			    mblk_t	*mp, char *value, caddr_t cp)
 {
 	char *end;
-	uint32_t status, cfg_value;
+	uint32_t cfg_value;
 	p_nxge_param_t pa = (p_nxge_param_t)cp;
-	uint32_t cfg_it = B_FALSE;
-	nxge_rcr_param_t *threshold;
-	p_nxge_dma_pt_cfg_t	p_dma_cfgp;
-	p_nxge_hw_pt_cfg_t	p_cfgp;
-	uint32_t *val_ptr, *old_val_ptr;
+
 	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_rx_intr_pkts"));
 
-	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
-	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
-
-	cfg_value = (uint32_t)mi_strtol(value, &end, BASE_HEX);
-		/* now do decoding */
-		/*
-		 * format is
-		 * bit[30]= enable
-		 * bit[29]= remove
-		 * bits[23-16] = rdc
-		 * bits[15-0] = blanking parameter
-		 *
-		 */
-	threshold = (nxge_rcr_param_t *)&cfg_value;
-	if ((threshold->rdc < p_cfgp->max_rdcs) &&
-		(threshold->cfg_val < NXGE_RDC_RCR_TIMEOUT_MAX) &&
-		(threshold->cfg_val >= NXGE_RDC_RCR_TIMEOUT_MIN)) {
-		val_ptr = (uint32_t *)pa->value;
-		old_val_ptr = (uint32_t *)pa->old_value;
-		if (val_ptr[threshold->rdc] != cfg_value) {
-			old_val_ptr[threshold->rdc] = val_ptr[threshold->rdc];
-			val_ptr[threshold->rdc] = cfg_value;
-			p_dma_cfgp->rcr_threshold[threshold->rdc] =
-				    threshold->cfg_val;
-			cfg_it = B_TRUE;
-		}
-	} else {
+	cfg_value = (uint32_t)mi_strtol(value, &end, BASE_ANY);
+
+	if ((cfg_value > NXGE_RDC_RCR_THRESHOLD_MAX) ||
+		(cfg_value < NXGE_RDC_RCR_THRESHOLD_MIN)) {
 		return (EINVAL);
 	}
-	if (cfg_it == B_TRUE) {
-		status = nxge_param_rx_intr_set(nxgep, threshold->cfg_val,
-						    threshold->rdc,
-						    SET_RX_INTR_PKTS);
-		if (status != NXGE_OK)
-		return (EINVAL);
+
+	if ((pa->value != cfg_value)) {
+		pa->old_value = pa->value;
+		pa->value = cfg_value;
+		nxgep->intr_threshold = pa->value;
 	}
+
 	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_rx_intr_pkts"));
 	return (0);
 }
@@ -1332,62 +1276,22 @@
 		    mblk_t	*mp, char *value, caddr_t cp)
 {
 	char *end;
-	uint32_t status = 0, cfg_value;
+	uint32_t cfg_value;
 	p_nxge_param_t pa = (p_nxge_param_t)cp;
-	uint32_t cfg_it = B_FALSE;
-	nxge_rcr_param_t *tout;
-	p_nxge_dma_pt_cfg_t	p_dma_cfgp;
-	p_nxge_hw_pt_cfg_t	p_cfgp;
-	uint32_t *val_ptr, *old_val_ptr;
 
 	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_rx_intr_time"));
 
-	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
-	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
-
-	cfg_value = (uint32_t)mi_strtol(value, &end, BASE_HEX);
-		/* now do decoding */
-		/*
-		 * format is
-		 * bit[30]= enable
-		 * bit[29]= remove
-		 * bits[23-16] = rdc
-		 * bits[15-0] = blanking parameter
-		 *
-		 */
-	tout = (nxge_rcr_param_t *)&cfg_value;
-	NXGE_DEBUG_MSG((nxgep, NDD_CTL,
-			    " nxge_param_rx_intr_time value %x",
-			    cfg_value));
-	NXGE_DEBUG_MSG((nxgep, NDD_CTL,
-			    " nxge_param_rx_intr_time %x %x",
-			    tout->rdc, tout->cfg_val));
-	if ((tout->rdc < p_cfgp->max_rdcs) &&
-		(tout->cfg_val < NXGE_RDC_RCR_TIMEOUT_MAX) &&
-		(tout->cfg_val >= NXGE_RDC_RCR_TIMEOUT_MIN)) {
-		val_ptr = (uint32_t *)pa->value;
-		old_val_ptr = (uint32_t *)pa->old_value;
-		if (val_ptr[tout->rdc] != cfg_value) {
-			old_val_ptr[tout->rdc] = val_ptr[tout->rdc];
-			val_ptr[tout->rdc] = cfg_value;
-			p_dma_cfgp->rcr_timeout[tout->rdc] = tout->cfg_val;
-			cfg_it = B_TRUE;
-		}
-	} else {
+	cfg_value = (uint32_t)mi_strtol(value, &end, BASE_ANY);
+
+	if ((cfg_value > NXGE_RDC_RCR_TIMEOUT_MAX) ||
+		(cfg_value < NXGE_RDC_RCR_TIMEOUT_MIN)) {
 		return (EINVAL);
 	}
 
-	if (cfg_it == B_TRUE) {
-		if (tout->remove)
-			status = nxge_param_rx_intr_set(nxgep,
-						    tout->cfg_val, tout->rdc,
-						    SET_RX_INTR_TIME_DISABLE);
-		else
-			status = nxge_param_rx_intr_set(nxgep,
-						    tout->cfg_val, tout->rdc,
-						    SET_RX_INTR_TIME_ENABLE);
-		if (status != NXGE_OK)
-			return (EINVAL);
+	if ((pa->value != cfg_value)) {
+		pa->old_value = pa->value;
+		pa->value = cfg_value;
+		nxgep->intr_timeout = pa->value;
 	}
 
 	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_rx_intr_time"));
--- a/usr/src/uts/sun4v/io/nxge/nxge_rxdma.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/io/nxge/nxge_rxdma.c	Fri Dec 22 12:42:28 2006 -0800
@@ -65,7 +65,6 @@
 #define	RDC_NPI_DIRECT
 #endif
 
-#define	USE_DYNAMIC_BLANKING
 
 #ifdef	USE_DYNAMIC_BLANKING
 uint16_t	nxge_rx_intr_timeout = 0x8008;
@@ -152,6 +151,8 @@
 nxge_status_t
 nxge_rx_port_fatal_err_recover(p_nxge_t);
 
+static uint16_t
+nxge_get_pktbuf_size(p_nxge_t nxgep, int bufsz_type, rbr_cfig_b_t rbr_cfgb);
 
 nxge_status_t
 nxge_init_rxdma_channels(p_nxge_t nxgep)
@@ -1000,7 +1001,7 @@
 
 	NXGE_DEBUG_MSG((nxgep, RX_CTL,
 					"==> nxge_rx_parse_header: "
-					"buffer $%p headr_size %d",
+					"buffer $%p hdr_size %d",
 					pkt_buf_addr_p, hdr_size));
 
 
@@ -1581,7 +1582,7 @@
 	nxge_mp->free = B_TRUE;
 	nxge_mp->rx_use_bcopy = B_FALSE;
 
-	atomic_add_32(&nxge_mblks_pending, 1);
+	atomic_inc_32(&nxge_mblks_pending);
 
 	goto nxge_allocb_exit;
 
@@ -1644,6 +1645,7 @@
 #else
 	atomic_inc_32(&nxge_mp->ref_cnt);
 #endif
+	atomic_inc_32(&nxge_mblks_pending);
 
 
 nxge_dupb_exit:
@@ -1873,7 +1875,9 @@
 		"nxge_freeb:rx_msg_p = $%p (block pending %d)",
 		rx_msg_p, nxge_mblks_pending));
 
+
 	ref_cnt = atomic_add_32_nv(&rx_msg_p->ref_cnt, -1);
+	atomic_dec_32(&nxge_mblks_pending);
 	if (!ref_cnt) {
 		buffer = rx_msg_p->buffer;
 		size = rx_msg_p->block_size;
@@ -1881,10 +1885,12 @@
 			"will free: rx_msg_p = $%p (block pending %d)",
 			(long long)rx_msg_p, nxge_mblks_pending));
 
-		KMEM_FREE(rx_msg_p, sizeof (rx_msg_t));
 		if (!rx_msg_p->use_buf_pool) {
 			KMEM_FREE(buffer, size);
 		}
+
+		KMEM_FREE(rx_msg_p, sizeof (rx_msg_t));
+		return;
 	}
 
 #if !defined(RX_USE_RECLAIM_POST)
@@ -2043,6 +2049,7 @@
 #if !defined(_BIG_ENDIAN) && defined(RDC_NPI_DIRECT)
 static void
 nxge_rx_pkts_vring(p_nxge_t nxgep, uint_t vindex, p_nxge_ldv_t ldvp,
+				    rx_dma_ctl_stat_t cs)
 #else
 static void
 nxge_rx_pkts_vring(p_nxge_t nxgep, uint_t vindex, p_nxge_ldv_t ldvp)
@@ -2068,10 +2075,10 @@
 #ifdef  NXGE_DEBUG
 		NXGE_DEBUG_MSG((nxgep, RX_CTL,
 			"==> nxge_rx_pkts_vring:calling mac_rx "
-			"LEN %d mp $%p mp->b_next $%p rcrp $%p "
+			"LEN %d mp $%p mp->b_cont $%p mp->b_next $%p rcrp $%p "
 			"mac_handle $%p",
-			(mp->b_wptr - mp->b_rptr),
-			mp, mp->b_next,
+			mp->b_wptr - mp->b_rptr,
+			mp, mp->b_cont, mp->b_next,
 			rcrp, rcrp->rcr_mac_handle));
 
 		NXGE_DEBUG_MSG((nxgep, RX_CTL,
@@ -2080,16 +2087,25 @@
 			mp,
 			mp->b_rptr,
 			mp->b_wptr,
-			nxge_dump_packet((char *)mp->b_rptr, 64)));
-
+			nxge_dump_packet((char *)mp->b_rptr,
+			mp->b_wptr - mp->b_rptr)));
+		if (mp->b_cont) {
+			NXGE_DEBUG_MSG((nxgep, RX_CTL,
+				"==> nxge_rx_pkts_vring: dump b_cont packets "
+				"(mp->b_cont $%p b_rptr $%p b_wptr $%p):\n %s",
+				mp->b_cont,
+				mp->b_cont->b_rptr,
+				mp->b_cont->b_wptr,
+				nxge_dump_packet((char *)mp->b_cont->b_rptr,
+				mp->b_cont->b_wptr - mp->b_cont->b_rptr)));
+		}
 		if (mp->b_next) {
 			NXGE_DEBUG_MSG((nxgep, RX_CTL,
 				"==> nxge_rx_pkts_vring: dump next packets "
 				"(b_rptr $%p): %s",
 				mp->b_next->b_rptr,
 				nxge_dump_packet((char *)mp->b_next->b_rptr,
-				64)));
-
+				mp->b_next->b_wptr - mp->b_next->b_rptr)));
 		}
 #endif
 
@@ -2151,6 +2167,8 @@
 	boolean_t		multi;
 #ifdef USE_DYNAMIC_BLANKING
 	uint64_t rcr_cfg_b = 0x0ull;
+#else
+	rcrcfig_b_t rcr_cfg_b;
 #endif
 
 #ifndef RDC_NPI_DIRECT
@@ -2273,13 +2291,23 @@
 		/*
 		 * message chaining modes
 		 */
-		if (nmp && !multi) {
+		if (nmp) {
 			nmp->b_next = NULL;
-			*tail_mp = nmp;
-			tail_mp = &nmp->b_next;
-			nmp = mp_cont = NULL;
+			if (!multi && !mp_cont) { /* frame fits a partition */
+				*tail_mp = nmp;
+				tail_mp = &nmp->b_next;
+				nmp = NULL;
+			} else if (multi && !mp_cont) { /* first segment */
+				*tail_mp = nmp;
+				tail_mp = &nmp->b_cont;
+			} else if (multi && mp_cont) {	/* mid of multi segs */
+				*tail_mp = mp_cont;
+				tail_mp = &mp_cont->b_cont;
+			} else if (!multi && mp_cont) { /* last segment */
+				tail_mp = &nmp->b_next;
+				nmp = NULL;
+			}
 		}
-
 		NXGE_DEBUG_MSG((nxgep, RX_CTL,
 			"==> nxge_rx_pkts: loop: rcr channel %d "
 			"before updating: multi %d "
@@ -2339,6 +2367,19 @@
 #ifdef USE_DYNAMIC_BLANKING
 	RXDMA_REG_WRITE64(handle, RCRCFIG_B_REG,
 			    channel, rcr_cfg_b);
+#else
+	if ((nxgep->intr_timeout != rcr_p->intr_timeout) ||
+		(nxgep->intr_threshold != rcr_p->intr_threshold)) {
+		rcr_p->intr_timeout = nxgep->intr_timeout;
+		rcr_p->intr_threshold = nxgep->intr_threshold;
+		rcr_cfg_b.value = 0x0ULL;
+		if (rcr_p->intr_timeout)
+			rcr_cfg_b.bits.ldw.entout = 1;
+		rcr_cfg_b.bits.ldw.timeout = rcr_p->intr_timeout;
+		rcr_cfg_b.bits.ldw.pthres = rcr_p->intr_threshold;
+		RXDMA_REG_WRITE64(handle, RCRCFIG_B_REG,
+				    channel, rcr_cfg_b.value);
+	}
 #endif
 
 #ifdef RDC_NPI_DIRECT
@@ -2384,6 +2425,7 @@
 	uint16_t		l2_len;
 	uint16_t		skip_len;
 	uint8_t			pktbufsz_type;
+	uint16_t		pktbufsz;
 	uint64_t		rcr_entry;
 	uint64_t		*pkt_buf_addr_pp;
 	uint64_t		*pkt_buf_addr_p;
@@ -2401,10 +2443,10 @@
 
 	uint64_t			pkt_type;
 	uint64_t			frag;
+	static uint32_t		bytes_read;
 #ifdef	NXGE_DEBUG
 	int			dump_len;
 #endif
-
 	NXGE_DEBUG_MSG((nxgep, RX2_CTL, "==> nxge_receive_packet"));
 	first_entry = (*mp == NULL) ? B_TRUE : B_FALSE;
 
@@ -2429,7 +2471,7 @@
 
 	NXGE_DEBUG_MSG((nxgep, RX2_CTL,
 		"==> nxge_receive_packet: entryp $%p entry 0x%0llx "
-		"pkt_buf_addr_pp $%p l2_len %d multi %d "
+		"pkt_buf_addr_pp $%p l2_len %d multi 0x%llx "
 		"error_type 0x%x pkt_type 0x%x  "
 		"pktbufsz_type %d ",
 		rcr_desc_rd_head_p,
@@ -2441,7 +2483,7 @@
 
 	NXGE_DEBUG_MSG((nxgep, RX2_CTL,
 		"==> nxge_receive_packet: entryp $%p entry 0x%0llx "
-		"pkt_buf_addr_pp $%p l2_len %d multi %d "
+		"pkt_buf_addr_pp $%p l2_len %d multi 0x%llx "
 		"error_type 0x%x pkt_type 0x%x ", rcr_desc_rd_head_p,
 		rcr_entry, pkt_buf_addr_pp, l2_len,
 		multi,
@@ -2808,9 +2850,25 @@
 			nmp->b_rptr));
 	}
 	if (nmp != NULL) {
+		pktbufsz = nxge_get_pktbuf_size(nxgep, pktbufsz_type,
+			rx_rbr_p->rbr_cfgb);
 		if (!rx_msg_p->rx_use_bcopy) {
-			nmp->b_rptr = &nmp->b_rptr[skip_len];
-			nmp->b_wptr = &nmp->b_rptr[l2_len];
+			if (first_entry) {
+				bytes_read = 0;
+				nmp->b_rptr = &nmp->b_rptr[skip_len];
+				if (l2_len > pktbufsz - skip_len)
+					nmp->b_wptr = &nmp->b_rptr[pktbufsz
+						- skip_len];
+				else
+					nmp->b_wptr = &nmp->b_rptr[l2_len];
+			} else {
+				if (l2_len - bytes_read > pktbufsz)
+					nmp->b_wptr = &nmp->b_rptr[pktbufsz];
+				else
+					nmp->b_wptr =
+					    &nmp->b_rptr[l2_len - bytes_read];
+			}
+			bytes_read += nmp->b_wptr - nmp->b_rptr;
 			NXGE_DEBUG_MSG((nxgep, RX_CTL,
 				"==> nxge_receive_packet after dupb: "
 				"rbr consumed %d "
@@ -2890,7 +2948,7 @@
 					B_TRUE: B_FALSE);
 
 		NXGE_DEBUG_MSG((nxgep, RX_CTL, "==> nxge_receive_packet: "
-			"is_valid 0x%x multi %d pkt %d frag %d error %d",
+			"is_valid 0x%x multi 0x%llx pkt %d frag %d error %d",
 			is_valid, multi, is_tcp_udp, frag, error_type));
 
 		if (is_tcp_udp && !frag && !error_type) {
@@ -2898,7 +2956,7 @@
 				HCK_FULLCKSUM_OK | HCK_FULLCKSUM, 0);
 			NXGE_DEBUG_MSG((nxgep, RX_CTL,
 				"==> nxge_receive_packet: Full tcp/udp cksum "
-				"is_valid 0x%x multi %d pkt %d frag %d "
+				"is_valid 0x%x multi 0x%llx pkt %d frag %d "
 				"error %d",
 				is_valid, multi, is_tcp_udp, frag, error_type));
 		}
@@ -3120,11 +3178,9 @@
 				" fatal error on Port #%d\n",
 				portn));
 		status = nxge_ipp_fatal_err_recover(nxgep);
-#ifdef	NXGE_FM
 		if (status == NXGE_OK) {
 			FM_SERVICE_RESTORED(nxgep);
 		}
-#endif
 	}
 
 	if (rxchan_fatal) {
@@ -3133,11 +3189,9 @@
 				" fatal error on Channel #%d\n",
 				channel));
 		status = nxge_rxdma_fatal_err_recover(nxgep, channel);
-#ifdef	NXGE_FM
 		if (status == NXGE_OK) {
 			FM_SERVICE_RESTORED(nxgep);
 		}
-#endif
 	}
 
 	NXGE_DEBUG_MSG((nxgep, RX2_CTL, "<== nxge_rx_err_evnts"));
@@ -3188,20 +3242,28 @@
 	num_chunks = dma_buf_poolp->num_chunks;
 	dma_buf_p = dma_buf_poolp->dma_buf_pool_p;
 	dma_cntl_p = dma_cntl_poolp->dma_buf_pool_p;
+
 	rx_rbr_rings = (p_rx_rbr_rings_t)
-			KMEM_ZALLOC(sizeof (rx_rbr_rings_t), KM_SLEEP);
-	rbr_rings = (p_rx_rbr_ring_t *)KMEM_ZALLOC(
-			sizeof (p_rx_rbr_ring_t) * ndmas, KM_SLEEP);
-
+		KMEM_ZALLOC(sizeof (rx_rbr_rings_t), KM_SLEEP);
+	rbr_rings = (p_rx_rbr_ring_t *)
+		KMEM_ZALLOC(sizeof (p_rx_rbr_ring_t) * ndmas, KM_SLEEP);
 	rx_rcr_rings = (p_rx_rcr_rings_t)
-			KMEM_ZALLOC(sizeof (rx_rcr_rings_t), KM_SLEEP);
-	rcr_rings = (p_rx_rcr_ring_t *)KMEM_ZALLOC(
-			sizeof (p_rx_rcr_ring_t) * ndmas, KM_SLEEP);
-
+		KMEM_ZALLOC(sizeof (rx_rcr_rings_t), KM_SLEEP);
+	rcr_rings = (p_rx_rcr_ring_t *)
+		KMEM_ZALLOC(sizeof (p_rx_rcr_ring_t) * ndmas, KM_SLEEP);
 	rx_mbox_areas_p = (p_rx_mbox_areas_t)
-			KMEM_ZALLOC(sizeof (rx_mbox_areas_t), KM_SLEEP);
-	rx_mbox_p = (p_rx_mbox_t *)KMEM_ZALLOC(
-			sizeof (p_rx_mbox_t) * ndmas, KM_SLEEP);
+		KMEM_ZALLOC(sizeof (rx_mbox_areas_t), KM_SLEEP);
+	rx_mbox_p = (p_rx_mbox_t *)
+		KMEM_ZALLOC(sizeof (p_rx_mbox_t) * ndmas, KM_SLEEP);
+
+	/*
+	 * Timeout should be set based on the system clock divider.
+	 * The following timeout value of 1 assumes that the
+	 * granularity (1000) is 3 microseconds running at 300MHz.
+	 */
+
+	nxgep->intr_threshold = RXDMA_RCR_PTHRES_DEFAULT;
+	nxgep->intr_timeout = RXDMA_RCR_TO_DEFAULT;
 
 	/*
 	 * Map descriptors from the buffer polls for each dam channel.
@@ -3654,10 +3716,9 @@
 
 	/* Map in the receive completion ring */
 	rcrp = (p_rx_rcr_ring_t)
-			KMEM_ZALLOC(sizeof (rx_rcr_ring_t), KM_SLEEP);
+		KMEM_ZALLOC(sizeof (rx_rcr_ring_t), KM_SLEEP);
 	rcrp->rdc = dma_channel;
 
-
 	nxge_port_rcr_size = nxgep->nxge_port_rcr_size;
 	rcrp->comp_size = nxge_port_rcr_size;
 	rcrp->comp_wrap_mask = nxge_port_rcr_size - 1;
@@ -3698,7 +3759,8 @@
 	 * Zero out buffer block ring descriptors.
 	 */
 	bzero((caddr_t)dmap->kaddrp, dmap->alength);
-
+	rcrp->intr_timeout = nxgep->intr_timeout;
+	rcrp->intr_threshold = nxgep->intr_threshold;
 	rcrp->full_hdr_flag = B_FALSE;
 	rcrp->sw_priv_hdr_len = 0;
 
@@ -3719,8 +3781,8 @@
 	 * The following timeout value of 1 assumes that the
 	 * granularity (1000) is 3 microseconds running at 300MHz.
 	 */
-	cfgb_p->bits.ldw.pthres = RXDMA_RCR_PTHRES_DEFAULT;
-	cfgb_p->bits.ldw.timeout = RXDMA_RCR_TO_DEFAULT;
+	cfgb_p->bits.ldw.pthres = rcrp->intr_threshold;
+	cfgb_p->bits.ldw.timeout = rcrp->intr_timeout;
 	cfgb_p->bits.ldw.entout = 1;
 
 	/* Map in the mailbox */
@@ -3864,7 +3926,7 @@
 
 	rbrp->block_size = nxgep->rx_default_block_size;
 
-	if (!nxge_jumbo_enable) {
+	if (!nxge_jumbo_enable && !nxgep->param_arr[param_accept_jumbo].value) {
 		rbrp->pkt_buf_size2 = RBR_BUFSZ2_2K;
 		rbrp->pkt_buf_size2_bytes = RBR_BUFSZ2_2K_BYTES;
 		rbrp->npi_pkt_buf_size2 = SIZE_2KB;
@@ -3981,7 +4043,7 @@
 #ifdef RXBUFF_USE_SEPARATE_UP_CNTR
 			rx_msg_p->release = B_TRUE;
 #endif
-			nxge_freeb(rx_msg_p);
+			freeb(rx_msg_p->rx_mblk_p);
 			rx_msg_ring[index] = NULL;
 		}
 	}
@@ -4052,7 +4114,7 @@
 			"rx_msg_p $%p",
 			rx_msg_p));
 		if (rx_msg_p != NULL) {
-			nxge_freeb(rx_msg_p);
+			freeb(rx_msg_p->rx_mblk_p);
 			rx_msg_ring[i] = NULL;
 		}
 	}
@@ -4546,11 +4608,9 @@
 			    " fatal error on Port #%d\n",
 				portn));
 		status = nxge_rx_port_fatal_err_recover(nxgep);
-#ifdef	NXGE_FM
 		if (status == NXGE_OK) {
 			FM_SERVICE_RESTORED(nxgep);
 		}
-#endif
 	}
 
 	return (status);
@@ -4871,3 +4931,98 @@
 		break;
 	}
 }
+
+
+static uint16_t
+nxge_get_pktbuf_size(p_nxge_t nxgep, int bufsz_type, rbr_cfig_b_t rbr_cfgb)
+{
+	uint16_t sz = RBR_BKSIZE_8K_BYTES;
+
+	switch (bufsz_type) {
+	case RCR_PKTBUFSZ_0:
+		switch (rbr_cfgb.bits.ldw.bufsz0) {
+		case RBR_BUFSZ0_256B:
+			sz = RBR_BUFSZ0_256_BYTES;
+			break;
+		case RBR_BUFSZ0_512B:
+			sz = RBR_BUFSZ0_512B_BYTES;
+			break;
+		case RBR_BUFSZ0_1K:
+			sz = RBR_BUFSZ0_1K_BYTES;
+			break;
+		case RBR_BUFSZ0_2K:
+			sz = RBR_BUFSZ0_2K_BYTES;
+			break;
+		default:
+			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
+			"nxge_get_pktbug_size: bad bufsz0"));
+			break;
+		}
+		break;
+	case RCR_PKTBUFSZ_1:
+		switch (rbr_cfgb.bits.ldw.bufsz1) {
+		case RBR_BUFSZ1_1K:
+			sz = RBR_BUFSZ1_1K_BYTES;
+			break;
+		case RBR_BUFSZ1_2K:
+			sz = RBR_BUFSZ1_2K_BYTES;
+			break;
+		case RBR_BUFSZ1_4K:
+			sz = RBR_BUFSZ1_4K_BYTES;
+			break;
+		case RBR_BUFSZ1_8K:
+			sz = RBR_BUFSZ1_8K_BYTES;
+			break;
+		default:
+			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
+			"nxge_get_pktbug_size: bad bufsz1"));
+			break;
+		}
+		break;
+	case RCR_PKTBUFSZ_2:
+		switch (rbr_cfgb.bits.ldw.bufsz2) {
+		case RBR_BUFSZ2_2K:
+			sz = RBR_BUFSZ2_2K_BYTES;
+			break;
+		case RBR_BUFSZ2_4K:
+			sz = RBR_BUFSZ2_4K_BYTES;
+			break;
+		case RBR_BUFSZ2_8K:
+			sz = RBR_BUFSZ2_8K_BYTES;
+			break;
+		case RBR_BUFSZ2_16K:
+			sz = RBR_BUFSZ2_16K_BYTES;
+			break;
+		default:
+			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
+			"nxge_get_pktbug_size: bad bufsz2"));
+			break;
+		}
+		break;
+	case RCR_SINGLE_BLOCK:
+		switch (rbr_cfgb.bits.ldw.bksize) {
+		case BKSIZE_4K:
+			sz = RBR_BKSIZE_4K_BYTES;
+			break;
+		case BKSIZE_8K:
+			sz = RBR_BKSIZE_8K_BYTES;
+			break;
+		case BKSIZE_16K:
+			sz = RBR_BKSIZE_16K_BYTES;
+			break;
+		case BKSIZE_32K:
+			sz = RBR_BKSIZE_32K_BYTES;
+			break;
+		default:
+			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
+			"nxge_get_pktbug_size: bad bksize"));
+			break;
+		}
+		break;
+	default:
+		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
+		"nxge_get_pktbug_size: bad bufsz_type"));
+		break;
+	}
+	return (sz);
+}
--- a/usr/src/uts/sun4v/io/nxge/nxge_send.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/io/nxge/nxge_send.c	Fri Dec 22 12:42:28 2006 -0800
@@ -116,8 +116,7 @@
 	statsp = nxgep->statsp;
 
 	if (nxgep->statsp->port_stats.lb_mode == nxge_lb_normal) {
-		if ((!statsp->mac_stats.link_up) ||
-			(FM_GET_DEVSTATE(nxgep) <= DDI_DEVSTATE_DEGRADED)) {
+		if (!statsp->mac_stats.link_up) {
 			freemsg(mp);
 			NXGE_DEBUG_MSG((nxgep, TX_CTL, "==> nxge_start: "
 				"link not up or LB mode"));
@@ -243,19 +242,22 @@
 			"len %d pkt_len %d pack_len %d",
 			nmblks, len, pkt_len, pack_len));
 		/*
-		 * Hardware limits the transfer length to 4K.
-		 * If len is more than 4K, we need to break
-		 * nmp into two chunks: Make first chunk smaller
-		 * than 4K. The second chunk will be broken into
-		 * less than 4K (if needed) during the next pass.
+		 * Hardware limits the transfer length to 4K for NIU and
+		 * 4076 (TX_MAX_TRANSFER_LENGTH) for Neptune. But we just
+		 * use TX_MAX_TRANSFER_LENGTH as the limit for both.
+		 * If len is longer than the limit, then we break nmp into
+		 * two chunks: Make the first chunk equal to the limit and
+		 * the second chunk for the remaining data. If the second
+		 * chunk is still larger than the limit, then it will be
+		 * broken into two in the next pass.
 		 */
-		if (len > TX_MAX_TRANSFER_LENGTH) {
+		if (len > TX_MAX_TRANSFER_LENGTH - TX_PKT_HEADER_SIZE) {
 			t_mp = dupb(nmp);
-			nmp->b_wptr = nmp->b_rptr + TX_MAX_TRANSFER_LENGTH;
+			nmp->b_wptr = nmp->b_rptr +
+				(TX_MAX_TRANSFER_LENGTH - TX_PKT_HEADER_SIZE);
 			t_mp->b_rptr = nmp->b_wptr;
 			t_mp->b_cont = nmp->b_cont;
 			nmp->b_cont = t_mp;
-
 			len = MBLKL(nmp);
 		}
 
@@ -733,7 +735,6 @@
 			sop_index * sizeof (tx_desc_t),
 			nsdescs * sizeof (tx_desc_t),
 			DDI_DMA_SYNC_FORDEV);
-
 		NXGE_DEBUG_MSG((nxgep, TX_CTL, "nxge_start(20): sync 1 "
 			"cs_off = 0x%02X cs_s_off = 0x%02X "
 			"pkt_len %d ngathers %d sop_index %d\n",
--- a/usr/src/uts/sun4v/io/nxge/nxge_txc.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/io/nxge/nxge_txc.c	Fri Dec 22 12:42:28 2006 -0800
@@ -199,7 +199,7 @@
 		return (NXGE_ERROR);
 	}
 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
-			    " nxge_txc_handle_sys_erors: errored port %d",
+			    " nxge_txc_handle_sys_errors: errored port %d",
 			    err_portn));
 	if (my_err) {
 		status = nxge_txc_handle_port_errors(nxgep, err_status);
@@ -329,15 +329,13 @@
 
 	if (txport_fatal) {
 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
-				" nxge_txc_handle_sys_errors:"
+				" nxge_txc_handle_port_errors:"
 				" fatal Error on Port#%d\n",
 				portn));
 		status = nxge_tx_port_fatal_err_recover(nxgep);
-#ifdef	NXGE_FM
 		if (status == NXGE_OK) {
 			FM_SERVICE_RESTORED(nxgep);
 		}
-#endif
 	}
 
 	return (status);
--- a/usr/src/uts/sun4v/io/nxge/nxge_txdma.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/io/nxge/nxge_txdma.c	Fri Dec 22 12:42:28 2006 -0800
@@ -2905,11 +2905,9 @@
 			channel, cs.value));
 		status = nxge_txdma_fatal_err_recover(nxgep, channel,
 								tx_ring_p);
-#ifdef	NXGE_FM
 		if (status == NXGE_OK) {
 			FM_SERVICE_RESTORED(nxgep);
 		}
-#endif
 	}
 
 	NXGE_DEBUG_MSG((nxgep, RX2_CTL, "<== nxge_tx_err_evnts"));
--- a/usr/src/uts/sun4v/io/nxge/nxge_virtual.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/io/nxge/nxge_virtual.c	Fri Dec 22 12:42:28 2006 -0800
@@ -29,7 +29,7 @@
 #include	<sys/nxge/nxge_mac.h>
 
 static void nxge_get_niu_property(dev_info_t *, niu_type_t *);
-static void nxge_get_mac_addr_properties(p_nxge_t);
+static nxge_status_t nxge_get_mac_addr_properties(p_nxge_t);
 static nxge_status_t nxge_use_cfg_n2niu_properties(p_nxge_t);
 static void nxge_use_cfg_neptune_properties(p_nxge_t);
 static void nxge_use_cfg_dma_config(p_nxge_t);
@@ -1779,7 +1779,10 @@
 		break;
 	}
 
-	nxge_get_mac_addr_properties(nxgep);
+	status = nxge_get_mac_addr_properties(nxgep);
+	if (status != NXGE_OK) {
+		return (NXGE_ERROR);
+	}
 		/*
 		 * read the configuration type.
 		 * If none is specified, used default.
@@ -3102,9 +3105,6 @@
 {
 	int			i, maxldvs, maxldgs, start, end, nldvs;
 	int			ldv, endldg;
-#ifdef	S11
-	int			ldg;
-#endif
 	uint8_t			func;
 	uint8_t			channel;
 	uint8_t			chn_start;
@@ -3189,18 +3189,12 @@
 		"==> nxge_ldgv_init_n2: maxldvs %d maxldgs %d",
 		maxldvs, maxldgs));
 	/* logical start_ldg is ldv */
-#if S11
-	ldg = p_cfgp->start_ldg;
-#endif
 	ptr = ldgp;
 	for (i = 0; i < maxldgs; i++) {
 		ptr->func = func;
 		ptr->arm = B_TRUE;
 		ptr->vldg_index = (uint8_t)i;
 		ptr->ldg_timer = NXGE_TIMER_LDG;
-#if S11
-		ptr->ldg = ldg++;
-#endif
 		ptr->ldg = p_cfgp->ldg[i];
 		ptr->sys_intr_handler = nxge_intr;
 		ptr->nldvs = 0;
@@ -3213,9 +3207,6 @@
 		ptr++;
 	}
 
-#ifdef	S11
-	ldg = p_cfgp->start_ldg;
-#endif
 	endldg = NXGE_INT_MAX_LDG;
 	nldvs = 0;
 	ldgvp->nldvs = 0;
@@ -3238,13 +3229,6 @@
 		ldvp->ldv_intr_handler = nxge_mac_intr;
 		ldvp->ldv_ldf_masks = 0;
 		ldvp->nxgep = nxgep;
-#if S11
-		if (!func) {
-			ldgp->ldg = NXGE_N2_MAC_0_LDG;
-		} else {
-			ldgp->ldg = NXGE_N2_MAC_1_LDG;
-		}
-#endif
 		NXGE_DEBUG_MSG((nxgep, INT_CTL,
 			"==> nxge_ldgv_init_n2(mac): maxldvs %d ldv %d "
 			"ldg %d ldgptr $%p ldvptr $%p",
@@ -3260,9 +3244,6 @@
 		ldvp->ldv_intr_handler = nxge_mif_intr;
 		ldvp->ldv_ldf_masks = 0;
 		ldvp->nxgep = nxgep;
-#ifdef	S11
-		ldgp->ldg = NXGE_N2_MIF_LDG;
-#endif
 		NXGE_DEBUG_MSG((nxgep, INT_CTL,
 			"==> nxge_ldgv_init_n2(mif): maxldvs %d ldv %d "
 			"ldg %d ldgptr $%p ldvptr $%p",
@@ -3275,13 +3256,6 @@
 	ldvp->use_timer = B_TRUE;
 	if (own_sys_err && p_cfgp->ser_ldvid) {
 		ldv = p_cfgp->ser_ldvid;
-#ifdef	NXGE_SYSERR_USE_INT
-		ldvp->use_timer = B_FALSE;
-#else
-		ldvp->use_timer = B_TRUE;
-#endif
-		ldvp->use_timer = B_FALSE;
-
 		/*
 		 * Unmask the system interrupt states.
 		 */
@@ -3302,7 +3276,7 @@
 		"ldg %d ldgptr $%p ldvptr p%p",
 		maxldvs, ldv, ldgp->ldg, ldgp, ldvp));
 
-	if (ldvp->use_timer == B_FALSE) {
+	if (own_sys_err && p_cfgp->ser_ldvid) {
 		(void) nxge_ldgv_setup(&ldgp, &ldvp, ldv, endldg, nrequired_p);
 	} else {
 		ldvp++;
@@ -3332,10 +3306,6 @@
 		ldvp->ldv_intr_handler = nxge_rx_intr;
 		ldvp->ldv_ldf_masks = 0;
 		ldvp->nxgep = nxgep;
-#ifdef	S11
-		ldgp->ldg = ((NXGE_N2_RXDMA_START_LDG + i) +
-				(func * NXGE_N2_LDG_GAP));
-#endif
 		ldgp->ldg = p_cfgp->ldg[chn_start];
 
 		NXGE_DEBUG_MSG((nxgep, INT_CTL,
@@ -3367,10 +3337,6 @@
 		ldvp->vdma_index = (uint8_t)i;
 		ldvp->ldv_intr_handler = nxge_tx_intr;
 		ldvp->ldv_ldf_masks = 0;
-#ifdef	S11
-		ldgp->ldg = ((NXGE_N2_TXDMA_START_LDG + i) +
-				(func * NXGE_N2_LDG_GAP));
-#endif
 		ldgp->ldg = p_cfgp->ldg[chn_start];
 		ldvp->nxgep = nxgep;
 		NXGE_DEBUG_MSG((nxgep, INT_CTL,
@@ -3578,6 +3544,7 @@
 	/*
 	 * Function 0 owns system error interrupts.
 	 */
+	ldvp->use_timer = B_TRUE;
 	if (own_sys_err) {
 		ldv = NXGE_SYS_ERROR_LD;
 		ldvp->ldv = (uint8_t)ldv;
@@ -3585,11 +3552,6 @@
 		ldvp->ldv_intr_handler = nxge_syserr_intr;
 		ldvp->ldv_ldf_masks = 0;
 		ldvp->nxgep = nxgep;
-#ifdef	NXGE_SYSERR_USE_INT
-		ldvp->use_timer = B_FALSE;
-#else
-		ldvp->use_timer = B_TRUE;
-#endif
 		ldgvp->ldvp_syserr = ldvp;
 		/*
 		 * Unmask the system interrupt states.
@@ -3607,10 +3569,7 @@
 		ldvp->ldv_intr_handler = nxge_syserr_intr;
 		ldvp->nxgep = nxgep;
 		ldvp->ldv_ldf_masks = 0;
-		ldvp->use_timer = B_TRUE;
 		ldgvp->ldvp_syserr = ldvp;
-		(void) nxge_ldgv_setup(&ldgp, &ldvp, ldv, endldg, nrequired_p);
-		nldvs++;
 	}
 
 	ldgvp->ldg_intrs = *nrequired_p;
@@ -3859,7 +3818,7 @@
 	return (NXGE_OK);
 }
 
-void
+static nxge_status_t
 nxge_get_mac_addr_properties(p_nxge_t nxgep)
 {
 	uchar_t 		*prop_val;
@@ -3919,6 +3878,7 @@
 		} else {
 			NXGE_ERROR_MSG((NULL, NXGE_ERR_CTL,
 			"nxge_get_mac_addr_properties, espc access failed"));
+			return (NXGE_ERROR);
 		}
 	}
 
@@ -3967,6 +3927,8 @@
 	 * Initialize alt. mac addr. in the mac pool
 	 */
 	(void) nxge_init_mmac(nxgep);
+
+	return (NXGE_OK);
 }
 
 void
--- a/usr/src/uts/sun4v/io/nxge/nxge_zcp.c	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/io/nxge/nxge_zcp.c	Fri Dec 22 12:42:28 2006 -0800
@@ -27,6 +27,8 @@
 
 #include <nxge_impl.h>
 #include <nxge_zcp.h>
+#include <nxge_ipp.h>
+
 
 nxge_status_t
 nxge_zcp_init(p_nxge_t nxgep)
@@ -88,6 +90,9 @@
 		break;
 	}
 
+	if ((rs = npi_zcp_clear_istatus(handle)) != NPI_SUCCESS)
+		return (NXGE_ERROR | rs);
+
 	if ((rs = npi_zcp_get_istatus(handle, &istatus)) != NPI_SUCCESS)
 		return (NXGE_ERROR | rs);
 
@@ -206,12 +211,21 @@
 		((portn == 1) && (istatus & ICFG_ZCP_CFIFO_ECC1)) ||
 		((portn == 2) && (istatus & ICFG_ZCP_CFIFO_ECC2)) ||
 		((portn == 3) && (istatus & ICFG_ZCP_CFIFO_ECC3))) {
-		statsp->cfifo_ecc++;
-		NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
-				NXGE_FM_EREPORT_ZCP_CFIFO_ECC);
-		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
-			"nxge_zcp_err_evnts: port%d buf_cfifo_ecc", portn));
-		rxport_fatal = B_TRUE;
+		boolean_t ue_ecc_valid;
+
+		if ((status = nxge_ipp_eccue_valid_check(nxgep,
+						&ue_ecc_valid)) != NXGE_OK)
+			return (status);
+
+		if (ue_ecc_valid) {
+			statsp->cfifo_ecc++;
+			NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
+					NXGE_FM_EREPORT_ZCP_CFIFO_ECC);
+			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
+			"nxge_zcp_err_evnts: port%d buf_cfifo_ecc",
+					portn));
+			rxport_fatal = B_TRUE;
+		}
 	}
 
 	/*
@@ -241,11 +255,9 @@
 			    " fatal Error on  Port #%d\n",
 			    portn));
 		status = nxge_zcp_fatal_err_recover(nxgep);
-#ifdef	NXGE_FM
 		if (status == NXGE_OK) {
 			FM_SERVICE_RESTORED(nxgep);
 		}
-#endif
 	}
 	return (status);
 }
--- a/usr/src/uts/sun4v/nxge/Makefile	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/nxge/Makefile	Fri Dec 22 12:42:28 2006 -0800
@@ -94,6 +94,7 @@
 #CFLAGS += -DNXGE_DEBUG
 # Enable NPI debug
 #CFLAGS += -DNPI_DEBUG
+#CFLAGS += -DNXGE_FM
 #CFLAGS += -DUSE_RX_BUFF_ATTR
 
 #CFLAGS += -DNIU_PA_WORKAROUND
@@ -101,6 +102,7 @@
 CFLAGS += -DNIU_LP_WORKAROUND
 
 LINTFLAGS += -DSOLARIS
+LINTFLAGS += -DNXGE_FM
 LINTFLAGS += -DNIU_LP_WORKAROUND
 #
 # STREAMS, DDI API limitations and other ON header file definitions such as ethernet.h
--- a/usr/src/uts/sun4v/sys/Makefile	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/sys/Makefile	Fri Dec 22 12:42:28 2006 -0800
@@ -92,6 +92,7 @@
 
 CLOSED_HDRS=	\
 	memtestio_ni.h		\
+	memtestio_n2.h		\
 	memtestio_v.h
 
 NXGEHDRS=			\
--- a/usr/src/uts/sun4v/sys/bignum.h	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/sys/bignum.h	Fri Dec 22 12:42:28 2006 -0800
@@ -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.
  */
 
@@ -142,10 +141,10 @@
 void ncp_RSA_key_finish(RSAkey *key);
 BIG_ERR_CODE ncp_big_mont_rr(BIGNUM *result, BIGNUM *n);
 BIG_ERR_CODE ncp_big_modexp(BIGNUM *result, BIGNUM *a, BIGNUM *e,
-    BIGNUM *n, BIGNUM *n_rr, void *ncp);
+    BIGNUM *n, BIGNUM *n_rr, void *ncp, void *reqp);
 BIG_ERR_CODE ncp_big_modexp_crt(BIGNUM *result, BIGNUM *a, BIGNUM *dmodpminus1,
     BIGNUM *dmodqminus1, BIGNUM *p, BIGNUM *q, BIGNUM *pinvmodq,
-    BIGNUM *p_rr, BIGNUM *q_rr, void *ncp);
+    BIGNUM *p_rr, BIGNUM *q_rr, void *ncp, void *reqp);
 int ncp_big_cmp_abs(BIGNUM *a, BIGNUM *b);
 BIG_ERR_CODE ncp_randombignum(BIGNUM *r, int lengthinbits);
 BIG_ERR_CODE ncp_big_div_pos(BIGNUM *result, BIGNUM *remainder,
@@ -154,7 +153,8 @@
     BIGNUM *m, BIGNUM *e);
 BIG_ERR_CODE ncp_big_add(BIGNUM *result, BIGNUM *aa, BIGNUM *bb);
 BIG_ERR_CODE ncp_big_mul(BIGNUM *result, BIGNUM *aa, BIGNUM *bb);
-BIG_ERR_CODE ncp_big_nextprime_pos(BIGNUM *result, BIGNUM *n, void *ncp);
+BIG_ERR_CODE ncp_big_nextprime_pos(BIGNUM *result, BIGNUM *n, void *ncp,
+    void *reqp);
 BIG_ERR_CODE ncp_big_sub_pos(BIGNUM *result, BIGNUM *aa, BIGNUM *bb);
 BIG_ERR_CODE ncp_big_copy(BIGNUM *dest, BIGNUM *src);
 BIG_ERR_CODE ncp_big_sub(BIGNUM *result, BIGNUM *aa, BIGNUM *bb);
--- a/usr/src/uts/sun4v/sys/n2cp.h	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/sys/n2cp.h	Fri Dec 22 12:42:28 2006 -0800
@@ -53,7 +53,7 @@
 #define	N_MBLKL(mp)	((uint64_t)(mp)->b_wptr - (uint64_t)(mp)->b_rptr)
 
 /*
- * NCP Structures.
+ * N2CP Structures.
  */
 typedef struct n2cp n2cp_t;
 typedef struct n2cp_minor n2cp_minor_t;
@@ -64,10 +64,16 @@
 typedef	struct n2cp_hash_ctx n2cp_hash_ctx_t;
 typedef	struct n2cp_hmac_ctx n2cp_hmac_ctx_t;
 
-
 #define	N2CP_MAX_NCWQS		8
 #define	N2CP_MAX_CPUS_PER_CWQ	8
-#define	N2CP_MAX_HELPERTHREADS   (N2CP_MAX_NCWQS * N2CP_MAX_CPUS_PER_CWQ)
+#define	N2CP_MAX_HELPERTHREADS	(N2CP_MAX_NCWQS * N2CP_MAX_CPUS_PER_CWQ)
+
+/*
+ * Device flags (n2cp_t.n_flags)
+ */
+#define	N2CP_FAILED		0x0000001
+#define	N2CP_ATTACHED		0x0000002
+#define	N2CP_REGISTERED		0x0000004
 
 /*
  * HW limitaions for Data and Key. For an input greater than 64KB, Driver will
@@ -144,6 +150,7 @@
 	struct cwq_cwjob	*cj_prev;
 	struct cwq_cwjob	*cj_next;
 	void			*cj_ctx;	/* ptr to n2cp_request */
+	int			cj_error;
 } cwq_cwjob_t;
 
 typedef struct {
@@ -188,27 +195,16 @@
 	int		mm_ncpus;
 	int		mm_nextcpuidx;
 	/*
-	 * Only protects mm_nextcpuidx field.
+	 * Only protects mm_nextcpuidx
 	 */
 	kmutex_t	mm_lock;
-	/*
-	 * xxx - maybe need RW lock for mm_state?
-	 */
 	int		mm_state;	/* CWQ_STATE_... */
-
 	cwq_t		mm_queue;
 } cwq_entry_t;
 
 typedef struct {
 	int		mc_cpuid;
 	int		mc_cwqid;
-	/*
-	 * xxx - maybe need RW lock for mm_state?
-	 * Mirrors mm_state in mau_entry_t.  Duplicated
-	 * for speed so we don't have search mau_entry
-	 * table.  Field rarely updated.
-	 */
-	int		mc_state;	/* CWQ_STATE_... */
 } cpu_entry_t;
 
 typedef struct {
@@ -218,9 +214,10 @@
 	int		m_cwqlistsz;
 	cwq_entry_t	*m_cwqlist;
 	int		m_ncwqs;
+	int		m_ncwqs_online;
 	int		m_nextcwqidx;
 	/*
-	 * Only protects m_nextcwqidx field.
+	 * Only protects m_nextcwqidx,  field.
 	 */
 	kmutex_t	m_lock;
 
@@ -232,6 +229,40 @@
 	int		m_ncpus;
 } n2cp_cwq2cpu_map_t;
 
+#define	SECOND				1000000 /* micro seconds */
+#define	N2CP_JOB_STALL_LIMIT		2
+
+typedef uint64_t	n2cp_counter_t;
+
+/* Information for performing periodic timeout (stall) checks */
+typedef struct n2cp_timeout {
+	clock_t		ticks;	/* Number of clock ticks before next check */
+	timeout_id_t	id;	/* ID of timeout thread (used in detach) */
+	n2cp_counter_t	count;	/* Number of timeout checks made (statistic) */
+} n2cp_timeout_t;
+
+/*
+ * Job timeout information:
+ *
+ * A timeout condition will be detected if all "submitted" jobs have not been
+ * "reclaimed" (completed) and we have not made any "progress" within the
+ * cumulative timeout "limit".  The cumulative timeout "limit" is incremented
+ * with a job specific timeout value (usually one second) each time a new job
+ * is submitted.
+ */
+typedef struct n2cp_job_info {
+	kmutex_t	lock;		/* Lock for all other elements */
+	n2cp_counter_t	submitted;	/* Number of jobs submitted */
+	n2cp_counter_t	reclaimed;	/* Number of jobs completed */
+	n2cp_counter_t	progress;	/* Progress recorded during TO check */
+	n2cp_timeout_t	timeout;	/* Timeout processing information */
+	struct {
+		clock_t count;		/* Ticks since last completion */
+		clock_t addend;		/* Added to count during TO check */
+		clock_t limit;		/* Cumulative timeout value */
+	} stalled;
+} n2cp_job_info_t;
+
 #define	MAX_FIXED_IV_WORDS	8
 typedef struct fixed_iv {
 	int		ivsize;
@@ -336,7 +367,7 @@
 		kstat_named_t	ns_nintr;
 		kstat_named_t	ns_nintr_err;
 		kstat_named_t	ns_nintr_jobs;
-	}			ns_cwq[N2CP_MAX_NCWQS];
+	} ns_cwq[N2CP_MAX_NCWQS];
 };
 
 
@@ -461,6 +492,7 @@
 	uint16_t		nr_pkt_length;
 	crypto_req_handle_t	nr_kcfreq;
 	n2cp_t			*nr_n2cp;
+	clock_t			nr_timeout;
 	int			nr_errno;
 	/*
 	 * Consumer's I/O buffers.
@@ -533,6 +565,10 @@
 
 	md_t				*n_mdp;
 	n2cp_cwq2cpu_map_t		n_cwqmap;
+
+	kmutex_t			n_timeout_lock;
+	n2cp_timeout_t			n_timeout;
+	n2cp_job_info_t			n_job[N2CP_MAX_NCWQS];
 };
 
 /* CK_AES_CTR_PARAMS provides the parameters to the CKM_AES_CTR mechanism */
@@ -620,8 +656,7 @@
 void	n2cp_diperror(dev_info_t *, const char *, ...);
 void	n2cp_dipverror(dev_info_t *, const char *, va_list);
 void	n2cp_dump_cwb(cwq_cw_t *cw);
-
-
+void	n2cp_offline_cwq(n2cp_t *n2cp, int cwq_id);
 
 /*
  * n2cp_kstat.c
@@ -704,7 +739,7 @@
  */
 int	n2cp_init_cwq2cpu_map(n2cp_t *);
 void	n2cp_deinit_cwq2cpu_map(n2cp_t *);
-int	n2cp_map_cwq_to_cpu(n2cp_t *, int);
+int	n2cp_map_cwq_to_cpu(n2cp_t *, int, int);
 int	n2cp_map_cpu_to_cwq(n2cp_t *, int);
 int	n2cp_map_nextcwq(n2cp_t *);
 cwq_entry_t	*n2cp_map_findcwq(n2cp_t *, int);
@@ -743,6 +778,13 @@
 
 #endif /* N2_ERRATUM_175 */
 
+#define	n2cp_setfailed(n2cp)		((n2cp)->n_flags |= N2CP_FAILED)
+#define	n2cp_isfailed(n2cp)		((n2cp)->n_flags & N2CP_FAILED)
+#define	n2cp_setregistered(n2cp)	((n2cp)->n_flags |= N2CP_REGISTERED)
+#define	n2cp_clrregistered(n2cp)	((n2cp)->n_flags &= ~N2CP_REGISTERED)
+#define	n2cp_isregistered(n2cp)		((n2cp)->n_flags & N2CP_REGISTERED)
+
+
 #endif /* _KERNEL */
 
 #ifdef	__cplusplus
--- a/usr/src/uts/sun4v/sys/ncp.h	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/sys/ncp.h	Fri Dec 22 12:42:28 2006 -0800
@@ -112,8 +112,6 @@
 typedef struct ncp_request ncp_request_t;
 typedef struct ncp_stat ncp_stat_t;
 
-
-
 /*
  * Linked-list linkage.
  */
@@ -142,6 +140,8 @@
 	uint16_t		nr_pkt_length;
 	crypto_req_handle_t	nr_kcf_req;
 	ncp_t			*nr_ncp;
+	clock_t			nr_timeout;
+
 	/*
 	 * Consumer's I/O buffers.
 	 */
@@ -165,7 +165,6 @@
 	uint8_t			nr_outbuf[RSA_MAX_KEY_LEN];
 
 	unsigned		nr_inlen;
-
 	unsigned		nr_modlen;
 	unsigned		nr_explen;
 	unsigned		nr_plen;
@@ -273,6 +272,13 @@
 };
 
 /*
+ * Device flags (ncp_t.n_flags)
+ */
+#define	NCP_FAILED		0x0000001
+#define	NCP_ATTACHED		0x0000002
+#define	NCP_REGISTERED		0x0000004
+
+/*
  * IMPORTANT:
  *	NCP_MAQUEUE_NENTRIES *must* be a power-of-2.
  *	requirement: sizeof (ncs_hvdesc_t) == 64
@@ -313,6 +319,7 @@
 	ncp_desc_t		*dj_jobp;
 	struct ncp_descjob	*dj_prev;
 	struct ncp_descjob	*dj_next;
+	int			dj_error;
 } ncp_descjob_t;
 
 /*
@@ -359,27 +366,16 @@
 	int		mm_ncpus;
 	int		mm_nextcpuidx;
 	/*
-	 * Only protects mm_nextcpuidx field.
+	 * Only protects mm_nextcpuidx
 	 */
 	kmutex_t	mm_lock;
-	/*
-	 * xxx - maybe need RW lock for mm_state?
-	 */
 	int		mm_state;	/* MAU_STATE_... */
-
 	ncp_mau_queue_t	mm_queue;
 } mau_entry_t;
 
 typedef struct {
 	int		mc_cpuid;
 	int		mc_mauid;
-	/*
-	 * xxx - maybe need RW lock for mm_state?
-	 * Mirrors mm_state in mau_entry_t.  Duplicated
-	 * for speed so we don't have search mau_entry
-	 * table.  Field rarely updated.
-	 */
-	int		mc_state;	/* MAU_STATE_... */
 } cpu_entry_t;
 
 typedef struct {
@@ -389,6 +385,7 @@
 	int		m_maulistsz;
 	mau_entry_t	*m_maulist;
 	int		m_nmaus;
+	int		m_nmaus_online;
 	int		m_nextmauidx;
 	/*
 	 * Only protects m_nextmauidx field.
@@ -403,6 +400,40 @@
 	int		m_ncpus;
 } ncp_mau2cpu_map_t;
 
+
+#define	SECOND			1000000	/* micro seconds */
+#define	NCP_JOB_STALL_LIMIT	2
+typedef u_longlong_t ncp_counter_t;
+
+/* Information for performing periodic timeout (stall) checks */
+typedef struct ncp_timeout {
+	clock_t		ticks;	/* Number of clock ticks before next check */
+	timeout_id_t	id;	/* ID of timeout thread (used in detach) */
+	ncp_counter_t	count;	/* Number of timeout checks made (statistic) */
+} ncp_timeout_t;
+
+/*
+ * Job timeout information:
+ *
+ * A timeout condition will be detected if all "submitted" jobs have not been
+ * "reclaimed" (completed) and we have not made any "progress" within the
+ * cumulative timeout "limit".  The cumulative timeout "limit" is incremented
+ * with a job specific timeout value (usually one second) each time a new job
+ * is submitted.
+ */
+typedef struct ncp_job_info {
+	kmutex_t	lock;		/* Lock for all other elements */
+	ncp_counter_t	submitted;	/* Number of jobs submitted */
+	ncp_counter_t	reclaimed;	/* Number of jobs completed */
+	ncp_counter_t	progress;	/* Progress recorded during TO check */
+	ncp_timeout_t	timeout;	/* Timeout processing information */
+	struct {
+		clock_t count;		/* Ticks since last completion */
+		clock_t addend;		/* Added to count during TO check */
+		clock_t limit;		/* Cumulative timeout value */
+	} stalled;
+} ncp_job_info_t;
+
 struct ncp {
 	uint_t				n_hvapi_major_version;
 	uint_t				n_hvapi_minor_version;
@@ -416,6 +447,8 @@
 
 	ddi_taskq_t			*n_taskq;
 
+	uint_t				n_flags;	/* dev state flags */
+
 	int				n_max_nmaus;
 	int				n_max_cpus_per_mau;
 
@@ -439,6 +472,9 @@
 
 	md_t				*n_mdp;
 	ncp_mau2cpu_map_t		n_maumap;
+	kmutex_t			n_timeout_lock;
+	ncp_timeout_t			n_timeout;
+	ncp_job_info_t			n_job[NCP_MAX_MAX_NMAUS];
 };
 
 #endif	/* _KERNEL */
@@ -533,6 +569,7 @@
 int	ncp_map_mau_to_cpu(ncp_t *, int);
 int	ncp_map_nextmau(ncp_t *);
 mau_entry_t	*ncp_map_findmau(ncp_t *, int);
+void	ncp_offline_mau(ncp_t *ncp, int mid);
 
 /*
  * ncp_kstat.c
@@ -569,6 +606,12 @@
 
 int	ncp_free_context(crypto_ctx_t *);
 
+#define	ncp_setfailed(ncp)	((ncp)->n_flags |= NCP_FAILED)
+#define	ncp_isfailed(ncp)	((ncp)->n_flags & NCP_FAILED)
+#define	ncp_setregistered(ncp)	((ncp)->n_flags |= NCP_REGISTERED)
+#define	ncp_clrregistered(ncp)	((ncp)->n_flags &= ~NCP_REGISTERED)
+#define	ncp_isregistered(ncp)	((ncp)->n_flags & NCP_REGISTERED)
+
 #ifdef	__cplusplus
 }
 #endif
--- a/usr/src/uts/sun4v/sys/ncs.h	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/sys/ncs.h	Fri Dec 22 12:42:28 2006 -0800
@@ -58,6 +58,12 @@
 typedef union ma_ma		ma_ma_t;
 typedef uint64_t		ma_np_t;
 
+/* MAU error type */
+#define	MAU_ERR_OK	0x00
+#define	MAU_ERR_INVOP	0x01
+#define	MAU_ERR_HWE	0x02
+#define	MAU_ERR_MASK	0x03
+
 /*
  * Modulare Arithmetic Unit (MA) control register definition.
  */
@@ -89,6 +95,11 @@
 	} bits;
 };
 
+/* CWQ error type */
+#define	CWQ_ERR_OK		0x00
+#define	CWQ_ERR_PROTOCOL	0x04
+#define	CWQ_ERR_HWE		0x08
+#define	CWQ_ERR_MASK		0x0C
 
 typedef struct {
 	union {
@@ -139,7 +150,7 @@
 #define	cw_dst_addr	_ux._cw_dst_addr
 #define	cw_csr		_ux._cw_csr
 
-#endif /* _ASM */
+#endif /* !_ASM */
 
 /* Values for ma_ctl operation field */
 #define	MA_OP_LOAD		0x0
--- a/usr/src/uts/sun4v/sys/niagararegs.h	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/sys/niagararegs.h	Fri Dec 22 12:42:28 2006 -0800
@@ -143,21 +143,39 @@
 /*
  * Bits defined in L2 Error Status Register
  *
+ *	(Niagara 1)
  * +---+---+---+---+----+----+----+----+----+----+----+----+----+----+
  * |MEU|MEC|RW |RSV|MODA|VCID|LDAC|LDAU|LDWC|LDWU|LDRC|LDRU|LDSC|LDSU|
  * +---+---+---+---+----+----+----+----+----+----+----+----+----+----+
  *  63  62  61  60   59 58-54  53   52   51   50   49   48   47   46
  *
+ *	(Niagara 2)
+ * +---+---+---+----+--------+----+----+----+----+----+----+----+----+
+ * |MEU|MEC|RW |MODA|  VCID  |LDAC|LDAU|LDWC|LDWU|LDRC|LDRU|LDSC|LDSU|
+ * +---+---+---+----+--------+----+----+----+----+----+----+----+----+
+ *  63  62  61  60     59-54   53   52   51   50   49   48   47   46
+ *
+ *      (Niagara 1)
  * +---+---+---+---+---+---+---+---+---+---+---+-------+------+
  * |LTC|LRU|LVU|DAC|DAU|DRC|DRU|DSC|DSU|VEC|VEU| RSVD1 | SYND |
  * +---+---+---+---+---+---+---+---+---+---+---+-------+------+
  *  45  44  43  42  41  40  39  38  37  36  35   34-32   31-0
+ *
+ *      (Niagara 2)
+ * +---+---+---+---+---+---+---+---+---+---+---+---+----+-----+
+ * |LTC|LRU|LVU|DAC|DAU|DRC|DRU|DSC|DSU|VEC|VEU|LVC|RSVD| SYND|
+ * +---+---+---+---+---+---+---+---+---+---+---+---+----+-----+
+ *  45  44  43  42  41  40  39  38  37  36  35  34  33-28 27-0
+ *
+ * Note that relative to error status bits, Niagara-1 is a strict subset of
+ * Niagara-2.
  */
+
 #define	NI_L2AFSR_MEU 	0x8000000000000000ULL
 #define	NI_L2AFSR_MEC	0x4000000000000000ULL
 #define	NI_L2AFSR_RW 	0x2000000000000000ULL
-#define	NI_L2AFSR_RSVD0	0x1000000000000000ULL
-#define	NI_L2AFSR_MODA	0x0800000000000000ULL
+#define	NI2_L2AFSR_MODA	0x1000000000000000ULL
+#define	NI1_L2AFSR_MODA	0x0800000000000000ULL
 #define	NI_L2AFSR_VCID	0x07C0000000000000ULL
 #define	NI_L2AFSR_LDAC	0x0020000000000000ULL
 #define	NI_L2AFSR_LDAU	0x0010000000000000ULL
@@ -178,8 +196,9 @@
 #define	NI_L2AFSR_DSU	0x0000002000000000ULL
 #define	NI_L2AFSR_VEC	0x0000001000000000ULL
 #define	NI_L2AFSR_VEU	0x0000000800000000ULL
-#define	NI_L2AFSR_RSVD1	0x0000000700000000ULL
-#define	NI_L2AFSR_SYND	0x00000000FFFFFFFFULL
+#define	NI_L2AFSR_LVC	0x0000000400000000ULL
+#define	NI1_L2AFSR_SYND	0x00000000FFFFFFFFULL
+#define	NI2_L2AFSR_SYND	0x000000000FFFFFFFULL
 
 /*
  * These L2 bit masks are used to determine if another bit of higher priority
@@ -193,19 +212,21 @@
 #define	NI_L2AFSR_P04	(NI_L2AFSR_P03 | NI_L2AFSR_LDWU)
 #define	NI_L2AFSR_P05	(NI_L2AFSR_P04 | NI_L2AFSR_LDRU)
 #define	NI_L2AFSR_P06	(NI_L2AFSR_P05 | NI_L2AFSR_DAU | NI_L2AFSR_DRU)
-#define	NI_L2AFSR_P07	(NI_L2AFSR_P06 | NI_L2AFSR_LTC)
-#define	NI_L2AFSR_P08	(NI_L2AFSR_P07 | NI_L2AFSR_LDAC | NI_L2AFSR_LDSC)
-#define	NI_L2AFSR_P09	(NI_L2AFSR_P08 | NI_L2AFSR_LDWC)
-#define	NI_L2AFSR_P10	(NI_L2AFSR_P09 | NI_L2AFSR_LDRC)
-#define	NI_L2AFSR_P11	(NI_L2AFSR_P10 | NI_L2AFSR_DAC | NI_L2AFSR_DRC)
+#define	NI_L2AFSR_P07   (NI_L2AFSR_P06 | NI_L2AFSR_LVC)
+#define	NI_L2AFSR_P08	(NI_L2AFSR_P07 | NI_L2AFSR_LTC)
+#define	NI_L2AFSR_P09	(NI_L2AFSR_P08 | NI_L2AFSR_LDAC | NI_L2AFSR_LDSC)
+#define	NI_L2AFSR_P10	(NI_L2AFSR_P09 | NI_L2AFSR_LDWC)
+#define	NI_L2AFSR_P11	(NI_L2AFSR_P10 | NI_L2AFSR_LDRC)
+#define	NI_L2AFSR_P12	(NI_L2AFSR_P11 | NI_L2AFSR_DAC | NI_L2AFSR_DRC)
 
 /*
- * Bits defined in DRAM Error Status Register
+ * Bits defined in DRAM Error Status Register (Niagara-2)
+ * Niagara-1 is strict subset
  *
- * +---+---+---+---+---+---+---+----------+------+
- * |MEU|MEC|DAC|DAU|DSC|DSU|DBU| RESERVED | SYND |
- * +---+---+---+---+---+---+---+----------+------+
- *  63  62  61  60  59  58  57    56-16     15-0
+ * +---+---+---+---+---+---+---+---+---+---+----------+------+
+ * |MEU|MEC|DAC|DAU|DSC|DSU|DBU|MEB|FBU|FBR| RESERVED | SYND |
+ * +---+---+---+---+---+---+---+---+---+---+----------+------+
+ *  63  62  61  60  59  58  57  56  55  54    53-16     15-0
  *
  */
 #define	NI_DMAFSR_MEU 	0x8000000000000000ULL
@@ -215,11 +236,13 @@
 #define	NI_DMAFSR_DSC	0x0800000000000000ULL
 #define	NI_DMAFSR_DSU	0x0400000000000000ULL
 #define	NI_DMAFSR_DBU	0x0200000000000000ULL
-#define	NI_DMAFSR_RSVD	0x01FFFFFFFFFF0000ULL
+#define	NI_DMAFSR_MEB	0x0100000000000000ULL
+#define	NI_DMAFSR_FBU	0x0080000000000000ULL
+#define	NI_DMAFSR_FBR	0x0040000000000000ULL
 #define	NI_DMAFSR_SYND	0x000000000000FFFFULL
 
 /* Bit mask for DRAM priority determination */
-#define	NI_DMAFSR_P01	(NI_DMAFSR_DSU | NI_DMAFSR_DAU)
+#define	NI_DMAFSR_P01	(NI_DMAFSR_DSU | NI_DMAFSR_DAU | NI_DMAFSR_FBU)
 
 /*
  * The following is the syndrome value placed in memory
--- a/usr/src/uts/sun4v/sys/nxge/nxge.h	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/sys/nxge/nxge.h	Fri Dec 22 12:42:28 2006 -0800
@@ -543,7 +543,7 @@
 	nxge_txc_t		txc;
 	nxge_classify_t		classifier;
 
-	mac_handle_t		mach;	/* mac module handle    */
+	mac_handle_t		mach;	/* mac module handle */
 	p_nxge_stats_t		statsp;
 	uint32_t		param_count;
 	p_nxge_param_t		param_arr;
@@ -648,7 +648,8 @@
 	boolean_t 		nxge_htraffic;
 	uint32_t 		nxge_ncpus;
 	uint32_t 		nxge_cpumask;
-	uint32_t 		nxge_intrpkt;
+	uint16_t 		intr_timeout;
+	uint16_t 		intr_threshold;
 	uchar_t 		nxge_rxmode;
 	uint32_t 		active_threads;
 
--- a/usr/src/uts/sun4v/sys/nxge/nxge_common.h	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/sys/nxge/nxge_common.h	Fri Dec 22 12:42:28 2006 -0800
@@ -158,9 +158,13 @@
 	/* RBR Configuration B */
 	uint32_t	bksize;		/* Block size is fixed. */
 #define	RBR_BKSIZE_4K			0
+#define	RBR_BKSIZE_4K_BYTES		(4 * 1024)
 #define	RBR_BKSIZE_8K			1
+#define	RBR_BKSIZE_8K_BYTES		(8 * 1024)
 #define	RBR_BKSIZE_16K			2
+#define	RBR_BKSIZE_16K_BYTES		(16 * 1024)
 #define	RBR_BKSIZE_32K			3
+#define	RBR_BKSIZE_32K_BYTES		(32 * 1024)
 
 	uint32_t	bufsz2;
 #define	RBR_BUFSZ2_2K			0
--- a/usr/src/uts/sun4v/sys/nxge/nxge_common_impl.h	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/sys/nxge/nxge_common_impl.h	Fri Dec 22 12:42:28 2006 -0800
@@ -52,86 +52,84 @@
 #define	AXIS_WAIT_PER_LOOP		(AXIS_WAIT_R/AXIS_WAIT_LOOP)
 #endif
 
-
-
-#define		NO_DEBUG	0x0000000000000000ULL
-#define		MDT_CTL		0x0000000000000001ULL
-#define		RX_CTL		0x0000000000000002ULL
-#define		TX_CTL		0x0000000000000004ULL
-#define		OBP_CTL		0x0000000000000008ULL
+#define	NO_DEBUG	0x0000000000000000ULL
+#define	MDT_CTL		0x0000000000000001ULL
+#define	RX_CTL		0x0000000000000002ULL
+#define	TX_CTL		0x0000000000000004ULL
+#define	OBP_CTL		0x0000000000000008ULL
 
-#define		VPD_CTL		0x0000000000000010ULL
-#define		DDI_CTL		0x0000000000000020ULL
-#define		MEM_CTL		0x0000000000000040ULL
-#define		SAP_CTL		0x0000000000000080ULL
+#define	VPD_CTL		0x0000000000000010ULL
+#define	DDI_CTL		0x0000000000000020ULL
+#define	MEM_CTL		0x0000000000000040ULL
+#define	SAP_CTL		0x0000000000000080ULL
 
-#define		IOC_CTL		0x0000000000000100ULL
-#define		MOD_CTL		0x0000000000000200ULL
-#define		DMA_CTL		0x0000000000000400ULL
-#define		STR_CTL		0x0000000000000800ULL
+#define	IOC_CTL		0x0000000000000100ULL
+#define	MOD_CTL		0x0000000000000200ULL
+#define	DMA_CTL		0x0000000000000400ULL
+#define	STR_CTL		0x0000000000000800ULL
 
-#define		INT_CTL		0x0000000000001000ULL
-#define		SYSERR_CTL	0x0000000000002000ULL
-#define		KST_CTL		0x0000000000004000ULL
-#define		PCS_CTL		0x0000000000008000ULL
+#define	INT_CTL		0x0000000000001000ULL
+#define	SYSERR_CTL	0x0000000000002000ULL
+#define	KST_CTL		0x0000000000004000ULL
+#define	PCS_CTL		0x0000000000008000ULL
 
-#define		MII_CTL		0x0000000000010000ULL
-#define		MIF_CTL		0x0000000000020000ULL
-#define		FCRAM_CTL	0x0000000000040000ULL
-#define		MAC_CTL		0x0000000000080000ULL
+#define	MII_CTL		0x0000000000010000ULL
+#define	MIF_CTL		0x0000000000020000ULL
+#define	FCRAM_CTL	0x0000000000040000ULL
+#define	MAC_CTL		0x0000000000080000ULL
 
-#define		IPP_CTL		0x0000000000100000ULL
-#define		DMA2_CTL	0x0000000000200000ULL
-#define		RX2_CTL		0x0000000000400000ULL
-#define		TX2_CTL		0x0000000000800000ULL
+#define	IPP_CTL		0x0000000000100000ULL
+#define	DMA2_CTL	0x0000000000200000ULL
+#define	RX2_CTL		0x0000000000400000ULL
+#define	TX2_CTL		0x0000000000800000ULL
 
-#define		MEM2_CTL	0x0000000001000000ULL
-#define		MEM3_CTL	0x0000000002000000ULL
-#define		NXGE_CTL	0x0000000004000000ULL
-#define		NDD_CTL		0x0000000008000000ULL
-#define		NDD2_CTL	0x0000000010000000ULL
+#define	MEM2_CTL	0x0000000001000000ULL
+#define	MEM3_CTL	0x0000000002000000ULL
+#define	NXGE_CTL	0x0000000004000000ULL
+#define	NDD_CTL		0x0000000008000000ULL
+#define	NDD2_CTL	0x0000000010000000ULL
 
-#define		TCAM_CTL	0x0000000020000000ULL
-#define		CFG_CTL		0x0000000040000000ULL
-#define		CFG2_CTL	0x0000000080000000ULL
+#define	TCAM_CTL	0x0000000020000000ULL
+#define	CFG_CTL		0x0000000040000000ULL
+#define	CFG2_CTL	0x0000000080000000ULL
 
-#define		FFLP_CTL	TCAM_CTL | FCRAM_CTL
+#define	FFLP_CTL	TCAM_CTL | FCRAM_CTL
 
-#define		VIR_CTL		0x0000000100000000ULL
-#define		VIR2_CTL	0x0000000200000000ULL
+#define	VIR_CTL		0x0000000100000000ULL
+#define	VIR2_CTL	0x0000000200000000ULL
 
-#define		NXGE_NOTE	0x0000001000000000ULL
-#define		NXGE_ERR_CTL	0x0000002000000000ULL
+#define	NXGE_NOTE	0x0000001000000000ULL
+#define	NXGE_ERR_CTL	0x0000002000000000ULL
 
-#define		DUMP_ALWAYS	0x2000000000000000ULL
+#define	DUMP_ALWAYS	0x2000000000000000ULL
 
 /* NPI Debug and Error defines */
-#define		NPI_RDC_CTL	0x0000000000000001ULL
-#define		NPI_TDC_CTL	0x0000000000000002ULL
-#define		NPI_TXC_CTL	0x0000000000000004ULL
-#define		NPI_IPP_CTL	0x0000000000000008ULL
+#define	NPI_RDC_CTL	0x0000000000000001ULL
+#define	NPI_TDC_CTL	0x0000000000000002ULL
+#define	NPI_TXC_CTL	0x0000000000000004ULL
+#define	NPI_IPP_CTL	0x0000000000000008ULL
 
-#define		NPI_XPCS_CTL	0x0000000000000010ULL
-#define		NPI_PCS_CTL	0x0000000000000020ULL
-#define		NPI_ESR_CTL	0x0000000000000040ULL
-#define		NPI_BMAC_CTL	0x0000000000000080ULL
-#define		NPI_XMAC_CTL	0x0000000000000100ULL
-#define		NPI_MAC_CTL	NPI_BMAC_CTL | NPI_XMAC_CTL
+#define	NPI_XPCS_CTL	0x0000000000000010ULL
+#define	NPI_PCS_CTL	0x0000000000000020ULL
+#define	NPI_ESR_CTL	0x0000000000000040ULL
+#define	NPI_BMAC_CTL	0x0000000000000080ULL
+#define	NPI_XMAC_CTL	0x0000000000000100ULL
+#define	NPI_MAC_CTL	NPI_BMAC_CTL | NPI_XMAC_CTL
 
-#define		NPI_ZCP_CTL	0x0000000000000200ULL
-#define		NPI_TCAM_CTL	0x0000000000000400ULL
-#define		NPI_FCRAM_CTL	0x0000000000000800ULL
-#define		NPI_FFLP_CTL	NPI_TCAM_CTL | NPI_FCRAM_CTL
+#define	NPI_ZCP_CTL	0x0000000000000200ULL
+#define	NPI_TCAM_CTL	0x0000000000000400ULL
+#define	NPI_FCRAM_CTL	0x0000000000000800ULL
+#define	NPI_FFLP_CTL	NPI_TCAM_CTL | NPI_FCRAM_CTL
 
-#define		NPI_VIR_CTL	0x0000000000001000ULL
-#define		NPI_PIO_CTL	0x0000000000002000ULL
-#define		NPI_VIO_CTL	0x0000000000004000ULL
+#define	NPI_VIR_CTL	0x0000000000001000ULL
+#define	NPI_PIO_CTL	0x0000000000002000ULL
+#define	NPI_VIO_CTL	0x0000000000004000ULL
 
-#define		NPI_REG_CTL	0x0000000040000000ULL
-#define		NPI_CTL		0x0000000080000000ULL
-#define		NPI_ERR_CTL	0x0000000080000000ULL
+#define	NPI_REG_CTL	0x0000000040000000ULL
+#define	NPI_CTL		0x0000000080000000ULL
+#define	NPI_ERR_CTL	0x0000000080000000ULL
 
-#if	defined(SOLARIS) && defined(_KERNEL)
+#if defined(SOLARIS) && defined(_KERNEL)
 
 #include <sys/types.h>
 #include <sys/ddi.h>
@@ -145,16 +143,14 @@
 #define	NXGE_DEBUG_MSG(params)
 #endif
 
-#if	1
+#if 1
 #define	NXGE_ERROR_MSG(params)	nxge_debug_msg params
 #define	NXGE_WARN_MSG(params)	nxge_debug_msg params
 #else
 #define	NXGE_ERROR_MSG(params)
 #define	NXGE_WARN_MSG(params)
-
 #endif
 
-
 typedef kmutex_t			nxge_os_mutex_t;
 typedef	krwlock_t			nxge_os_rwlock_t;
 
@@ -171,8 +167,8 @@
 typedef frtn_t				nxge_os_frtn_t;
 
 #define	NXGE_MUTEX_DRIVER		MUTEX_DRIVER
-#define	MUTEX_INIT(lock, name, type, arg)	\
-					mutex_init(lock, name, type, arg)
+#define	MUTEX_INIT(lock, name, type, arg) \
+	mutex_init(lock, name, type, arg)
 #define	MUTEX_ENTER(lock)		mutex_enter(lock)
 #define	MUTEX_TRY_ENTER(lock)		mutex_tryenter(lock)
 #define	MUTEX_EXIT(lock)		mutex_exit(lock)
@@ -190,55 +186,45 @@
 
 #define	NXGE_DELAY(microseconds)	 (drv_usecwait(microseconds))
 
-#define	NXGE_PIO_READ8(handle, devaddr, offset)		\
+#define	NXGE_PIO_READ8(handle, devaddr, offset) \
 	(ddi_get8(handle, (uint8_t *)((caddr_t)devaddr + offset)))
 
-#define	NXGE_PIO_READ16(handle, devaddr, offset)		\
+#define	NXGE_PIO_READ16(handle, devaddr, offset) \
 	(ddi_get16(handle, (uint16_t *)((caddr_t)devaddr + offset)))
 
-#define	NXGE_PIO_READ32(handle, devaddr, offset)		\
+#define	NXGE_PIO_READ32(handle, devaddr, offset) \
 	(ddi_get32(handle, (uint32_t *)((caddr_t)devaddr + offset)))
 
-#define	NXGE_PIO_READ64(handle, devaddr, offset)		\
+#define	NXGE_PIO_READ64(handle, devaddr, offset) \
 	(ddi_get64(handle, (uint64_t *)((caddr_t)devaddr + offset)))
 
-#define	NXGE_PIO_WRITE8(handle, devaddr, offset, data)	\
+#define	NXGE_PIO_WRITE8(handle, devaddr, offset, data) \
 	(ddi_put8(handle, (uint8_t *)((caddr_t)devaddr + offset), data))
 
-#define	NXGE_PIO_WRITE16(handle, devaddr, offset, data)	\
+#define	NXGE_PIO_WRITE16(handle, devaddr, offset, data) \
 	(ddi_get16(handle, (uint16_t *)((caddr_t)devaddr + offset), data))
 
 #define	NXGE_PIO_WRITE32(handle, devaddr, offset, data)	\
 	(ddi_put32(handle, (uint32_t *)((caddr_t)devaddr + offset), data))
 
-#define	NXGE_PIO_WRITE64(handle, devaddr, offset, data)	\
+#define	NXGE_PIO_WRITE64(handle, devaddr, offset, data) \
 	(ddi_put64(handle, (uint64_t *)((caddr_t)devaddr + offset), data))
 
-#define	NXGE_NPI_PIO_READ8(npi_handle, offset)		\
-	(ddi_get8(NPI_REGH(npi_handle),			\
+#define	NXGE_NPI_PIO_READ8(npi_handle, offset) \
+	(ddi_get8(NPI_REGH(npi_handle),	\
 	(uint8_t *)(NPI_REGP(npi_handle) + offset)))
 
-#define	NXGE_NPI_PIO_READ16(npi_handle, offset)		\
-	(ddi_get16(NPI_REGH(npi_handle),		\
+#define	NXGE_NPI_PIO_READ16(npi_handle, offset) \
+	(ddi_get16(NPI_REGH(npi_handle), \
 	(uint16_t *)(NPI_REGP(npi_handle) + offset)))
 
-#define	NXGE_NPI_PIO_READ32(npi_handle, offset)		\
-	(ddi_get32(NPI_REGH(npi_handle),		\
+#define	NXGE_NPI_PIO_READ32(npi_handle, offset) \
+	(ddi_get32(NPI_REGH(npi_handle), \
 	(uint32_t *)(NPI_REGP(npi_handle) + offset)))
 
-#ifdef SW_SIM
-#define	NXGE_NPI_PIO_READ64(npi_handle, offset)		\
-	(*(uint64_t *)(NPI_REGP(npi_handle) + offset))
-
-#elif AXIS_DEBUG
-#define	NXGE_NPI_PIO_READ64(npi_handle, offset)		  \
-	ddi_get64(NPI_REGH(npi_handle),		\
-	(uint64_t *)(NPI_REGP(npi_handle) + offset));
-#else
 #define	NXGE_NPI_PIO_READ64(npi_handle, offset)		\
 	(ddi_get64(NPI_REGH(npi_handle),		\
 	(uint64_t *)(NPI_REGP(npi_handle) + offset)))
-#endif
 
 #define	NXGE_NPI_PIO_WRITE8(npi_handle, offset, data)	\
 	(ddi_put8(NPI_REGH(npi_handle),			\
@@ -252,22 +238,10 @@
 	(ddi_put32(NPI_REGH(npi_handle),		\
 	(uint32_t *)(NPI_REGP(npi_handle) + offset), data))
 
-#ifdef SW_SIM
-#define	NXGE_NPI_PIO_WRITE64(npi_handle, offset, data)	\
-	(*((uint64_t *)(NPI_REGP(npi_handle) + (uint64_t)offset)) = \
-	(uint64_t)data);
-#elif defined(AXIS_DEBUG) && !defined(LEGION)
-#define	NXGE_NPI_PIO_WRITE64(npi_handle, offset, data)	{ \
-	ddi_put64(NPI_REGH(npi_handle),		\
-	(uint64_t *)(NPI_REGP(npi_handle) + offset), data); \
-}
-#else
 #define	NXGE_NPI_PIO_WRITE64(npi_handle, offset, data)	\
 	(ddi_put64(NPI_REGH(npi_handle),		\
 	(uint64_t *)(NPI_REGP(npi_handle) + offset), data))
 
-#endif
-
 #define	NXGE_MEM_PIO_READ8(npi_handle)		\
 	(ddi_get8(NPI_REGH(npi_handle), (uint8_t *)NPI_REGP(npi_handle)))
 
@@ -317,639 +291,14 @@
 		ddi_check_acc_handle(nxgep->dev_regs->nxge_regh)
 #define	FM_GET_DEVSTATE(nxgep)\
 		ddi_get_devstate(nxgep->dip)
-#ifdef	NXGE_FM
 #define	FM_SERVICE_RESTORED(nxgep)\
 		ddi_fm_service_impact(nxgep->dip, DDI_SERVICE_RESTORED)
 #define	NXGE_FM_REPORT_ERROR(nxgep, portn, chan, ereport_id)\
 		nxge_fm_report_error(nxgep, portn, chan, ereport_id)
-#else
-#define	FM_SERVICE_RESTORED(nxgep)
-#define	NXGE_FM_REPORT_ERROR(nxgep, portn, chan, ereport_id)
-#endif
-
-#elif	defined(LINUX) && defined(__KERNEL_)
-
-#include <linux/config.h>
-#include <linux/version.h>
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/compiler.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/pci.h>
-#include <linux/mm.h>
-#include <linux/highmem.h>
-#include <linux/list.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/ethtool.h>
-#include <linux/crc32.h>
-#include <linux/random.h>
-/* #include <linux/mii.h> */
-#include <linux/if_vlan.h>
-#include <linux/llc.h>
-#include <linux/ip.h>
-#include <linux/ipv6.h>
-#include <linux/tcp.h>
-#include <linux/udp.h>
-
-#include <net/checksum.h>
-
-#include <asm/atomic.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/byteorder.h>
-#include <asm/uaccess.h>
-
-typedef unsigned char	uchar_t;
-typedef unsigned short	ushort_t;
-typedef unsigned int	uint_t;
-typedef unsigned long	ulong_t;
-
-#define	uintptr_t	unsigned long
-
-#define	ETHERADDRL ETH_ALEN
-/*
- * Ethernet address - 6 octets
- */
-struct	ether_addr {
-	uchar_t ether_addr_octet[ETHERADDRL];
-};
-
-typedef struct ether_addr ether_addr_st, *p_ether_addr_t;
-
-typedef enum {
-#undef B_FALSE
-	B_FALSE = 0,
-#undef B_TRUE
-	B_TRUE = 1
-} boolean_t;
-
-typedef enum  {
-	BKSIZE_4K,
-	BKSIZE_8K,
-	BKSIZE_16K,
-	BKSIZE_32K
-} nxge_rx_block_size_t;
-
-#ifdef NXGE_DEBUG
-#define	NXGE_DEBUG_MSG(params) nxge_debug_msg params
-#define	NXGE_WARN_MSG(params) nxge_debug_msg params
-#else
-#define	NXGE_DEBUG_MSG(params)
-#define	NXGE_WARN_MSG(params)
-#endif
-
-#define	NXGE_ERROR_MSG(params) nxge_debug_msg params
-
-#define	NPI_INPUT_ERR(funcname, param, val) \
-	printk(KERN_ERR "%s: Invalid Input: %s <0x%x>\n", funcname, param, \
-		(int)val);
-
-#define	NPI_HW_ERR(funcname, reg, val) \
-	printk(KERN_ERR "%s: HW Error: %s <0x%x>\n", funcname, reg, (int)val);
-
-
-#define	IS_PORT_NUM_VALID(portn) \
-	(portn < 4)
-
-
-typedef spinlock_t			nxge_os_mutex_t;
-typedef	rwlock_t			nxge_os_rwlock_t;
-
-typedef	struct pci_dev			nxge_dev_info_t;
-typedef	void * 				nxge_intr_cookie_t;
-
-typedef void *				nxge_os_acc_handle_t;
-typedef	nxge_os_acc_handle_t		npi_reg_handle_t;
-typedef char				*npi_reg_ptr_t;
-
-typedef void *				nxge_os_dma_handle_t;
-typedef void				nxge_os_dma_common_t;
-typedef void				nxge_os_block_mv_t;
-typedef int				nxge_os_frtn_t;
-
-#define	MUTEX_INIT(lock, nm, tp, arg)	spin_lock_init((lock))
-#define	MUTEX_ENTER(lock)		spin_lock((lock))
-#define	MUTEX_TRY_ENTER(lock)		spin_trylock((lock))
-#define	MUTEX_EXIT(lock)		spin_unlock((lock))
-#define	MUTEX_ENTER_INT(lock, flags)	spin_lock_irqsave(lock, flags)
-#define	MUTEX_EXIT_INT(lock, flags)	spin_unlock_irqrestore(lock, flags)
-#define	MUTEX_DESTROY(lock)
-
-#define	RW_INIT(lock, nm, tp, arg)	rw_lock_init((lock))
-#define	RW_ENTER_WRITER(lock)		write_lock(lock)
-#define	RW_ENTER_READER(lock)		read_lock(lock)
-#define	RW_EXIT(lock)			write_unlock(lock)
-#define	RW_EXIT_READ(lock)		read_unlock(lock)
-#define	RW_DESTROY(lock)
-
-#define	NXGE_DELAY(microseconds)	(udelay(microseconds))
-
-static inline void * nxge_kzalloc(size_t size, int flag)
-{
-	void * ptr = kmalloc(size, flag);
-	if (ptr != NULL)
-		memset(ptr, 0, size);
-
-	return (ptr);
-}
-
-#define	KMEM_ALLOC(size, flag)		kmalloc(size, flag)
-#define	KMEM_ZALLOC(size, flag)		nxge_kzalloc(size, flag)
-#define	KMEM_FREE(buf, size)		kfree(buf)
-
-#ifndef readq
-static inline uint64_t readq(void *addr)
-{
-	uint64_t ret = readl(addr + 4);
-	ret <<= 32;
-	ret |= readl(addr);
-
-	return (ret);
-}
-#endif
-
-#ifndef writeq
-static inline void writeq(uint64_t val, void *addr)
-{
-	writel((uint32_t)(val), addr);
-	writel((uint32_t)(val >> 32), (addr + 4));
-}
-
-/*
- * In 32 bit modes, some registers have to be written in a
- * particular order to expect correct hardware operation. The
- * macro SPECIAL_REG_WRITE is used to perform such ordered
- * writes. Defines UF(Upper First) and LF(Lower First) will
- * be used to specify the required write order.
- */
-#define	UF	1
-#define	LF	2
-static inline void SPECIAL_REG_WRITE(uint64_t val, void *addr, int order)
-{
-	if (order == LF) {
-		writel((uint32_t)(val), addr);
-		writel((uint32_t)(val >> 32), (addr + 4));
-	} else {
-	writel((uint32_t)(val >> 32), (addr + 4));
-	writel((uint32_t)(val), addr);
-	}
-}
-#else
-#define	SPECIAL_REG_WRITE(val, addr, dummy) writeq(val, addr)
-#endif
-
-#define	NXGE_PIO_READ8(handle, devaddr, offset)		\
-	(readb((caddr_t)devaddr + offset))
-
-#define	NXGE_PIO_READ16(handle, devaddr, offset)	\
-	(readw((caddr_t)devaddr + offset))
-
-#define	NXGE_PIO_READ32(handle, devaddr, offset)	\
-	(readl((caddr_t)devaddr + offset))
-
-#ifdef SW_SIM
-#define	NXGE_PIO_READ64(handle, devaddr, offset)	\
-	(*((uint64_t *)(devaddr + offset)))
-#elif AXIS_DEBUG
-#define	NXGE_PIO_READ64(handle, devaddr, offset) {	\
-	readq((caddr_t)devaddr + offset);		\
-	mdelay(100);					\
-}
-#else
-#define	NXGE_PIO_READ64(handle, devaddr, offset)	\
-	(readq((caddr_t)devaddr + offset))
-#endif
-
-#define	NXGE_PIO_WRITE8(handle, devaddr, offset, data)	\
-	(writeb(data, ((caddr_t)devaddr + offset))
-
-#define	NXGE_PIO_WRITE16(handle, devaddr, offset, data)	\
-	(writew(data, ((caddr_t)devaddr + offset)))
-
-#define	NXGE_PIO_WRITE32(handle, devaddr, offset, data)	\
-	(writel(data, ((caddr_t)devaddr + offset)))
-
-#ifdef SW_SIM
-#define	NXGE_PIO_WRITE64(handle, devaddr, offset, data)	\
-	(*((uint64_t *)(devaddr + offset)) = \
-	(uint64_t)data);
-#elif AXIS_DEBUG
-#define	NXGE_PIO_WRITE64(handle, devaddr, offset, data) {	\
-	mdelay(100);						\
-	writeq(data, ((caddr_t)devaddr + offset));		\
-}
-#else
-#define	NXGE_PIO_WRITE64(handle, devaddr, offset, data)	\
-	(writeq(data, ((caddr_t)devaddr + offset)))
-#endif
-
-#define	NXGE_NPI_PIO_READ8(npi_handle, offset)	\
-	(readb(NPI_REGP(npi_handle) + offset))
-
-#define	NXGE_NPI_PIO_READ16(npi_handle, offset)	\
-	(readw(NPI_REGP(npi_handle) + offset))
-
-#define	NXGE_NPI_PIO_READ32(npi_handle, offset)	\
-	(readl(NPI_REGP(npi_handle) + offset))
-
-#ifndef SW_SIM
-#define	NXGE_NPI_PIO_READ64(npi_handle, offset)	\
-	(readq(NPI_REGP(npi_handle) + offset))
-#else
-#define	NXGE_NPI_PIO_READ64(npi_handle, offset)	\
-	(*((uint64_t *)(NPI_REGP(npi_handle) + offset)))
-#endif /* SW_SIM */
-
-#define	NXGE_NPI_PIO_WRITE8(npi_handle, offset, data)	\
-	(writeb(data, NPI_REGP(npi_handle) + offset))
-
-#define	NXGE_NPI_PIO_WRITE16(npi_handle, offset, data)	\
-	(writew(data, NPI_REGP(npi_handle) + offset))
-
-#define	NXGE_NPI_PIO_WRITE32(npi_handle, offset, data)	\
-	(writel(data, NPI_REGP(npi_handle) + offset))
-
-#ifndef SW_SIM
-#define	NXGE_NPI_PIO_WRITE64(npi_handle, offset, data)	\
-	(writeq(data, NPI_REGP(npi_handle) + offset))
-#else
-#define	NXGE_NPI_PIO_WRITE64(npi_handle, offset, data)	\
-	(*((uint64_t *)(NPI_REGP(npi_handle) + (uint64_t)offset)) = \
-	(uint64_t)data);
-#endif /* SW_SIM */
-
-#define	NXGE_MEM_PIO_READ8(npi_handle)	(*((uint8_t *)NPI_REGP(npi_handle)))
-
-#define	NXGE_MEM_PIO_READ16(npi_handle)	(*((uint16_t *)NPI_REGP(npi_handle)))
-
-#define	NXGE_MEM_PIO_READ32(npi_handle)	(*((uint32_t *)NPI_REGP(npi_handle)))
-
-#define	NXGE_MEM_PIO_READ64(npi_handle)	(*((uint64_t *)NPI_REGP(npi_handle)))
-
-#define	NXGE_MEM_PIO_WRITE8(npi_handle, data)	\
-	(*((uint8_t *)NPI_REGP(npi_handle))) = ((uint8_t)data)
-
-#define	NXGE_MEM_PIO_WRITE16(npi_handle, data)	\
-	(*((uint16_t *)NPI_REGP(npi_handle))) = ((uint16_t)data)
-
-#define	NXGE_MEM_PIO_WRITE32(npi_handle, data)	\
-	(*((uint32_t *)NPI_REGP(npi_handle))) = ((uint32_t)data)
-
-#define	NXGE_MEM_PIO_WRITE64(npi_handle, data)	\
-	(*((uint64_t *)NPI_REGP(npi_handle))) = ((uint64_t)data)
-
-#elif	defined(COSIM)
-
-#include <sys/types.h>
-#include <sys/conf.h>
-#if	defined(SOLARIS) && !defined(IODIAG)
-#include <sys/varargs.h>
-#include <ne_sim_solaris.h>
-#endif
-
-#ifdef NXGE_DEBUG
-#define	NXGE_DEBUG_MSG(params) nxge_debug_msg params
-#define	NXGE_ERROR_MSG(params) nxge_debug_msg params
-#else
-#define	NXGE_DEBUG_MSG(params)
-#define	NXGE_ERROR_MSG(params)
-#endif
-
-#if !defined(ETHERADDRL)
-#define	ETHERADDRL 6
-
-/*
- * Ethernet address - 6 octets
- */
-struct	ether_addr {
-	uchar_t ether_addr_octet[ETHERADDRL];
-};
-
-typedef struct ether_addr ether_addr_st, *p_ether_addr_t;
-#endif
-
-#ifdef LINUX
-#include <stdint.h>
-#include <stdio.h>
-#include <stdarg.h>
-#ifndef COSIM_LINUX_DEF
-#define	COSIM_LINUX_DEF
-typedef uint8_t uchar_t;
-typedef uint32_t uint_t;
-typedef uint64_t dma_addr_t;
-
-typedef enum {
-#undef B_FALSE
-	B_FALSE = 0,
-#undef B_TRUE
-	B_TRUE = 1
-} boolean_t;
-
-#endif
-
-typedef enum  {
-	BKSIZE_4K,
-	BKSIZE_8K,
-	BKSIZE_16K,
-	BKSIZE_32K
-} nxge_rx_block_size_t;
-
-#define	IS_PORT_NUM_VALID(portn) \
-	(portn < 4)
-
-#define	GFP_KERNEL	0
-
-#endif /* LINUX in COSIM */
-
-#include <ht_client.h>
-#include <ht_lib.h>
-
-#include <pthread.h>
-
-
-typedef pthread_mutex_t		nxge_os_mutex_t;
-typedef	unsigned int		nxge_os_rwlock_t;
-
-typedef	void * 			nxge_dev_info_t;
-typedef	void * 			nxge_intr_cookie_t;
-typedef void *			nxge_os_dma_handle_t;
-typedef void *			nxge_os_acc_handle_t;
-typedef	nxge_os_acc_handle_t	npi_reg_handle_t;
-typedef	uint64_t		npi_reg_ptr_t;
-
-#if defined(IODIAG)
-#define	timeout(a, b, c)	()
-#define	untimeout(a)	()
-#define	drv_usectohz(a)	()
-#define	drv_usecwait(a)
-#define	ether_cmp(a, b)	(bcmp((caddr_t)a, (caddr_t)b, 6))
-
-typedef int			nxge_os_dma_common_t;
-typedef int			nxge_os_block_mv_t;
-typedef int			nxge_os_frtn_t;
-typedef void *			p_mblk_t;
-typedef void *			MBLKP;
-
-#define	NXGE_MUTEX_DRIVER	NULL
-#define	MUTEX_INIT(lock, name, type, arg)	pthread_mutex_init(lock, NULL)
-
-#define	MUTEX_ENTER(lock)	pthread_mutex_lock((pthread_mutex_t *)lock)
-
-#define	MUTEX_TRY_ENTER(lock)	pthread_mutex_trylock(lock)
-
-#define	MUTEX_EXIT(lock)	pthread_mutex_unlock(lock)
-
-#define	MUTEX_ENTER_INT(lock, flags)	MUTEX_ENTER(lock)
-
-#define	MUTEX_EXIT_INT(lock, flags)	MUTEX_EXIT(lock)
-
-#define	MUTEX_DESTROY(lock)	pthread_mutex_destroy(lock)
-
-#else
-typedef struct _nxge_dma_common_t	nxge_os_dma_common_t;
-typedef struct _nxge_block_mv_t		nxge_os_block_mv_t;
-typedef frtn_t			nxge_os_frtn_t;
-
-#define	NXGE_MUTEX_DRIVER	NULL
-#define	MUTEX_INIT(lock, name, type, arg)
-#define	MUTEX_ENTER(lock)
-#define	MUTEX_TRY_ENTER(lock)
-#define	MUTEX_EXIT(lock)
-#define	MUTEX_ENTER_INT(lock, flags)	MUTEX_ENTER(lock)
-#define	MUTEX_EXIT_INT(lock, flags)	MUTEX_EXIT(lock)
-#define	MUTEX_DESTROY(lock)
-#endif
-
-#define	KMEM_ALLOC(size, flag)		malloc(size)
-#if defined(IODIAG)
-#define	KMEM_ZALLOC(size, flag)		kmem_zalloc(size, flag)
-#else
-#define	KMEM_ZALLOC(size, flag)		malloc(size)
-#endif
-#define	KMEM_FREE(buf, size)		free(buf)
-#define	RW_INIT(lock, name, type, arg)
-#define	RW_ENTER_WRITER(lock)
-#define	RW_ENTER_READER(lock)
-#define	RW_TRY_ENTER(lock, type)
-#define	RW_EXIT(lock)
-#define	RW_EXIT_READ(lock)
-#define	RW_DESTROY(lock)
-#define	NXGE_NOTIFY_NETWORK_STACK(nxgep, event)
-#define	FM_REPORT_FAULT(nxgep, impact, location, msg)
-#define	FM_CHECK_DEV_HANDLE(nxgep)	NULL
-#define	FM_SERVICE_RESTORED(nxgep)
-#define	FM_GET_DEVSTATE(nxgep)	NULL
-#define	NXGE_FM_REPORT_ERROR(nxgep, portn, chan, ereport_id)
-#define	SERVICE_LOST		NULL
-#define	SERVICE_DEGRADED	NULL
-#define	SERVICE_UNAFFECTED	NULL
-#define	SERVICE_RESTORED	NULL
-
-#define	DATAPATH_FAULT		NULL
-#define	DEVICE_FAULT		NULL
-#define	EXTERNAL_FAULT		NULL
-
-#define	NOTE_LINK_UP		NULL
-#define	NOTE_LINK_DOWN		NULL
-#define	NOTE_SPEED		NULL
-#define	NOTE_PHYS_ADDR		NULL
-#define	NOTE_AGGR_AVAIL		NULL
-#define	NOTE_AGGR_UNAVAIL	NULL
-
-#define	kmem_free(buf, size) free(buf)
-
-
-#define	NXGE_DELAY(microseconds)
-
-#define	NXGE_PIO_READ8(handle, devaddr, offset)		\
-	(*(uint8_t *)((caddr_t)devaddr + offset))
-
-#define	NXGE_PIO_READ16(handle, devaddr, offset)	\
-	(*(uint16_t *)((caddr_t)devaddr + offset))
-
-#define	NXGE_PIO_READ32(handle, devaddr, offset)	\
-	(*(uint32_t *)((caddr_t)devaddr + offset))
-
-#define	NXGE_PIO_READ64(handle, devaddr, offset)	\
-	(*(uint64_t *)((caddr_t)devaddr + offset))
-
-#define	NXGE_PIO_WRITE8(handle, devaddr, offset, data)	\
-	(*((uint8_t *)((caddr_t)devaddr + offset)) = (uint8_t)data);
-
-#define	NXGE_PIO_WRITE16(handle, devaddr, offset, data)	\
-	(*((uint16_t *)((caddr_t)devaddr + offset)) = (uint16_t)data);
-
-#define	NXGE_PIO_WRITE32(handle, devaddr, offset, data)	\
-	(*((uint32_t *)((caddr_t)devaddr + offset)) = (uint32_t)data);
-
-#define	NXGE_PIO_WRITE64(handle, devaddr, offset, data)	\
-	(*((uint64_t *)((caddr_t)devaddr + offset)) = (uint64_t)data);
-
-#ifdef IODIAG_NEPTUNE
-#define	NXGE_NPI_PIO_WRITE64(handle, offset, value) {	\
-	htSetQWord((uint64_t)offset, value);		\
-	us_delay(100000);				\
-}
-#else
-#define	NXGE_NPI_PIO_WRITE64(handle, offset, value) \
-	htSetQWord((uint64_t)offset, value)
-#endif
-
-#define	NXGE_NPI_PIO_WRITE32(handle, offset, value) \
-	htSetDWord((uint64_t)offset, value)
-
-#define	NXGE_NPI_PIO_READ64(handle, offset) \
-	htread64((uint64_t)offset)
-
-#define	NXGE_NPI_PIO_READ32(handle, offset) \
-	htread32((uint64_t)offset)
-
-#define	NXGE_MEM_PIO_READ8(npi_handle)	(*(uint8_t *)(NPI_REGP(npi_handle)))
-
-#define	NXGE_MEM_PIO_READ16(npi_handle)	(*(uint16_t *)(NPI_REGP(npi_handle)))
-
-#define	NXGE_MEM_PIO_READ32(npi_handle)	(*(uint32_t *)(NPI_REGP(npi_handle)))
-
-#define	NXGE_MEM_PIO_READ64(npi_handle)	(*(uint64_t *)(NPI_REGP(npi_handle)))
-
-#define	NXGE_MEM_PIO_WRITE8(npi_handle, data)	\
-	(*((uint8_t *)NPI_REGP(npi_handle)) = (uint8_t)data);
-
-#define	NXGE_MEM_PIO_WRITE16(npi_handle, data)	\
-	(*((uint16_t *)NPI_REGP(npi_handle)) = (uint16_t)data);
-
-#define	NXGE_MEM_PIO_WRITE32(npi_handle, data)	\
-	(*((uint32_t *)NPI_REGP(npi_handle)) = (uint32_t)data);
-
-#define	NXGE_MEM_PIO_WRITE64(npi_handle, data)	\
-	(*((uint64_t *)NPI_REGP(npi_handle)) = (uint64_t)data);
-
-#define	NPI_INPUT_ERR(funcname, param, val) \
-	printf("%s: Invalid Input: %s <0x%x>\n", funcname, param, (int)val);
-
-#define	NPI_HW_ERR(funcname, reg, val) \
-	printf("%s: HW Error: %s <0x%x>\n", funcname, reg, (int)val);
-
-
-
-#elif	defined(SW_SIM)
-typedef unsigned int			nxge_os_mutex_t;
-typedef	unsigned int			nxge_os_rwlock_t;
-
-typedef	unsigned int			nxge_dev_info_t;
-typedef	void * 				nxge_intr_cookie_t;
-typedef void *				nxge_os_acc_handle_t;
-typedef	nxge_os_acc_handle_t		npi_reg_handle_t;
-typedef	uint64_t			npi_reg_ptr_t;
-
-typedef unsigned int			nxge_os_dma_handle_t;
-typedef unsigned int			nxge_os_dma_common_t;
-typedef unsigned int				nxge_os_block_mv_t;
-typedef int				nxge_os_frtn_t;
-typedef void *			p_mblk_t;
-
-typedef struct ether_addr ether_addr_st, *p_ether_addr_t;
-#define	NXGE_MUTEX_DRIVER		MUTEX_DRIVER
-#define	MUTEX_INIT(lock, name, type, arg)	\
-					mutex_init(lock, name, type, arg)
-#define	MUTEX_ENTER(lock)		mutex_enter(lock)
-#define	MUTEX_TRY_ENTER(lock)		mutex_tryenter(lock)
-#define	MUTEX_EXIT(lock)		mutex_exit(lock)
-#define	MUTEX_DESTROY(lock)		mutex_destroy(lock)
-
-#define	RW_INIT(lock, nm, tp, arg)
-#define	RW_ENTER_WRITER(lock)
-#define	RW_ENTER_READER(lock)
-#define	RW_EXIT(lock)
-#define	RW_DESTROY(lock)
-
-#define	NXGE_DELAY(microseconds)
-
-#define	NXGE_PIO_READ8(handle, devaddr, offset)		\
-	(*(uint8_t *)((caddr_t)devaddr + offset))
-
-#define	NXGE_PIO_READ16(handle, devaddr, offset)	\
-	(*(uint16_t *)((caddr_t)devaddr + offset))
-
-#define	NXGE_PIO_READ32(handle, devaddr, offset)	\
-	(*(uint32_t *)((caddr_t)devaddr + offset))
-
-#define	NXGE_PIO_READ64(handle, devaddr, offset)	\
-	(*(uint64_t *)((caddr_t)devaddr + offset))
-
-#define	NXGE_PIO_WRITE8(handle, devaddr, offset, data)	\
-	(*((uint8_t *)((caddr_t)devaddr + offset)) = (uint8_t)data);
-
-#define	NXGE_PIO_WRITE16(handle, devaddr, offset, data)	\
-	(*((uint16_t *)((caddr_t)devaddr + offset)) = (uint16_t)data);
-
-#define	NXGE_PIO_WRITE32(handle, devaddr, offset, data)	\
-	(*((uint32_t *)((caddr_t)devaddr + offset)) = (uint32_t)data);
-
-#define	NXGE_PIO_WRITE64(handle, devaddr, offset, data)	\
-	(*((uint64_t *)((caddr_t)devaddr + offset)) = (uint64_t)data);
-
-
-#define	NXGE_NPI_PIO_READ8(npi_handle, offset)	\
-	(*((uint8_t *)(NPI_REGP(npi_handle) + offset)))
-
-#define	NXGE_NPI_PIO_READ16(npi_handle, offset)	\
-	(*((uint16_t *)(NPI_REGP(npi_handle) + offset)))
-
-#define	NXGE_NPI_PIO_READ32(npi_handle, offset)	\
-	(*((uint32_t *)(NPI_REGP(npi_handle) + offset)));
-
-#define	NXGE_NPI_PIO_READ64(npi_handle, offset)	\
-	(*(uint64_t *)(NPI_REGP(npi_handle) + offset));
-
-#define	NXGE_NPI_PIO_WRITE8(npi_handle, offset, data)	\
-	(*((uint8_t *)(NPI_REGP(npi_handle) + offset)) = (uint8_t)data);
-
-#define	NXGE_NPI_PIO_WRITE16(npi_handle, offset, data)	\
-	(*((uint16_t *)(NPI_REGP(npi_handle) + offset)) = (uint16_t)data);
-
-#define	NXGE_NPI_PIO_WRITE32(npi_handle, offset, data)	\
-	(*((uint32_t *)(NPI_REGP(npi_handle) + offset)) = (uint32_t)data);
-
-#define	NXGE_NPI_PIO_WRITE64(npi_handle, offset, data)	\
-	(*((uint64_t *)(NPI_REGP(npi_handle) + (uint64_t)offset)) = \
-		(uint64_t)data);
-
-#define	NXGE_MEM_PIO_READ8(npi_handle)	(*(uint8_t *)(NPI_REGP(npi_handle)))
-
-#define	NXGE_MEM_PIO_READ16(npi_handle)	(*(uint16_t *)(NPI_REGP(npi_handle)))
-
-#define	NXGE_MEM_PIO_READ32(npi_handle)	(*(uint32_t *)(NPI_REGP(npi_handle)))
-
-#define	NXGE_MEM_PIO_READ64(npi_handle)	(*(uint64_t *)(NPI_REGP(npi_handle)))
-
-#define	NXGE_MEM_PIO_WRITE8(npi_handle, data)	\
-	(*((uint8_t *)NPI_REGP(npi_handle)) = (uint8_t)data);
-
-#define	NXGE_MEM_PIO_WRITE16(npi_handle, data)	\
-	(*((uint16_t *)NPI_REGP(npi_handle)) = (uint16_t)data);
-
-#define	NXGE_MEM_PIO_WRITE32(npi_handle, data)	\
-	(*((uint32_t *)NPI_REGP(npi_handle)) = (uint32_t)data);
-
-#define	NXGE_MEM_PIO_WRITE64(npi_handle, data)	\
-	(*((uint64_t *)NPI_REGP(npi_handle)) = (uint64_t)data);
-
-
-#define	NPI_INPUT_ERR(funcname, param, val) \
-	printf("%s: Invalid Input: %s <0x%x>\n", funcname, param, (int)val);
-
-#define	NPI_HW_ERR(funcname, reg, val) \
-	printf("%s: HW Error: %s <0x%x>\n", funcname, reg, (int)val);
-
+#define	FM_CHECK_ACC_HANDLE(nxgep, handle)\
+		fm_check_acc_handle(handle)
+#define	FM_CHECK_DMA_HANDLE(nxgep, handle)\
+		fm_check_dma_handle(handle)
 
 #endif
 
--- a/usr/src/uts/sun4v/sys/nxge/nxge_fflp_hw.h	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/sys/nxge/nxge_fflp_hw.h	Fri Dec 22 12:42:28 2006 -0800
@@ -1299,15 +1299,11 @@
 
 #if defined(SOLARIS) || defined(COSIM)
 #include <netinet/in.h>
-#else
-#include <linux/in.h>
-#include <linux/in6.h>
 #endif
 
-
 typedef union flow_template {
 
-    struct {
+	struct {
 #if defined(_BIG_ENDIAN)
 		uint32_t l4_0:16;  /* src port */
 		uint32_t l4_1:16;  /* dest Port */
--- a/usr/src/uts/sun4v/sys/nxge/nxge_flow.h	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/sys/nxge/nxge_flow.h	Fri Dec 22 12:42:28 2006 -0800
@@ -34,20 +34,8 @@
 
 #if defined(SOLARIS) && defined(_KERNEL)
 #include <netinet/in.h>
-#define	 S6_addr32		_S6_un._S6_u32
-#elif defined(LINUX) && defined(__KERNEL_)
-#include <linux/in.h>
-#include <linux/in6.h>
-#define	 S6_addr32		s6_addr32
-#elif defined(COSIM) || defined(IODIAG)
-#include <netinet/in.h>
-#if defined(LINUX)
-#define	S6_addr32		s6_addr32
-#else
-#define	S6_addr32		_S6_un._S6_u32
+#define	S6_addr32	_S6_un._S6_u32
 #endif
-#endif
-
 
 typedef struct tcpip4_spec_s {
 	in_addr_t  ip4src;
--- a/usr/src/uts/sun4v/sys/nxge/nxge_fm.h	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/sys/nxge/nxge_fm.h	Fri Dec 22 12:42:28 2006 -0800
@@ -34,6 +34,7 @@
 
 #include <sys/ddi.h>
 
+#define	ERNAME_DETAILED_ERR_TYPE	"detailed error type"
 #define	ERNAME_ERR_PORTN		"port number"
 #define	ERNAME_ERR_DCHAN		"dma channel number"
 #define	ERNAME_TCAM_ERR_LOG		"tcam error log"
@@ -101,6 +102,7 @@
 
 typedef	struct _nxge_fm_ereport_attr {
 	uint32_t		index;
+	char			*str;
 	char			*eclass;
 	ddi_fault_impact_t	impact;
 } nxge_fm_ereport_attr_t;
--- a/usr/src/uts/sun4v/sys/nxge/nxge_impl.h	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/sys/nxge/nxge_impl.h	Fri Dec 22 12:42:28 2006 -0800
@@ -91,7 +91,7 @@
 #if	defined(_KERNEL)
 #include 	<sys/mac.h>
 #include	<sys/mac_impl.h>
-#include 	<sys/mac_ether.h>
+#include	<sys/mac_ether.h>
 #endif
 
 #if	defined(sun4v)
@@ -260,7 +260,7 @@
 #define	NXGE_RDC_RCR_THRESHOLD		8
 #define	NXGE_RDC_RCR_TIMEOUT		16
 
-#define	NXGE_RDC_RCR_THRESHOLD_MAX	256
+#define	NXGE_RDC_RCR_THRESHOLD_MAX	1024
 #define	NXGE_RDC_RCR_TIMEOUT_MAX	64
 #define	NXGE_RDC_RCR_THRESHOLD_MIN	1
 #define	NXGE_RDC_RCR_TIMEOUT_MIN	1
@@ -588,12 +588,16 @@
 extern int drv_priv(cred_t *);
 extern void nxge_fm_report_error(p_nxge_t, uint8_t,
 			uint8_t, nxge_fm_ereport_id_t);
+extern int fm_check_acc_handle(ddi_acc_handle_t);
+extern int fm_check_dma_handle(ddi_dma_handle_t);
 
 #pragma weak    secpolicy_net_config
 
 /* nxge_classify.c */
 nxge_status_t nxge_classify_init(p_nxge_t);
+nxge_status_t nxge_classify_uninit(p_nxge_t);
 nxge_status_t nxge_set_hw_classify_config(p_nxge_t);
+nxge_status_t nxge_classify_exit_sw(p_nxge_t);
 
 /* nxge_fflp.c */
 void nxge_put_tcam(p_nxge_t, p_mblk_t);
--- a/usr/src/uts/sun4v/sys/nxge/nxge_ipp.h	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/sys/nxge/nxge_ipp.h	Fri Dec 22 12:42:28 2006 -0800
@@ -74,6 +74,7 @@
 nxge_status_t nxge_ipp_disable(p_nxge_t);
 nxge_status_t nxge_ipp_handle_sys_errors(p_nxge_t);
 nxge_status_t nxge_ipp_fatal_err_recover(p_nxge_t);
+nxge_status_t nxge_ipp_eccue_valid_check(p_nxge_t, boolean_t *);
 void nxge_ipp_inject_err(p_nxge_t, uint32_t);
 
 #ifdef	__cplusplus
--- a/usr/src/uts/sun4v/sys/nxge/nxge_ipp_hw.h	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/sys/nxge/nxge_ipp_hw.h	Fri Dec 22 12:42:28 2006 -0800
@@ -237,8 +237,8 @@
 
 /* DFIFO RD/WR pointers mask */
 
-#define	IPP_XMAC_DFIFO_PTR_MASK			0xFFF
-#define	IPP_BMAC_DFIFO_PTR_MASK			0x7FF
+#define	IPP_XMAC_DFIFO_PTR_MASK			0x7FF
+#define	IPP_BMAC_DFIFO_PTR_MASK			0x3FF
 
 #define	IPP_ECC_CNT_MASK			0xFF
 #define	IPP_BAD_CS_CNT_MASK			0x3FFF
--- a/usr/src/uts/sun4v/sys/nxge/nxge_rxdma.h	Fri Dec 22 11:52:51 2006 -0800
+++ b/usr/src/uts/sun4v/sys/nxge/nxge_rxdma.h	Fri Dec 22 12:42:28 2006 -0800
@@ -271,6 +271,8 @@
 	uint64_t		rcr_tail_pp;
 	uint64_t		rcr_head_pp;
 	struct _rx_rbr_ring_t	*rx_rbr_p;
+	uint32_t		intr_timeout;
+	uint32_t		intr_threshold;
 	uint64_t		max_receive_pkts;
 	p_mblk_t		rx_first_mp;
 	mac_resource_handle_t	rcr_mac_handle;