mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-03 23:09:16 +00:00
kern: SvcFlushDataCache, SvcFlushEntireDataCache
This commit is contained in:
parent
e4b30f4022
commit
0993ae0685
4 changed files with 37 additions and 7 deletions
|
@ -64,6 +64,10 @@ namespace ams::kern::arch::arm64::cpu {
|
||||||
EnsureInstructionConsistency();
|
EnsureInstructionConsistency();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ALWAYS_INLINE void Yield() {
|
||||||
|
__asm__ __volatile__("yield" ::: "memory");
|
||||||
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE void SwitchProcess(u64 ttbr, u32 proc_id) {
|
ALWAYS_INLINE void SwitchProcess(u64 ttbr, u32 proc_id) {
|
||||||
SetTtbr0El1(ttbr);
|
SetTtbr0El1(ttbr);
|
||||||
ContextIdRegisterAccessor(0).SetProcId(proc_id).Store();
|
ContextIdRegisterAccessor(0).SetProcId(proc_id).Store();
|
||||||
|
|
|
@ -60,7 +60,7 @@ namespace ams::kern::arch::arm64::cpu {
|
||||||
|
|
||||||
void Wait() {
|
void Wait() {
|
||||||
while (!this->done) {
|
while (!this->done) {
|
||||||
__asm__ __volatile__("yield");
|
cpu::Yield();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,7 +173,7 @@ namespace ams::kern::arch::arm64::cpu {
|
||||||
Kernel::GetInterruptManager().SendInterProcessorInterrupt(KInterruptName_CacheOperation, target_mask);
|
Kernel::GetInterruptManager().SendInterProcessorInterrupt(KInterruptName_CacheOperation, target_mask);
|
||||||
this->ProcessOperation();
|
this->ProcessOperation();
|
||||||
while (this->target_cores != 0) {
|
while (this->target_cores != 0) {
|
||||||
__asm__ __volatile__("yield");
|
cpu::Yield();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Request all cores. */
|
/* Request all cores. */
|
||||||
|
|
|
@ -86,7 +86,7 @@ namespace ams::kern {
|
||||||
void KDebugLogImpl::PutChar(char c) {
|
void KDebugLogImpl::PutChar(char c) {
|
||||||
while (ReadUartRegister(UartRegister_LSR) & 0x100) {
|
while (ReadUartRegister(UartRegister_LSR) & 0x100) {
|
||||||
/* While the FIFO is full, yield. */
|
/* While the FIFO is full, yield. */
|
||||||
__asm__ __volatile__("yield" ::: "memory");
|
cpu::Yield();
|
||||||
}
|
}
|
||||||
WriteUartRegister(UartRegister_THR, c);
|
WriteUartRegister(UartRegister_THR, c);
|
||||||
cpu::DataSynchronizationBarrier();
|
cpu::DataSynchronizationBarrier();
|
||||||
|
|
|
@ -73,6 +73,32 @@ namespace ams::kern::svc {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FlushEntireDataCache() {
|
||||||
|
/* Flushing cache takes up to 1ms, so determine our minimum end tick. */
|
||||||
|
const s64 timeout = KHardwareTimer::GetTick() + ams::svc::Tick(TimeSpan::FromMilliSeconds(1));
|
||||||
|
|
||||||
|
/* Flush the entire data cache. */
|
||||||
|
cpu::FlushEntireDataCache();
|
||||||
|
|
||||||
|
/* Wait for 1ms to have passed. */
|
||||||
|
while (KHardwareTimer::GetTick() < timeout) {
|
||||||
|
cpu::Yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Result FlushDataCache(uintptr_t address, size_t size) {
|
||||||
|
/* Succeed if there's nothing to do. */
|
||||||
|
R_SUCCEED_IF(size == 0);
|
||||||
|
|
||||||
|
/* Validate that the region is within range. */
|
||||||
|
R_UNLESS(GetCurrentProcess().GetPageTable().Contains(address, size), svc::ResultInvalidCurrentMemory());
|
||||||
|
|
||||||
|
/* Flush the cache. */
|
||||||
|
R_TRY(cpu::FlushDataCache(reinterpret_cast<void *>(address), size));
|
||||||
|
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
Result InvalidateProcessDataCache(ams::svc::Handle process_handle, uint64_t address, uint64_t size) {
|
Result InvalidateProcessDataCache(ams::svc::Handle process_handle, uint64_t address, uint64_t size) {
|
||||||
/* Validate address/size. */
|
/* Validate address/size. */
|
||||||
R_UNLESS(size > 0, svc::ResultInvalidSize());
|
R_UNLESS(size > 0, svc::ResultInvalidSize());
|
||||||
|
@ -148,11 +174,11 @@ namespace ams::kern::svc {
|
||||||
/* ============================= 64 ABI ============================= */
|
/* ============================= 64 ABI ============================= */
|
||||||
|
|
||||||
void FlushEntireDataCache64() {
|
void FlushEntireDataCache64() {
|
||||||
MESOSPHERE_PANIC("Stubbed SvcFlushEntireDataCache64 was called.");
|
return FlushEntireDataCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result FlushDataCache64(ams::svc::Address address, ams::svc::Size size) {
|
Result FlushDataCache64(ams::svc::Address address, ams::svc::Size size) {
|
||||||
MESOSPHERE_PANIC("Stubbed SvcFlushDataCache64 was called.");
|
return FlushDataCache(address, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result InvalidateProcessDataCache64(ams::svc::Handle process_handle, uint64_t address, uint64_t size) {
|
Result InvalidateProcessDataCache64(ams::svc::Handle process_handle, uint64_t address, uint64_t size) {
|
||||||
|
@ -170,11 +196,11 @@ namespace ams::kern::svc {
|
||||||
/* ============================= 64From32 ABI ============================= */
|
/* ============================= 64From32 ABI ============================= */
|
||||||
|
|
||||||
void FlushEntireDataCache64From32() {
|
void FlushEntireDataCache64From32() {
|
||||||
MESOSPHERE_PANIC("Stubbed SvcFlushEntireDataCache64From32 was called.");
|
return FlushEntireDataCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result FlushDataCache64From32(ams::svc::Address address, ams::svc::Size size) {
|
Result FlushDataCache64From32(ams::svc::Address address, ams::svc::Size size) {
|
||||||
MESOSPHERE_PANIC("Stubbed SvcFlushDataCache64From32 was called.");
|
return FlushDataCache(address, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result InvalidateProcessDataCache64From32(ams::svc::Handle process_handle, uint64_t address, uint64_t size) {
|
Result InvalidateProcessDataCache64From32(ams::svc::Handle process_handle, uint64_t address, uint64_t size) {
|
||||||
|
|
Loading…
Reference in a new issue