Annotation of sys/arch/arm/arm/fiq.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: fiq.c,v 1.1 2004/02/01 05:09:48 drahn Exp $ */
2: /* $NetBSD: fiq.c,v 1.5 2002/04/03 23:33:27 thorpej Exp $ */
3:
4: /*
5: * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
6: * All rights reserved.
7: *
8: * Written by Jason R. Thorpe for Wasabi Systems, Inc.
9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
18: * 3. All advertising materials mentioning features or use of this software
19: * must display the following acknowledgement:
20: * This product includes software developed for the NetBSD Project by
21: * Wasabi Systems, Inc.
22: * 4. The name of Wasabi Systems, Inc. may not be used to endorse
23: * or promote products derived from this software without specific prior
24: * written permission.
25: *
26: * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
27: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
30: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36: * POSSIBILITY OF SUCH DAMAGE.
37: */
38:
39: #include <sys/cdefs.h>
40:
41: #include <sys/param.h>
42: #include <sys/systm.h>
43:
44: #include <arm/cpufunc.h>
45: #include <arm/fiq.h>
46:
47: #ifdef __PROG32
48: #include <uvm/uvm.h>
49: #endif
50:
51: TAILQ_HEAD(, fiqhandler) fiqhandler_stack =
52: TAILQ_HEAD_INITIALIZER(fiqhandler_stack);
53:
54: extern char fiqvector[];
55: extern char fiq_nullhandler[], fiq_nullhandler_end[];
56:
57: #ifdef __PROG32
58: #define IRQ_BIT I32_bit
59: #define FIQ_BIT F32_bit
60: #else
61: #define IRQ_BIT R15_IRQ_DISABLE
62: #define FIQ_BIT R15_FIQ_DISABLE
63: #endif /* __PROG32 */
64:
65: /*
66: * fiq_installhandler:
67: *
68: * Actually install the FIQ handler down at the FIQ vector.
69: *
70: * Note: If the FIQ is invoked via an extra layer of
71: * indirection, the actual FIQ code store lives in the
72: * data segment, so there is no need to manipulate
73: * the vector page's protection.
74: */
75: static void
76: fiq_installhandler(void *func, size_t size)
77: {
78: #if defined(__PROG32) && !defined(__ARM_FIQ_INDIRECT)
79: vector_page_setprot(VM_PROT_READ|VM_PROT_WRITE);
80: #endif
81:
82: memcpy(fiqvector, func, size);
83:
84: #ifdef __PROG32
85: #if !defined(__ARM_FIQ_INDIRECT)
86: vector_page_setprot(VM_PROT_READ);
87: #endif
88: cpu_icache_sync_range((vaddr_t) fiqvector, size);
89: #endif
90: }
91:
92: /*
93: * fiq_claim:
94: *
95: * Claim the FIQ vector.
96: */
97: int
98: fiq_claim(struct fiqhandler *fh)
99: {
100: struct fiqhandler *ofh;
101: u_int oldirqstate;
102: int error = 0;
103:
104: if (fh->fh_size > 0x100)
105: return (EFBIG);
106:
107: oldirqstate = disable_interrupts(FIQ_BIT);
108:
109: if ((ofh = TAILQ_FIRST(&fiqhandler_stack)) != NULL) {
110: if ((ofh->fh_flags & FH_CANPUSH) == 0) {
111: error = EBUSY;
112: goto out;
113: }
114:
115: /* Save the previous FIQ handler's registers. */
116: if (ofh->fh_regs != NULL)
117: fiq_getregs(ofh->fh_regs);
118: }
119:
120: /* Set FIQ mode registers to ours. */
121: if (fh->fh_regs != NULL)
122: fiq_setregs(fh->fh_regs);
123:
124: TAILQ_INSERT_HEAD(&fiqhandler_stack, fh, fh_list);
125:
126: /* Now copy the actual handler into place. */
127: fiq_installhandler(fh->fh_func, fh->fh_size);
128:
129: /* Make sure FIQs are enabled when we return. */
130: oldirqstate &= ~FIQ_BIT;
131:
132: out:
133: restore_interrupts(oldirqstate);
134: return (error);
135: }
136:
137: /*
138: * fiq_release:
139: *
140: * Release the FIQ vector.
141: */
142: void
143: fiq_release(struct fiqhandler *fh)
144: {
145: u_int oldirqstate;
146: struct fiqhandler *ofh;
147:
148: oldirqstate = disable_interrupts(FIQ_BIT);
149:
150: /*
151: * If we are the currently active FIQ handler, then we
152: * need to save our registers and pop the next one back
153: * into the vector.
154: */
155: if (fh == TAILQ_FIRST(&fiqhandler_stack)) {
156: if (fh->fh_regs != NULL)
157: fiq_getregs(fh->fh_regs);
158: TAILQ_REMOVE(&fiqhandler_stack, fh, fh_list);
159: if ((ofh = TAILQ_FIRST(&fiqhandler_stack)) != NULL) {
160: if (ofh->fh_regs != NULL)
161: fiq_setregs(ofh->fh_regs);
162: fiq_installhandler(ofh->fh_func, ofh->fh_size);
163: }
164: } else
165: TAILQ_REMOVE(&fiqhandler_stack, fh, fh_list);
166:
167: if (TAILQ_FIRST(&fiqhandler_stack) == NULL) {
168: /* Copy the NULL handler back down into the vector. */
169: fiq_installhandler(fiq_nullhandler,
170: (size_t)(fiq_nullhandler_end - fiq_nullhandler));
171:
172: /* Make sure FIQs are disabled when we return. */
173: oldirqstate |= FIQ_BIT;
174: }
175:
176: restore_interrupts(oldirqstate);
177: }
CVSweb