FreeNOS
BroadcomInterrupt.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2025 Ivan Tan
3 * Copyright (C) 2015 Niek Linnenbank
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <Log.h>
20#include "BroadcomInterrupt.h"
21
22#define INTERRUPT_BASE_ADDR 0xB000
23#define INTERRUPT_BASICPEND (INTERRUPT_BASE_ADDR+0x200)
24#define INTERRUPT_IRQPEND1 (INTERRUPT_BASE_ADDR+0x204)
25#define INTERRUPT_IRQPEND2 (INTERRUPT_BASE_ADDR+0x208)
26#define INTERRUPT_FIQCONTROL (INTERRUPT_BASE_ADDR+0x20C)
27#define INTERRUPT_ENABLEIRQ1 (INTERRUPT_BASE_ADDR+0x210)
28#define INTERRUPT_ENABLEIRQ2 (INTERRUPT_BASE_ADDR+0x214)
29#define INTERRUPT_ENABLEBASICIRQ (INTERRUPT_BASE_ADDR+0x218)
30#define INTERRUPT_DISABLEIRQ1 (INTERRUPT_BASE_ADDR+0x21C)
31#define INTERRUPT_DISABLEIRQ2 (INTERRUPT_BASE_ADDR+0x220)
32#define INTERRUPT_DISABLEBASICIRQ (INTERRUPT_BASE_ADDR+0x224)
33 #define IRQSYSTIMERC1 1
34 #define IRQSYSTIMERC3 3
35 #define IRQAUX 29
36 #define IRQUART 57
37
39{
40 // disable all IRQ sources first, just to be "safe"
41 m_io.write(INTERRUPT_DISABLEIRQ1, 0xFFFFFFFF);
42 m_io.write(INTERRUPT_DISABLEIRQ2, 0xFFFFFFFF);
43}
44
46{
47 // enable the respective interrupt
48 if(vector < 32)
49 {
50 // only 1 bits are recognized when writing to the (en/dis)able regs.
51 // using |= here could be problematic since it would likely be
52 // implemented as multiple instructions: at least a read, an or,
53 // and a write. if we interrupted _after_ the read instruction or
54 // the or instruction, and disabled certain bits in the IRQ
55 // routine, the |= would write back the old state of the enable
56 // bits. This would effectively be re-enabling interrupts that we
57 // wanted disabled.
58 m_io.write(INTERRUPT_ENABLEIRQ1, (1<<vector));
59 }
60 else
61 {
62 m_io.write(INTERRUPT_ENABLEIRQ2, (1<<(vector-32)));
63 }
64 return Success;
65}
66
68{
69 // disable IRQs for this device before NULL-ing the vector. otherwise,
70 // we might interrupt with a NULL_VECT in the handler's address.
71 // because the interrupt wasn't ACKed because we never went to the
72 // handler routine, the device will continue to assert its IRQ line,
73 // which will put us in a never-ending IRQ loop.
74 if(vector < 32)
75 {
76 m_io.write(INTERRUPT_DISABLEIRQ1, (1<<vector));
77 }
78 else
79 {
80 m_io.write(INTERRUPT_DISABLEIRQ2, (1<<(vector-32)));
81 }
82 return Success;
83}
84
86{
87 return Success;
88}
89
91{
92 for (Size i = 0; i < 64; i++)
93 {
94 if (isTriggered(i))
95 {
96 irq = i;
97 return Success;
98 }
99 }
100
101 return NotFound;
102}
103
105{
107
108 switch (vector)
109 {
110 case 9: return (basic & (1 << 11));
111 }
114
115 if (vector < 32)
116 return (pend1 & (1 << vector));
117 else
118 return (pend2 & (1 << (vector-32)));
119}
#define INTERRUPT_DISABLEIRQ1
#define INTERRUPT_DISABLEIRQ2
#define INTERRUPT_DISABLEIRQ1
#define INTERRUPT_IRQPEND1
#define INTERRUPT_ENABLEIRQ2
#define INTERRUPT_BASICPEND
#define INTERRUPT_IRQPEND2
#define INTERRUPT_DISABLEIRQ2
#define INTERRUPT_ENABLEIRQ1
void write(u32 reg, u32 data)
write to memory mapped I/O register
Definition ARMIO.h:46
u32 read(u32 reg) const
read from memory mapped I/O register
Definition ARMIO.h:62
ARMIO m_io
I/O instance.
virtual bool isTriggered(uint vector)
Check if an IRQ vector is set.
virtual Result disable(uint vector)
Disable an IRQ vector.
BroadcomInterrupt()
Constructor.
virtual Result clear(uint vector)
Clear an IRQ vector.
virtual Result enable(uint vector)
Enable an IRQ vector.
virtual Result nextPending(uint &irq)
Retrieve the next pending interrupt (IRQ).
Interrupt controller interface.
Result
Result codes.
unsigned int u32
Unsigned 32-bit number.
Definition Types.h:53
unsigned int uint
Unsigned integer number.
Definition Types.h:44
unsigned int Size
Any sane size indicator cannot go negative.
Definition Types.h:128