kern: KDevicePageTable::Finalize, InfoType_RandomEntropy

This commit is contained in:
Michael Scire 2020-07-21 03:30:18 -07:00 committed by SciresM
parent 0c82709af4
commit 3265927ed7
3 changed files with 50 additions and 1 deletions

View file

@ -147,6 +147,8 @@ namespace ams::kern {
constexpr KProcessAddress GetEntryPoint() const { return this->code_address; }
constexpr u64 GetRandomEntropy(size_t i) const { return this->entropy[i]; }
constexpr bool IsSuspended() const {
return this->is_suspended;
}

View file

@ -528,7 +528,42 @@ namespace ams::kern::board::nintendo::nx {
}
void KDevicePageTable::Finalize() {
MESOSPHERE_UNIMPLEMENTED();
/* Get the page table manager. */
auto &ptm = Kernel::GetPageTableManager();
/* Detach from all devices. */
{
KScopedLightLock lk(g_lock);
for (size_t i = 0; i < ams::svc::DeviceName_Count; ++i) {
const auto device_name = static_cast<ams::svc::DeviceName>(i);
if ((this->attached_device & (1ul << device_name)) != 0) {
WriteMcRegister(GetDeviceAsidRegisterOffset(device_name), IsHsSupported(device_name) ? this->hs_detached_value : this->detached_value);
SmmuSynchronizationBarrier();
}
}
}
/* Forcibly unmap all pages. */
this->UnmapImpl(0, (1ul << DeviceVirtualAddressBits), true);
/* Release all asids. */
for (size_t i = 0; i < TableCount; ++i) {
if (this->table_asids[i] != g_reserved_asid) {
/* Set the table to the reserved table. */
SetTable(this->table_asids[i], g_reserved_table_phys_addr);
/* Close the table. */
const KVirtualAddress table_vaddr = this->tables[i];
MESOSPHERE_ASSERT(ptm.GetRefCount(table_vaddr) == 1);
MESOSPHERE_ABORT_UNLESS(ptm.Close(table_vaddr, 1));
/* Free the table. */
ptm.Free(table_vaddr);
/* Release the asid. */
g_asid_manager.Release(this->table_asids[i]);
}
}
}
Result KDevicePageTable::Attach(ams::svc::DeviceName device_name, u64 space_address, u64 space_size) {

View file

@ -132,6 +132,18 @@ namespace ams::kern::svc {
}
}
break;
case ams::svc::InfoType_RandomEntropy:
{
/* Verify the input handle is invalid. */
R_UNLESS(handle == ams::svc::InvalidHandle, svc::ResultInvalidHandle());
/* Verify the requested entropy is valid. */
R_UNLESS(info_subtype < 4, svc::ResultInvalidCombination());
/* Get the entropy. */
*out = GetCurrentProcess().GetRandomEntropy(info_subtype);
}
break;
default:
return svc::ResultInvalidEnumValue();
}