changeset 5248:d7358c93caa7

6567332 Support for CPC on greyhound/barcelona processors
author ksadhukh
date Fri, 12 Oct 2007 11:22:11 -0700
parents 6a1142bafc41
children 17ef077de620
files usr/src/pkgdefs/SUNWcpcu/prototype_i386 usr/src/uts/i86pc/os/cpuid.c usr/src/uts/intel/opteron_pcbe/Makefile usr/src/uts/intel/pcbe/opteron_pcbe.c usr/src/uts/intel/sys/x86_archext.h
diffstat 5 files changed, 197 insertions(+), 77 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/pkgdefs/SUNWcpcu/prototype_i386	Fri Oct 12 09:20:32 2007 -0700
+++ b/usr/src/pkgdefs/SUNWcpcu/prototype_i386	Fri Oct 12 11:22:11 2007 -0700
@@ -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 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 #ident	"%Z%%M%	%I%	%E% SMI"
@@ -46,12 +45,14 @@
 d none usr/bin/i86 755 root bin
 f none usr/bin/i86/cputrack 555 root bin
 f none usr/kernel/pcbe/pcbe.AuthenticAMD.15 755 root sys
+l none usr/kernel/pcbe/pcbe.AuthenticAMD.16=pcbe.AuthenticAMD.15 755 root sys
 f none usr/kernel/pcbe/pcbe.GenuineIntel.6 755 root sys
 l none usr/kernel/pcbe/pcbe.GenuineIntel.5=pcbe.GenuineIntel.6 755 root sys
 f none usr/kernel/pcbe/pcbe.GenuineIntel.15 755 root sys
 d none usr/kernel/pcbe/amd64 755 root sys
 f none usr/kernel/pcbe/amd64/pcbe.GenuineIntel.15 755 root sys
 f none usr/kernel/pcbe/amd64/pcbe.AuthenticAMD.15 755 root sys
+l none usr/kernel/pcbe/amd64/pcbe.AuthenticAMD.16=pcbe.AuthenticAMD.15 755 root sys
 f none usr/kernel/pcbe/amd64/pcbe.GenuineIntel.6 755 root sys
 l none usr/kernel/pcbe/amd64/pcbe.GenuineIntel.5=pcbe.GenuineIntel.6 755 root sys
 d none usr/bin/amd64 755 root bin
--- a/usr/src/uts/i86pc/os/cpuid.c	Fri Oct 12 09:20:32 2007 -0700
+++ b/usr/src/uts/i86pc/os/cpuid.c	Fri Oct 12 11:22:11 2007 -0700
@@ -268,11 +268,14 @@
 	cpi->cpi_family >= 0xf)
 
 /*
- * AMD family 0xf socket types.
- * First index is 0 for revs B thru E, 1 for F and G.
+ * AMD family 0xf and family 0x10 socket types.
+ * First index :
+ *		0 for family 0xf, revs B thru E
+ *		1 for family 0xf, revs F and G
+ *		2 for family 0x10, rev B
  * Second index by (model & 0x3)
  */
-static uint32_t amd_skts[2][4] = {
+static uint32_t amd_skts[3][4] = {
 	{
 		X86_SOCKET_754,		/* 0b00 */
 		X86_SOCKET_940,		/* 0b01 */
@@ -284,14 +287,18 @@
 		X86_SOCKET_F1207,	/* 0b01 */
 		X86_SOCKET_UNKNOWN,	/* 0b10 */
 		X86_SOCKET_AM2		/* 0b11 */
+	},
+	{
+		X86_SOCKET_F1207,	/* 0b00 */
+		X86_SOCKET_F1207,	/* 0b01 */
+		X86_SOCKET_F1207,	/* 0b10 */
+		X86_SOCKET_F1207	/* 0b11 */
 	}
 };
 
 /*
- * Table for mapping AMD Family 0xf model/stepping combination to
- * chip "revision" and socket type.  Only rm_family 0xf is used at the
- * moment, but AMD family 0x10 will extend the exsiting revision names
- * so will likely also use this table.
+ * Table for mapping AMD Family 0xf and AMD Family 0x10 model/stepping
+ * combination to chip "revision" and socket type.
  *
  * The first member of this array that matches a given family, extended model
  * plus model range, and stepping range will be considered a match.
@@ -337,6 +344,10 @@
 	 * Rev G has extended model 0x6.
 	 */
 	{ 0xf, 0x60, 0x6f, 0x0, 0xf, X86_CHIPREV_AMD_F_REV_G, "G", 1 },
+	/*
+	 * Family 0x10 Rev B has model 0x2.
+	 */
+	{ 0x10, 0x02, 0x02, 0x0, 0xa, X86_CHIPREV_AMD_10_REV_B, "B", 2 }
 };
 
 /*
@@ -372,9 +383,9 @@
 	int i;
 
 	/*
-	 * Currently only AMD family 0xf uses these fields.
+	 * Currently only AMD family 0xf and family 0x10 use these fields.
 	 */
