Wed Jun 8 05:13:00 2011 UTC ()
Add an e500_idlespin to detect calls to idlespin when interrupts are blocked
or disabled.


(matt)
diff -r1.8 -r1.9 src/sys/arch/powerpc/booke/e500_intr.c

cvs diff -r1.8 -r1.9 src/sys/arch/powerpc/booke/e500_intr.c (expand / switch to unified diff)

--- src/sys/arch/powerpc/booke/e500_intr.c 2011/06/05 16:52:24 1.8
+++ src/sys/arch/powerpc/booke/e500_intr.c 2011/06/08 05:13:00 1.9
@@ -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
1122static void 1122static void
 1123e500_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
 1134static void
1123e500_intr_cpu_attach(struct cpu_info *ci) 1135e500_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
1185static void 1199static void
1186e500_intr_cpu_send_ipi(cpuid_t target, uint32_t ipimsg) 1200e500_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