mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-11-15 09:36:35 +00:00
thermosphere: fix wrong icfgr shift; fix list handling bug
This commit is contained in:
parent
03fe744bc4
commit
c42aef6ba7
3 changed files with 13 additions and 7 deletions
|
@ -104,8 +104,8 @@ static void configureInterrupt(u16 id, u8 prio, bool isLevelSensitive)
|
|||
|
||||
if (id >= 32) {
|
||||
u32 cfgr = gicd->icfgr[id / 16];
|
||||
cfgr &= ~(3 << (2 * (id % 16)));
|
||||
cfgr |= (!isLevelSensitive ? 3 : 1) << (2 * (id % 16));
|
||||
cfgr &= ~(3 << IRQ_CFGR_SHIFT(id));
|
||||
cfgr |= (!isLevelSensitive ? 3 : 1) << IRQ_CFGR_SHIFT(id);
|
||||
gicd->icfgr[id / 16] = cfgr;
|
||||
gicd->itargetsr[id] |= currentCoreCtx->gicInterfaceMask;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
#define IRQ_PRIORITY_HOST 0
|
||||
#define IRQ_PRIORITY_GUEST 1
|
||||
|
||||
#define IRQ_CFGR_SHIFT(id) (2*((id) % 16))
|
||||
|
||||
typedef struct IrqManager {
|
||||
RecursiveSpinlock lock;
|
||||
ArmGicV2 gic;
|
||||
|
|
|
@ -135,7 +135,7 @@ void vgicDebugPrintLrList(void)
|
|||
DEBUG("core %u lr [", currentCoreCtx->coreId);
|
||||
for (u32 i = 0; i < g_irqManager.numListRegisters; i++) {
|
||||
if (g_vgicUsedLrMap[currentCoreCtx->coreId] & BITL(i)) {
|
||||
DEBUG("%u,", vgicGetVirqStateIndex(vgicGetVirqState(currentCoreCtx->coreId, g_irqManager.gic.gich->lr[i].virtualId)));
|
||||
DEBUG("%u,", g_irqManager.gic.gich->lr[i].virtualId);
|
||||
} else {
|
||||
DEBUG("-,");
|
||||
}
|
||||
|
@ -157,6 +157,7 @@ static void vgicEnqueueVirqState(VirqStateList *list, VirqState *elem)
|
|||
if (list->first == vgicGetQueueEnd()) {
|
||||
list->first = list->last = elem;
|
||||
elem->listPrev = elem->listNext = VIRQLIST_END_ID;
|
||||
//vgicDebugPrintList(list);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -178,7 +179,9 @@ static void vgicEnqueueVirqState(VirqStateList *list, VirqState *elem)
|
|||
// Otherwise, insert before
|
||||
u32 idx = vgicGetVirqStateIndex(elem);
|
||||
u32 posidx = vgicGetVirqStateIndex(pos);
|
||||
|
||||
u32 previdx = pos->listPrev;
|
||||
VirqState *prev = vgicGetPrevQueuedVirqState(pos);
|
||||
|
||||
elem->listNext = posidx;
|
||||
elem->listPrev = previdx;
|
||||
|
@ -188,10 +191,10 @@ static void vgicEnqueueVirqState(VirqStateList *list, VirqState *elem)
|
|||
if (pos == list->first) {
|
||||
list->first = elem;
|
||||
} else {
|
||||
VirqState *prev = vgicGetPrevQueuedVirqState(pos);
|
||||
prev->listNext = idx;
|
||||
}
|
||||
}
|
||||
//vgicDebugPrintList(list);
|
||||
}
|
||||
|
||||
static void vgicDequeueVirqState(VirqStateList *list, VirqState *elem)
|
||||
|
@ -217,6 +220,7 @@ static void vgicDequeueVirqState(VirqStateList *list, VirqState *elem)
|
|||
}
|
||||
|
||||
elem->listPrev = elem->listNext = VIRQLIST_INVALID_ID;
|
||||
//vgicDebugPrintList(list);
|
||||
}
|
||||
|
||||
static inline void vgicNotifyOtherCoreList(u32 coreList)
|
||||
|
@ -235,7 +239,7 @@ static inline bool vgicIsVirqEdgeTriggered(u16 id)
|
|||
if (id < 16) {
|
||||
return true;
|
||||
} else {
|
||||
return (g_irqManager.gic.gicd->icfgr[id / 16] & (2 << (id % 16))) != 0;
|
||||
return (g_irqManager.gic.gicd->icfgr[id / 16] & (2 << IRQ_CFGR_SHIFT(id))) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -409,8 +413,8 @@ static inline void vgicSetInterruptConfigBits(u16 id, u32 config)
|
|||
|
||||
// Expose bit(2n) as nonprogrammable to the guest no matter what the physical distributor actually behaves
|
||||
u32 cfg = g_irqManager.gic.gicd->icfgr[id / 16];
|
||||
cfg &= ~(2 << (id % 16));
|
||||
cfg |= (config & 2) << (id % 16);
|
||||
cfg &= ~(2 << IRQ_CFGR_SHIFT(id));
|
||||
cfg |= (config & 2) << IRQ_CFGR_SHIFT(id);
|
||||
g_irqManager.gic.gicd->icfgr[id / 16] = cfg;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue