FreeNOS
ARMGenericInterrupt.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2019 Niek Linnenbank
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include <Log.h>
19 #include "ARMGenericInterrupt.h"
20 
22  Address distRegisterBase,
23  Address cpuRegisterBase)
24  : IntController()
25 {
26  // Set I/O register bases
27  m_dist.setBase(distRegisterBase);
28  m_cpu.setBase(cpuRegisterBase);
29 
30  // Read number of interrupt lines available
32  NOTICE(m_numIrqs << " IRQ lines");
33 }
34 
36 {
37  if (performReset)
38  {
39  // Set all interrupts in group 0 and disable all interrupts
40  for (uint i = 0; i < numRegisters(1); i++)
41  {
42  m_dist.write(GICD_GROUPR + (i * 4), 0);
43  m_dist.write(GICD_ICENABLER + (i * 4), ~0);
44  }
45 
46  // Set interrupt configuration to level triggered (2-bits)
47  for (uint i = 0; i < (m_numIrqs / 2); i++)
48  {
49  m_dist.write(GICD_ICFGR + (i * 4), 0);
50  }
51 
52  // Set interrupt priority
53  for (uint i = 0; i < (m_numIrqs / 4); i++)
54  {
55  m_dist.write(GICD_IPRIORITYR + (i * 4), 0xA0A0A0A0);
56  }
57 
58  // All interrupts are assigned to core0.
59  // Ignore the first 32 PPIs, which are local and banked per core.
60  for (uint i = 8; i < (m_numIrqs / 4); i++)
61  {
62  m_dist.write(GICD_ITARGETSR + (i * 4),
63  (1 << 0) | (1 << 8) | (1 << 16) | (1 << 24));
64  }
65 
66  // Enable all groups
68  }
69 
70  // Set minimum priority level and enable all groups
71  m_cpu.write(GICC_PMR, 0xF0);
73 
74  return Success;
75 }
76 
78  const uint irq)
79 {
80  m_dist.write(GICD_SGIR, ((1 << targetCoreId) << 16) | irq);
81  return Success;
82 }
83 
85 {
86  if (!isSoftwareInterrupt(irq))
87  {
88  m_dist.set(GICD_ISENABLER + (4 * (irq / 32)), (1 << (irq % 32)));
89  }
90  return Success;
91 }
92 
94 {
95  if (!isSoftwareInterrupt(irq))
96  {
97  m_dist.set(GICD_ICENABLER + (4 * (irq / 32)), (1 << (irq % 32)));
98  }
99  return Success;
100 }
101 
103 {
104  if (isSoftwareInterrupt(irq))
105  {
106  // Clear all pending bits for SGIs, regardless of which core is the sender
108  }
109 
110  // The saved IAR contains target CPU bits for SGIs
113  return Success;
114 }
115 
117 {
119 
121 
122  // Is this a spurious (unexpected) interrupt?
123  if (irq == 1023)
124  {
125  return NotFound;
126  }
127  else
128  return Success;
129 }
130 
132 {
133  // Unused
134  return false;
135 }
136 
138 {
139  if (m_numIrqs % 32)
140  return ((m_numIrqs * bits) / 32) + 1;
141  else
142  return (m_numIrqs * bits) / 32;
143 }
144 
146 {
147  return irq < NumberOfSoftwareInterrupts;
148 }
ARMGenericInterrupt::GICD_ICENABLER
@ GICD_ICENABLER
Definition: ARMGenericInterrupt.h:54
ARMGenericInterrupt::CpuIrqAckMask
@ CpuIrqAckMask
Definition: ARMGenericInterrupt.h:98
ARMGenericInterrupt::GICD_SGIR
@ GICD_SGIR
Definition: ARMGenericInterrupt.h:61
IntController
Interrupt controller interface.
Definition: IntController.h:35
ARMGenericInterrupt::GICC_IAR
@ GICC_IAR
Definition: ARMGenericInterrupt.h:84
ARMGenericInterrupt::isSoftwareInterrupt
bool isSoftwareInterrupt(const uint irq) const
Check if the given IRQ is an SGI.
Definition: ARMGenericInterrupt.cpp:145
ARMGenericInterrupt::initialize
Result initialize(bool performReset=true)
Initialize the controller.
Definition: ARMGenericInterrupt.cpp:35
NOTICE
#define NOTICE(msg)
Output a notice message.
Definition: Log.h:75
ARMGenericInterrupt::send
virtual Result send(const uint targetCoreId, const uint irq)
Raise a software generated interrupt (SGI).
Definition: ARMGenericInterrupt.cpp:77
ARMGenericInterrupt::isTriggered
virtual bool isTriggered(uint irq)
Check if an IRQ vector is set.
Definition: ARMGenericInterrupt.cpp:131
ARMIO::write
void write(u32 reg, u32 data)
write to memory mapped I/O register
Definition: ARMIO.h:46
ARMGenericInterrupt::GICD_GROUPR
@ GICD_GROUPR
Definition: ARMGenericInterrupt.h:52
IntController::Success
@ Success
Definition: IntController.h:44
Address
unsigned long Address
A memory address.
Definition: Types.h:131
ARMGenericInterrupt::m_numIrqs
Size m_numIrqs
Number of interrupts supported.
Definition: ARMGenericInterrupt.h:207
Log.h
IntController::NotFound
@ NotFound
Definition: IntController.h:48
uint
unsigned int uint
Unsigned integer number.
Definition: Types.h:44
ARMGenericInterrupt::GICD_CPENDSGIR
@ GICD_CPENDSGIR
Definition: ARMGenericInterrupt.h:62
ARMGenericInterrupt::NumberOfSoftwareInterrupts
static const Size NumberOfSoftwareInterrupts
Total number of software generated interrupts (SGI)
Definition: ARMGenericInterrupt.h:43
ARMGenericInterrupt::GICC_EOIR
@ GICC_EOIR
Definition: ARMGenericInterrupt.h:85
ARMGenericInterrupt::GICC_CTRL
@ GICC_CTRL
Definition: ARMGenericInterrupt.h:82
IO::setBase
void setBase(const Address base)
Set memory I/O base offset.
Definition: IO.cpp:33
ARMGenericInterrupt::enable
virtual Result enable(uint irq)
Enable hardware interrupt (IRQ).
Definition: ARMGenericInterrupt.cpp:84
ARMGenericInterrupt::GICC_PMR
@ GICC_PMR
Definition: ARMGenericInterrupt.h:83
ARMGenericInterrupt::clear
virtual Result clear(uint irq)
Clear hardware interrupt (IRQ).
Definition: ARMGenericInterrupt.cpp:102
ARMGenericInterrupt::m_savedIrqAck
u32 m_savedIrqAck
Saved value of the Interrupt-Acknowledge register.
Definition: ARMGenericInterrupt.h:210
ARMGenericInterrupt::disable
virtual Result disable(uint irq)
Disable hardware interrupt (IRQ).
Definition: ARMGenericInterrupt.cpp:93
ARMGenericInterrupt::GICD_CTRL
@ GICD_CTRL
Definition: ARMGenericInterrupt.h:50
Size
unsigned int Size
Any sane size indicator cannot go negative.
Definition: Types.h:128
ARMGenericInterrupt::GICD_TYPER
@ GICD_TYPER
Definition: ARMGenericInterrupt.h:51
ARMIO::read
u32 read(u32 reg) const
read from memory mapped I/O register
Definition: ARMIO.h:62
ARMGenericInterrupt::numRegisters
Size numRegisters(Size bits) const
Calculate the number of 32-bit registers needed to represent given number of bits per IRQ.
Definition: ARMGenericInterrupt.cpp:137
ARMGenericInterrupt::GICD_IPRIORITYR
@ GICD_IPRIORITYR
Definition: ARMGenericInterrupt.h:58
ARMGenericInterrupt.h
ARMGenericInterrupt::GICD_ITARGETSR
@ GICD_ITARGETSR
Definition: ARMGenericInterrupt.h:59
ARMGenericInterrupt::ARMGenericInterrupt
ARMGenericInterrupt(Address distRegisterBase, Address cpuRegisterBase)
Constructor.
Definition: ARMGenericInterrupt.cpp:21
ARMGenericInterrupt::CpuCtrlGroup1
@ CpuCtrlGroup1
Definition: ARMGenericInterrupt.h:93
ARMGenericInterrupt::GICD_ISENABLER
@ GICD_ISENABLER
Definition: ARMGenericInterrupt.h:53
ARMGenericInterrupt::CpuCtrlGroup0
@ CpuCtrlGroup0
Definition: ARMGenericInterrupt.h:92
ARMGenericInterrupt::m_dist
ARMIO m_dist
ARM Generic Interrupt Controller Distributor Interface.
Definition: ARMGenericInterrupt.h:201
ARMIO::set
void set(Address addr, u32 data)
Set bits in memory mapped register.
Definition: ARMIO.h:109
ARMGenericInterrupt::m_cpu
ARMIO m_cpu
ARM Generic Interrupt Controller CPU Interface.
Definition: ARMGenericInterrupt.h:204
ARMGenericInterrupt::DistCtrlGroup0
@ DistCtrlGroup0
Definition: ARMGenericInterrupt.h:68
ARMGenericInterrupt::GICC_DIR
@ GICC_DIR
Definition: ARMGenericInterrupt.h:87
IntController::Result
Result
Result codes.
Definition: IntController.h:42
ARMGenericInterrupt::DistCtrlGroup1
@ DistCtrlGroup1
Definition: ARMGenericInterrupt.h:69
ARMGenericInterrupt::DistTypeIrqsMask
@ DistTypeIrqsMask
Definition: ARMGenericInterrupt.h:74
ARMGenericInterrupt::GICD_ICFGR
@ GICD_ICFGR
Definition: ARMGenericInterrupt.h:60
ARMGenericInterrupt::nextPending
virtual Result nextPending(uint &irq)
Retrieve the next pending interrupt (IRQ).
Definition: ARMGenericInterrupt.cpp:116