Tue Jun 14 22:36:13 2011 UTC ()
Take the fast softint support in e500_intr.c and make generic so that it can
be used to provide fast softint for other interrupt implementations.


(matt)
diff -r1.9 -r1.10 src/sys/arch/powerpc/booke/e500_intr.c
diff -r1.78 -r1.79 src/sys/arch/powerpc/conf/files.powerpc
diff -r1.79 -r1.80 src/sys/arch/powerpc/include/cpu.h
diff -r0 -r1.1 src/sys/arch/powerpc/include/softint.h
diff -r1.6 -r1.7 src/sys/arch/powerpc/include/booke/cpuvar.h
diff -r0 -r1.1 src/sys/arch/powerpc/powerpc/softint_machdep.c

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

--- src/sys/arch/powerpc/booke/e500_intr.c 2011/06/08 05:13:00 1.9
+++ src/sys/arch/powerpc/booke/e500_intr.c 2011/06/14 22:36:12 1.10
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: e500_intr.c,v 1.9 2011/06/08 05:13:00 matt Exp $ */ 1/* $NetBSD: e500_intr.c,v 1.10 2011/06/14 22:36:12 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 *
@@ -40,57 +40,43 @@ @@ -40,57 +40,43 @@
40 40
41#include <sys/param.h> 41#include <sys/param.h>
42#include <sys/proc.h> 42#include <sys/proc.h>
43#include <sys/intr.h> 43#include <sys/intr.h>
44#include <sys/cpu.h> 44#include <sys/cpu.h>
45#include <sys/kmem.h> 45#include <sys/kmem.h>
46#include <sys/atomic.h> 46#include <sys/atomic.h>
47#include <sys/bus.h> 47#include <sys/bus.h>
48#include <sys/xcall.h> 48#include <sys/xcall.h>
49#include <sys/bitops.h> 49#include <sys/bitops.h>
50 50
51#include <uvm/uvm_extern.h> 51#include <uvm/uvm_extern.h>
52 52
 53#ifdef __HAVE_FAST_SOFTINTS
 54#include <powerpc/softint.h>
 55#endif
 56
53#include <powerpc/spr.h> 57#include <powerpc/spr.h>
54#include <powerpc/booke/spr.h> 58#include <powerpc/booke/spr.h>
55 59
56#include <powerpc/booke/cpuvar.h> 60#include <powerpc/booke/cpuvar.h>
57#include <powerpc/booke/e500reg.h> 61#include <powerpc/booke/e500reg.h>
58#include <powerpc/booke/e500var.h> 62#include <powerpc/booke/e500var.h>
59#include <powerpc/booke/openpicreg.h> 63#include <powerpc/booke/openpicreg.h>
60 64
61#define IPL2CTPR(ipl) ((ipl) + 15 - IPL_HIGH) 65#define IPL2CTPR(ipl) ((ipl) + 15 - IPL_HIGH)
62#define CTPR2IPL(ctpr) ((ctpr) - (15 - IPL_HIGH)) 66#define CTPR2IPL(ctpr) ((ctpr) - (15 - IPL_HIGH))
63 67
64#define IST_PERCPU_P(ist) ((ist) >= IST_TIMER) 68#define IST_PERCPU_P(ist) ((ist) >= IST_TIMER)
65 69
66#ifdef __HAVE_PREEMPTION 
67#define IPL_PREEMPT_SOFTMASK (1 << IPL_NONE) 
68#else 
69#define IPL_PREEMPT_SOFTMASK 0 
70#endif 
71 
72#define IPL_SOFTMASK \ 
73 ((1 << IPL_SOFTSERIAL) | (1 << IPL_SOFTNET ) \ 
74 |(1 << IPL_SOFTBIO ) | (1 << IPL_SOFTCLOCK ) \ 
75 |IPL_PREEMPT_SOFTMASK) 
76 
77#define SOFTINT2IPL_MAP \ 
78 ((IPL_SOFTSERIAL << (4*SOFTINT_SERIAL)) \ 
79 |(IPL_SOFTNET << (4*SOFTINT_NET )) \ 
80 |(IPL_SOFTBIO << (4*SOFTINT_BIO )) \ 
81 |(IPL_SOFTCLOCK << (4*SOFTINT_CLOCK ))) 
82#define SOFTINT2IPL(si_level) ((SOFTINT2IPL_MAP >> (4 * si_level)) & 0x0f) 
83 
84struct e500_intr_irq_info { 70struct e500_intr_irq_info {
85 bus_addr_t irq_vpr; 71 bus_addr_t irq_vpr;
86 bus_addr_t irq_dr; 72 bus_addr_t irq_dr;
87 u_int irq_vector; 73 u_int irq_vector;
88}; 74};
89 75
90struct intr_source { 76struct intr_source {
91 int (*is_func)(void *); 77 int (*is_func)(void *);
92 void *is_arg; 78 void *is_arg;
93 int8_t is_ipl; 79 int8_t is_ipl;
94 uint8_t is_ist; 80 uint8_t is_ist;
95 uint8_t is_irq; 81 uint8_t is_irq;
96 bus_size_t is_vpr; 82 bus_size_t is_vpr;
@@ -364,53 +350,49 @@ static void e500_intr_disestablish(void @@ -364,53 +350,49 @@ static void e500_intr_disestablish(void
364static void e500_intr_cpu_attach(struct cpu_info *ci); 350static void e500_intr_cpu_attach(struct cpu_info *ci);
365static void e500_intr_cpu_hatch(struct cpu_info *ci); 351static void e500_intr_cpu_hatch(struct cpu_info *ci);
366static void e500_intr_cpu_send_ipi(cpuid_t, uintptr_t); 352static void e500_intr_cpu_send_ipi(cpuid_t, uintptr_t);
367static void e500_intr_init(void); 353static void e500_intr_init(void);
368static const char *e500_intr_string(int, int); 354static const char *e500_intr_string(int, int);
369static void e500_critintr(struct trapframe *tf); 355static void e500_critintr(struct trapframe *tf);
370static void e500_decrintr(struct trapframe *tf); 356static void e500_decrintr(struct trapframe *tf);
371static void e500_extintr(struct trapframe *tf); 357static void e500_extintr(struct trapframe *tf);
372static void e500_fitintr(struct trapframe *tf); 358static void e500_fitintr(struct trapframe *tf);
373static void e500_wdogintr(struct trapframe *tf); 359static void e500_wdogintr(struct trapframe *tf);
374static void e500_spl0(void); 360static void e500_spl0(void);
375static int e500_splraise(int); 361static int e500_splraise(int);
376static void e500_splx(int); 362static void e500_splx(int);
377#ifdef __HAVE_FAST_SOFTINTS 
378static void e500_softint_init_md(lwp_t *l, u_int si_level, uintptr_t *machdep_p); 
379static void e500_softint_trigger(uintptr_t machdep); 
380#endif 
381 363
382const struct intrsw e500_intrsw = { 364const struct intrsw e500_intrsw = {
383 .intrsw_establish = e500_intr_establish, 365 .intrsw_establish = e500_intr_establish,
384 .intrsw_disestablish = e500_intr_disestablish, 366 .intrsw_disestablish = e500_intr_disestablish,
385 .intrsw_init = e500_intr_init, 367 .intrsw_init = e500_intr_init,
386 .intrsw_cpu_attach = e500_intr_cpu_attach, 368 .intrsw_cpu_attach = e500_intr_cpu_attach,
387 .intrsw_cpu_hatch = e500_intr_cpu_hatch, 369 .intrsw_cpu_hatch = e500_intr_cpu_hatch,
388 .intrsw_cpu_send_ipi = e500_intr_cpu_send_ipi, 370 .intrsw_cpu_send_ipi = e500_intr_cpu_send_ipi,
389 .intrsw_string = e500_intr_string, 371 .intrsw_string = e500_intr_string,
390 372
391 .intrsw_critintr = e500_critintr, 373 .intrsw_critintr = e500_critintr,
392 .intrsw_decrintr = e500_decrintr, 374 .intrsw_decrintr = e500_decrintr,
393 .intrsw_extintr = e500_extintr, 375 .intrsw_extintr = e500_extintr,
394 .intrsw_fitintr = e500_fitintr, 376 .intrsw_fitintr = e500_fitintr,
395 .intrsw_wdogintr = e500_wdogintr, 377 .intrsw_wdogintr = e500_wdogintr,
396 378
397 .intrsw_splraise = e500_splraise, 379 .intrsw_splraise = e500_splraise,
398 .intrsw_splx = e500_splx, 380 .intrsw_splx = e500_splx,
399 .intrsw_spl0 = e500_spl0, 381 .intrsw_spl0 = e500_spl0,
400 382
401#ifdef __HAVE_FAST_SOFTINTS 383#ifdef __HAVE_FAST_SOFTINTS
402 .intrsw_softint_init_md = e500_softint_init_md, 384 .intrsw_softint_init_md = powerpc_softint_init_md,
403 .intrsw_softint_trigger = e500_softint_trigger, 385 .intrsw_softint_trigger = powerpc_softint_trigger,
404#endif 386#endif
405}; 387};
406 388
407static inline uint32_t  389static inline uint32_t
408openpic_read(struct cpu_softc *cpu, bus_size_t offset) 390openpic_read(struct cpu_softc *cpu, bus_size_t offset)
409{ 391{
410 392
411 return bus_space_read_4(cpu->cpu_bst, cpu->cpu_bsh, 393 return bus_space_read_4(cpu->cpu_bst, cpu->cpu_bsh,
412 OPENPIC_BASE + offset); 394 OPENPIC_BASE + offset);
413} 395}
414 396
415static inline void  397static inline void
416openpic_write(struct cpu_softc *cpu, bus_size_t offset, uint32_t val) 398openpic_write(struct cpu_softc *cpu, bus_size_t offset, uint32_t val)
@@ -444,84 +426,26 @@ e500_intr_name_lookup(const struct e500_ @@ -444,84 +426,26 @@ e500_intr_name_lookup(const struct e500_
444 426
445static const char * 427static const char *
446e500_intr_onchip_name_lookup(int irq) 428e500_intr_onchip_name_lookup(int irq)
447{ 429{
448 const char *name; 430 const char *name;
449 431
450 name = e500_intr_name_lookup(e500_intr_info.ii_onchip_intr_names, irq); 432 name = e500_intr_name_lookup(e500_intr_info.ii_onchip_intr_names, irq);
451 if (name == NULL) 433 if (name == NULL)
452 name = e500_intr_name_lookup(e500_onchip_intr_names, irq); 434 name = e500_intr_name_lookup(e500_onchip_intr_names, irq);
453 435
454 return name; 436 return name;
455} 437}
456 438
457#ifdef __HAVE_FAST_SOFTINTS 
458static inline void 
459e500_softint_deliver(struct cpu_info *ci, struct cpu_softc *cpu, 
460 int ipl, int si_level) 
461{ 
462 KASSERT(ci->ci_data.cpu_softints & (1 << ipl)); 
463 ci->ci_data.cpu_softints ^= 1 << ipl; 
464 softint_fast_dispatch(cpu->cpu_softlwps[si_level], ipl); 
465 KASSERT(cpu->cpu_softlwps[si_level]->l_ctxswtch == 0); 
466 KASSERTMSG(ci->ci_cpl == IPL_HIGH, 
467 ("%s: cpl (%d) != HIGH", __func__, ci->ci_cpl)); 
468} 
469 
470static inline void 
471e500_softint(struct cpu_info *ci, struct cpu_softc *cpu, int old_ipl, 
472 vaddr_t pc) 
473{ 
474 const u_int softint_mask = (IPL_SOFTMASK << old_ipl) & IPL_SOFTMASK; 
475 u_int softints; 
476 
477 KASSERT(ci->ci_mtx_count == 0); 
478 KASSERT(ci->ci_cpl == IPL_HIGH); 
479 while ((softints = (ci->ci_data.cpu_softints & softint_mask)) != 0) { 
480 KASSERT(old_ipl < IPL_SOFTSERIAL); 
481 if (softints & (1 << IPL_SOFTSERIAL)) { 
482 e500_softint_deliver(ci, cpu, IPL_SOFTSERIAL, 
483 SOFTINT_SERIAL); 
484 continue; 
485 } 
486 KASSERT(old_ipl < IPL_SOFTNET); 
487 if (softints & (1 << IPL_SOFTNET)) { 
488 e500_softint_deliver(ci, cpu, IPL_SOFTNET, 
489 SOFTINT_NET); 
490 continue; 
491 } 
492 KASSERT(old_ipl < IPL_SOFTBIO); 
493 if (softints & (1 << IPL_SOFTBIO)) { 
494 e500_softint_deliver(ci, cpu, IPL_SOFTBIO, 
495 SOFTINT_BIO); 
496 continue; 
497 } 
498 KASSERT(old_ipl < IPL_SOFTCLOCK); 
499 if (softints & (1 << IPL_SOFTCLOCK)) { 
500 e500_softint_deliver(ci, cpu, IPL_SOFTCLOCK, 
501 SOFTINT_CLOCK); 
502 continue; 
503 } 
504#ifdef __HAVE_PREEMPTION 
505 KASSERT(old_ipl == IPL_NONE); 
506 if (softints & (1 << IPL_NONE)) { 
507 ci->ci_data.cpu_softints ^= (1 << IPL_NONE); 
508 kpreempt(pc); 
509 } 
510#endif 
511 } 
512} 
513#endif /* __HAVE_FAST_SOFTINTS */ 
514 
515static inline void 439static inline void
516e500_splset(struct cpu_info *ci, int ipl) 440e500_splset(struct cpu_info *ci, int ipl)
517{ 441{
518 struct cpu_softc * const cpu = ci->ci_softc; 442 struct cpu_softc * const cpu = ci->ci_softc;
519 //KASSERT(!cpu_intr_p() || ipl >= IPL_VM); 443 //KASSERT(!cpu_intr_p() || ipl >= IPL_VM);
520 KASSERT((curlwp->l_pflag & LP_INTR) == 0 || ipl != IPL_NONE); 444 KASSERT((curlwp->l_pflag & LP_INTR) == 0 || ipl != IPL_NONE);
521#if 0 445#if 0
522 u_int ctpr = ipl; 446 u_int ctpr = ipl;
523 KASSERT(openpic_read(cpu, OPENPIC_CTPR) == ci->ci_cpl); 447 KASSERT(openpic_read(cpu, OPENPIC_CTPR) == ci->ci_cpl);
524#elif 0 448#elif 0
525 u_int old_ctpr = (ci->ci_cpl >= IPL_VM ? 15 : ci->ci_cpl); 449 u_int old_ctpr = (ci->ci_cpl >= IPL_VM ? 15 : ci->ci_cpl);
526 u_int ctpr = (ipl >= IPL_VM ? 15 : ipl); 450 u_int ctpr = (ipl >= IPL_VM ? 15 : ipl);
527 KASSERT(openpic_read(cpu, OPENPIC_CTPR) == old_ctpr); 451 KASSERT(openpic_read(cpu, OPENPIC_CTPR) == old_ctpr);
@@ -537,27 +461,27 @@ e500_splset(struct cpu_info *ci, int ipl @@ -537,27 +461,27 @@ e500_splset(struct cpu_info *ci, int ipl
537 ci->ci_cpl = ipl; 461 ci->ci_cpl = ipl;
538} 462}
539 463
540static void 464static void
541e500_spl0(void) 465e500_spl0(void)
542{ 466{
543 struct cpu_info * const ci = curcpu(); 467 struct cpu_info * const ci = curcpu();
544 468
545 wrtee(0); 469 wrtee(0);
546 470
547#ifdef __HAVE_FAST_SOFTINTS 471#ifdef __HAVE_FAST_SOFTINTS
548 if (__predict_false(ci->ci_data.cpu_softints != 0)) { 472 if (__predict_false(ci->ci_data.cpu_softints != 0)) {
549 e500_splset(ci, IPL_HIGH); 473 e500_splset(ci, IPL_HIGH);
550 e500_softint(ci, ci->ci_softc, IPL_NONE, 474 powerpc_softint(ci, IPL_NONE,
551 (vaddr_t)__builtin_return_address(0)); 475 (vaddr_t)__builtin_return_address(0));
552 } 476 }
553#endif /* __HAVE_FAST_SOFTINTS */ 477#endif /* __HAVE_FAST_SOFTINTS */
554 e500_splset(ci, IPL_NONE); 478 e500_splset(ci, IPL_NONE);
555 479
556 wrtee(PSL_EE); 480 wrtee(PSL_EE);
557} 481}
558 482
559static void 483static void
560e500_splx(int ipl) 484e500_splx(int ipl)
561{ 485{
562 struct cpu_info * const ci = curcpu(); 486 struct cpu_info * const ci = curcpu();
563 const int old_ipl = ci->ci_cpl; 487 const int old_ipl = ci->ci_cpl;
@@ -570,27 +494,27 @@ e500_splx(int ipl) @@ -570,27 +494,27 @@ e500_splx(int ipl)
570 if (__predict_false(ipl > old_ipl)) { 494 if (__predict_false(ipl > old_ipl)) {
571 printf("%s: %p: cpl=%u: ignoring splx(%u) to raise ipl\n", 495 printf("%s: %p: cpl=%u: ignoring splx(%u) to raise ipl\n",
572 __func__, __builtin_return_address(0), old_ipl, ipl); 496 __func__, __builtin_return_address(0), old_ipl, ipl);
573 if (old_ipl == IPL_NONE) 497 if (old_ipl == IPL_NONE)
574 Debugger(); 498 Debugger();
575 } 499 }
576 500
577 // const 501 // const
578 register_t msr = wrtee(0); 502 register_t msr = wrtee(0);
579#ifdef __HAVE_FAST_SOFTINTS 503#ifdef __HAVE_FAST_SOFTINTS
580 const u_int softints = (ci->ci_data.cpu_softints << ipl) & IPL_SOFTMASK; 504 const u_int softints = (ci->ci_data.cpu_softints << ipl) & IPL_SOFTMASK;
581 if (__predict_false(softints != 0)) { 505 if (__predict_false(softints != 0)) {
582 e500_splset(ci, IPL_HIGH); 506 e500_splset(ci, IPL_HIGH);
583 e500_softint(ci, ci->ci_softc, ipl, 507 powerpc_softint(ci, ipl,
584 (vaddr_t)__builtin_return_address(0)); 508 (vaddr_t)__builtin_return_address(0));
585 } 509 }
586#endif /* __HAVE_FAST_SOFTINTS */ 510#endif /* __HAVE_FAST_SOFTINTS */
587 e500_splset(ci, ipl); 511 e500_splset(ci, ipl);
588#if 1 512#if 1
589 if (ipl < IPL_VM && old_ipl >= IPL_VM) 513 if (ipl < IPL_VM && old_ipl >= IPL_VM)
590 msr = PSL_EE; 514 msr = PSL_EE;
591#endif 515#endif
592 wrtee(msr); 516 wrtee(msr);
593} 517}
594 518
595static int 519static int
596e500_splraise(int ipl) 520e500_splraise(int ipl)
@@ -612,47 +536,26 @@ e500_splraise(int ipl) @@ -612,47 +536,26 @@ e500_splraise(int ipl)
612 } else if (ipl == IPL_NONE) { 536 } else if (ipl == IPL_NONE) {
613 panic("%s: %p: cpl=%u: attempt to splraise(IPL_NONE)", 537 panic("%s: %p: cpl=%u: attempt to splraise(IPL_NONE)",
614 __func__, __builtin_return_address(0), old_ipl); 538 __func__, __builtin_return_address(0), old_ipl);
615#if 0 539#if 0
616 } else if (old_ipl > ipl) { 540 } else if (old_ipl > ipl) {
617 printf("%s: %p: cpl=%u: ignoring splraise(%u) to lower ipl\n", 541 printf("%s: %p: cpl=%u: ignoring splraise(%u) to lower ipl\n",
618 __func__, __builtin_return_address(0), old_ipl, ipl); 542 __func__, __builtin_return_address(0), old_ipl, ipl);
619#endif 543#endif
620 } 544 }
621 545
622 return old_ipl; 546 return old_ipl;
623} 547}
624 548
625#ifdef __HAVE_FAST_SOFTINTS 
626static void 
627e500_softint_init_md(lwp_t *l, u_int si_level, uintptr_t *machdep_p) 
628{ 
629 struct cpu_info * const ci = l->l_cpu; 
630 struct cpu_softc * const cpu = ci->ci_softc; 
631 
632 *machdep_p = 1 << SOFTINT2IPL(si_level); 
633 KASSERT(*machdep_p & IPL_SOFTMASK); 
634 cpu->cpu_softlwps[si_level] = l; 
635} 
636 
637static void 
638e500_softint_trigger(uintptr_t machdep) 
639{ 
640 struct cpu_info * const ci = curcpu(); 
641 
642 atomic_or_uint(&ci->ci_data.cpu_softints, machdep); 
643} 
644#endif /* __HAVE_FAST_SOFTINTS */ 
645 
646static int 549static int
647e500_intr_spurious(void *arg) 550e500_intr_spurious(void *arg)
648{ 551{
649 return 0; 552 return 0;
650} 553}
651 554
652static bool 555static bool
653e500_intr_irq_info_get(struct cpu_info *ci, u_int irq, int ipl, int ist, 556e500_intr_irq_info_get(struct cpu_info *ci, u_int irq, int ipl, int ist,
654 struct e500_intr_irq_info *ii) 557 struct e500_intr_irq_info *ii)
655{ 558{
656 const struct e500_intr_info * const info = &e500_intr_info; 559 const struct e500_intr_info * const info = &e500_intr_info;
657 bool ok; 560 bool ok;
658 561
@@ -1012,27 +915,27 @@ e500_extintr(struct trapframe *tf) @@ -1012,27 +915,27 @@ e500_extintr(struct trapframe *tf)
1012 break; 915 break;
1013 } 916 }
1014 917
1015 ci->ci_idepth--; 918 ci->ci_idepth--;
1016 919
1017#ifdef __HAVE_FAST_SOFTINTS 920#ifdef __HAVE_FAST_SOFTINTS
1018 /* 921 /*
1019 * Before exiting, deal with any softints that need to be dealt with. 922 * Before exiting, deal with any softints that need to be dealt with.
1020 */ 923 */
1021 const u_int softints = (ci->ci_data.cpu_softints << old_ipl) & IPL_SOFTMASK; 924 const u_int softints = (ci->ci_data.cpu_softints << old_ipl) & IPL_SOFTMASK;
1022 if (__predict_false(softints != 0)) { 925 if (__predict_false(softints != 0)) {
1023 KASSERT(old_ipl < IPL_VM); 926 KASSERT(old_ipl < IPL_VM);
1024 e500_splset(ci, IPL_HIGH); /* pop to high */ 927 e500_splset(ci, IPL_HIGH); /* pop to high */
1025 e500_softint(ci, cpu, old_ipl, /* deal with them */ 928 powerpc_softint(ci, old_ipl, /* deal with them */
1026 tf->tf_srr0); 929 tf->tf_srr0);
1027 e500_splset(ci, old_ipl); /* and drop back */ 930 e500_splset(ci, old_ipl); /* and drop back */
1028 } 931 }
1029#endif /* __HAVE_FAST_SOFTINTS */ 932#endif /* __HAVE_FAST_SOFTINTS */
1030#if 1 933#if 1
1031 KASSERT(ci->ci_cpl == old_ipl); 934 KASSERT(ci->ci_cpl == old_ipl);
1032#else 935#else
1033 e500_splset(ci, old_ipl); /* and drop back */ 936 e500_splset(ci, old_ipl); /* and drop back */
1034#endif 937#endif
1035 938
1036// printf("%s(%p): idepth=%d exit\n", __func__, tf, ci->ci_idepth); 939// printf("%s(%p): idepth=%d exit\n", __func__, tf, ci->ci_idepth);
1037} 940}
1038 941
@@ -1225,27 +1128,27 @@ e500_intr_cpu_send_ipi(cpuid_t target, u @@ -1225,27 +1128,27 @@ e500_intr_cpu_send_ipi(cpuid_t target, u
1225 if (ipimsg) 1128 if (ipimsg)
1226 atomic_or_32(&dst_ci->ci_pending_ipis, ipimsg); 1129 atomic_or_32(&dst_ci->ci_pending_ipis, ipimsg);
1227 } 1130 }
1228 1131
1229 openpic_write(cpu, OPENPIC_IPIDR(0), dstmask); 1132 openpic_write(cpu, OPENPIC_IPIDR(0), dstmask);
1230} 1133}
1231 1134
1232typedef void (*ipifunc_t)(void); 1135typedef void (*ipifunc_t)(void);
1233 1136
1234#ifdef __HAVE_PREEEMPTION 1137#ifdef __HAVE_PREEEMPTION
1235static void 1138static void
1236e500_ipi_kpreempt(void) 1139e500_ipi_kpreempt(void)
1237{ 1140{
1238 e500_softint_trigger(1 << IPL_NONE); 1141 poowerpc_softint_trigger(1 << IPL_NONE);
1239} 1142}
1240#endif 1143#endif
1241 1144
1242static const ipifunc_t e500_ipifuncs[] = { 1145static const ipifunc_t e500_ipifuncs[] = {
1243 [ilog2(IPI_XCALL)] = xc_ipi_handler, 1146 [ilog2(IPI_XCALL)] = xc_ipi_handler,
1244 [ilog2(IPI_HALT)] = e500_ipi_halt, 1147 [ilog2(IPI_HALT)] = e500_ipi_halt,
1245#ifdef __HAVE_PREEMPTION 1148#ifdef __HAVE_PREEMPTION
1246 [ilog2(IPI_KPREEMPT)] = e500_ipi_kpreempt, 1149 [ilog2(IPI_KPREEMPT)] = e500_ipi_kpreempt,
1247#endif 1150#endif
1248 [ilog2(IPI_TLB1SYNC)] = e500_tlb1_sync, 1151 [ilog2(IPI_TLB1SYNC)] = e500_tlb1_sync,
1249}; 1152};
1250 1153
1251static int 1154static int