-	if (cpi->cpi_family != 0xf)
+	if (cpi->cpi_family != 0xf && cpi->cpi_family != 0x10)
 		return;
 
 	family = cpi->cpi_family;
--- a/usr/src/uts/intel/opteron_pcbe/Makefile	Fri Oct 12 09:20:32 2007 -0700
+++ b/usr/src/uts/intel/opteron_pcbe/Makefile	Fri Oct 12 11:22:11 2007 -0700
@@ -19,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 #ident	"%Z%%M%	%I%	%E% SMI"
@@ -36,6 +36,7 @@
 OBJECTS		= $(OPTERON_PCBE_OBJS:%=$(OBJS_DIR)/%)
 LINTS		= $(OPTERON_PCBE_OBJS:%.o=$(LINTS_DIR)/%.ln)
 ROOTMODULE	= $(USR_PCBE_DIR)/$(MODULE)
+ROOTLINK	= $(USR_PCBE_DIR)/pcbe.AuthenticAMD.16
 
 #
 #	Include common rules.
@@ -48,7 +49,7 @@
 ALL_TARGET	= $(BINARY)
 LINT_MODULE	= opteron_pcbe
 LINT_TARGET	= $(LINT_MODULE).lint
-INSTALL_TARGET	= $(BINARY) $(ROOTMODULE)
+INSTALL_TARGET	= $(BINARY) $(ROOTMODULE) $(ROOTLINK)
 
 #
 # For now, disable these lint checks; maintainers should endeavor
@@ -79,6 +80,9 @@
 
 install:	$(INSTALL_DEPS)
 
+$(ROOTLINK):    $(ROOTMODULE)
+	-$(RM) $@; ln $(ROOTMODULE) $@
+
 #
 #	Include common targets.
 #
--- a/usr/src/uts/intel/pcbe/opteron_pcbe.c	Fri Oct 12 09:20:32 2007 -0700
+++ b/usr/src/uts/intel/pcbe/opteron_pcbe.c	Fri Oct 12 11:22:11 2007 -0700
@@ -81,6 +81,8 @@
  * Define offsets and masks for the fields in the Performance
  * Event-Select (PES) registers.
  */
+#define	OPT_PES_HOST_SHIFT	41
+#define	OPT_PES_GUEST_SHIFT	40
 #define	OPT_PES_CMASK_SHIFT	24
 #define	OPT_PES_CMASK_MASK	0xFF
 #define	OPT_PES_INV_SHIFT	23
@@ -93,13 +95,15 @@
 #define	OPT_PES_UMASK_SHIFT	8
 #define	OPT_PES_UMASK_MASK	0xFF
 
