| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: e500_intr.c,v 1.8 2011/06/05 16:52:24 matt Exp $ */ | | 1 | /* $NetBSD: e500_intr.c,v 1.9 2011/06/08 05:13:00 matt Exp $ */ |
2 | /*- | | 2 | /*- |
3 | * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc. | | 3 | * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc. |
4 | * All rights reserved. | | 4 | * All rights reserved. |
5 | * | | 5 | * |
6 | * This code is derived from software contributed to The NetBSD Foundation | | 6 | * This code is derived from software contributed to The NetBSD Foundation |
7 | * by Raytheon BBN Technologies Corp and Defense Advanced Research Projects | | 7 | * by Raytheon BBN Technologies Corp and Defense Advanced Research Projects |
8 | * Agency and which was developed by Matt Thomas of 3am Software Foundry. | | 8 | * Agency and which was developed by Matt Thomas of 3am Software Foundry. |
9 | * | | 9 | * |
10 | * This material is based upon work supported by the Defense Advanced Research | | 10 | * This material is based upon work supported by the Defense Advanced Research |
11 | * Projects Agency and Space and Naval Warfare Systems Center, Pacific, under | | 11 | * Projects Agency and Space and Naval Warfare Systems Center, Pacific, under |
12 | * Contract No. N66001-09-C-2073. | | 12 | * Contract No. N66001-09-C-2073. |
13 | * Approved for Public Release, Distribution Unlimited | | 13 | * Approved for Public Release, Distribution Unlimited |
14 | * | | 14 | * |
| @@ -1110,26 +1110,38 @@ e500_intr_init(void) | | | @@ -1110,26 +1110,38 @@ e500_intr_init(void) |
1110 | e500_intr_sources = is; | | 1110 | e500_intr_sources = is; |
1111 | e500_intr_last_source = is + nirq; | | 1111 | e500_intr_last_source = is + nirq; |
1112 | | | 1112 | |
1113 | /* | | 1113 | /* |
1114 | * Initialize all the external interrupts as active low. | | 1114 | * Initialize all the external interrupts as active low. |
1115 | */ | | 1115 | */ |
1116 | for (u_int irq = 0; irq < e500_intr_info.ii_external_sources; irq++) { | | 1116 | for (u_int irq = 0; irq < e500_intr_info.ii_external_sources; irq++) { |
1117 | openpic_write(cpu, OPENPIC_EIVPR(irq), | | 1117 | openpic_write(cpu, OPENPIC_EIVPR(irq), |
1118 | VPR_VECTOR_MAKE(irq) | VPR_LEVEL_LOW); | | 1118 | VPR_VECTOR_MAKE(irq) | VPR_LEVEL_LOW); |
1119 | } | | 1119 | } |
1120 | } | | 1120 | } |
1121 | | | 1121 | |
1122 | static void | | 1122 | static void |
| | | 1123 | e500_idlespin(void) |
| | | 1124 | { |
| | | 1125 | KASSERTMSG(curcpu()->ci_cpl == IPL_NONE, |
| | | 1126 | ("%s: cpu%u: ci_cpl (%d) != 0", __func__, cpu_number(), |
| | | 1127 | curcpu()->ci_cpl)); |
| | | 1128 | KASSERTMSG(CTPR2IPL(openpic_read(curcpu()->ci_softc, OPENPIC_CTPR)) == IPL_NONE, |
| | | 1129 | ("%s: cpu%u: CTPR (%d) != IPL_NONE", __func__, cpu_number(), |
| | | 1130 | CTPR2IPL(openpic_read(curcpu()->ci_softc, OPENPIC_CTPR)))); |
| | | 1131 | KASSERT(mfmsr() & PSL_EE); |
| | | 1132 | } |
| | | 1133 | |
| | | 1134 | static void |
1123 | e500_intr_cpu_attach(struct cpu_info *ci) | | 1135 | e500_intr_cpu_attach(struct cpu_info *ci) |
1124 | { | | 1136 | { |
1125 | struct cpu_softc * const cpu = ci->ci_softc; | | 1137 | struct cpu_softc * const cpu = ci->ci_softc; |
1126 | const char * const xname = device_xname(ci->ci_dev); | | 1138 | const char * const xname = device_xname(ci->ci_dev); |
1127 | | | 1139 | |
1128 | const u_int32_t frr = openpic_read(cpu, OPENPIC_FRR); | | 1140 | const u_int32_t frr = openpic_read(cpu, OPENPIC_FRR); |
1129 | const u_int nirq = FRR_NIRQ_GET(frr) + 1; | | 1141 | const u_int nirq = FRR_NIRQ_GET(frr) + 1; |
1130 | // const u_int ncpu = FRR_NCPU_GET(frr) + 1; | | 1142 | // const u_int ncpu = FRR_NCPU_GET(frr) + 1; |
1131 | | | 1143 | |
1132 | const struct e500_intr_info * const info = &e500_intr_info; | | 1144 | const struct e500_intr_info * const info = &e500_intr_info; |
1133 | | | 1145 | |
1134 | cpu->cpu_clock_gtbcr = OPENPIC_GTBCR(ci->ci_cpuid, E500_CLOCK_TIMER); | | 1146 | cpu->cpu_clock_gtbcr = OPENPIC_GTBCR(ci->ci_cpuid, E500_CLOCK_TIMER); |
1135 | | | 1147 | |
| @@ -1170,26 +1182,28 @@ e500_intr_cpu_attach(struct cpu_info *ci | | | @@ -1170,26 +1182,28 @@ e500_intr_cpu_attach(struct cpu_info *ci |
1170 | evcnt_attach_dynamic(evcnt, EVCNT_TYPE_INTR, | | 1182 | evcnt_attach_dynamic(evcnt, EVCNT_TYPE_INTR, |
1171 | NULL, xname, e500_timer_intr_names[j].in_name); | | 1183 | NULL, xname, e500_timer_intr_names[j].in_name); |
1172 | } | | 1184 | } |
1173 | | | 1185 | |
1174 | for (size_t j = 0; j < info->ii_ipi_sources; j++, evcnt++) { | | 1186 | for (size_t j = 0; j < info->ii_ipi_sources; j++, evcnt++) { |
1175 | evcnt_attach_dynamic(evcnt, EVCNT_TYPE_INTR, | | 1187 | evcnt_attach_dynamic(evcnt, EVCNT_TYPE_INTR, |
1176 | NULL, xname, e500_ipi_intr_names[j].in_name); | | 1188 | NULL, xname, e500_ipi_intr_names[j].in_name); |
1177 | } | | 1189 | } |
1178 | | | 1190 | |
1179 | for (size_t j = 0; j < info->ii_mi_sources; j++, evcnt++) { | | 1191 | for (size_t j = 0; j < info->ii_mi_sources; j++, evcnt++) { |
1180 | evcnt_attach_dynamic(evcnt, EVCNT_TYPE_INTR, | | 1192 | evcnt_attach_dynamic(evcnt, EVCNT_TYPE_INTR, |
1181 | NULL, xname, e500_mi_intr_names[j].in_name); | | 1193 | NULL, xname, e500_mi_intr_names[j].in_name); |
1182 | } | | 1194 | } |
| | | 1195 | |
| | | 1196 | ci->ci_idlespin = e500_idlespin; |
1183 | } | | 1197 | } |
1184 | | | 1198 | |
1185 | static void | | 1199 | static void |
1186 | e500_intr_cpu_send_ipi(cpuid_t target, uint32_t ipimsg) | | 1200 | e500_intr_cpu_send_ipi(cpuid_t target, uint32_t ipimsg) |
1187 | { | | 1201 | { |
1188 | struct cpu_info * const ci = curcpu(); | | 1202 | struct cpu_info * const ci = curcpu(); |
1189 | struct cpu_softc * const cpu = ci->ci_softc; | | 1203 | struct cpu_softc * const cpu = ci->ci_softc; |
1190 | uint32_t dstmask; | | 1204 | uint32_t dstmask; |
1191 | | | 1205 | |
1192 | if (target >= ncpu) { | | 1206 | if (target >= ncpu) { |
1193 | CPU_INFO_ITERATOR cii; | | 1207 | CPU_INFO_ITERATOR cii; |
1194 | struct cpu_info *dst_ci; | | 1208 | struct cpu_info *dst_ci; |
1195 | | | 1209 | |