thermosphere: major refactor of memory map
- use recursive stage 1 page table (thanks @fincs for this idea) - NULL now unmapped - no identity mapping - image + GICv2 now mapped at the same address for every platform - tempbss mapped just after "real" bss, can now steal unused mem from the latter - no hardcoded VAs for other MMIO devices - tegra: remove timers, use the generic timer instead
This commit is contained in:
@@ -29,26 +29,21 @@ static void initGic(void)
|
||||
{
|
||||
// Reinits the GICD and GICC (for non-secure mode, obviously)
|
||||
if (currentCoreCtx->isBootCore && !currentCoreCtx->warmboot) {
|
||||
initGicV2Pointers(&g_irqManager.gic);
|
||||
|
||||
// Disable interrupt handling & global interrupt distribution
|
||||
g_irqManager.gic.gicd->ctlr = 0;
|
||||
gicd->ctlr = 0;
|
||||
|
||||
// Get some info
|
||||
g_irqManager.numSharedInterrupts = 32 * (g_irqManager.gic.gicd->typer & 0x1F); // number of interrupt lines / 32
|
||||
g_irqManager.numSharedInterrupts = 32 * (gicd->typer & 0x1F); // number of interrupt lines / 32
|
||||
|
||||
// unimplemented priority bits (lowest significant) are RAZ/WI
|
||||
g_irqManager.gic.gicd->ipriorityr[0] = 0xFF;
|
||||
g_irqManager.priorityShift = 8 - __builtin_popcount(g_irqManager.gic.gicd->ipriorityr[0]);
|
||||
g_irqManager.numPriorityLevels = (u8)BIT(__builtin_popcount(g_irqManager.gic.gicd->ipriorityr[0]));
|
||||
gicd->ipriorityr[0] = 0xFF;
|
||||
g_irqManager.priorityShift = 8 - __builtin_popcount(gicd->ipriorityr[0]);
|
||||
g_irqManager.numPriorityLevels = (u8)BIT(__builtin_popcount(gicd->ipriorityr[0]));
|
||||
|
||||
g_irqManager.numCpuInterfaces = (u8)(1 + ((g_irqManager.gic.gicd->typer >> 5) & 7));
|
||||
g_irqManager.numListRegisters = (u8)(1 + (g_irqManager.gic.gich->vtr & 0x3F));
|
||||
g_irqManager.numCpuInterfaces = (u8)(1 + ((gicd->typer >> 5) & 7));
|
||||
g_irqManager.numListRegisters = (u8)(1 + (gich->vtr & 0x3F));
|
||||
}
|
||||
|
||||
volatile ArmGicV2Controller *gicc = g_irqManager.gic.gicc;
|
||||
volatile ArmGicV2Distributor *gicd = g_irqManager.gic.gicd;
|
||||
|
||||
// Only one core will reset the GIC state for the shared peripheral interrupts
|
||||
|
||||
u32 numInterrupts = 32;
|
||||
@@ -135,7 +130,6 @@ static inline bool checkGuestTimerInterrupts(ExceptionStackFrame *frame, u16 irq
|
||||
|
||||
static void doConfigureInterrupt(u16 id, u8 prio, bool isLevelSensitive)
|
||||
{
|
||||
volatile ArmGicV2Distributor *gicd = g_irqManager.gic.gicd;
|
||||
gicd->icenabler[id / 32] = BIT(id % 32);
|
||||
|
||||
if (id >= 32) {
|
||||
@@ -177,7 +171,7 @@ void configureInterrupt(u16 id, u8 prio, bool isLevelSensitive)
|
||||
void irqSetAffinity(u16 id, u8 affinity)
|
||||
{
|
||||
u64 flags = recursiveSpinlockLockMaskIrq(&g_irqManager.lock);
|
||||
g_irqManager.gic.gicd->itargetsr[id] = affinity;
|
||||
gicd->itargetsr[id] = affinity;
|
||||
recursiveSpinlockUnlockRestoreIrq(&g_irqManager.lock, flags);
|
||||
}
|
||||
|
||||
@@ -206,7 +200,6 @@ void handleIrqException(ExceptionStackFrame *frame, bool isLowerEl, bool isA32)
|
||||
{
|
||||
(void)isLowerEl;
|
||||
(void)isA32;
|
||||
volatile ArmGicV2Controller *gicc = g_irqManager.gic.gicc;
|
||||
|
||||
// Acknowledge the interrupt. Interrupt goes from pending to active.
|
||||
u32 iar = gicc->iar;
|
||||
@@ -277,7 +270,7 @@ void handleIrqException(ExceptionStackFrame *frame, bool isLowerEl, bool isA32)
|
||||
|
||||
// Bottom half part
|
||||
if (hasBottomHalf) {
|
||||
exceptionEnterInterruptibleHypervisorCode(frame);
|
||||
exceptionEnterInterruptibleHypervisorCode();
|
||||
unmaskIrq();
|
||||
if (transportIface != NULL) {
|
||||
transportInterfaceIrqHandlerBottomHalf(transportIface);
|
||||
|
||||
Reference in New Issue
Block a user