-#define	OPT_PES_INV		(1 << OPT_PES_INV_SHIFT)
-#define	OPT_PES_ENABLE		(1 << OPT_PES_ENABLE_SHIFT)
-#define	OPT_PES_INT		(1 << OPT_PES_INT_SHIFT)
-#define	OPT_PES_PC		(1 << OPT_PES_PC_SHIFT)
-#define	OPT_PES_EDGE		(1 << OPT_PES_EDGE_SHIFT)
-#define	OPT_PES_OS		(1 << OPT_PES_OS_SHIFT)
-#define	OPT_PES_USR		(1 << OPT_PES_USR_SHIFT)
+#define	OPT_PES_INV		(1ULL << OPT_PES_INV_SHIFT)
+#define	OPT_PES_ENABLE		(1ULL << OPT_PES_ENABLE_SHIFT)
+#define	OPT_PES_INT		(1ULL << OPT_PES_INT_SHIFT)
+#define	OPT_PES_PC		(1ULL << OPT_PES_PC_SHIFT)
+#define	OPT_PES_EDGE		(1ULL << OPT_PES_EDGE_SHIFT)
+#define	OPT_PES_OS		(1ULL << OPT_PES_OS_SHIFT)
+#define	OPT_PES_USR		(1ULL << OPT_PES_USR_SHIFT)
+#define	OPT_PES_HOST		(1ULL << OPT_PES_HOST_SHIFT)
+#define	OPT_PES_GUEST		(1ULL << OPT_PES_GUEST_SHIFT)
 
 typedef struct _opt_pcbe_config {
 	uint8_t		opt_picno;	/* Counter number: 0, 1, 2, or 3 */
@@ -114,11 +118,11 @@
 	{ 3, 0, 0 }
 };
 