cvs diff -r1.78 -r1.79 src/sys/arch/powerpc/conf/files.powerpc (expand / switch to unified diff)

--- src/sys/arch/powerpc/conf/files.powerpc 2011/06/12 03:35:45 1.78
+++ src/sys/arch/powerpc/conf/files.powerpc 2011/06/14 22:36:12 1.79
@@ -1,38 +1,39 @@ @@ -1,38 +1,39 @@
1# $NetBSD: files.powerpc,v 1.78 2011/06/12 03:35:45 rmind Exp $ 1# $NetBSD: files.powerpc,v 1.79 2011/06/14 22:36:12 matt Exp $
2 2
3defflag opt_altivec.h ALTIVEC K_ALTIVEC PPC_HAVE_SPE 3defflag opt_altivec.h ALTIVEC K_ALTIVEC PPC_HAVE_SPE
4defflag opt_openpic.h OPENPIC OPENPIC_SERIAL_MODE OPENPIC_DISTRIBUTE 4defflag opt_openpic.h OPENPIC OPENPIC_SERIAL_MODE OPENPIC_DISTRIBUTE
5defparam opt_ppcparam.h L2CR_CONFIG L3CR_CONFIG INTSTK CLOCKBASE 5defparam opt_ppcparam.h L2CR_CONFIG L3CR_CONFIG INTSTK CLOCKBASE
6defflag opt_ppcarch.h PPC_OEA PPC_OEA601 PPC_OEA64 PPC_OEA64_BRIDGE PPC_MPC8XX PPC_IBM4XX PPC_IBM403 PPC_BOOKE 6defflag opt_ppcarch.h PPC_OEA PPC_OEA601 PPC_OEA64 PPC_OEA64_BRIDGE PPC_MPC8XX PPC_IBM4XX PPC_IBM403 PPC_BOOKE
7defflag opt_pmap.h PMAPDEBUG PMAPCHECK PMAPCOUNTERS 7defflag opt_pmap.h PMAPDEBUG PMAPCHECK PMAPCOUNTERS
8defparam opt_pmap.h PTEGCOUNT PMAP_MEMLIMIT 8defparam opt_pmap.h PTEGCOUNT PMAP_MEMLIMIT
9 9
10file arch/powerpc/powerpc/copystr.c 10file arch/powerpc/powerpc/copystr.c
11file arch/powerpc/powerpc/core_machdep.c coredump 11file arch/powerpc/powerpc/core_machdep.c coredump
12file arch/powerpc/powerpc/fixup.c ppc_booke | (ppc_oea & ppc_oea64) | (ppc_oea & ppc_oea64_bridge) | (ppc_oea64 & ppc_oea64_bridge) 12file arch/powerpc/powerpc/fixup.c ppc_booke | (ppc_oea & ppc_oea64) | (ppc_oea & ppc_oea64_bridge) | (ppc_oea64 & ppc_oea64_bridge)
13file arch/powerpc/powerpc/fubyte.c 13file arch/powerpc/powerpc/fubyte.c
14file arch/powerpc/powerpc/fuswintr.c 14file arch/powerpc/powerpc/fuswintr.c
15file arch/powerpc/powerpc/ipkdb_glue.c ipkdb 15file arch/powerpc/powerpc/ipkdb_glue.c ipkdb
16file arch/powerpc/powerpc/kgdb_machdep.c kgdb 16file arch/powerpc/powerpc/kgdb_machdep.c kgdb
17file arch/powerpc/powerpc/kobj_machdep.c modular 17file arch/powerpc/powerpc/kobj_machdep.c modular
18file arch/powerpc/powerpc/lock_stubs.S 18file arch/powerpc/powerpc/lock_stubs.S
19file arch/powerpc/powerpc/openpic.c openpic 19file arch/powerpc/powerpc/openpic.c openpic
20file arch/powerpc/powerpc/pmap_subr.c ppc_oea | ppc_oea64 | ppc_oea64_bridge | ppc_oea601 20file arch/powerpc/powerpc/pmap_subr.c ppc_oea | ppc_oea64 | ppc_oea64_bridge | ppc_oea601
21file arch/powerpc/powerpc/powerpc_machdep.c 21file arch/powerpc/powerpc/powerpc_machdep.c
22file arch/powerpc/powerpc/process_machdep.c 22file arch/powerpc/powerpc/process_machdep.c
23file arch/powerpc/powerpc/setfault.S 23file arch/powerpc/powerpc/setfault.S
24file arch/powerpc/powerpc/sig_machdep.c 24file arch/powerpc/powerpc/sig_machdep.c
25file arch/powerpc/powerpc/sigcode.S 25file arch/powerpc/powerpc/sigcode.S
 26file arch/powerpc/powerpc/softint_machdep.c
