kern: refactor to use m_ for member variables
This commit is contained in:
@@ -18,47 +18,47 @@
|
||||
namespace ams::kern::arch::arm {
|
||||
|
||||
void KInterruptController::SetupInterruptLines(s32 core_id) const {
|
||||
const size_t ITLines = (core_id == 0) ? 32 * ((this->gicd->typer & 0x1F) + 1) : NumLocalInterrupts;
|
||||
const size_t ITLines = (core_id == 0) ? 32 * ((m_gicd->typer & 0x1F) + 1) : NumLocalInterrupts;
|
||||
|
||||
for (size_t i = 0; i < ITLines / 32; i++) {
|
||||
this->gicd->icenabler[i] = 0xFFFFFFFF;
|
||||
this->gicd->icpendr[i] = 0xFFFFFFFF;
|
||||
this->gicd->icactiver[i] = 0xFFFFFFFF;
|
||||
this->gicd->igroupr[i] = 0;
|
||||
m_gicd->icenabler[i] = 0xFFFFFFFF;
|
||||
m_gicd->icpendr[i] = 0xFFFFFFFF;
|
||||
m_gicd->icactiver[i] = 0xFFFFFFFF;
|
||||
m_gicd->igroupr[i] = 0;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ITLines; i++) {
|
||||
this->gicd->ipriorityr.bytes[i] = 0xFF;
|
||||
this->gicd->itargetsr.bytes[i] = 0x00;
|
||||
m_gicd->ipriorityr.bytes[i] = 0xFF;
|
||||
m_gicd->itargetsr.bytes[i] = 0x00;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ITLines / 16; i++) {
|
||||
this->gicd->icfgr[i] = 0x00000000;
|
||||
m_gicd->icfgr[i] = 0x00000000;
|
||||
}
|
||||
}
|
||||
|
||||
void KInterruptController::Initialize(s32 core_id) {
|
||||
/* Setup pointers to ARM mmio. */
|
||||
this->gicd = GetPointer<volatile GicDistributor >(KMemoryLayout::GetDeviceVirtualAddress(KMemoryRegionType_InterruptDistributor));
|
||||
this->gicc = GetPointer<volatile GicCpuInterface>(KMemoryLayout::GetDeviceVirtualAddress(KMemoryRegionType_InterruptCpuInterface));
|
||||
m_gicd = GetPointer<volatile GicDistributor >(KMemoryLayout::GetDeviceVirtualAddress(KMemoryRegionType_InterruptDistributor));
|
||||
m_gicc = GetPointer<volatile GicCpuInterface>(KMemoryLayout::GetDeviceVirtualAddress(KMemoryRegionType_InterruptCpuInterface));
|
||||
|
||||
/* Clear CTLRs. */
|
||||
this->gicc->ctlr = 0;
|
||||
m_gicc->ctlr = 0;
|
||||
if (core_id == 0) {
|
||||
this->gicd->ctlr = 0;
|
||||
m_gicd->ctlr = 0;
|
||||
}
|
||||
|
||||
this->gicc->pmr = 0;
|
||||
this->gicc->bpr = 7;
|
||||
m_gicc->pmr = 0;
|
||||
m_gicc->bpr = 7;
|
||||
|
||||
/* Setup all interrupt lines. */
|
||||
SetupInterruptLines(core_id);
|
||||
|
||||
/* Set CTLRs. */
|
||||
if (core_id == 0) {
|
||||
this->gicd->ctlr = 1;
|
||||
m_gicd->ctlr = 1;
|
||||
}
|
||||
this->gicc->ctlr = 1;
|
||||
m_gicc->ctlr = 1;
|
||||
|
||||
/* Set the mask for this core. */
|
||||
SetGicMask(core_id);
|
||||
@@ -70,9 +70,9 @@ namespace ams::kern::arch::arm {
|
||||
void KInterruptController::Finalize(s32 core_id) {
|
||||
/* Clear CTLRs. */
|
||||
if (core_id == 0) {
|
||||
this->gicd->ctlr = 0;
|
||||
m_gicd->ctlr = 0;
|
||||
}
|
||||
this->gicc->ctlr = 0;
|
||||
m_gicc->ctlr = 0;
|
||||
|
||||
/* Set the priority level. */
|
||||
SetPriorityLevel(PriorityLevel_High);
|
||||
@@ -85,27 +85,27 @@ namespace ams::kern::arch::arm {
|
||||
/* Save isenabler. */
|
||||
for (size_t i = 0; i < util::size(state->isenabler); ++i) {
|
||||
constexpr size_t Offset = 0;
|
||||
state->isenabler[i] = this->gicd->isenabler[i + Offset];
|
||||
this->gicd->isenabler[i + Offset] = 0xFFFFFFFF;
|
||||
state->isenabler[i] = m_gicd->isenabler[i + Offset];
|
||||
m_gicd->isenabler[i + Offset] = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
/* Save ipriorityr. */
|
||||
for (size_t i = 0; i < util::size(state->ipriorityr); ++i) {
|
||||
constexpr size_t Offset = 0;
|
||||
state->ipriorityr[i] = this->gicd->ipriorityr.words[i + Offset];
|
||||
this->gicd->ipriorityr.words[i + Offset] = 0xFFFFFFFF;
|
||||
state->ipriorityr[i] = m_gicd->ipriorityr.words[i + Offset];
|
||||
m_gicd->ipriorityr.words[i + Offset] = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
/* Save itargetsr. */
|
||||
for (size_t i = 0; i < util::size(state->itargetsr); ++i) {
|
||||
constexpr size_t Offset = 0;
|
||||
state->itargetsr[i] = this->gicd->itargetsr.words[i + Offset];
|
||||
state->itargetsr[i] = m_gicd->itargetsr.words[i + Offset];
|
||||
}
|
||||
|
||||
/* Save icfgr. */
|
||||
for (size_t i = 0; i < util::size(state->icfgr); ++i) {
|
||||
constexpr size_t Offset = 0;
|
||||
state->icfgr[i] = this->gicd->icfgr[i + Offset];
|
||||
state->icfgr[i] = m_gicd->icfgr[i + Offset];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,27 +113,27 @@ namespace ams::kern::arch::arm {
|
||||
/* Save isenabler. */
|
||||
for (size_t i = 0; i < util::size(state->isenabler); ++i) {
|
||||
constexpr size_t Offset = util::size(LocalState{}.isenabler);
|
||||
state->isenabler[i] = this->gicd->isenabler[i + Offset];
|
||||
this->gicd->isenabler[i + Offset] = 0xFFFFFFFF;
|
||||
state->isenabler[i] = m_gicd->isenabler[i + Offset];
|
||||
m_gicd->isenabler[i + Offset] = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
/* Save ipriorityr. */
|
||||
for (size_t i = 0; i < util::size(state->ipriorityr); ++i) {
|
||||
constexpr size_t Offset = util::size(LocalState{}.ipriorityr);
|
||||
state->ipriorityr[i] = this->gicd->ipriorityr.words[i + Offset];
|
||||
this->gicd->ipriorityr.words[i + Offset] = 0xFFFFFFFF;
|
||||
state->ipriorityr[i] = m_gicd->ipriorityr.words[i + Offset];
|
||||
m_gicd->ipriorityr.words[i + Offset] = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
/* Save itargetsr. */
|
||||
for (size_t i = 0; i < util::size(state->itargetsr); ++i) {
|
||||
constexpr size_t Offset = util::size(LocalState{}.itargetsr);
|
||||
state->itargetsr[i] = this->gicd->itargetsr.words[i + Offset];
|
||||
state->itargetsr[i] = m_gicd->itargetsr.words[i + Offset];
|
||||
}
|
||||
|
||||
/* Save icfgr. */
|
||||
for (size_t i = 0; i < util::size(state->icfgr); ++i) {
|
||||
constexpr size_t Offset = util::size(LocalState{}.icfgr);
|
||||
state->icfgr[i] = this->gicd->icfgr[i + Offset];
|
||||
state->icfgr[i] = m_gicd->icfgr[i + Offset];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,26 +141,26 @@ namespace ams::kern::arch::arm {
|
||||
/* Restore ipriorityr. */
|
||||
for (size_t i = 0; i < util::size(state->ipriorityr); ++i) {
|
||||
constexpr size_t Offset = 0;
|
||||
this->gicd->ipriorityr.words[i + Offset] = state->ipriorityr[i];
|
||||
m_gicd->ipriorityr.words[i + Offset] = state->ipriorityr[i];
|
||||
}
|
||||
|
||||
/* Restore itargetsr. */
|
||||
for (size_t i = 0; i < util::size(state->itargetsr); ++i) {
|
||||
constexpr size_t Offset = 0;
|
||||
this->gicd->itargetsr.words[i + Offset] = state->itargetsr[i];
|
||||
m_gicd->itargetsr.words[i + Offset] = state->itargetsr[i];
|
||||
}
|
||||
|
||||
/* Restore icfgr. */
|
||||
for (size_t i = 0; i < util::size(state->icfgr); ++i) {
|
||||
constexpr size_t Offset = 0;
|
||||
this->gicd->icfgr[i + Offset] = state->icfgr[i];
|
||||
m_gicd->icfgr[i + Offset] = state->icfgr[i];
|
||||
}
|
||||
|
||||
/* Restore isenabler. */
|
||||
for (size_t i = 0; i < util::size(state->isenabler); ++i) {
|
||||
constexpr size_t Offset = 0;
|
||||
this->gicd->icenabler[i + Offset] = 0xFFFFFFFF;
|
||||
this->gicd->isenabler[i + Offset] = state->isenabler[i];
|
||||
m_gicd->icenabler[i + Offset] = 0xFFFFFFFF;
|
||||
m_gicd->isenabler[i + Offset] = state->isenabler[i];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,26 +168,26 @@ namespace ams::kern::arch::arm {
|
||||
/* Restore ipriorityr. */
|
||||
for (size_t i = 0; i < util::size(state->ipriorityr); ++i) {
|
||||
constexpr size_t Offset = util::size(LocalState{}.ipriorityr);
|
||||
this->gicd->ipriorityr.words[i + Offset] = state->ipriorityr[i];
|
||||
m_gicd->ipriorityr.words[i + Offset] = state->ipriorityr[i];
|
||||
}
|
||||
|
||||
/* Restore itargetsr. */
|
||||
for (size_t i = 0; i < util::size(state->itargetsr); ++i) {
|
||||
constexpr size_t Offset = util::size(LocalState{}.itargetsr);
|
||||
this->gicd->itargetsr.words[i + Offset] = state->itargetsr[i];
|
||||
m_gicd->itargetsr.words[i + Offset] = state->itargetsr[i];
|
||||
}
|
||||
|
||||
/* Restore icfgr. */
|
||||
for (size_t i = 0; i < util::size(state->icfgr); ++i) {
|
||||
constexpr size_t Offset = util::size(LocalState{}.icfgr);
|
||||
this->gicd->icfgr[i + Offset] = state->icfgr[i];
|
||||
m_gicd->icfgr[i + Offset] = state->icfgr[i];
|
||||
}
|
||||
|
||||
/* Restore isenabler. */
|
||||
for (size_t i = 0; i < util::size(state->isenabler); ++i) {
|
||||
constexpr size_t Offset = util::size(LocalState{}.isenabler);
|
||||
this->gicd->icenabler[i + Offset] = 0xFFFFFFFF;
|
||||
this->gicd->isenabler[i + Offset] = state->isenabler[i];
|
||||
m_gicd->icenabler[i + Offset] = 0xFFFFFFFF;
|
||||
m_gicd->isenabler[i + Offset] = state->isenabler[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,38 +46,38 @@ namespace ams::kern::arch::arm64::cpu {
|
||||
private:
|
||||
static inline KLightLock s_lock;
|
||||
private:
|
||||
u64 counter;
|
||||
s32 which;
|
||||
bool done;
|
||||
u64 m_counter;
|
||||
s32 m_which;
|
||||
bool m_done;
|
||||
public:
|
||||
constexpr KPerformanceCounterInterruptHandler() : KInterruptHandler(), counter(), which(), done() { /* ... */ }
|
||||
constexpr KPerformanceCounterInterruptHandler() : KInterruptHandler(), m_counter(), m_which(), m_done() { /* ... */ }
|
||||
|
||||
static KLightLock &GetLock() { return s_lock; }
|
||||
|
||||
void Setup(s32 w) {
|
||||
this->done = false;
|
||||
this->which = w;
|
||||
m_done = false;
|
||||
m_which = w;
|
||||
}
|
||||
|
||||
void Wait() {
|
||||
while (!this->done) {
|
||||
while (!m_done) {
|
||||
cpu::Yield();
|
||||
}
|
||||
}
|
||||
|
||||
u64 GetCounter() const { return this->counter; }
|
||||
u64 GetCounter() const { return m_counter; }
|
||||
|
||||
/* Nintendo misuses this per their own API, but it's functional. */
|
||||
virtual KInterruptTask *OnInterrupt(s32 interrupt_id) override {
|
||||
MESOSPHERE_UNUSED(interrupt_id);
|
||||
|
||||
if (this->which < 0) {
|
||||
this->counter = cpu::GetCycleCounter();
|
||||
if (m_which < 0) {
|
||||
m_counter = cpu::GetCycleCounter();
|
||||
} else {
|
||||
this->counter = cpu::GetPerformanceCounter(this->which);
|
||||
m_counter = cpu::GetPerformanceCounter(m_which);
|
||||
}
|
||||
DataMemoryBarrier();
|
||||
this->done = true;
|
||||
m_done = true;
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
@@ -93,11 +93,11 @@ namespace ams::kern::arch::arm64::cpu {
|
||||
FlushDataCache,
|
||||
};
|
||||
private:
|
||||
KLightLock lock;
|
||||
KLightLock cv_lock;
|
||||
KLightConditionVariable cv;
|
||||
std::atomic<u64> target_cores;
|
||||
volatile Operation operation;
|
||||
KLightLock m_lock;
|
||||
KLightLock m_cv_lock;
|
||||
KLightConditionVariable m_cv;
|
||||
std::atomic<u64> m_target_cores;
|
||||
volatile Operation m_operation;
|
||||
private:
|
||||
static void ThreadFunction(uintptr_t _this) {
|
||||
reinterpret_cast<KCacheHelperInterruptHandler *>(_this)->ThreadFunctionImpl();
|
||||
@@ -108,9 +108,9 @@ namespace ams::kern::arch::arm64::cpu {
|
||||
while (true) {
|
||||
/* Wait for a request to come in. */
|
||||
{
|
||||
KScopedLightLock lk(this->cv_lock);
|
||||
while ((this->target_cores & (1ul << core_id)) == 0) {
|
||||
this->cv.Wait(std::addressof(this->cv_lock));
|
||||
KScopedLightLock lk(m_cv_lock);
|
||||
while ((m_target_cores & (1ul << core_id)) == 0) {
|
||||
m_cv.Wait(std::addressof(m_cv_lock));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,9 +119,9 @@ namespace ams::kern::arch::arm64::cpu {
|
||||
|
||||
/* Broadcast, if there's nothing pending. */
|
||||
{
|
||||
KScopedLightLock lk(this->cv_lock);
|
||||
if (this->target_cores == 0) {
|
||||
this->cv.Broadcast();
|
||||
KScopedLightLock lk(m_cv_lock);
|
||||
if (m_target_cores == 0) {
|
||||
m_cv.Broadcast();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -129,7 +129,7 @@ namespace ams::kern::arch::arm64::cpu {
|
||||
|
||||
void ProcessOperation();
|
||||
public:
|
||||
constexpr KCacheHelperInterruptHandler() : KInterruptHandler(), lock(), cv_lock(), cv(), target_cores(), operation(Operation::Idle) { /* ... */ }
|
||||
constexpr KCacheHelperInterruptHandler() : KInterruptHandler(), m_lock(), m_cv_lock(), m_cv(), m_target_cores(), m_operation(Operation::Idle) { /* ... */ }
|
||||
|
||||
void Initialize(s32 core_id) {
|
||||
/* Reserve a thread from the system limit. */
|
||||
@@ -154,7 +154,7 @@ namespace ams::kern::arch::arm64::cpu {
|
||||
}
|
||||
|
||||
void RequestOperation(Operation op) {
|
||||
KScopedLightLock lk(this->lock);
|
||||
KScopedLightLock lk(m_lock);
|
||||
|
||||
/* Create core masks for us to use. */
|
||||
constexpr u64 AllCoresMask = (1ul << cpu::NumCores) - 1ul;
|
||||
@@ -162,48 +162,48 @@ namespace ams::kern::arch::arm64::cpu {
|
||||
|
||||
if ((op == Operation::InstructionMemoryBarrier) || (Kernel::GetState() == Kernel::State::Initializing)) {
|
||||
/* Check that there's no on-going operation. */
|
||||
MESOSPHERE_ABORT_UNLESS(this->operation == Operation::Idle);
|
||||
MESOSPHERE_ABORT_UNLESS(this->target_cores == 0);
|
||||
MESOSPHERE_ABORT_UNLESS(m_operation == Operation::Idle);
|
||||
MESOSPHERE_ABORT_UNLESS(m_target_cores == 0);
|
||||
|
||||
/* Set operation. */
|
||||
this->operation = op;
|
||||
m_operation = op;
|
||||
|
||||
/* For certain operations, we want to send an interrupt. */
|
||||
this->target_cores = other_cores_mask;
|
||||
m_target_cores = other_cores_mask;
|
||||
|
||||
const u64 target_mask = this->target_cores;
|
||||
const u64 target_mask = m_target_cores;
|
||||
DataSynchronizationBarrier();
|
||||
Kernel::GetInterruptManager().SendInterProcessorInterrupt(KInterruptName_CacheOperation, target_mask);
|
||||
|
||||
this->ProcessOperation();
|
||||
while (this->target_cores != 0) {
|
||||
while (m_target_cores != 0) {
|
||||
cpu::Yield();
|
||||
}
|
||||
|
||||
/* Go idle again. */
|
||||
this->operation = Operation::Idle;
|
||||
m_operation = Operation::Idle;
|
||||
} else {
|
||||
/* Lock condvar so that we can send and wait for acknowledgement of request. */
|
||||
KScopedLightLock cv_lk(this->cv_lock);
|
||||
KScopedLightLock cv_lk(m_cv_lock);
|
||||
|
||||
/* Check that there's no on-going operation. */
|
||||
MESOSPHERE_ABORT_UNLESS(this->operation == Operation::Idle);
|
||||
MESOSPHERE_ABORT_UNLESS(this->target_cores == 0);
|
||||
MESOSPHERE_ABORT_UNLESS(m_operation == Operation::Idle);
|
||||
MESOSPHERE_ABORT_UNLESS(m_target_cores == 0);
|
||||
|
||||
/* Set operation. */
|
||||
this->operation = op;
|
||||
m_operation = op;
|
||||
|
||||
/* Request all cores. */
|
||||
this->target_cores = AllCoresMask;
|
||||
m_target_cores = AllCoresMask;
|
||||
|
||||
/* Use the condvar. */
|
||||
this->cv.Broadcast();
|
||||
while (this->target_cores != 0) {
|
||||
this->cv.Wait(std::addressof(this->cv_lock));
|
||||
m_cv.Broadcast();
|
||||
while (m_target_cores != 0) {
|
||||
m_cv.Wait(std::addressof(m_cv_lock));
|
||||
}
|
||||
|
||||
/* Go idle again. */
|
||||
this->operation = Operation::Idle;
|
||||
m_operation = Operation::Idle;
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -283,7 +283,7 @@ namespace ams::kern::arch::arm64::cpu {
|
||||
}
|
||||
|
||||
void KCacheHelperInterruptHandler::ProcessOperation() {
|
||||
switch (this->operation) {
|
||||
switch (m_operation) {
|
||||
case Operation::Idle:
|
||||
break;
|
||||
case Operation::InstructionMemoryBarrier:
|
||||
@@ -299,7 +299,7 @@ namespace ams::kern::arch::arm64::cpu {
|
||||
break;
|
||||
}
|
||||
|
||||
this->target_cores &= ~(1ul << GetCurrentCoreId());
|
||||
m_target_cores &= ~(1ul << GetCurrentCoreId());
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void SetEventLocally() {
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace ams::kern::arch::arm64 {
|
||||
InitializeGlobalTimer();
|
||||
|
||||
/* Set maximum time. */
|
||||
this->maximum_time = static_cast<s64>(std::min<u64>(std::numeric_limits<s64>::max(), cpu::CounterTimerPhysicalTimerCompareValueRegisterAccessor().GetCompareValue()));
|
||||
m_maximum_time = static_cast<s64>(std::min<u64>(std::numeric_limits<s64>::max(), cpu::CounterTimerPhysicalTimerCompareValueRegisterAccessor().GetCompareValue()));
|
||||
|
||||
/* Bind the interrupt task for this core. */
|
||||
Kernel::GetInterruptManager().BindHandler(this, KInterruptName_NonSecurePhysicalTimer, GetCurrentCoreId(), KInterruptController::PriorityLevel_Timer, true, true);
|
||||
@@ -41,7 +41,7 @@ namespace ams::kern::arch::arm64 {
|
||||
|
||||
/* Disable the timer interrupt while we handle this. */
|
||||
DisableInterrupt();
|
||||
if (const s64 next_time = this->DoInterruptTaskImpl(GetTick()); 0 < next_time && next_time <= this->maximum_time) {
|
||||
if (const s64 next_time = this->DoInterruptTaskImpl(GetTick()); 0 < next_time && next_time <= m_maximum_time) {
|
||||
/* We have a next time, so we should set the time to interrupt and turn the interrupt on. */
|
||||
SetCompareValue(next_time);
|
||||
EnableInterrupt();
|
||||
|
||||
@@ -18,11 +18,11 @@
|
||||
namespace ams::kern::arch::arm64 {
|
||||
|
||||
void KInterruptManager::Initialize(s32 core_id) {
|
||||
this->interrupt_controller.Initialize(core_id);
|
||||
m_interrupt_controller.Initialize(core_id);
|
||||
}
|
||||
|
||||
void KInterruptManager::Finalize(s32 core_id) {
|
||||
this->interrupt_controller.Finalize(core_id);
|
||||
m_interrupt_controller.Finalize(core_id);
|
||||
}
|
||||
|
||||
void KInterruptManager::Save(s32 core_id) {
|
||||
@@ -34,18 +34,18 @@ namespace ams::kern::arch::arm64 {
|
||||
|
||||
/* If on core 0, save the global interrupts. */
|
||||
if (core_id == 0) {
|
||||
MESOSPHERE_ABORT_UNLESS(!this->global_state_saved);
|
||||
this->interrupt_controller.SaveGlobal(std::addressof(this->global_state));
|
||||
this->global_state_saved = true;
|
||||
MESOSPHERE_ABORT_UNLESS(!m_global_state_saved);
|
||||
m_interrupt_controller.SaveGlobal(std::addressof(m_global_state));
|
||||
m_global_state_saved = true;
|
||||
}
|
||||
|
||||
/* Ensure all cores get to this point before continuing. */
|
||||
cpu::SynchronizeAllCores();
|
||||
|
||||
/* Save all local interrupts. */
|
||||
MESOSPHERE_ABORT_UNLESS(!this->local_state_saved[core_id]);
|
||||
this->interrupt_controller.SaveCoreLocal(std::addressof(this->local_states[core_id]));
|
||||
this->local_state_saved[core_id] = true;
|
||||
MESOSPHERE_ABORT_UNLESS(!m_local_state_saved[core_id]);
|
||||
m_interrupt_controller.SaveCoreLocal(std::addressof(m_local_states[core_id]));
|
||||
m_local_state_saved[core_id] = true;
|
||||
|
||||
/* Ensure all cores get to this point before continuing. */
|
||||
cpu::SynchronizeAllCores();
|
||||
@@ -88,18 +88,18 @@ namespace ams::kern::arch::arm64 {
|
||||
cpu::SynchronizeAllCores();
|
||||
|
||||
/* Restore all local interrupts. */
|
||||
MESOSPHERE_ASSERT(this->local_state_saved[core_id]);
|
||||
this->interrupt_controller.RestoreCoreLocal(std::addressof(this->local_states[core_id]));
|
||||
this->local_state_saved[core_id] = false;
|
||||
MESOSPHERE_ASSERT(m_local_state_saved[core_id]);
|
||||
m_interrupt_controller.RestoreCoreLocal(std::addressof(m_local_states[core_id]));
|
||||
m_local_state_saved[core_id] = false;
|
||||
|
||||
/* Ensure all cores get to this point before continuing. */
|
||||
cpu::SynchronizeAllCores();
|
||||
|
||||
/* If on core 0, restore the global interrupts. */
|
||||
if (core_id == 0) {
|
||||
MESOSPHERE_ASSERT(this->global_state_saved);
|
||||
this->interrupt_controller.RestoreGlobal(std::addressof(this->global_state));
|
||||
this->global_state_saved = false;
|
||||
MESOSPHERE_ASSERT(m_global_state_saved);
|
||||
m_interrupt_controller.RestoreGlobal(std::addressof(m_global_state));
|
||||
m_global_state_saved = false;
|
||||
}
|
||||
|
||||
/* Ensure all cores get to this point before continuing. */
|
||||
@@ -108,7 +108,7 @@ namespace ams::kern::arch::arm64 {
|
||||
|
||||
bool KInterruptManager::OnHandleInterrupt() {
|
||||
/* Get the interrupt id. */
|
||||
const u32 raw_irq = this->interrupt_controller.GetIrq();
|
||||
const u32 raw_irq = m_interrupt_controller.GetIrq();
|
||||
const s32 irq = KInterruptController::ConvertRawIrq(raw_irq);
|
||||
|
||||
/* Trace the interrupt. */
|
||||
@@ -126,7 +126,7 @@ namespace ams::kern::arch::arm64 {
|
||||
if (entry.handler != nullptr) {
|
||||
/* Set manual clear needed if relevant. */
|
||||
if (entry.manually_cleared) {
|
||||
this->interrupt_controller.SetPriorityLevel(irq, KInterruptController::PriorityLevel_Low);
|
||||
m_interrupt_controller.SetPriorityLevel(irq, KInterruptController::PriorityLevel_Low);
|
||||
entry.needs_clear = true;
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ namespace ams::kern::arch::arm64 {
|
||||
if (entry.handler != nullptr) {
|
||||
/* Set manual clear needed if relevant. */
|
||||
if (entry.manually_cleared) {
|
||||
this->interrupt_controller.Disable(irq);
|
||||
m_interrupt_controller.Disable(irq);
|
||||
entry.needs_clear = true;
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ namespace ams::kern::arch::arm64 {
|
||||
}
|
||||
|
||||
/* Acknowledge the interrupt. */
|
||||
this->interrupt_controller.EndOfInterrupt(raw_irq);
|
||||
m_interrupt_controller.EndOfInterrupt(raw_irq);
|
||||
|
||||
/* If we found no task, then we don't need to reschedule. */
|
||||
if (task == nullptr) {
|
||||
@@ -273,16 +273,16 @@ namespace ams::kern::arch::arm64 {
|
||||
|
||||
/* Configure the interrupt as level or edge. */
|
||||
if (level) {
|
||||
this->interrupt_controller.SetLevel(irq);
|
||||
m_interrupt_controller.SetLevel(irq);
|
||||
} else {
|
||||
this->interrupt_controller.SetEdge(irq);
|
||||
m_interrupt_controller.SetEdge(irq);
|
||||
}
|
||||
|
||||
/* Configure the interrupt. */
|
||||
this->interrupt_controller.Clear(irq);
|
||||
this->interrupt_controller.SetTarget(irq, core_id);
|
||||
this->interrupt_controller.SetPriorityLevel(irq, priority);
|
||||
this->interrupt_controller.Enable(irq);
|
||||
m_interrupt_controller.Clear(irq);
|
||||
m_interrupt_controller.SetTarget(irq, core_id);
|
||||
m_interrupt_controller.SetPriorityLevel(irq, priority);
|
||||
m_interrupt_controller.Enable(irq);
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
@@ -303,19 +303,19 @@ namespace ams::kern::arch::arm64 {
|
||||
entry.priority = static_cast<u8>(priority);
|
||||
|
||||
/* Configure the interrupt. */
|
||||
this->interrupt_controller.Clear(irq);
|
||||
this->interrupt_controller.SetPriorityLevel(irq, priority);
|
||||
this->interrupt_controller.Enable(irq);
|
||||
m_interrupt_controller.Clear(irq);
|
||||
m_interrupt_controller.SetPriorityLevel(irq, priority);
|
||||
m_interrupt_controller.Enable(irq);
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result KInterruptManager::UnbindGlobal(s32 irq) {
|
||||
for (size_t core_id = 0; core_id < cpu::NumCores; core_id++) {
|
||||
this->interrupt_controller.ClearTarget(irq, static_cast<s32>(core_id));
|
||||
m_interrupt_controller.ClearTarget(irq, static_cast<s32>(core_id));
|
||||
}
|
||||
this->interrupt_controller.SetPriorityLevel(irq, KInterruptController::PriorityLevel_Low);
|
||||
this->interrupt_controller.Disable(irq);
|
||||
m_interrupt_controller.SetPriorityLevel(irq, KInterruptController::PriorityLevel_Low);
|
||||
m_interrupt_controller.Disable(irq);
|
||||
|
||||
GetGlobalInterruptEntry(irq).handler = nullptr;
|
||||
|
||||
@@ -326,8 +326,8 @@ namespace ams::kern::arch::arm64 {
|
||||
auto &entry = this->GetLocalInterruptEntry(irq);
|
||||
R_UNLESS(entry.handler != nullptr, svc::ResultInvalidState());
|
||||
|
||||
this->interrupt_controller.SetPriorityLevel(irq, KInterruptController::PriorityLevel_Low);
|
||||
this->interrupt_controller.Disable(irq);
|
||||
m_interrupt_controller.SetPriorityLevel(irq, KInterruptController::PriorityLevel_Low);
|
||||
m_interrupt_controller.Disable(irq);
|
||||
|
||||
entry.handler = nullptr;
|
||||
|
||||
@@ -345,7 +345,7 @@ namespace ams::kern::arch::arm64 {
|
||||
|
||||
/* Clear and enable. */
|
||||
entry.needs_clear = false;
|
||||
this->interrupt_controller.Enable(irq);
|
||||
m_interrupt_controller.Enable(irq);
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
@@ -360,7 +360,7 @@ namespace ams::kern::arch::arm64 {
|
||||
|
||||
/* Clear and set priority. */
|
||||
entry.needs_clear = false;
|
||||
this->interrupt_controller.SetPriorityLevel(irq, entry.priority);
|
||||
m_interrupt_controller.SetPriorityLevel(irq, entry.priority);
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
|
||||
@@ -21,13 +21,13 @@ namespace ams::kern::arch::arm64 {
|
||||
|
||||
class AlignedMemoryBlock {
|
||||
private:
|
||||
uintptr_t before_start;
|
||||
uintptr_t before_end;
|
||||
uintptr_t after_start;
|
||||
uintptr_t after_end;
|
||||
size_t current_alignment;
|
||||
uintptr_t m_before_start;
|
||||
uintptr_t m_before_end;
|
||||
uintptr_t m_after_start;
|
||||
uintptr_t m_after_end;
|
||||
size_t m_current_alignment;
|
||||
public:
|
||||
constexpr AlignedMemoryBlock(uintptr_t start, size_t num_pages, size_t alignment) : before_start(0), before_end(0), after_start(0), after_end(0), current_alignment(0) {
|
||||
constexpr AlignedMemoryBlock(uintptr_t start, size_t num_pages, size_t alignment) : m_before_start(0), m_before_end(0), m_after_start(0), m_after_end(0), m_current_alignment(0) {
|
||||
MESOSPHERE_ASSERT(util::IsAligned(start, PageSize));
|
||||
MESOSPHERE_ASSERT(num_pages > 0);
|
||||
|
||||
@@ -38,41 +38,41 @@ namespace ams::kern::arch::arm64 {
|
||||
alignment = KPageTable::GetSmallerAlignment(alignment * PageSize) / PageSize;
|
||||
}
|
||||
|
||||
this->before_start = start_page;
|
||||
this->before_end = util::AlignUp(start_page, alignment);
|
||||
this->after_start = this->before_end;
|
||||
this->after_end = start_page + num_pages;
|
||||
this->current_alignment = alignment;
|
||||
MESOSPHERE_ASSERT(this->current_alignment > 0);
|
||||
m_before_start = start_page;
|
||||
m_before_end = util::AlignUp(start_page, alignment);
|
||||
m_after_start = m_before_end;
|
||||
m_after_end = start_page + num_pages;
|
||||
m_current_alignment = alignment;
|
||||
MESOSPHERE_ASSERT(m_current_alignment > 0);
|
||||
}
|
||||
|
||||
constexpr void SetAlignment(size_t alignment) {
|
||||
/* We can only ever decrease the granularity. */
|
||||
MESOSPHERE_ASSERT(this->current_alignment >= alignment / PageSize);
|
||||
this->current_alignment = alignment / PageSize;
|
||||
MESOSPHERE_ASSERT(m_current_alignment >= alignment / PageSize);
|
||||
m_current_alignment = alignment / PageSize;
|
||||
}
|
||||
|
||||
constexpr size_t GetAlignment() const {
|
||||
return this->current_alignment * PageSize;
|
||||
return m_current_alignment * PageSize;
|
||||
}
|
||||
|
||||
constexpr void FindBlock(uintptr_t &out, size_t &num_pages) {
|
||||
if ((this->after_end - this->after_start) >= this->current_alignment) {
|
||||
if ((m_after_end - m_after_start) >= m_current_alignment) {
|
||||
/* Select aligned memory from after block. */
|
||||
const size_t available_pages = util::AlignDown(this->after_end, this->current_alignment) - this->after_start;
|
||||
const size_t available_pages = util::AlignDown(m_after_end, m_current_alignment) - m_after_start;
|
||||
if (num_pages == 0 || available_pages < num_pages) {
|
||||
num_pages = available_pages;
|
||||
}
|
||||
out = this->after_start * PageSize;
|
||||
this->after_start += num_pages;
|
||||
} else if ((this->before_end - this->before_start) >= this->current_alignment) {
|
||||
out = m_after_start * PageSize;
|
||||
m_after_start += num_pages;
|
||||
} else if ((m_before_end - m_before_start) >= m_current_alignment) {
|
||||
/* Select aligned memory from before block. */
|
||||
const size_t available_pages = this->before_end - util::AlignUp(this->before_start, this->current_alignment);
|
||||
const size_t available_pages = m_before_end - util::AlignUp(m_before_start, m_current_alignment);
|
||||
if (num_pages == 0 || available_pages < num_pages) {
|
||||
num_pages = available_pages;
|
||||
}
|
||||
this->before_end -= num_pages;
|
||||
out = this->before_end * PageSize;
|
||||
m_before_end -= num_pages;
|
||||
out = m_before_end * PageSize;
|
||||
} else {
|
||||
/* Neither after or before can get an aligned bit of memory. */
|
||||
out = 0;
|
||||
@@ -95,32 +95,32 @@ namespace ams::kern::arch::arm64 {
|
||||
static constexpr size_t NumWords = AsidCount / BitsPerWord;
|
||||
static constexpr WordType FullWord = ~WordType(0u);
|
||||
private:
|
||||
WordType state[NumWords];
|
||||
KLightLock lock;
|
||||
u8 hint;
|
||||
WordType m_state[NumWords];
|
||||
KLightLock m_lock;
|
||||
u8 m_hint;
|
||||
private:
|
||||
constexpr bool TestImpl(u8 asid) const {
|
||||
return this->state[asid / BitsPerWord] & (1u << (asid % BitsPerWord));
|
||||
return m_state[asid / BitsPerWord] & (1u << (asid % BitsPerWord));
|
||||
}
|
||||
constexpr void ReserveImpl(u8 asid) {
|
||||
MESOSPHERE_ASSERT(!this->TestImpl(asid));
|
||||
this->state[asid / BitsPerWord] |= (1u << (asid % BitsPerWord));
|
||||
m_state[asid / BitsPerWord] |= (1u << (asid % BitsPerWord));
|
||||
}
|
||||
|
||||
constexpr void ReleaseImpl(u8 asid) {
|
||||
MESOSPHERE_ASSERT(this->TestImpl(asid));
|
||||
this->state[asid / BitsPerWord] &= ~(1u << (asid % BitsPerWord));
|
||||
m_state[asid / BitsPerWord] &= ~(1u << (asid % BitsPerWord));
|
||||
}
|
||||
|
||||
constexpr u8 FindAvailable() const {
|
||||
for (size_t i = 0; i < util::size(this->state); i++) {
|
||||
if (this->state[i] == FullWord) {
|
||||
for (size_t i = 0; i < util::size(m_state); i++) {
|
||||
if (m_state[i] == FullWord) {
|
||||
continue;
|
||||
}
|
||||
const WordType clear_bit = (this->state[i] + 1) ^ (this->state[i]);
|
||||
const WordType clear_bit = (m_state[i] + 1) ^ (m_state[i]);
|
||||
return BitsPerWord * i + BitsPerWord - 1 - ClearLeadingZero(clear_bit);
|
||||
}
|
||||
if (this->state[util::size(this->state)-1] == FullWord) {
|
||||
if (m_state[util::size(m_state)-1] == FullWord) {
|
||||
MESOSPHERE_PANIC("Unable to reserve ASID");
|
||||
}
|
||||
__builtin_unreachable();
|
||||
@@ -130,26 +130,26 @@ namespace ams::kern::arch::arm64 {
|
||||
return __builtin_clzll(value) - (BITSIZEOF(unsigned long long) - BITSIZEOF(WordType));
|
||||
}
|
||||
public:
|
||||
constexpr KPageTableAsidManager() : state(), lock(), hint() {
|
||||
constexpr KPageTableAsidManager() : m_state(), m_lock(), m_hint() {
|
||||
for (size_t i = 0; i < NumReservedAsids; i++) {
|
||||
this->ReserveImpl(ReservedAsids[i]);
|
||||
}
|
||||
}
|
||||
|
||||
u8 Reserve() {
|
||||
KScopedLightLock lk(this->lock);
|
||||
KScopedLightLock lk(m_lock);
|
||||
|
||||
if (this->TestImpl(this->hint)) {
|
||||
this->hint = this->FindAvailable();
|
||||
if (this->TestImpl(m_hint)) {
|
||||
m_hint = this->FindAvailable();
|
||||
}
|
||||
|
||||
this->ReserveImpl(this->hint);
|
||||
this->ReserveImpl(m_hint);
|
||||
|
||||
return this->hint++;
|
||||
return m_hint++;
|
||||
}
|
||||
|
||||
void Release(u8 asid) {
|
||||
KScopedLightLock lk(this->lock);
|
||||
KScopedLightLock lk(m_lock);
|
||||
this->ReleaseImpl(asid);
|
||||
}
|
||||
};
|
||||
@@ -165,15 +165,15 @@ namespace ams::kern::arch::arm64 {
|
||||
|
||||
Result KPageTable::InitializeForKernel(void *table, KVirtualAddress start, KVirtualAddress end) {
|
||||
/* Initialize basic fields. */
|
||||
this->asid = 0;
|
||||
this->manager = std::addressof(Kernel::GetPageTableManager());
|
||||
m_asid = 0;
|
||||
m_manager = std::addressof(Kernel::GetPageTableManager());
|
||||
|
||||
/* Allocate a page for ttbr. */
|
||||
const u64 asid_tag = (static_cast<u64>(this->asid) << 48ul);
|
||||
const KVirtualAddress page = this->manager->Allocate();
|
||||
const u64 asid_tag = (static_cast<u64>(m_asid) << 48ul);
|
||||
const KVirtualAddress page = m_manager->Allocate();
|
||||
MESOSPHERE_ASSERT(page != Null<KVirtualAddress>);
|
||||
cpu::ClearPageToZero(GetVoidPointer(page));
|
||||
this->ttbr = GetInteger(KPageTableBase::GetLinearMappedPhysicalAddress(page)) | asid_tag;
|
||||
m_ttbr = GetInteger(KPageTableBase::GetLinearMappedPhysicalAddress(page)) | asid_tag;
|
||||
|
||||
/* Initialize the base page table. */
|
||||
MESOSPHERE_R_ABORT_UNLESS(KPageTableBase::InitializeForKernel(true, table, start, end));
|
||||
@@ -186,17 +186,17 @@ namespace ams::kern::arch::arm64 {
|
||||
MESOSPHERE_UNUSED(id);
|
||||
|
||||
/* Get an ASID */
|
||||
this->asid = g_asid_manager.Reserve();
|
||||
auto asid_guard = SCOPE_GUARD { g_asid_manager.Release(this->asid); };
|
||||
m_asid = g_asid_manager.Reserve();
|
||||
auto asid_guard = SCOPE_GUARD { g_asid_manager.Release(m_asid); };
|
||||
|
||||
/* Set our manager. */
|
||||
this->manager = pt_manager;
|
||||
m_manager = pt_manager;
|
||||
|
||||
/* Allocate a new table, and set our ttbr value. */
|
||||
const KVirtualAddress new_table = this->manager->Allocate();
|
||||
const KVirtualAddress new_table = m_manager->Allocate();
|
||||
R_UNLESS(new_table != Null<KVirtualAddress>, svc::ResultOutOfResource());
|
||||
this->ttbr = EncodeTtbr(GetPageTablePhysicalAddress(new_table), asid);
|
||||
auto table_guard = SCOPE_GUARD { this->manager->Free(new_table); };
|
||||
m_ttbr = EncodeTtbr(GetPageTablePhysicalAddress(new_table), m_asid);
|
||||
auto table_guard = SCOPE_GUARD { m_manager->Free(new_table); };
|
||||
|
||||
/* Initialize our base table. */
|
||||
const size_t as_width = GetAddressSpaceWidth(as_type);
|
||||
@@ -308,7 +308,7 @@ namespace ams::kern::arch::arm64 {
|
||||
}
|
||||
|
||||
/* Release our asid. */
|
||||
g_asid_manager.Release(this->asid);
|
||||
g_asid_manager.Release(m_asid);
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
@@ -18,19 +18,19 @@
|
||||
namespace ams::kern::arch::arm64 {
|
||||
|
||||
void KPageTableImpl::InitializeForKernel(void *tb, KVirtualAddress start, KVirtualAddress end) {
|
||||
this->table = static_cast<L1PageTableEntry *>(tb);
|
||||
this->is_kernel = true;
|
||||
this->num_entries = util::AlignUp(end - start, L1BlockSize) / L1BlockSize;
|
||||
m_table = static_cast<L1PageTableEntry *>(tb);
|
||||
m_is_kernel = true;
|
||||
m_num_entries = util::AlignUp(end - start, L1BlockSize) / L1BlockSize;
|
||||
}
|
||||
|
||||
void KPageTableImpl::InitializeForProcess(void *tb, KVirtualAddress start, KVirtualAddress end) {
|
||||
this->table = static_cast<L1PageTableEntry *>(tb);
|
||||
this->is_kernel = false;
|
||||
this->num_entries = util::AlignUp(end - start, L1BlockSize) / L1BlockSize;
|
||||
m_table = static_cast<L1PageTableEntry *>(tb);
|
||||
m_is_kernel = false;
|
||||
m_num_entries = util::AlignUp(end - start, L1BlockSize) / L1BlockSize;
|
||||
}
|
||||
|
||||
L1PageTableEntry *KPageTableImpl::Finalize() {
|
||||
return this->table;
|
||||
return m_table;
|
||||
}
|
||||
|
||||
bool KPageTableImpl::ExtractL3Entry(TraversalEntry *out_entry, TraversalContext *out_context, const L3PageTableEntry *l3_entry, KProcessAddress virt_addr) const {
|
||||
@@ -119,21 +119,21 @@ namespace ams::kern::arch::arm64 {
|
||||
out_entry->phys_addr = Null<KPhysicalAddress>;
|
||||
out_entry->block_size = L1BlockSize;
|
||||
out_entry->sw_reserved_bits = 0;
|
||||
out_context->l1_entry = this->table + this->num_entries;
|
||||
out_context->l1_entry = m_table + m_num_entries;
|
||||
out_context->l2_entry = nullptr;
|
||||
out_context->l3_entry = nullptr;
|
||||
|
||||
/* Validate that we can read the actual entry. */
|
||||
const size_t l0_index = GetL0Index(address);
|
||||
const size_t l1_index = GetL1Index(address);
|
||||
if (this->is_kernel) {
|
||||
if (m_is_kernel) {
|
||||
/* Kernel entries must be accessed via TTBR1. */
|
||||
if ((l0_index != MaxPageTableEntries - 1) || (l1_index < MaxPageTableEntries - this->num_entries)) {
|
||||
if ((l0_index != MaxPageTableEntries - 1) || (l1_index < MaxPageTableEntries - m_num_entries)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
/* User entries must be accessed with TTBR0. */
|
||||
if ((l0_index != 0) || l1_index >= this->num_entries) {
|
||||
if ((l0_index != 0) || l1_index >= m_num_entries) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -212,15 +212,15 @@ namespace ams::kern::arch::arm64 {
|
||||
}
|
||||
} else {
|
||||
/* We need to update the l1 entry. */
|
||||
const size_t l1_index = context->l1_entry - this->table;
|
||||
if (l1_index < this->num_entries) {
|
||||
const size_t l1_index = context->l1_entry - m_table;
|
||||
if (l1_index < m_num_entries) {
|
||||
valid = this->ExtractL1Entry(out_entry, context, context->l1_entry, Null<KProcessAddress>);
|
||||
} else {
|
||||
/* Invalid, end traversal. */
|
||||
out_entry->phys_addr = Null<KPhysicalAddress>;
|
||||
out_entry->block_size = L1BlockSize;
|
||||
out_entry->sw_reserved_bits = 0;
|
||||
context->l1_entry = this->table + this->num_entries;
|
||||
context->l1_entry = m_table + m_num_entries;
|
||||
context->l2_entry = nullptr;
|
||||
context->l3_entry = nullptr;
|
||||
return false;
|
||||
@@ -262,14 +262,14 @@ namespace ams::kern::arch::arm64 {
|
||||
/* Validate that we can read the actual entry. */
|
||||
const size_t l0_index = GetL0Index(address);
|
||||
const size_t l1_index = GetL1Index(address);
|
||||
if (this->is_kernel) {
|
||||
if (m_is_kernel) {
|
||||
/* Kernel entries must be accessed via TTBR1. */
|
||||
if ((l0_index != MaxPageTableEntries - 1) || (l1_index < MaxPageTableEntries - this->num_entries)) {
|
||||
if ((l0_index != MaxPageTableEntries - 1) || (l1_index < MaxPageTableEntries - m_num_entries)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
/* User entries must be accessed with TTBR0. */
|
||||
if ((l0_index != 0) || l1_index >= this->num_entries) {
|
||||
if ((l0_index != 0) || l1_index >= m_num_entries) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -322,14 +322,14 @@ namespace ams::kern::arch::arm64 {
|
||||
/* Validate that we can read the actual entry. */
|
||||
const size_t l0_index = GetL0Index(cur);
|
||||
const size_t l1_index = GetL1Index(cur);
|
||||
if (this->is_kernel) {
|
||||
if (m_is_kernel) {
|
||||
/* Kernel entries must be accessed via TTBR1. */
|
||||
if ((l0_index != MaxPageTableEntries - 1) || (l1_index < MaxPageTableEntries - this->num_entries)) {
|
||||
if ((l0_index != MaxPageTableEntries - 1) || (l1_index < MaxPageTableEntries - m_num_entries)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
/* User entries must be accessed with TTBR0. */
|
||||
if ((l0_index != 0) || l1_index >= this->num_entries) {
|
||||
if ((l0_index != 0) || l1_index >= m_num_entries) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -482,8 +482,8 @@ namespace ams::kern::arch::arm64 {
|
||||
#if defined(MESOSPHERE_BUILD_FOR_DEBUGGING)
|
||||
{
|
||||
++num_tables;
|
||||
for (size_t l1_index = 0; l1_index < this->num_entries; ++l1_index) {
|
||||
auto &l1_entry = this->table[l1_index];
|
||||
for (size_t l1_index = 0; l1_index < m_num_entries; ++l1_index) {
|
||||
auto &l1_entry = m_table[l1_index];
|
||||
if (l1_entry.IsTable()) {
|
||||
++num_tables;
|
||||
for (size_t l2_index = 0; l2_index < MaxPageTableEntries; ++l2_index) {
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace ams::kern::arch::arm64 {
|
||||
|
||||
void KSupervisorPageTable::Initialize(s32 core_id) {
|
||||
/* Get the identity mapping ttbr0. */
|
||||
this->ttbr0_identity[core_id] = cpu::GetTtbr0El1();
|
||||
m_ttbr0_identity[core_id] = cpu::GetTtbr0El1();
|
||||
|
||||
/* Set sctlr_el1 */
|
||||
cpu::SystemControlRegisterAccessor().SetWxn(true).Store();
|
||||
@@ -35,7 +35,7 @@ namespace ams::kern::arch::arm64 {
|
||||
const u64 kernel_vaddr_start = 0xFFFFFF8000000000ul;
|
||||
const u64 kernel_vaddr_end = 0xFFFFFFFFFFE00000ul;
|
||||
void *table = GetVoidPointer(KPageTableBase::GetLinearMappedVirtualAddress(ttbr1));
|
||||
this->page_table.InitializeForKernel(table, kernel_vaddr_start, kernel_vaddr_end);
|
||||
m_page_table.InitializeForKernel(table, kernel_vaddr_start, kernel_vaddr_end);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -117,38 +117,38 @@ namespace ams::kern::arch::arm64 {
|
||||
/* Determine LR and SP. */
|
||||
if (is_user) {
|
||||
/* Usermode thread. */
|
||||
this->lr = reinterpret_cast<uintptr_t>(::ams::kern::arch::arm64::UserModeThreadStarter);
|
||||
this->sp = SetupStackForUserModeThreadStarter(u_pc, k_sp, u_sp, arg, is_64_bit);
|
||||
m_lr = reinterpret_cast<uintptr_t>(::ams::kern::arch::arm64::UserModeThreadStarter);
|
||||
m_sp = SetupStackForUserModeThreadStarter(u_pc, k_sp, u_sp, arg, is_64_bit);
|
||||
} else {
|
||||
/* Kernel thread. */
|
||||
MESOSPHERE_ASSERT(is_64_bit);
|
||||
|
||||
if (is_main) {
|
||||
/* Main thread. */
|
||||
this->lr = GetInteger(u_pc);
|
||||
this->sp = GetInteger(k_sp);
|
||||
m_lr = GetInteger(u_pc);
|
||||
m_sp = GetInteger(k_sp);
|
||||
} else {
|
||||
/* Generic Kernel thread. */
|
||||
this->lr = reinterpret_cast<uintptr_t>(::ams::kern::arch::arm64::SupervisorModeThreadStarter);
|
||||
this->sp = SetupStackForSupervisorModeThreadStarter(u_pc, k_sp, arg);
|
||||
m_lr = reinterpret_cast<uintptr_t>(::ams::kern::arch::arm64::SupervisorModeThreadStarter);
|
||||
m_sp = SetupStackForSupervisorModeThreadStarter(u_pc, k_sp, arg);
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear callee-saved registers. */
|
||||
for (size_t i = 0; i < util::size(this->callee_saved.registers); i++) {
|
||||
this->callee_saved.registers[i] = 0;
|
||||
for (size_t i = 0; i < util::size(m_callee_saved.registers); i++) {
|
||||
m_callee_saved.registers[i] = 0;
|
||||
}
|
||||
|
||||
/* Clear FPU state. */
|
||||
this->fpcr = 0;
|
||||
this->fpsr = 0;
|
||||
this->cpacr = 0;
|
||||
for (size_t i = 0; i < util::size(this->fpu_registers); i++) {
|
||||
this->fpu_registers[i] = 0;
|
||||
m_fpcr = 0;
|
||||
m_fpsr = 0;
|
||||
m_cpacr = 0;
|
||||
for (size_t i = 0; i < util::size(m_fpu_registers); i++) {
|
||||
m_fpu_registers[i] = 0;
|
||||
}
|
||||
|
||||
/* Lock the context, if we're a main thread. */
|
||||
this->locked = is_main;
|
||||
m_locked = is_main;
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
@@ -159,7 +159,7 @@ namespace ams::kern::arch::arm64 {
|
||||
}
|
||||
|
||||
void KThreadContext::SetArguments(uintptr_t arg0, uintptr_t arg1) {
|
||||
u64 *stack = reinterpret_cast<u64 *>(this->sp);
|
||||
u64 *stack = reinterpret_cast<u64 *>(m_sp);
|
||||
stack[0] = arg0;
|
||||
stack[1] = arg1;
|
||||
}
|
||||
@@ -199,11 +199,11 @@ namespace ams::kern::arch::arm64 {
|
||||
void KThreadContext::SetFpuRegisters(const u128 *v, bool is_64_bit) {
|
||||
if (is_64_bit) {
|
||||
for (size_t i = 0; i < KThreadContext::NumFpuRegisters; ++i) {
|
||||
this->fpu_registers[i] = v[i];
|
||||
m_fpu_registers[i] = v[i];
|
||||
}
|
||||
} else {
|
||||
for (size_t i = 0; i < KThreadContext::NumFpuRegisters / 2; ++i) {
|
||||
this->fpu_registers[i] = v[i];
|
||||
m_fpu_registers[i] = v[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user