mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-11-15 09:36:35 +00:00
thermosphere: yikes
This commit is contained in:
parent
37b14bc4b8
commit
7130b6efd1
2 changed files with 38 additions and 21 deletions
|
@ -28,10 +28,10 @@
|
||||||
typedef struct IrqManager {
|
typedef struct IrqManager {
|
||||||
RecursiveSpinlock lock;
|
RecursiveSpinlock lock;
|
||||||
ArmGicV2 gic;
|
ArmGicV2 gic;
|
||||||
|
u16 numSharedInterrupts;
|
||||||
u8 priorityShift;
|
u8 priorityShift;
|
||||||
u8 numPriorityLevels;
|
u8 numPriorityLevels;
|
||||||
u8 numCpuInterfaces;
|
u8 numCpuInterfaces;
|
||||||
u8 numSharedInterrupts;
|
|
||||||
u8 numListRegisters;
|
u8 numListRegisters;
|
||||||
// Note: we don't store interrupt handlers since we will handle some SGI + uart interrupt(s)...
|
// Note: we don't store interrupt handlers since we will handle some SGI + uart interrupt(s)...
|
||||||
} IrqManager;
|
} IrqManager;
|
||||||
|
|
|
@ -394,7 +394,7 @@ static inline u8 vgicGetInterruptTargets(u16 id)
|
||||||
return (id < 32 || irqIsGuest(id)) ? g_irqManager.gic.gicd->itargetsr[id] : 0;
|
return (id < 32 || irqIsGuest(id)) ? g_irqManager.gic.gicd->itargetsr[id] : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void vgicSetInterruptConfigByte(u16 id, u32 config)
|
static inline void vgicSetInterruptConfigBits(u16 id, u32 config)
|
||||||
{
|
{
|
||||||
// Ignored for SGIs, implementation defined for PPIs
|
// Ignored for SGIs, implementation defined for PPIs
|
||||||
if (id < 32 || !irqIsGuest(id)) {
|
if (id < 32 || !irqIsGuest(id)) {
|
||||||
|
@ -407,7 +407,7 @@ static inline void vgicSetInterruptConfigByte(u16 id, u32 config)
|
||||||
g_irqManager.gic.gicd->icfgr[id / 16] = cfg;
|
g_irqManager.gic.gicd->icfgr[id / 16] = cfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u32 vgicGetInterruptConfigByte(u16 id, u32 config)
|
static inline u32 vgicGetInterruptConfigBits(u16 id, u32 config)
|
||||||
{
|
{
|
||||||
return (irqIsGuest(id) && vgicIsVirqEdgeTriggered(id)) ? 2 : 0;
|
return (irqIsGuest(id) && vgicIsVirqEdgeTriggered(id)) ? 2 : 0;
|
||||||
}
|
}
|
||||||
|
@ -477,13 +477,13 @@ static void handleVgicMmioWrite(ExceptionStackFrame *frame, DataAbortIss dabtIss
|
||||||
case GICDOFF(icfgr) ... GICDOFF(icfgr) + 31/4:
|
case GICDOFF(icfgr) ... GICDOFF(icfgr) + 31/4:
|
||||||
// Write ignored because of an implementation-defined choice
|
// Write ignored because of an implementation-defined choice
|
||||||
break;
|
break;
|
||||||
case GICDOFF(igroupr) ... GICDOFF(igroupr) + 511/32:
|
case GICDOFF(igroupr) ... GICDOFF(igroupr) + 1023/8:
|
||||||
// Write ignored because we don't implement Group 1 here
|
// Write ignored because we don't implement Group 1 here
|
||||||
break;
|
break;
|
||||||
case GICDOFF(ispendr) ... GICDOFF(ispendr) + 511/32:
|
case GICDOFF(ispendr) ... GICDOFF(ispendr) + 1023/8:
|
||||||
case GICDOFF(icpendr) ... GICDOFF(icpendr) + 511/32:
|
case GICDOFF(icpendr) ... GICDOFF(icpendr) + 1023/8:
|
||||||
case GICDOFF(isactiver) ... GICDOFF(isactiver) + 511/32:
|
case GICDOFF(isactiver) ... GICDOFF(isactiver) + 1023/8:
|
||||||
case GICDOFF(icactiver) ... GICDOFF(icactiver) + 511/32:
|
case GICDOFF(icactiver) ... GICDOFF(icactiver) + 1023/8:
|
||||||
case GICDOFF(cpendsgir) ... GICDOFF(cpendsgir) + 15:
|
case GICDOFF(cpendsgir) ... GICDOFF(cpendsgir) + 15:
|
||||||
case GICDOFF(spendsgir) ... GICDOFF(spendsgir) + 15:
|
case GICDOFF(spendsgir) ... GICDOFF(spendsgir) + 15:
|
||||||
// Write ignored, not implemented (at least not yet, TODO)
|
// Write ignored, not implemented (at least not yet, TODO)
|
||||||
|
@ -493,14 +493,14 @@ static void handleVgicMmioWrite(ExceptionStackFrame *frame, DataAbortIss dabtIss
|
||||||
vgicSetDistributorControlRegister(val);
|
vgicSetDistributorControlRegister(val);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GICDOFF(isenabler) ... GICDOFF(isenabler) + 511/32: {
|
case GICDOFF(isenabler) ... GICDOFF(isenabler) + 1023/8: {
|
||||||
u32 base = 32 * (offset - GICDOFF(isenabler));
|
u32 base = 32 * (offset - GICDOFF(isenabler));
|
||||||
FOREACH_BIT(tmp, pos, val) {
|
FOREACH_BIT(tmp, pos, val) {
|
||||||
vgicSetInterruptEnabledState((u16)(base + pos));
|
vgicSetInterruptEnabledState((u16)(base + pos));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GICDOFF(icenabler) ... GICDOFF(icenabler) + 511/32: {
|
case GICDOFF(icenabler) ... GICDOFF(icenabler) + 1023/8: {
|
||||||
u32 base = 32 * (offset - GICDOFF(icenabler));
|
u32 base = 32 * (offset - GICDOFF(icenabler));
|
||||||
FOREACH_BIT(tmp, pos, val) {
|
FOREACH_BIT(tmp, pos, val) {
|
||||||
vgicClearInterruptEnabledState((u16)(base + pos));
|
vgicClearInterruptEnabledState((u16)(base + pos));
|
||||||
|
@ -508,7 +508,7 @@ static void handleVgicMmioWrite(ExceptionStackFrame *frame, DataAbortIss dabtIss
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case GICDOFF(ipriorityr) ... GICDOFF(ipriorityr) + 511: {
|
case GICDOFF(ipriorityr) ... GICDOFF(ipriorityr) + 1023: {
|
||||||
u16 base = (u16)(offset - GICDOFF(ipriorityr));
|
u16 base = (u16)(offset - GICDOFF(ipriorityr));
|
||||||
for (u16 i = 0; i < sz; i++) {
|
for (u16 i = 0; i < sz; i++) {
|
||||||
vgicSetInterruptPriorityByte(base + i, (u8)val);
|
vgicSetInterruptPriorityByte(base + i, (u8)val);
|
||||||
|
@ -517,7 +517,7 @@ static void handleVgicMmioWrite(ExceptionStackFrame *frame, DataAbortIss dabtIss
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case GICDOFF(itargetsr) + 32 ... GICDOFF(itargetsr) + 511: {
|
case GICDOFF(itargetsr) + 32 ... GICDOFF(itargetsr) + 1023: {
|
||||||
u16 base = (u16)(offset - GICDOFF(itargetsr));
|
u16 base = (u16)(offset - GICDOFF(itargetsr));
|
||||||
for (u16 i = 0; i < sz; i++) {
|
for (u16 i = 0; i < sz; i++) {
|
||||||
vgicSetInterruptTargets(base + i, (u8)val);
|
vgicSetInterruptTargets(base + i, (u8)val);
|
||||||
|
@ -526,6 +526,15 @@ static void handleVgicMmioWrite(ExceptionStackFrame *frame, DataAbortIss dabtIss
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case GICDOFF(icfgr) + 32/4 ... GICDOFF(icfgr) + 1023/4: {
|
||||||
|
u16 base = (u16)((offset & 0xFF) / 2);
|
||||||
|
for (u16 i = 0; i < 16; i++) {
|
||||||
|
vgicSetInterruptConfigBits(base + i, val & 3);
|
||||||
|
val >>= 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case GICDOFF(sgir):
|
case GICDOFF(sgir):
|
||||||
vgicSendSgi((u16)(val & 0xF), (val >> 24) & 3, (val >> 16) & 0xFF);
|
vgicSendSgi((u16)(val & 0xF), (val >> 24) & 3, (val >> 16) & 0xFF);
|
||||||
break;
|
break;
|
||||||
|
@ -549,13 +558,13 @@ static void handleVgicMmioRead(ExceptionStackFrame *frame, DataAbortIss dabtIss,
|
||||||
case GICDOFF(icfgr) ... GICDOFF(icfgr) + 31/4:
|
case GICDOFF(icfgr) ... GICDOFF(icfgr) + 31/4:
|
||||||
// RAZ because of an implementation-defined choice
|
// RAZ because of an implementation-defined choice
|
||||||
break;
|
break;
|
||||||
case GICDOFF(igroupr) ... GICDOFF(igroupr) + 511/32:
|
case GICDOFF(igroupr) ... GICDOFF(igroupr) + 1023/8:
|
||||||
// RAZ because we don't implement Group 1 here
|
// RAZ because we don't implement Group 1 here
|
||||||
break;
|
break;
|
||||||
case GICDOFF(ispendr) ... GICDOFF(ispendr) + 511/32:
|
case GICDOFF(ispendr) ... GICDOFF(ispendr) + 1023/8:
|
||||||
case GICDOFF(icpendr) ... GICDOFF(icpendr) + 511/32:
|
case GICDOFF(icpendr) ... GICDOFF(icpendr) + 1023/8:
|
||||||
case GICDOFF(isactiver) ... GICDOFF(isactiver) + 511/32:
|
case GICDOFF(isactiver) ... GICDOFF(isactiver) + 1023/8:
|
||||||
case GICDOFF(icactiver) ... GICDOFF(icactiver) + 511/32:
|
case GICDOFF(icactiver) ... GICDOFF(icactiver) + 1023/8:
|
||||||
case GICDOFF(cpendsgir) ... GICDOFF(cpendsgir) + 15:
|
case GICDOFF(cpendsgir) ... GICDOFF(cpendsgir) + 15:
|
||||||
case GICDOFF(spendsgir) ... GICDOFF(spendsgir) + 15:
|
case GICDOFF(spendsgir) ... GICDOFF(spendsgir) + 15:
|
||||||
// RAZ, not implemented (at least not yet, TODO)
|
// RAZ, not implemented (at least not yet, TODO)
|
||||||
|
@ -571,8 +580,8 @@ static void handleVgicMmioRead(ExceptionStackFrame *frame, DataAbortIss dabtIss,
|
||||||
val = vgicGetDistributorImplementerIdentificationRegister();
|
val = vgicGetDistributorImplementerIdentificationRegister();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GICDOFF(isenabler) ... GICDOFF(isenabler) + 511/32:
|
case GICDOFF(isenabler) ... GICDOFF(isenabler) + 1023/8:
|
||||||
case GICDOFF(icenabler) ... GICDOFF(icenabler) + 511/32: {
|
case GICDOFF(icenabler) ... GICDOFF(icenabler) + 1023/8: {
|
||||||
u16 base = (u16)(32 * (offset & 0x7F));
|
u16 base = (u16)(32 * (offset & 0x7F));
|
||||||
for (u16 i = 0; i < 32; i++) {
|
for (u16 i = 0; i < 32; i++) {
|
||||||
val |= vgicGetInterruptEnabledState(base + i) ? BIT(i) : 0;
|
val |= vgicGetInterruptEnabledState(base + i) ? BIT(i) : 0;
|
||||||
|
@ -580,7 +589,7 @@ static void handleVgicMmioRead(ExceptionStackFrame *frame, DataAbortIss dabtIss,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case GICDOFF(ipriorityr) ... GICDOFF(ipriorityr) + 511: {
|
case GICDOFF(ipriorityr) ... GICDOFF(ipriorityr) + 1023: {
|
||||||
u16 base = (u16)(offset - GICDOFF(ipriorityr));
|
u16 base = (u16)(offset - GICDOFF(ipriorityr));
|
||||||
for (u16 i = 0; i < sz; i++) {
|
for (u16 i = 0; i < sz; i++) {
|
||||||
val |= vgicGetInterruptPriorityByte(base + i) << (8 * i);
|
val |= vgicGetInterruptPriorityByte(base + i) << (8 * i);
|
||||||
|
@ -588,7 +597,7 @@ static void handleVgicMmioRead(ExceptionStackFrame *frame, DataAbortIss dabtIss,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case GICDOFF(itargetsr) ... GICDOFF(itargetsr) + 511: {
|
case GICDOFF(itargetsr) ... GICDOFF(itargetsr) + 1023: {
|
||||||
u16 base = (u16)(offset - GICDOFF(itargetsr));
|
u16 base = (u16)(offset - GICDOFF(itargetsr));
|
||||||
for (u16 i = 0; i < sz; i++) {
|
for (u16 i = 0; i < sz; i++) {
|
||||||
val |= (u32)vgicGetInterruptTargets(base + i) << (8 * i);
|
val |= (u32)vgicGetInterruptTargets(base + i) << (8 * i);
|
||||||
|
@ -596,6 +605,14 @@ static void handleVgicMmioRead(ExceptionStackFrame *frame, DataAbortIss dabtIss,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case GICDOFF(icfgr) + 32/4 ... GICDOFF(icfgr) + 1023/4: {
|
||||||
|
u16 base = (u16)((offset & 0xFF) / 2);
|
||||||
|
for (u16 i = 0; i < 16; i++) {
|
||||||
|
val |= vgicGetInterruptConfigBits(base + i, val & 3) << (2 * i);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case GICDOFF(sgir):
|
case GICDOFF(sgir):
|
||||||
// Write-only register
|
// Write-only register
|
||||||
dumpUnhandledDataAbort(dabtIss, addr, "GICD read to write-only register GCID_SGIR");
|
dumpUnhandledDataAbort(dabtIss, addr, "GICD read to write-only register GCID_SGIR");
|
||||||
|
|
Loading…
Reference in a new issue