26file arch/powerpc/powerpc/subyte.c 27file arch/powerpc/powerpc/subyte.c
27file arch/powerpc/powerpc/suword.c 28file arch/powerpc/powerpc/suword.c
28file arch/powerpc/powerpc/suswintr.c 29file arch/powerpc/powerpc/suswintr.c
29file arch/powerpc/powerpc/sys_machdep.c 30file arch/powerpc/powerpc/sys_machdep.c
30file arch/powerpc/powerpc/syscall.c 31file arch/powerpc/powerpc/syscall.c
31file arch/powerpc/powerpc/vm_machdep.c 32file arch/powerpc/powerpc/vm_machdep.c
32file arch/powerpc/powerpc/setjmp.S ddb | kgdb 33file arch/powerpc/powerpc/setjmp.S ddb | kgdb
33file arch/powerpc/powerpc/db_memrw.c ddb | kgdb 34file arch/powerpc/powerpc/db_memrw.c ddb | kgdb
34file arch/powerpc/powerpc/db_disasm.c ddb 35file arch/powerpc/powerpc/db_disasm.c ddb
35file arch/powerpc/powerpc/db_interface.c ddb | kgdb 36file arch/powerpc/powerpc/db_interface.c ddb | kgdb
36file arch/powerpc/powerpc/db_trace.c ddb 37file arch/powerpc/powerpc/db_trace.c ddb
37file arch/powerpc/powerpc/fpu.c 38file arch/powerpc/powerpc/fpu.c
38 39