-typedef struct _opt_event {
+typedef struct _amd_event {
 	char		*name;
-	uint8_t		emask;		/* Event mask setting */
+	uint16_t	emask;		/* Event mask setting */
 	uint8_t		umask_valid;	/* Mask of unreserved UNIT_MASK bits */
-} opt_event_t;
+} amd_event_t;
 
 /*
  * Base MSR addresses for the PerfEvtSel registers and the counters themselves.
@@ -131,44 +135,33 @@
 
 #define	EV_END {NULL, 0, 0}
 
-#define	OPT_cmn_events							\
-	{ "FP_dispatched_fpu_ops",			0x0, 0x1F },	\
+#define	AMD_cmn_events							\
+	{ "FP_dispatched_fpu_ops",			0x0, 0x3F },	\
 	{ "FP_cycles_no_fpu_ops_retired",		0x1, 0x0 },	\
 	{ "FP_dispatched_fpu_ops_ff",			0x2, 0x0 },	\
 	{ "LS_seg_reg_load",				0x20, 0x7F },	\
 	{ "LS_uarch_resync_self_modify",		0x21, 0x0 },	\
 	{ "LS_uarch_resync_snoop",			0x22, 0x0 },	\
 	{ "LS_buffer_2_full",				0x23, 0x0 },	\
-	{ "LS_locked_operation",			0x24, 0x7 },	\
 	{ "LS_retired_cflush",				0x26, 0x0 },	\
 	{ "LS_retired_cpuid",				0x27, 0x0 },	\
 	{ "DC_access",					0x40, 0x0 },	\
 	{ "DC_miss",					0x41, 0x0 },	\
 	{ "DC_refill_from_L2",				0x42, 0x1F },	\
 	{ "DC_refill_from_system",			0x43, 0x1F },	\
-	{ "DC_copyback",				0x44, 0x1F },	\
-	{ "DC_dtlb_L1_miss_L2_hit",			0x45, 0x0 },	\
-	{ "DC_dtlb_L1_miss_L2_miss",			0x46, 0x0 },	\
 	{ "DC_misaligned_data_ref",			0x47, 0x0 },	\
 	{ "DC_uarch_late_cancel_access",		0x48, 0x0 },	\
 	{ "DC_uarch_early_cancel_access",		0x49, 0x0 },	\
-	{ "DC_1bit_ecc_error_found",			0x4A, 0x3 },	\
 	{ "DC_dispatched_prefetch_instr",		0x4B, 0x7 },	\
 	{ "DC_dcache_accesses_by_locks",		0x4C, 0x2 },	\
 	{ "BU_memory_requests",				0x65, 0x83},	\
 	{ "BU_data_prefetch",				0x67, 0x3 },	\
-	{ "BU_system_read_responses",			0x6C, 0x7 },	\
-	{ "BU_quadwords_written_to_system",		0x6D, 0x1 },	\
 	{ "BU_cpu_clk_unhalted",			0x76, 0x0 },	\
-	{ "BU_internal_L2_req",				0x7D, 0x1F },	\
-	{ "BU_fill_req_missed_L2",			0x7E, 0x7 },	\
-	{ "BU_fill_into_L2",				0x7F, 0x1 },	\
 	{ "IC_fetch",					0x80, 0x0 },	\
 	{ "IC_miss",					0x81, 0x0 },	\
 	{ "IC_refill_from_L2",				0x82, 0x0 },	\
 	{ "IC_refill_from_system",			0x83, 0x0 },	\
 	{ "IC_itlb_L1_miss_L2_hit",			0x84, 0x0 },	\
-	{ "IC_itlb_L1_miss_L2_miss",			0x85, 0x0 },	\
 	{ "IC_uarch_resync_snoop",			0x86, 0x0 },	\
 	{ "IC_instr_fetch_stall",			0x87, 0x0 },	\
 	{ "IC_return_stack_hit",			0x88, 0x0 },	\
@@ -184,7 +177,6 @@
 	{ "FR_retired_near_rets",			0xC8, 0x0 },	\
 	{ "FR_retired_near_rets_mispred",		0xC9, 0x0 },	\
 	{ "FR_retired_taken_branches_mispred_addr_miscop",	0xCA, 0x0 },\
-	{ "FR_retired_fpu_instr",			0xCB, 0xF },	\
 	{ "FR_retired_fastpath_double_op_instr",	0xCC, 0x7 },	\
 	{ "FR_intr_masked_cycles",			0xCD, 0x0 },	\
 	{ "FR_intr_masked_while_pending_cycles",	0xCE, 0x0 },	\
@@ -205,10 +197,24 @@
 	{ "FR_num_brkpts_dr1",				0xDD, 0x0 },	\
 	{ "FR_num_brkpts_dr2",				0xDE, 0x0 },	\
 	{ "FR_num_brkpts_dr3",				0xDF, 0x0 },	\
+	{ "NB_mem_ctrlr_bypass_counter_saturation",	0xE4, 0xF }
+
+#define	OPT_events							\
+	{ "LS_locked_operation",			0x24, 0x7 },	\
+	{ "DC_copyback",				0x44, 0x1F },	\
+	{ "DC_dtlb_L1_miss_L2_hit",			0x45, 0x0 },	\
+	{ "DC_dtlb_L1_miss_L2_miss",			0x46, 0x0 },	\
+	{ "DC_1bit_ecc_error_found",			0x4A, 0x3 },	\
+	{ "BU_system_read_responses",			0x6C, 0x7 },	\
+	{ "BU_quadwords_written_to_system",		0x6D, 0x1 },	\
+	{ "BU_internal_L2_req",				0x7D, 0x1F },	\
+	{ "BU_fill_req_missed_L2",			0x7E, 0x7 },	\
+	{ "BU_fill_into_L2",				0x7F, 0x1 },	\
+	{ "IC_itlb_L1_miss_L2_miss",			0x85, 0x0 },	\
+	{ "FR_retired_fpu_instr",			0xCB, 0xF },	\
 	{ "NB_mem_ctrlr_page_access",			0xE0, 0x7 },	\
 	{ "NB_mem_ctrlr_page_table_overflow",		0xE1, 0x0 },	\
 	{ "NB_mem_ctrlr_turnaround",			0xE3, 0x7 },	\
-	{ "NB_mem_ctrlr_bypass_counter_saturation",	0xE4, 0xF },	\
 	{ "NB_ECC_errors",				0xE8, 0x80},	\
 	{ "NB_sized_commands",				0xEB, 0x7F },	\
 	{ "NB_probe_result",				0xEC, 0x7F},	\
@@ -224,47 +230,112 @@
 	{ "NB_cpu_io_to_mem_io",			0xE9, 0xFF},	\
 	{ "NB_cache_block_commands",			0xEA, 0x3D}
 
+#define	AMD_FAMILY_10h_cmn_events					\
+	{ "FP_retired_sse_ops",				0x3,   0x7F},	\
+	{ "FP_retired_move_ops",			0x4,   0xF},	\
+	{ "FP_retired_serialize_ops",			0x5,   0xF},	\
+	{ "FP_serialize_ops_cycles",			0x6,   0x3},	\
+	{ "DC_copyback",				0x44,  0x7F },	\
+	{ "DC_dtlb_L1_miss_L2_hit",			0x45,  0x3 },	\
+	{ "DC_dtlb_L1_miss_L2_miss",			0x46,  0x7 },	\
+	{ "DC_1bit_ecc_error_found",			0x4A,  0xF },	\
+	{ "DC_dtlb_L1_hit",				0x4D,  0x7 },	\
+	{ "BU_system_read_responses",			0x6C,  0x17 },	\
+	{ "BU_octwords_written_to_system",		0x6D,  0x1 },	\
+	{ "BU_internal_L2_req",				0x7D,  0x3F },	\
+	{ "BU_fill_req_missed_L2",			0x7E,  0xF },	\
+	{ "BU_fill_into_L2",				0x7F,  0x3 },	\
+	{ "IC_itlb_L1_miss_L2_miss",			0x85,  0x3 },	\
+	{ "IC_eviction",				0x8B,  0x0 },	\
+	{ "IC_cache_lines_invalidate",			0x8C,  0xF },	\
+	{ "IC_itlb_reload",				0x99,  0x0 },	\
+	{ "IC_itlb_reload_aborted",			0x9A,  0x0 },	\
+	{ "FR_retired_mmx_sse_fp_instr",		0xCB,  0x7 },	\
+	{ "NB_mem_ctrlr_page_access",			0xE0,  0xFF },	\
+	{ "NB_mem_ctrlr_page_table_overflow",		0xE1,  0x3 },	\
+	{ "NB_mem_ctrlr_turnaround",			0xE3,  0x3F },	\
+	{ "NB_thermal_status",				0xE8,  0x7C},	\
+	{ "NB_sized_commands",				0xEB,  0x3F },	\
+	{ "NB_probe_results_upstream_req",		0xEC,  0xFF},	\
+	{ "NB_gart_events",				0xEE,  0xFF },	\
+	{ "NB_ht_bus0_bandwidth",			0xF6,  0xBF },	\
+	{ "NB_ht_bus1_bandwidth",			0xF7,  0xBF },	\
+	{ "NB_ht_bus2_bandwidth",			0xF8,  0xBF },	\
+	{ "NB_ht_bus3_bandwidth",			0x1F9, 0xBF },	\
+	{ "LS_locked_operation",			0x24,  0xF },	\
+	{ "LS_cancelled_store_to_load_fwd_ops",		0x2A,  0x7 },	\
+	{ "LS_smi_received",				0x2B,  0x0 },	\
+	{ "LS_ineffective_prefetch",			0x52,  0x9 },	\
+	{ "LS_global_tlb_flush",			0x54,  0x0 },	\
+	{ "NB_mem_ctrlr_dram_cmd_slots_missed",		0xE2,  0x3 },	\
+	{ "NB_mem_ctrlr_req",				0x1F0, 0xFF },	\
+	{ "CB_cpu_to_dram_req_to_target",		0x1E0, 0xFF },	\
+	{ "CB_io_to_dram_req_to_target",		0x1E1, 0xFF },	\
+	{ "CB_cpu_read_cmd_latency_to_target_0_to_3",	0x1E2, 0xFF },	\
+	{ "CB_cpu_read_cmd_req_to_target_0_to_3",	0x1E3, 0xFF },	\
+	{ "CB_cpu_read_cmd_latency_to_target_4_to_7",	0x1E4, 0xFF },	\
+	{ "CB_cpu_read_cmd_req_to_target_4_to_7",	0x1E5, 0xFF },	\
+	{ "CB_cpu_cmd_latency_to_target_0_to_7",	0x1E6, 0xFF },	\
+	{ "CB_cpu_req_to_target_0_to_7",		0x1E7, 0xFF },	\
+	{ "L3_read_req",				0x4E0, 0xF7 },	\
+	{ "L3_miss",					0x4E1, 0xF7 },	\
+	{ "L3_l2_eviction_l3_fill",			0x4E2, 0xFF },	\
+	{ "L3_eviction",				0x4E3, 0xF  }
 
-static opt_event_t opt_events_cmn[] = {
-	OPT_cmn_events,
+static amd_event_t opt_events[] = {
+	AMD_cmn_events,
+	OPT_events,
 	EV_END
 };
 
-static opt_event_t opt_events_rev_D[] = {
-	OPT_cmn_events,
+static amd_event_t opt_events_rev_D[] = {
+	AMD_cmn_events,
+	OPT_events,
 	OPT_RevD_events,
 	EV_END
 };
 
-static opt_event_t opt_events_rev_E[] = {
-	OPT_cmn_events,
+static amd_event_t opt_events_rev_E[] = {
+	AMD_cmn_events,
+	OPT_events,
 	OPT_RevD_events,
 	OPT_RevE_events,
 	EV_END
 };
 
+static amd_event_t family_10h_events[] = {
+	AMD_cmn_events,
+	OPT_RevE_events,
+	AMD_FAMILY_10h_cmn_events,
+	EV_END
+};
+
 static char	*evlist;
 static size_t	evlist_sz;
-static opt_event_t *opt_events;
+static amd_event_t *amd_events = NULL;
+static uint_t amd_family;
 
 #define	BITS(v, u, l)   \
 	(((v) >> (l)) & ((1 << (1 + (u) - (l))) - 1))
 
-#define	OPTERON_FAMILY	15
+#define	OPTERON_FAMILY	0xf
+#define	AMD_FAMILY_10H	0x10
 
 static int
 opt_pcbe_init(void)
 {
-	opt_event_t		*evp;
+	amd_event_t		*evp;
 	uint32_t		rev;
 
+	amd_family = cpuid_getfamily(CPU);
+
 	/*
 	 * Make sure this really _is_ an Opteron or Athlon 64 system. The kernel
 	 * loads this module based on its name in the module directory, but it
 	 * could have been renamed.
 	 */
 	if (cpuid_getvendor(CPU) != X86_VENDOR_AMD ||
-	    cpuid_getfamily(CPU) != OPTERON_FAMILY)
+	    (amd_family != OPTERON_FAMILY && amd_family != AMD_FAMILY_10H))
 		return (-1);
 
 	/*
@@ -274,18 +345,21 @@
 
 	rev = cpuid_getchiprev(CPU);
 
-	if (!X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_F_REV_D)) {
-		opt_events = opt_events_cmn;
-	} else if X86_CHIPREV_MATCH(rev, X86_CHIPREV_AMD_F_REV_D) {
-		opt_events = opt_events_rev_D;
-	} else if (X86_CHIPREV_MATCH(rev, X86_CHIPREV_AMD_F_REV_E) ||
-	    X86_CHIPREV_MATCH(rev, X86_CHIPREV_AMD_F_REV_F) ||
-	    X86_CHIPREV_MATCH(rev, X86_CHIPREV_AMD_F_REV_G)) {
-			opt_events = opt_events_rev_E;
-	};
-
-	if (opt_events == NULL)
-		opt_events = opt_events_cmn;
+	if (amd_family == OPTERON_FAMILY) {
+		if (!X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_F_REV_D)) {
+			amd_events = opt_events;
+		} else if X86_CHIPREV_MATCH(rev, X86_CHIPREV_AMD_F_REV_D) {
+			amd_events = opt_events_rev_D;
+		} else if (X86_CHIPREV_MATCH(rev, X86_CHIPREV_AMD_F_REV_E) ||
+		    X86_CHIPREV_MATCH(rev, X86_CHIPREV_AMD_F_REV_F) ||
+		    X86_CHIPREV_MATCH(rev, X86_CHIPREV_AMD_F_REV_G)) {
+			amd_events = opt_events_rev_E;
+		} else {
+			amd_events = opt_events;
+		}
+	} else {
+		amd_events = family_10h_events;
+	}
 
 	/*
 	 * Construct event list.
@@ -295,13 +369,13 @@
 	 *
 	 * Second pass: Copy strings.
 	 */
