10 * See the License for the specific language governing permissions
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) 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 (c) 2012, Joyent, Inc. All rights reserved.
31 */
32
33 /*
34 * To understand how the apix module interacts with the interrupt subsystem read
35 * the theory statement in uts/i86pc/os/intr.c.
36 */
37
38 /*
39 * PSMI 1.1 extensions are supported only in 2.6 and later versions.
40 * PSMI 1.2 extensions are supported only in 2.7 and later versions.
41 * PSMI 1.3 and 1.4 extensions are supported in Solaris 10.
42 * PSMI 1.5 extensions are supported in Solaris Nevada.
43 * PSMI 1.6 extensions are supported in Solaris Nevada.
44 * PSMI 1.7 extensions are supported in Solaris Nevada.
45 */
46 #define PSMI_1_7
47
48 #include <sys/processor.h>
49 #include <sys/time.h>
50 #include <sys/psm.h>
58 #include <sys/sunddi.h>
59 #include <sys/ddi_impldefs.h>
60 #include <sys/pci.h>
61 #include <sys/promif.h>
62 #include <sys/x86_archext.h>
63 #include <sys/cpc_impl.h>
64 #include <sys/uadmin.h>
65 #include <sys/panic.h>
66 #include <sys/debug.h>
67 #include <sys/archsystm.h>
68 #include <sys/trap.h>
69 #include <sys/machsystm.h>
70 #include <sys/sysmacros.h>
71 #include <sys/cpuvar.h>
72 #include <sys/rm_platter.h>
73 #include <sys/privregs.h>
74 #include <sys/note.h>
75 #include <sys/pci_intr_lib.h>
76 #include <sys/spl.h>
77 #include <sys/clock.h>
78 #include <sys/dditypes.h>
79 #include <sys/sunddi.h>
80 #include <sys/x_call.h>
81 #include <sys/reboot.h>
82 #include <sys/mach_intr.h>
83 #include <sys/apix.h>
84 #include <sys/apix_irm_impl.h>
85
86 static int apix_probe();
87 static void apix_init();
88 static void apix_picinit(void);
89 static int apix_intr_enter(int, int *);
90 static void apix_intr_exit(int, int);
91 static void apix_setspl(int);
92 static int apix_disable_intr(processorid_t);
93 static void apix_enable_intr(processorid_t);
94 static int apix_get_clkvect(int);
95 static int apix_get_ipivect(int, int);
96 static void apix_post_cyclic_setup(void *);
97 static int apix_post_cpu_start();
1055 * APIC_CPU_ONLINE flag here rather than setting aci_status completely.
1056 */
1057 cpun = psm_get_cpu_id();
1058 apic_cpus[cpun].aci_status |= APIC_CPU_ONLINE;
1059
1060 apic_reg_ops->apic_write(APIC_DIVIDE_REG, apic_divide_reg_init);
1061
1062 return (PSM_SUCCESS);
1063 }
1064
1065 /*
1066 * If this module needs a periodic handler for the interrupt distribution, it
1067 * can be added here. The argument to the periodic handler is not currently
1068 * used, but is reserved for future.
1069 */
1070 static void
1071 apix_post_cyclic_setup(void *arg)
1072 {
1073 UNREFERENCED_1PARAMETER(arg);
1074
1075 /* cpu_lock is held */
1076 /* set up a periodic handler for intr redistribution */
1077
1078 /*
1079 * In peridoc mode intr redistribution processing is done in
1080 * apic_intr_enter during clk intr processing
1081 */
1082 if (!apic_oneshot)
1083 return;
1084
1085 /*
1086 * Register a periodical handler for the redistribution processing.
1087 * On X86, CY_LOW_LEVEL is mapped to the level 2 interrupt, so
1088 * DDI_IPL_2 should be passed to ddi_periodic_add() here.
1089 */
1090 apic_periodic_id = ddi_periodic_add(
1091 (void (*)(void *))apix_redistribute_compute, NULL,
1092 apic_redistribute_sample_interval, DDI_IPL_2);
1093 }
1094
1095 /*
1096 * Called the first time we enable x2apic mode on this cpu.
1097 * Update some of the function pointers to use x2apic routines.
1098 */
1099 void
1100 x2apic_update_psm()
1101 {
1102 struct psm_ops *pops = &apix_ops;
1103
1104 ASSERT(pops != NULL);
1105
1106 /*
1107 * The pcplusmp module's version of x2apic_update_psm makes additional
1108 * changes that we do not have to make here. It needs to make those
1109 * changes because pcplusmp relies on the TPR register and the means of
1110 * addressing that changes when using the local apic versus the x2apic.
1111 * It's also worth noting that the apix driver specific function end up
1112 * being apix_foo as opposed to apic_foo and x2apic_foo.
|
10 * See the License for the specific language governing permissions
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) 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 (c) 2013, Joyent, Inc. All rights reserved.
31 */
32
33 /*
34 * To understand how the apix module interacts with the interrupt subsystem read
35 * the theory statement in uts/i86pc/os/intr.c.
36 */
37
38 /*
39 * PSMI 1.1 extensions are supported only in 2.6 and later versions.
40 * PSMI 1.2 extensions are supported only in 2.7 and later versions.
41 * PSMI 1.3 and 1.4 extensions are supported in Solaris 10.
42 * PSMI 1.5 extensions are supported in Solaris Nevada.
43 * PSMI 1.6 extensions are supported in Solaris Nevada.
44 * PSMI 1.7 extensions are supported in Solaris Nevada.
45 */
46 #define PSMI_1_7
47
48 #include <sys/processor.h>
49 #include <sys/time.h>
50 #include <sys/psm.h>
58 #include <sys/sunddi.h>
59 #include <sys/ddi_impldefs.h>
60 #include <sys/pci.h>
61 #include <sys/promif.h>
62 #include <sys/x86_archext.h>
63 #include <sys/cpc_impl.h>
64 #include <sys/uadmin.h>
65 #include <sys/panic.h>
66 #include <sys/debug.h>
67 #include <sys/archsystm.h>
68 #include <sys/trap.h>
69 #include <sys/machsystm.h>
70 #include <sys/sysmacros.h>
71 #include <sys/cpuvar.h>
72 #include <sys/rm_platter.h>
73 #include <sys/privregs.h>
74 #include <sys/note.h>
75 #include <sys/pci_intr_lib.h>
76 #include <sys/spl.h>
77 #include <sys/clock.h>
78 #include <sys/cyclic.h>
79 #include <sys/dditypes.h>
80 #include <sys/sunddi.h>
81 #include <sys/x_call.h>
82 #include <sys/reboot.h>
83 #include <sys/mach_intr.h>
84 #include <sys/apix.h>
85 #include <sys/apix_irm_impl.h>
86
87 static int apix_probe();
88 static void apix_init();
89 static void apix_picinit(void);
90 static int apix_intr_enter(int, int *);
91 static void apix_intr_exit(int, int);
92 static void apix_setspl(int);
93 static int apix_disable_intr(processorid_t);
94 static void apix_enable_intr(processorid_t);
95 static int apix_get_clkvect(int);
96 static int apix_get_ipivect(int, int);
97 static void apix_post_cyclic_setup(void *);
98 static int apix_post_cpu_start();
1056 * APIC_CPU_ONLINE flag here rather than setting aci_status completely.
1057 */
1058 cpun = psm_get_cpu_id();
1059 apic_cpus[cpun].aci_status |= APIC_CPU_ONLINE;
1060
1061 apic_reg_ops->apic_write(APIC_DIVIDE_REG, apic_divide_reg_init);
1062
1063 return (PSM_SUCCESS);
1064 }
1065
1066 /*
1067 * If this module needs a periodic handler for the interrupt distribution, it
1068 * can be added here. The argument to the periodic handler is not currently
1069 * used, but is reserved for future.
1070 */
1071 static void
1072 apix_post_cyclic_setup(void *arg)
1073 {
1074 UNREFERENCED_1PARAMETER(arg);
1075
1076 cyc_handler_t cyh;
1077 cyc_time_t cyt;
1078
1079 /* cpu_lock is held */
1080 /* set up a periodic handler for intr redistribution */
1081
1082 /*
1083 * In peridoc mode intr redistribution processing is done in
1084 * apic_intr_enter during clk intr processing
1085 */
1086 if (!apic_oneshot)
1087 return;
1088
1089 /*
1090 * Register a periodical handler for the redistribution processing.
1091 * Though we would generally prefer to use the DDI interface for
1092 * periodic handler invocation, ddi_periodic_add(9F), we are
1093 * unfortunately already holding cpu_lock, which ddi_periodic_add will
1094 * attempt to take for us. Thus, we add our own cyclic directly:
1095 */
1096 cyh.cyh_func = (void (*)(void *))apix_redistribute_compute;
1097 cyh.cyh_arg = NULL;
1098 cyh.cyh_level = CY_LOW_LEVEL;
1099
1100 cyt.cyt_when = 0;
1101 cyt.cyt_interval = apic_redistribute_sample_interval;
1102
1103 apic_cyclic_id = cyclic_add(&cyh, &cyt);
1104 }
1105
1106 /*
1107 * Called the first time we enable x2apic mode on this cpu.
1108 * Update some of the function pointers to use x2apic routines.
1109 */
1110 void
1111 x2apic_update_psm()
1112 {
1113 struct psm_ops *pops = &apix_ops;
1114
1115 ASSERT(pops != NULL);
1116
1117 /*
1118 * The pcplusmp module's version of x2apic_update_psm makes additional
1119 * changes that we do not have to make here. It needs to make those
1120 * changes because pcplusmp relies on the TPR register and the means of
1121 * addressing that changes when using the local apic versus the x2apic.
1122 * It's also worth noting that the apix driver specific function end up
1123 * being apix_foo as opposed to apic_foo and x2apic_foo.
|