cvs diff -r1.79 -r1.80 src/sys/arch/powerpc/include/cpu.h (expand / switch to unified diff)

--- src/sys/arch/powerpc/include/cpu.h 2011/06/13 21:19:01 1.79
+++ src/sys/arch/powerpc/include/cpu.h 2011/06/14 22:36:12 1.80
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: cpu.h,v 1.79 2011/06/13 21:19:01 matt Exp $ */ 1/* $NetBSD: cpu.h,v 1.80 2011/06/14 22:36:12 matt Exp $ */
2 2
3/* 3/*
4 * Copyright (C) 1999 Wolfgang Solfrank. 4 * Copyright (C) 1999 Wolfgang Solfrank.
5 * Copyright (C) 1999 TooLs GmbH. 5 * Copyright (C) 1999 TooLs GmbH.
6 * Copyright (C) 1995-1997 Wolfgang Solfrank. 6 * Copyright (C) 1995-1997 Wolfgang Solfrank.
7 * Copyright (C) 1995-1997 TooLs GmbH. 7 * Copyright (C) 1995-1997 TooLs GmbH.
8 * All rights reserved. 8 * All rights reserved.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -58,26 +58,27 @@ struct cache_info { @@ -58,26 +58,27 @@ struct cache_info {
58#endif 58#endif
59 59
60#include <sys/cpu_data.h> 60#include <sys/cpu_data.h>
61 61
62struct cpu_info { 62struct cpu_info {
63 struct cpu_data ci_data; /* MI per-cpu data */ 63 struct cpu_data ci_data; /* MI per-cpu data */
64#ifdef _KERNEL 64#ifdef _KERNEL
65 device_t ci_dev; /* device of corresponding cpu */ 65 device_t ci_dev; /* device of corresponding cpu */
66 struct cpu_softc *ci_softc; /* private cpu info */ 66 struct cpu_softc *ci_softc; /* private cpu info */
67 struct lwp *ci_curlwp; /* current owner of the processor */ 67 struct lwp *ci_curlwp; /* current owner of the processor */
68 68
69 struct pcb *ci_curpcb; 69 struct pcb *ci_curpcb;
70 struct pmap *ci_curpm; 70 struct pmap *ci_curpm;
 71 struct lwp *ci_softlwps[SOFTINT_COUNT];