-	for (evp = opt_events; evp->name != NULL; evp++)
+	for (evp = amd_events; evp->name != NULL; evp++)
 		evlist_sz += strlen(evp->name) + 1;
 
 	evlist = kmem_alloc(evlist_sz + 1, KM_SLEEP);
 	evlist[0] = '\0';
 
-	for (evp = opt_events; evp->name != NULL; evp++) {
+	for (evp = amd_events; evp->name != NULL; evp++) {
 		(void) strcat(evlist, evp->name);
 		(void) strcat(evlist, ",");
 	}
@@ -322,15 +396,29 @@
 static const char *
 opt_pcbe_impl_name(void)
 {
-	return ("AMD Opteron & Athlon64");
+	if (amd_family == OPTERON_FAMILY) {
+		return ("AMD Opteron & Athlon64");
+	} else if (amd_family == AMD_FAMILY_10H) {
+		return ("AMD Family 10h");
+	} else {
+		return ("Unknown AMD processor");
+	}
 }
 
 static const char *
 opt_pcbe_cpuref(void)
 {
-	return ("See Chapter 10 of the \"BIOS and Kernel Developer's Guide "
-	    "for the AMD Athlon 64 and AMD Opteron Processors,\" "
-	    "AMD publication #26094");
+	if (amd_family == OPTERON_FAMILY) {
+		return ("See Chapter 10 of the \"BIOS and Kernel Developer's"
+		" Guide for the AMD Athlon 64 and AMD Opteron Processors,\" "
+		"AMD publication #26094");
+	} else if (amd_family == AMD_FAMILY_10H) {
+		return ("See section 3.15 of the \"BIOS and Kernel "
+		"Developer's Guide (BKDG) For AMD Family 10h Processors,\" "
+		"AMD publication #31116");
+	} else {
+		return ("Unknown AMD processor");
+	}
 }
 
 /*ARGSUSED*/
@@ -366,12 +454,12 @@
 	return (0xF);
 }
 
