kern: SvcFlushDataCache, SvcFlushEntireDataCache

This commit is contained in:
Michael Scire 2020-07-30 14:51:45 -07:00 committed by SciresM
parent e4b30f4022
commit 0993ae0685
4 changed files with 37 additions and 7 deletions

View file

@ -64,6 +64,10 @@ namespace ams::kern::arch::arm64::cpu {
EnsureInstructionConsistency();
}
ALWAYS_INLINE void Yield() {
__asm__ __volatile__("yield" ::: "memory");
}
ALWAYS_INLINE void SwitchProcess(u64 ttbr, u32 proc_id) {
SetTtbr0El1(ttbr);
ContextIdRegisterAccessor(0).SetProcId(proc_id).Store();

View file

@ -60,7 +60,7 @@ namespace ams::kern::arch::arm64::cpu {
void Wait() {
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);
this->ProcessOperation();
while (this->target_cores != 0) {
__asm__ __volatile__("yield");
cpu::Yield();
}
} else {
/* Request all cores. */

View file

@ -86,7 +86,7 @@ namespace ams::kern {
void KDebugLogImpl::PutChar(char c) {
while (ReadUartRegister(UartRegister_LSR) & 0x100) {
/* While the FIFO is full, yield. */
__asm__ __volatile__("yield" ::: "memory");
cpu::Yield();
}
WriteUartRegister(UartRegister_THR, c);
cpu::DataSynchronizationBarrier();

View file

@ -73,6 +73,32 @@ namespace ams::kern::svc {
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) {
/* Validate address/size. */
R_UNLESS(size > 0, svc::ResultInvalidSize());
@ -148,11 +174,11 @@ namespace ams::kern::svc {
/* ============================= 64 ABI ============================= */
void FlushEntireDataCache64() {
MESOSPHERE_PANIC("Stubbed SvcFlushEntireDataCache64 was called.");
return FlushEntireDataCache();
}
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) {
@ -170,11 +196,11 @@ namespace ams::kern::svc {
/* ============================= 64From32 ABI ============================= */
void FlushEntireDataCache64From32() {
MESOSPHERE_PANIC("Stubbed SvcFlushEntireDataCache64From32 was called.");
return FlushEntireDataCache();
}
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) {