71 int ci_cpuid; /* from SPR_PIR */ 72 int ci_cpuid; /* from SPR_PIR */
72 73
73 int ci_want_resched; 74 int ci_want_resched;
74 volatile uint64_t ci_lastintr; 75 volatile uint64_t ci_lastintr;
75 volatile u_long ci_lasttb; 76 volatile u_long ci_lasttb;
76 volatile int ci_tickspending; 77 volatile int ci_tickspending;
77 volatile int ci_cpl; 78 volatile int ci_cpl;
78 volatile int ci_iactive; 79 volatile int ci_iactive;
79 volatile int ci_idepth; 80 volatile int ci_idepth;
80#ifndef PPC_BOOKE 81#ifndef PPC_BOOKE
81 volatile imask_t ci_ipending; 82 volatile imask_t ci_ipending;
82#endif 83#endif
83 volatile uint32_t ci_pending_ipis; 84 volatile uint32_t ci_pending_ipis;

File Added: src/sys/arch/powerpc/include/softint.h
/*	$NetBSD: softint.h,v 1.1 2011/06/14 22:36:12 matt Exp $	*/
/*-
 * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Raytheon BBN Technologies Corp and Defense Advanced Research Projects
 * Agency and which was developed by Matt Thomas of 3am Software Foundry.
 *
 * This material is based upon work supported by the Defense Advanced Research
 * Projects Agency and Space and Naval Warfare Systems Center, Pacific, under
 * Contract No. N66001-09-C-2073.
 * Approved for Public Release, Distribution Unlimited
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#ifdef __INTR_PRIVATE
#ifndef _POWERPC_SOFTINT_H_
#define _POWERPC_SOFTINT_H_

#include <sys/intr.h>

#ifdef __HAVE_FAST_SOFTINTS

#ifdef __HAVE_PREEMPTION
#define	IPL_PREEMPT_SOFTMASK	(1 << IPL_NONE)
#else
#define	IPL_PREEMPT_SOFTMASK	0
#endif

#define	IPL_SOFTMASK \
	    ((1 << IPL_SOFTSERIAL) | (1 << IPL_SOFTNET   )	\
	    |(1 << IPL_SOFTBIO   ) | (1 << IPL_SOFTCLOCK )	\
	    |IPL_PREEMPT_SOFTMASK)

#define SOFTINT2IPL_MAP \
	    ((IPL_SOFTSERIAL << (4*SOFTINT_SERIAL))	\
	    |(IPL_SOFTNET    << (4*SOFTINT_NET   ))	\
	    |(IPL_SOFTBIO    << (4*SOFTINT_BIO   ))	\
	    |(IPL_SOFTCLOCK  << (4*SOFTINT_CLOCK )))
#define	SOFTINT2IPL(si_level)	((SOFTINT2IPL_MAP >> (4 * (si_level))) & 0x0f)
#define IPL2SOFTINT_MAP \
	    ((SOFTINT_SERIAL << (4*IPL_SOFTSERIAL))	\
	    |(SOFTINT_NET    << (4*IPL_SOFTNET   ))	\
	    |(SOFTINT_BIO    << (4*IPL_SOFTBIO   ))	\
	    |(SOFTINT_CLOCK  << (4*IPL_SOFTCLOCK )))
#define	IPL2SOFTINT(ipl)	((IPL2SOFTINT_MAP >> (4 * (ipl))) & 0x0f)

#ifdef _KERNEL
void	powerpc_softint(struct cpu_info *, int, vaddr_t);
void	powerpc_softint_init_md(lwp_t *, u_int, uintptr_t *);
void	powerpc_softint_trigger(uintptr_t);
#endif

#endif /* __HAVE_FAST_SOFTINTS */
#endif /* !_POWERPC_SOFTINT_H_ */
#endif /* __INTR_PRIVATE */

