11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25 /*
26 * Copyright (c) 2010, Intel Corporation.
27 * All rights reserved.
28 */
29 /*
30 * Copyright 2018 Joyent, Inc.
31 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
32 * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
33 */
34
35 #include <sys/types.h>
36 #include <sys/thread.h>
37 #include <sys/cpuvar.h>
38 #include <sys/cpu.h>
39 #include <sys/t_lock.h>
40 #include <sys/param.h>
41 #include <sys/proc.h>
42 #include <sys/disp.h>
43 #include <sys/class.h>
44 #include <sys/cmn_err.h>
45 #include <sys/debug.h>
46 #include <sys/note.h>
47 #include <sys/asm_linkage.h>
48 #include <sys/x_call.h>
49 #include <sys/systm.h>
50 #include <sys/var.h>
51 #include <sys/vtrace.h>
702
703 static void
704 workaround_applied(uint_t erratum)
705 {
706 if (erratum > 1000000)
707 cmn_err(CE_CONT, "?workaround applied for cpu issue #%d\n",
708 erratum);
709 else
710 cmn_err(CE_CONT, "?workaround applied for cpu erratum #%d\n",
711 erratum);
712 }
713
714 static void
715 msr_warning(cpu_t *cp, const char *rw, uint_t msr, int error)
716 {
717 cmn_err(CE_WARN, "cpu%d: couldn't %smsr 0x%x, error %d",
718 cp->cpu_id, rw, msr, error);
719 }
720
721 /*
722 * Determine the number of nodes in a Hammer / Greyhound / Griffin family
723 * system.
724 */
725 static uint_t
726 opteron_get_nnodes(void)
727 {
728 static uint_t nnodes = 0;
729
730 if (nnodes == 0) {
731 #ifdef DEBUG
732 uint_t family;
733
734 /*
735 * This routine uses a PCI config space based mechanism
736 * for retrieving the number of nodes in the system.
737 * Device 24, function 0, offset 0x60 as used here is not
738 * AMD processor architectural, and may not work on processor
739 * families other than those listed below.
740 *
741 * Callers of this routine must ensure that we're running on
742 * a processor which supports this mechanism.
743 * The assertion below is meant to catch calls on unsupported
744 * processors.
745 */
746 family = cpuid_getfamily(CPU);
747 ASSERT(family == 0xf || family == 0x10 || family == 0x11);
748 #endif /* DEBUG */
749
750 /*
751 * Obtain the number of nodes in the system from
752 * bits [6:4] of the Node ID register on node 0.
753 *
754 * The actual node count is NodeID[6:4] + 1
755 *
756 * The Node ID register is accessed via function 0,
757 * offset 0x60. Node 0 is device 24.
758 */
759 nnodes = ((pci_getl_func(0, 24, 0, 0x60) & 0x70) >> 4) + 1;
760 }
761 return (nnodes);
762 }
763
764 uint_t
765 do_erratum_298(struct cpu *cpu)
766 {
767 static int osvwrc = -3;
768 extern int osvw_opteron_erratum(cpu_t *, uint_t);
769
770 /*
771 * L2 Eviction May Occur During Processor Operation To Set
772 * Accessed or Dirty Bit.
773 */
774 if (osvwrc == -3) {
775 osvwrc = osvw_opteron_erratum(cpu, 298);
776 } else {
777 /* osvw return codes should be consistent for all cpus */
778 ASSERT(osvwrc == osvw_opteron_erratum(cpu, 298));
779 }
780
|
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25 /*
26 * Copyright (c) 2010, Intel Corporation.
27 * All rights reserved.
28 */
29 /*
30 * Copyright 2018 Joyent, Inc.
31 * Copyright 2018 Nexenta Systems, Inc.
32 * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
33 */
34
35 #include <sys/types.h>
36 #include <sys/thread.h>
37 #include <sys/cpuvar.h>
38 #include <sys/cpu.h>
39 #include <sys/t_lock.h>
40 #include <sys/param.h>
41 #include <sys/proc.h>
42 #include <sys/disp.h>
43 #include <sys/class.h>
44 #include <sys/cmn_err.h>
45 #include <sys/debug.h>
46 #include <sys/note.h>
47 #include <sys/asm_linkage.h>
48 #include <sys/x_call.h>
49 #include <sys/systm.h>
50 #include <sys/var.h>
51 #include <sys/vtrace.h>
702
703 static void
704 workaround_applied(uint_t erratum)
705 {
706 if (erratum > 1000000)
707 cmn_err(CE_CONT, "?workaround applied for cpu issue #%d\n",
708 erratum);
709 else
710 cmn_err(CE_CONT, "?workaround applied for cpu erratum #%d\n",
711 erratum);
712 }
713
714 static void
715 msr_warning(cpu_t *cp, const char *rw, uint_t msr, int error)
716 {
717 cmn_err(CE_WARN, "cpu%d: couldn't %smsr 0x%x, error %d",
718 cp->cpu_id, rw, msr, error);
719 }
720
721 /*
722 * Determine the number of nodes in a system.
723 *
724 * This routine uses a PCI config space based mechanism
725 * for retrieving the number of nodes in the system.
726 *
727 * Current processor families that support this mechanism are
728 * 0xf, 0x10, 0x11, and 0x15.
729 */
730 static uint_t
731 opteron_get_nnodes(void)
732 {
733 static uint_t nnodes = 0;
734
735 /*
736 * Obtain the number of nodes in the system from
737 * bits [6:4] of the Node ID register on node 0.
738 *
739 * The actual node count is NodeID[6:4] + 1
740 *
741 * The Node ID register is accessed via function 0,
742 * offset 0x60. Node 0 is device 24.
743 */
744 if (nnodes == 0)
745 nnodes = ((pci_getl_func(0, 24, 0, 0x60) & 0x70) >> 4) + 1;
746
747 return (nnodes);
748 }
749
750 uint_t
751 do_erratum_298(struct cpu *cpu)
752 {
753 static int osvwrc = -3;
754 extern int osvw_opteron_erratum(cpu_t *, uint_t);
755
756 /*
757 * L2 Eviction May Occur During Processor Operation To Set
758 * Accessed or Dirty Bit.
759 */
760 if (osvwrc == -3) {
761 osvwrc = osvw_opteron_erratum(cpu, 298);
762 } else {
763 /* osvw return codes should be consistent for all cpus */
764 ASSERT(osvwrc == osvw_opteron_erratum(cpu, 298));
765 }
766
|