-static opt_event_t *
+static amd_event_t *
 find_event(char *name)
 {
-	opt_event_t	*evp;
+	amd_event_t	*evp;
 
-	for (evp = opt_events; evp->name != NULL; evp++)
+	for (evp = amd_events; evp->name != NULL; evp++)
 		if (strcmp(name, evp->name) == 0)
 			return (evp);
 
@@ -384,10 +472,10 @@
     uint_t nattrs, kcpc_attr_t *attrs, void **data, void *token)
 {
 	opt_pcbe_config_t	*cfg;
-	opt_event_t		*evp;
-	opt_event_t		ev_raw = { "raw", 0, 0xFF };
+	amd_event_t		*evp;
+	amd_event_t		ev_raw = { "raw", 0, 0xFF };
 	int			i;
-	uint32_t		evsel = 0;
+	uint64_t		evsel = 0, evsel_tmp = 0;
 
 	/*
 	 * If we've been handed an existing configuration, we need only preset
@@ -415,7 +503,21 @@
 		evp = &ev_raw;
 	}
 
-	evsel |= evp->emask;
+	/*
+	 * Configuration of EventSelect register for family 10h processors.
+	 */
+	if (amd_family == AMD_FAMILY_10H) {
+
+		/* Set GuestOnly bit to 0 and HostOnly bit to 1 */
+		evsel &= ~OPT_PES_HOST;
+		evsel &= ~OPT_PES_GUEST;
+
+		/* Set bits [35:32] for extended part of Event Select field */
+		evsel_tmp = evp->emask & 0x0f00;
+		evsel |= evsel_tmp << 24;
+	}
+
+	evsel |= evp->emask & 0x00ff;
 
 	if (flags & CPC_COUNT_USER)
 		evsel |= OPT_PES_USR;
--- a/usr/src/uts/intel/sys/x86_archext.h	Fri Oct 12 09:20:32 2007 -0700
+++ b/usr/src/uts/intel/sys/x86_archext.h	Fri Oct 12 11:22:11 2007 -0700
@@ -412,8 +412,8 @@
 #define	X86_CHIPREV_UNKNOWN	0x0
 
 /*
- * Definitions for AMD Family 0xf.  Minor revisions C0 and CG are
- * sufficiently different that we will distinguish them; in all other
+ * Definitions for AMD Family 0xf and AMD Family 0x10. Minor revisions C0 and
+ * CG are sufficiently different that we will distinguish them; in all other
  * case we will identify the major revision.
  */
 #define	X86_CHIPREV_AMD_F_REV_B _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0xf, 0x0001)
@@ -423,6 +423,8 @@
 #define	X86_CHIPREV_AMD_F_REV_E _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0xf, 0x0010)
 #define	X86_CHIPREV_AMD_F_REV_F _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0xf, 0x0020)
 #define	X86_CHIPREV_AMD_F_REV_G _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0xf, 0x0040)
+#define	X86_CHIPREV_AMD_10_REV_B \
+	_X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x10, 0x0001)
 
 /*
  * Various socket/package types, extended as the need to distinguish