diff options
author | jake <jake@FreeBSD.org> | 2002-09-28 01:56:24 +0000 |
---|---|---|
committer | jake <jake@FreeBSD.org> | 2002-09-28 01:56:24 +0000 |
commit | eeddd0ac0f37eedb3aca3b542107639a01e1ada1 (patch) | |
tree | 359610d6f2ac88ea8259b73b5378f5aefd653142 /sys/sparc64 | |
parent | 0a7f0ba37e1b8729b985b90a1d9332963defdf07 (diff) | |
download | FreeBSD-src-eeddd0ac0f37eedb3aca3b542107639a01e1ada1.zip FreeBSD-src-eeddd0ac0f37eedb3aca3b542107639a01e1ada1.tar.gz |
Moved most interrupt related code to a new file, interrupt.S.
Diffstat (limited to 'sys/sparc64')
-rw-r--r-- | sys/sparc64/sparc64/exception.S | 149 | ||||
-rw-r--r-- | sys/sparc64/sparc64/interrupt.S | 183 |
2 files changed, 183 insertions, 149 deletions
diff --git a/sys/sparc64/sparc64/exception.S b/sys/sparc64/sparc64/exception.S index 5123ab6..ce1c573 100644 --- a/sys/sparc64/sparc64/exception.S +++ b/sys/sparc64/sparc64/exception.S @@ -1224,155 +1224,6 @@ END(tl1_sfsr_trap) INTR_LEVEL(1) .endm -ENTRY(intr_dequeue) - save %sp, -CCFSZ, %sp - -1: ldx [PCPU(IRHEAD)], %l0 - brnz,a,pt %l0, 2f - nop - - ret - restore - -2: wrpr %g0, PSTATE_NORMAL, %pstate - - ldx [%l0 + IR_NEXT], %l1 - brnz,pt %l1, 3f - stx %l1, [PCPU(IRHEAD)] - PCPU_ADDR(IRHEAD, %l1) - stx %l1, [PCPU(IRTAIL)] - -3: ldx [%l0 + IR_FUNC], %o0 - ldx [%l0 + IR_ARG], %o1 - ldx [%l0 + IR_VEC], %o2 - - ldx [PCPU(IRFREE)], %l1 - stx %l1, [%l0 + IR_NEXT] - stx %l0, [PCPU(IRFREE)] - - wrpr %g0, PSTATE_KERNEL, %pstate - - call %o0 - mov %o1, %o0 - ba,a %xcc, 1b - nop -END(intr_dequeue) - -/* - * Handle a vectored interrupt. - * - * This is either a data bearing mondo vector interrupt, or a cross trap - * request from another cpu. In either case the hardware supplies an - * interrupt packet, in the form of 3 data words which are read from internal - * registers. A data bearing mondo vector packet consists of an interrupt - * number in the first data word, and zero in 2nd and 3rd. We use the - * interrupt number to find the function, argument and priority from the - * intr_vector table, allocate and fill in an intr_request from the per-cpu - * free list, link it onto the per-cpu active list and finally post a softint - * at the desired priority. Cross trap requests come in 2 forms, direct - * and queued. Direct requests are distinguished by the first data word - * being zero. The 2nd data word carries a function to call and the 3rd - * an argument to pass. The function is jumped to directly. It executes - * in nucleus context on interrupt globals and with all interrupts disabled, - * therefore it must be fast, and the things that it can do are limited. - * Queued cross trap requests are handled much like mondo vectors, except - * that the function, argument and priority are contained in the interrupt - * packet itself. They are distinguished by the upper 4 bits of the data - * word being non-zero, which specifies the priority of the softint to - * deliver. - * - * Register usage: - * %g1 - pointer to intr_request - * %g2 - pointer to intr_vector, temp once required data is loaded - * %g3 - interrupt number for mondo vectors, unused otherwise - * %g4 - function, from the interrupt packet for cross traps, or - * loaded from the interrupt registers for mondo vecors - * %g5 - argument, as above for %g4 - * %g6 - softint priority - */ -ENTRY(intr_enqueue) - /* - * Load the interrupt packet from the hardware. - */ - wr %g0, ASI_SDB_INTR_R, %asi - ldxa [%g0 + AA_SDB_INTR_D0] %asi, %g3 - ldxa [%g0 + AA_SDB_INTR_D1] %asi, %g4 - ldxa [%g0 + AA_SDB_INTR_D2] %asi, %g5 - stxa %g0, [%g0] ASI_INTR_RECEIVE - membar #Sync - - /* - * If the first data word is zero this is a direct cross trap request. - * The 2nd word points to code to execute and the 3rd is an argument - * to pass. Jump to it. - */ - brnz,a,pt %g3, 1f - nop - jmpl %g4, %g0 - nop - /* NOTREACHED */ - - /* - * If the high 4 bits of the 1st data word are non-zero, this is a - * queued cross trap request to be delivered as a softint. The high - * 4 bits of the 1st data word specify a priority, and the 2nd and - * 3rd a function and argument. - */ -1: srlx %g3, 60, %g6 - brnz,a,pn %g6, 2f - clr %g3 - - /* - * Find the function, argument and desired priority from the - * intr_vector table. - */ - SET(intr_vectors, %g4, %g2) - sllx %g3, IV_SHIFT, %g4 - add %g2, %g4, %g2 - - ldx [%g2 + IV_FUNC], %g4 - ldx [%g2 + IV_ARG], %g5 - lduw [%g2 + IV_PRI], %g6 - - /* - * Get a intr_request from the free list. There should always be one - * unless we are getting an interrupt storm from stray interrupts, in - * which case the we will deference a NULL pointer and panic. - */ -2: ldx [PCPU(IRFREE)], %g1 - ldx [%g1 + IR_NEXT], %g2 - stx %g2, [PCPU(IRFREE)] - - /* - * Store the vector number, function, argument and priority. - */ - stw %g3, [%g1 + IR_VEC] - stx %g4, [%g1 + IR_FUNC] - stx %g5, [%g1 + IR_ARG] - stw %g6, [%g1 + IR_PRI] - - /* - * Link it onto the end of the active list. - */ - stx %g0, [%g1 + IR_NEXT] - ldx [PCPU(IRTAIL)], %g4 - stx %g1, [%g4] - add %g1, IR_NEXT, %g1 - stx %g1, [PCPU(IRTAIL)] - - /* - * Trigger a softint at the level indicated by the priority. - */ - mov 1, %g1 - sllx %g1, %g6, %g1 - wr %g1, 0, %asr20 - - /* - * Done, retry the instruction. - */ - retry -END(intr_enqueue) - .macro tl1_immu_miss /* * Load the context and the virtual page number from the tag access diff --git a/sys/sparc64/sparc64/interrupt.S b/sys/sparc64/sparc64/interrupt.S new file mode 100644 index 0000000..3353ff5 --- /dev/null +++ b/sys/sparc64/sparc64/interrupt.S @@ -0,0 +1,183 @@ +/*- + * Copyright (c) 2002 Jake Burkholder. + * All rights reserved. + * + * 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 AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#include <machine/asi.h> +#include <machine/asmacros.h> +#include <machine/ktr.h> +#include <machine/pstate.h> + +#include "assym.s" + +/* + * Handle a vectored interrupt. + * + * This is either a data bearing mondo vector interrupt, or a cross trap + * request from another cpu. In either case the hardware supplies an + * interrupt packet, in the form of 3 data words which are read from internal + * registers. A data bearing mondo vector packet consists of an interrupt + * number in the first data word, and zero in 2nd and 3rd. We use the + * interrupt number to find the function, argument and priority from the + * intr_vector table, allocate and fill in an intr_request from the per-cpu + * free list, link it onto the per-cpu active list and finally post a softint + * at the desired priority. Cross trap requests come in 2 forms, direct + * and queued. Direct requests are distinguished by the first data word + * being zero. The 2nd data word carries a function to call and the 3rd + * an argument to pass. The function is jumped to directly. It executes + * in nucleus context on interrupt globals and with all interrupts disabled, + * therefore it must be fast, and the things that it can do are limited. + * Queued cross trap requests are handled much like mondo vectors, except + * that the function, argument and priority are contained in the interrupt + * packet itself. They are distinguished by the upper 4 bits of the data + * word being non-zero, which specifies the priority of the softint to + * deliver. + * + * Register usage: + * %g1 - pointer to intr_request + * %g2 - pointer to intr_vector, temp once required data is loaded + * %g3 - interrupt number for mondo vectors, unused otherwise + * %g4 - function, from the interrupt packet for cross traps, or + * loaded from the interrupt registers for mondo vecors + * %g5 - argument, as above for %g4 + * %g6 - softint priority + */ +ENTRY(intr_enqueue) + /* + * Load the interrupt packet from the hardware. + */ + wr %g0, ASI_SDB_INTR_R, %asi + ldxa [%g0 + AA_SDB_INTR_D0] %asi, %g3 + ldxa [%g0 + AA_SDB_INTR_D1] %asi, %g4 + ldxa [%g0 + AA_SDB_INTR_D2] %asi, %g5 + stxa %g0, [%g0] ASI_INTR_RECEIVE + membar #Sync + + /* + * If the first data word is zero this is a direct cross trap request. + * The 2nd word points to code to execute and the 3rd is an argument + * to pass. Jump to it. + */ + brnz,a,pt %g3, 1f + nop + jmpl %g4, %g0 + nop + /* NOTREACHED */ + + /* + * If the high 4 bits of the 1st data word are non-zero, this is a + * queued cross trap request to be delivered as a softint. The high + * 4 bits of the 1st data word specify a priority, and the 2nd and + * 3rd a function and argument. + */ +1: srlx %g3, 60, %g6 + brnz,a,pn %g6, 2f + clr %g3 + + /* + * Find the function, argument and desired priority from the + * intr_vector table. + */ + SET(intr_vectors, %g4, %g2) + sllx %g3, IV_SHIFT, %g4 + add %g2, %g4, %g2 + + ldx [%g2 + IV_FUNC], %g4 + ldx [%g2 + IV_ARG], %g5 + lduw [%g2 + IV_PRI], %g6 + + /* + * Get a intr_request from the free list. There should always be one + * unless we are getting an interrupt storm from stray interrupts, in + * which case the we will deference a NULL pointer and panic. + */ +2: ldx [PCPU(IRFREE)], %g1 + ldx [%g1 + IR_NEXT], %g2 + stx %g2, [PCPU(IRFREE)] + + /* + * Store the vector number, function, argument and priority. + */ + stw %g3, [%g1 + IR_VEC] + stx %g4, [%g1 + IR_FUNC] + stx %g5, [%g1 + IR_ARG] + stw %g6, [%g1 + IR_PRI] + + /* + * Link it onto the end of the active list. + */ + stx %g0, [%g1 + IR_NEXT] + ldx [PCPU(IRTAIL)], %g4 + stx %g1, [%g4] + add %g1, IR_NEXT, %g1 + stx %g1, [PCPU(IRTAIL)] + + /* + * Trigger a softint at the level indicated by the priority. + */ + mov 1, %g1 + sllx %g1, %g6, %g1 + wr %g1, 0, %asr20 + + /* + * Done, retry the instruction. + */ + retry +END(intr_enqueue) + +ENTRY(intr_dequeue) + save %sp, -CCFSZ, %sp + +1: ldx [PCPU(IRHEAD)], %l0 + brnz,a,pt %l0, 2f + nop + + ret + restore + +2: wrpr %g0, PSTATE_NORMAL, %pstate + + ldx [%l0 + IR_NEXT], %l1 + brnz,pt %l1, 3f + stx %l1, [PCPU(IRHEAD)] + PCPU_ADDR(IRHEAD, %l1) + stx %l1, [PCPU(IRTAIL)] + +3: ldx [%l0 + IR_FUNC], %o0 + ldx [%l0 + IR_ARG], %o1 + ldx [%l0 + IR_VEC], %o2 + + ldx [PCPU(IRFREE)], %l1 + stx %l1, [%l0 + IR_NEXT] + stx %l0, [PCPU(IRFREE)] + + wrpr %g0, PSTATE_KERNEL, %pstate + + call %o0 + mov %o1, %o0 + ba,a %xcc, 1b + nop +END(intr_dequeue) |