mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-15 00:16:48 +00:00
thermosphere: fix is/ic registers usage; fix offset calculation
This commit is contained in:
parent
0811572889
commit
e49a035455
3 changed files with 16 additions and 19 deletions
|
@ -146,7 +146,7 @@ export QEMU := qemu-system-aarch64
|
||||||
#export QEMU := ~/qemu/aarch64-softmmu/qemu-system-aarch64
|
#export QEMU := ~/qemu/aarch64-softmmu/qemu-system-aarch64
|
||||||
|
|
||||||
QEMUFLAGS := -nographic -machine virt,secure=on,virtualization=on,gic-version=2 -cpu cortex-a57 -smp 4 -m 1024\
|
QEMUFLAGS := -nographic -machine virt,secure=on,virtualization=on,gic-version=2 -cpu cortex-a57 -smp 4 -m 1024\
|
||||||
-bios bl1.bin -d unimp -semihosting-config enable,target=native -serial mon:stdio
|
-bios bl1.bin -d unimp,guest_errors -semihosting-config enable,target=native -serial mon:stdio
|
||||||
|
|
||||||
# NOTE: copy bl1.bin, bl2.bin, bl31.bin from your own build of Arm Trusted Firmware!
|
# NOTE: copy bl1.bin, bl2.bin, bl31.bin from your own build of Arm Trusted Firmware!
|
||||||
|
|
||||||
|
|
|
@ -100,20 +100,17 @@ static void initGic(void)
|
||||||
static void configureInterrupt(u16 id, u8 prio, bool isLevelSensitive)
|
static void configureInterrupt(u16 id, u8 prio, bool isLevelSensitive)
|
||||||
{
|
{
|
||||||
volatile ArmGicV2Distributor *gicd = g_irqManager.gic.gicd;
|
volatile ArmGicV2Distributor *gicd = g_irqManager.gic.gicd;
|
||||||
gicd->icenabler[id / 32] |= BIT(id % 32);
|
gicd->icenabler[id / 32] = BIT(id % 32);
|
||||||
|
|
||||||
if (id >= 32) {
|
if (id >= 32) {
|
||||||
gicd->icfgr[id / 16] &= ~3 << (2 * (id % 16));
|
gicd->icfgr[id / 16] &= ~3 << (2 * (id % 16));
|
||||||
gicd->icfgr[id / 16] |= (!isLevelSensitive ? 2 : 0) << (2 * (id % 16));
|
gicd->icfgr[id / 16] |= (!isLevelSensitive ? 2 : 0) << (2 * (id % 16));
|
||||||
|
gicd->itargetsr[id] |= BIT(currentCoreCtx->gicInterfaceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id >= 16) {
|
gicd->icpendr[id / 32] = BIT(id % 32);
|
||||||
gicd->itargetsr[id] |= currentCoreCtx->gicInterfaceId;
|
gicd->ipriorityr[id] = (prio << g_irqManager.priorityShift) & 0xFF;
|
||||||
}
|
gicd->isenabler[id / 32] = BIT(id % 32);
|
||||||
|
|
||||||
gicd->icpendr[id / 32] |= BIT(id % 32);
|
|
||||||
gicd->ipriorityr[id] = (prio << g_irqManager.priorityShift) & 0xFF;
|
|
||||||
gicd->isenabler[id / 32] |= BIT(id % 32);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void initIrq(void)
|
void initIrq(void)
|
||||||
|
|
|
@ -301,7 +301,7 @@ static void vgicSetInterruptEnabledState(u16 id)
|
||||||
vgicNotifyOtherCoreList(g_irqManager.gic.gicd->itargetsr[id]);
|
vgicNotifyOtherCoreList(g_irqManager.gic.gicd->itargetsr[id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_irqManager.gic.gicd->isenabler[id / 32] |= BIT(id % 32);
|
g_irqManager.gic.gicd->isenabler[id / 32] = BIT(id % 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vgicClearInterruptEnabledState(u16 id)
|
static void vgicClearInterruptEnabledState(u16 id)
|
||||||
|
@ -319,7 +319,7 @@ static void vgicClearInterruptEnabledState(u16 id)
|
||||||
vgicNotifyOtherCoreList(BIT(vgicGetVirqStateCoreId(state)));
|
vgicNotifyOtherCoreList(BIT(vgicGetVirqStateCoreId(state)));
|
||||||
}
|
}
|
||||||
|
|
||||||
g_irqManager.gic.gicd->icenabler[id / 32] |= ~BIT(id % 32);
|
g_irqManager.gic.gicd->icenabler[id / 32] = BIT(id % 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool vgicGetInterruptEnabledState(u16 id)
|
static inline bool vgicGetInterruptEnabledState(u16 id)
|
||||||
|
@ -405,7 +405,7 @@ static inline void vgicSetInterruptConfigBits(u16 id, u32 config)
|
||||||
g_irqManager.gic.gicd->icfgr[id / 16] = cfg;
|
g_irqManager.gic.gicd->icfgr[id / 16] = cfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u32 vgicGetInterruptConfigBits(u16 id, u32 config)
|
static inline u32 vgicGetInterruptConfigBits(u16 id)
|
||||||
{
|
{
|
||||||
return (irqIsGuest(id) && vgicIsVirqEdgeTriggered(id)) ? 2 : 0;
|
return (irqIsGuest(id) && vgicIsVirqEdgeTriggered(id)) ? 2 : 0;
|
||||||
}
|
}
|
||||||
|
@ -492,14 +492,14 @@ static void handleVgicMmioWrite(ExceptionStackFrame *frame, DataAbortIss dabtIss
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GICDOFF(isenabler) ... GICDOFF(isenabler) + 1023/8: {
|
case GICDOFF(isenabler) ... GICDOFF(isenabler) + 1023/8: {
|
||||||
u32 base = 32 * (offset - GICDOFF(isenabler));
|
u32 base = 8 * (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) + 1023/8: {
|
case GICDOFF(icenabler) ... GICDOFF(icenabler) + 1023/8: {
|
||||||
u32 base = 32 * (offset - GICDOFF(icenabler));
|
u32 base = 8 * (offset - GICDOFF(icenabler));
|
||||||
FOREACH_BIT(tmp, pos, val) {
|
FOREACH_BIT(tmp, pos, val) {
|
||||||
vgicClearInterruptEnabledState((u16)(base + pos));
|
vgicClearInterruptEnabledState((u16)(base + pos));
|
||||||
}
|
}
|
||||||
|
@ -525,7 +525,7 @@ static void handleVgicMmioWrite(ExceptionStackFrame *frame, DataAbortIss dabtIss
|
||||||
}
|
}
|
||||||
|
|
||||||
case GICDOFF(icfgr) + 32/4 ... GICDOFF(icfgr) + 1023/4: {
|
case GICDOFF(icfgr) + 32/4 ... GICDOFF(icfgr) + 1023/4: {
|
||||||
u16 base = (u16)((offset & 0xFF) / 2);
|
u16 base = (u16)((offset & 0xFF) / 4);
|
||||||
for (u16 i = 0; i < 16; i++) {
|
for (u16 i = 0; i < 16; i++) {
|
||||||
vgicSetInterruptConfigBits(base + i, val & 3);
|
vgicSetInterruptConfigBits(base + i, val & 3);
|
||||||
val >>= 2;
|
val >>= 2;
|
||||||
|
@ -580,7 +580,7 @@ static void handleVgicMmioRead(ExceptionStackFrame *frame, DataAbortIss dabtIss,
|
||||||
|
|
||||||
case GICDOFF(isenabler) ... GICDOFF(isenabler) + 1023/8:
|
case GICDOFF(isenabler) ... GICDOFF(isenabler) + 1023/8:
|
||||||
case GICDOFF(icenabler) ... GICDOFF(icenabler) + 1023/8: {
|
case GICDOFF(icenabler) ... GICDOFF(icenabler) + 1023/8: {
|
||||||
u16 base = (u16)(32 * (offset & 0x7F));
|
u16 base = (u16)(8 * (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;
|
||||||
}
|
}
|
||||||
|
@ -604,9 +604,9 @@ static void handleVgicMmioRead(ExceptionStackFrame *frame, DataAbortIss dabtIss,
|
||||||
}
|
}
|
||||||
|
|
||||||
case GICDOFF(icfgr) + 32/4 ... GICDOFF(icfgr) + 1023/4: {
|
case GICDOFF(icfgr) + 32/4 ... GICDOFF(icfgr) + 1023/4: {
|
||||||
u16 base = (u16)((offset & 0xFF) / 2);
|
u16 base = (u16)((offset & 0xFF) / 4);
|
||||||
for (u16 i = 0; i < 16; i++) {
|
for (u16 i = 0; i < 16; i++) {
|
||||||
val |= vgicGetInterruptConfigBits(base + i, val & 3) << (2 * i);
|
val |= vgicGetInterruptConfigBits(base + i) << (2 * i);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -653,7 +653,7 @@ static void vgicCleanupPendingList(void)
|
||||||
if (id >= 32 || coreId == currentCoreCtx->coreId) {
|
if (id >= 32 || coreId == currentCoreCtx->coreId) {
|
||||||
u32 mask = g_irqManager.gic.gicd->ispendr[id / 32] & BIT(id % 32);
|
u32 mask = g_irqManager.gic.gicd->ispendr[id / 32] & BIT(id % 32);
|
||||||
if (mask == 0) {
|
if (mask == 0) {
|
||||||
g_irqManager.gic.gicd->icactiver[id / 32] = mask;
|
g_irqManager.gic.gicd->icactiver[id / 32] = BIT(id % 32);
|
||||||
pending = false;
|
pending = false;
|
||||||
} else {
|
} else {
|
||||||
pending = true;
|
pending = true;
|
||||||
|
|
Loading…
Reference in a new issue