source: mainline/kernel/arch/arm32/src/interrupt.c@ a5e5030

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a5e5030 was 00287cc, checked in by Martin Decky <martin@…>, 17 years ago

arm32: update for the new scheme of device drivers and keyboard/serial modules
streamline arm32 port (as GXemul is still the only machine supported), more cleanup is needed

  • Property mode set to 100644
File size: 3.9 KB
Line 
1/*
2 * Copyright (c) 2007 Petr Stepan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup arm32
30 * @{
31 */
32/** @file
33 * @brief Interrupts controlling routines.
34 */
35
36#include <arch/asm.h>
37#include <arch/regutils.h>
38#include <arch/drivers/gxemul.h>
39#include <ddi/irq.h>
40#include <ddi/device.h>
41#include <interrupt.h>
42
43/** Initial size of a table holding interrupt handlers. */
44#define IRQ_COUNT 8
45
46static irq_t gxemul_timer_irq;
47
48/** Disable interrupts.
49 *
50 * @return Old interrupt priority level.
51 */
52ipl_t interrupts_disable(void)
53{
54 ipl_t ipl = current_status_reg_read();
55
56 current_status_reg_control_write(STATUS_REG_IRQ_DISABLED_BIT | ipl);
57
58 return ipl;
59}
60
61/** Enable interrupts.
62 *
63 * @return Old interrupt priority level.
64 */
65ipl_t interrupts_enable(void)
66{
67 ipl_t ipl = current_status_reg_read();
68
69 current_status_reg_control_write(ipl & ~STATUS_REG_IRQ_DISABLED_BIT);
70
71 return ipl;
72}
73
74/** Restore interrupt priority level.
75 *
76 * @param ipl Saved interrupt priority level.
77 */
78void interrupts_restore(ipl_t ipl)
79{
80 current_status_reg_control_write(
81 (current_status_reg_read() & ~STATUS_REG_IRQ_DISABLED_BIT) |
82 (ipl & STATUS_REG_IRQ_DISABLED_BIT));
83}
84
85/** Read interrupt priority level.
86 *
87 * @return Current interrupt priority level.
88 */
89ipl_t interrupts_read(void)
90{
91 return current_status_reg_read();
92}
93
94/** Starts gxemul Real Time Clock device, which asserts regular interrupts.
95 *
96 * @param frequency Interrupts frequency (0 disables RTC).
97 */
98static void gxemul_timer_start(uint32_t frequency)
99{
100 *((uint32_t *) (gxemul_rtc + GXEMUL_RTC_FREQ_OFFSET))
101 = frequency;
102}
103
104static irq_ownership_t gxemul_timer_claim(irq_t *irq)
105{
106 return IRQ_ACCEPT;
107}
108
109/** Timer interrupt handler.
110 *
111 * @param irq Interrupt information.
112 * @param arg Not used.
113 */
114static void gxemul_timer_irq_handler(irq_t *irq)
115{
116 /*
117 * We are holding a lock which prevents preemption.
118 * Release the lock, call clock() and reacquire the lock again.
119 */
120 spinlock_unlock(&irq->lock);
121 clock();
122 spinlock_lock(&irq->lock);
123
124 /* acknowledge tick */
125 *((uint32_t *) (gxemul_rtc + GXEMUL_RTC_ACK_OFFSET))
126 = 0;
127}
128
129/** Initialize basic tables for exception dispatching
130 * and starts the timer.
131 */
132void interrupt_init(void)
133{
134 irq_init(IRQ_COUNT, IRQ_COUNT);
135
136 irq_initialize(&gxemul_timer_irq);
137 gxemul_timer_irq.devno = device_assign_devno();
138 gxemul_timer_irq.inr = GXEMUL_TIMER_IRQ;
139 gxemul_timer_irq.claim = gxemul_timer_claim;
140 gxemul_timer_irq.handler = gxemul_timer_irq_handler;
141
142 irq_register(&gxemul_timer_irq);
143
144 gxemul_timer_start(GXEMUL_TIMER_FREQ);
145}
146
147/** @}
148 */
Note: See TracBrowser for help on using the repository browser.