Skip to content

Commit 0f9311a

Browse files
authored
Merge pull request #1465 from sydpy/dev-postpone-interrupts
Postpone masked interrupts
2 parents de3f540 + a23ad9e commit 0f9311a

File tree

1 file changed

+29
-14
lines changed

1 file changed

+29
-14
lines changed

qiling/hw/intc/cm_nvic.py

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
#!/usr/bin/env python3
2-
#
2+
#
33
# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
44
#
55

66
import ctypes
7+
from qiling.arch.cortex_m_const import IRQ
78

89
from qiling.hw.peripheral import QlPeripheral
910

@@ -28,11 +29,11 @@ class Type(ctypes.Structure):
2829

2930
def __init__(self, ql, label):
3031
super().__init__(ql, label)
31-
32+
3233
# reference:
3334
# https://www.youtube.com/watch?v=uFBNf7F3l60
34-
# https://developer.arm.com/documentation/ddi0439/b/Nested-Vectored-Interrupt-Controller
35-
35+
# https://developer.arm.com/documentation/ddi0439/b/Nested-Vectored-Interrupt-Controller
36+
3637
self.instance = self.struct()
3738

3839
## The max number of interrupt request
@@ -50,8 +51,8 @@ def __init__(self, ql, label):
5051
(self.struct.ICPR, self.clear_pending),
5152
]
5253

53-
self.intrs = []
54-
self.interrupt_handler = self.ql.arch.interrupt_handler
54+
self.intrs = []
55+
self.interrupt_handler = self.ql.arch.interrupt_handler
5556

5657
def enable(self, IRQn):
5758
if IRQn >= 0:
@@ -79,7 +80,7 @@ def set_pending(self, IRQn):
7980
self.instance.ICPR[IRQn >> self.OFFSET] |= 1 << (IRQn & self.MASK)
8081
else:
8182
self.ql.hw.scb.set_pending(IRQn)
82-
83+
8384
if self.get_enable(IRQn):
8485
self.intrs.append(IRQn)
8586

@@ -100,19 +101,33 @@ def get_priority(self, IRQn):
100101
if IRQn >= 0:
101102
return self.instance.IPR[IRQn]
102103
else:
103-
return self.ql.hw.scb.get_priority(IRQn)
104-
104+
return self.ql.hw.scb.get_priority(IRQn)
105+
105106
def step(self):
106107
if not self.intrs:
107108
return
108109

109-
self.intrs.sort(key=lambda x: self.get_priority(x))
110-
110+
self.intrs.sort(key=lambda x: self.get_priority(x))
111+
112+
postponed = []
113+
111114
while self.intrs:
112115
IRQn = self.intrs.pop(0)
116+
117+
basepri = self.ql.arch.regs.basepri & 0xF0
118+
if (
119+
(basepri and basepri <= self.get_priority(IRQn))
120+
or (IRQn > IRQ.HARD_FAULT and (self.ql.arch.regs.primask & 0x1))
121+
or (IRQn != IRQ.NMI and (self.ql.arch.regs.faultmask & 0x1))
122+
):
123+
postponed.append(IRQn)
124+
continue
125+
113126
self.clear_pending(IRQn)
114127
self.interrupt_handler(self.ql, IRQn)
115128

129+
self.intrs = postponed
130+
116131
@QlPeripheral.monitor()
117132
def read(self, offset: int, size: int) -> int:
118133
buf = ctypes.create_string_buffer(size)
@@ -132,13 +147,13 @@ def write_byte(ofs, byte):
132147
ipr = self.struct.IPR
133148
if ipr.offset <= ofs < ipr.offset + ipr.size:
134149
byte &= 0xf0 # IPR[3: 0] reserved
135-
136-
ctypes.memmove(ctypes.addressof(self.instance) + ofs, bytes([byte]), 1)
150+
151+
ctypes.memmove(ctypes.addressof(self.instance) + ofs, bytes([byte]), 1)
137152

138153
for ofs in range(offset, offset + size):
139154
write_byte(ofs, value & 0xff)
140155
value >>= 8
141156

142157
@property
143158
def region(self):
144-
return [(0, self.struct.RESERVED5.offset), (self.struct.STIR.offset, ctypes.sizeof(self.struct))]
159+
return [(0, self.struct.RESERVED5.offset), (self.struct.STIR.offset, ctypes.sizeof(self.struct))]

0 commit comments

Comments
 (0)