cvs diff -r1.6 -r1.7 src/sys/arch/powerpc/include/booke/cpuvar.h (expand / switch to unified diff)

--- src/sys/arch/powerpc/include/booke/cpuvar.h 2011/06/05 16:52:25 1.6
+++ src/sys/arch/powerpc/include/booke/cpuvar.h 2011/06/14 22:36:12 1.7
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: cpuvar.h,v 1.6 2011/06/05 16:52:25 matt Exp $ */ 1/* $NetBSD: cpuvar.h,v 1.7 2011/06/14 22:36:12 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 *
@@ -47,27 +47,26 @@ struct cpunode_softc { @@ -47,27 +47,26 @@ struct cpunode_softc {
47 47
48struct cpu_softc { 48struct cpu_softc {
49 struct cpu_info *cpu_ci; 49 struct cpu_info *cpu_ci;
50 struct evcnt *cpu_evcnt_intrs; 50 struct evcnt *cpu_evcnt_intrs;
51 bus_space_tag_t cpu_bst; 51 bus_space_tag_t cpu_bst;
52 bus_space_tag_t cpu_le_bst; 52 bus_space_tag_t cpu_le_bst;
53 bus_space_handle_t cpu_bsh; 53 bus_space_handle_t cpu_bsh;
54 bus_addr_t cpu_clock_gtbcr; 54 bus_addr_t cpu_clock_gtbcr;
55 55
56 paddr_t cpu_highmem; 56 paddr_t cpu_highmem;
57 57
58 u_int cpu_pcpls[5]; 58 u_int cpu_pcpls[5];
59 struct evcnt cpu_evcnt_spurious_intr; 59 struct evcnt cpu_evcnt_spurious_intr;
60 struct lwp *cpu_softlwps[SOFTINT_COUNT]; 
61 60
62 struct evcnt cpu_ev_late_clock; 61 struct evcnt cpu_ev_late_clock;
63 u_long cpu_ticks_per_clock_intr; 62 u_long cpu_ticks_per_clock_intr;
64 struct evcnt cpu_ev_exec_trap_sync; 63 struct evcnt cpu_ev_exec_trap_sync;
65}; 64};
66 65
67struct cpunode_locators { 66struct cpunode_locators {
68 const char *cnl_name; 67 const char *cnl_name;
69 bus_addr_t cnl_addr; 68 bus_addr_t cnl_addr;
70 bus_size_t cnl_size; 69 bus_size_t cnl_size;
71 uint8_t cnl_instance; 70 uint8_t cnl_instance;
72 uint8_t cnl_nintr; 71 uint8_t cnl_nintr;
73 uint8_t cnl_intrs[4]; 72 uint8_t cnl_intrs[4];

File Added: src/sys/arch/powerpc/powerpc/softint_machdep.c
/*	$NetBSD: softint_machdep.c,v 1.1 2011/06/14 22:36:13 matt Exp $	*/
/*-
 * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Raytheon BBN Technologies Corp and Defense Advanced Research Projects
 * Agency and which was developed by Matt Thomas of 3am Software Foundry.
 *
 * This material is based upon work supported by the Defense Advanced Research
 * Projects Agency and Space and Naval Warfare Systems Center, Pacific, under
 * Contract No. N66001-09-C-2073.
 * Approved for Public Release, Distribution Unlimited
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#define __INTR_PRIVATE

#include <sys/param.h>
#include <sys/intr.h>
#include <sys/cpu.h>
#include <sys/atomic.h>

#ifdef __HAVE_FAST_SOFTINTS
#include <powerpc/softint.h>

__CTASSERT(IPL_NONE < IPL_SOFTCLOCK);
__CTASSERT(IPL_SOFTCLOCK < IPL_SOFTBIO);
__CTASSERT(IPL_SOFTBIO < IPL_SOFTNET);
__CTASSERT(IPL_SOFTNET < IPL_SOFTSERIAL);
__CTASSERT(IPL_SOFTSERIAL < IPL_VM);
__CTASSERT(IPL_SOFTSERIAL < sizeof(uint32_t)*2);

static inline void
softint_deliver(struct cpu_info *ci, int ipl)
{
	const int si_level = IPL2SOFTINT(ipl);
	KASSERT(ci->ci_data.cpu_softints & (1 << ipl));
	ci->ci_data.cpu_softints ^= 1 << ipl;
	softint_fast_dispatch(ci->ci_softlwps[si_level], ipl);
	KASSERT(ci->ci_softlwps[si_level]->l_ctxswtch == 0);
	KASSERTMSG(ci->ci_cpl == IPL_HIGH,
	    ("%s: cpl (%d) != HIGH", __func__, ci->ci_cpl));
}

void
powerpc_softint(struct cpu_info *ci, int old_ipl, vaddr_t pc)
{
	const u_int softint_mask = (IPL_SOFTMASK << old_ipl) & IPL_SOFTMASK;
	u_int softints;

	KASSERT(ci->ci_mtx_count == 0);
	KASSERT(ci->ci_cpl == IPL_HIGH);
	while ((softints = (ci->ci_data.cpu_softints & softint_mask)) != 0) {
		KASSERT(old_ipl < IPL_SOFTSERIAL);
		if (softints & (1 << IPL_SOFTSERIAL)) {
			softint_deliver(ci, IPL_SOFTSERIAL);
			continue;
		}
		KASSERT(old_ipl < IPL_SOFTNET);
		if (softints & (1 << IPL_SOFTNET)) {
			softint_deliver(ci, IPL_SOFTNET);
			continue;
		}
		KASSERT(old_ipl < IPL_SOFTBIO);
		if (softints & (1 << IPL_SOFTBIO)) {
			softint_deliver(ci, IPL_SOFTBIO);
			continue;
		}
		KASSERT(old_ipl < IPL_SOFTCLOCK);
		if (softints & (1 << IPL_SOFTCLOCK)) {
			softint_deliver(ci, IPL_SOFTCLOCK);
			continue;
		}
#ifdef __HAVE_PREEMPTION
		KASSERT(old_ipl == IPL_NONE);
		KASSERT(softints == (1 << IPL_NONE));
		ci->ci_data.cpu_softints ^= (1 << IPL_NONE);
		kpreempt(pc);
#endif
	}
}

void
powerpc_softint_init_md(lwp_t *l, u_int si_level, uintptr_t *machdep_p)
{
	struct cpu_info * const ci = l->l_cpu;

	*machdep_p = 1 << SOFTINT2IPL(si_level);
	KASSERT(*machdep_p & IPL_SOFTMASK);
	ci->ci_softlwps[si_level] = l;
}

void
powerpc_softint_trigger(uintptr_t machdep)
{
	struct cpu_info * const ci = curcpu();

	atomic_or_uint(&ci->ci_data.cpu_softints, machdep);
}

#endif /* __HAVE_FAST_SOFTINTS */