mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-30 18:34:38 +01:00
fatal: dynamically allocate memory as required (preferring system > nonsecure > unsafe)
This commit is contained in:
parent
982389dceb
commit
5fb6f52b9e
@ -78,6 +78,9 @@
|
|||||||
"svcReplyAndReceive": "0x43",
|
"svcReplyAndReceive": "0x43",
|
||||||
"svcReplyAndReceiveWithUserBuffer": "0x44",
|
"svcReplyAndReceiveWithUserBuffer": "0x44",
|
||||||
"svcCreateEvent": "0x45",
|
"svcCreateEvent": "0x45",
|
||||||
|
"svcMapPhysicalMemoryUnsafe": "0x48",
|
||||||
|
"svcUnmapPhysicalMemoryUnsafe": "0x48",
|
||||||
|
"svcSetUnsafeLimit": "0x4A",
|
||||||
"svcReadWriteRegister": "0x4E",
|
"svcReadWriteRegister": "0x4E",
|
||||||
"svcDebugActiveProcess": "0x60",
|
"svcDebugActiveProcess": "0x60",
|
||||||
"svcGetDebugEvent": "0x63",
|
"svcGetDebugEvent": "0x63",
|
||||||
@ -86,7 +89,9 @@
|
|||||||
"svcQueryDebugProcessMemory": "0x69",
|
"svcQueryDebugProcessMemory": "0x69",
|
||||||
"svcReadDebugProcessMemory": "0x6a",
|
"svcReadDebugProcessMemory": "0x6a",
|
||||||
"svcGetDebugThreadParam": "0x6d",
|
"svcGetDebugThreadParam": "0x6d",
|
||||||
"svcCallSecureMonitor": "0x7f"
|
"svcCallSecureMonitor": "0x7f",
|
||||||
|
"svcMapInsecureMemory": "0x90",
|
||||||
|
"svcUnmapInsecureMemory": "0x91"
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
"type": "min_kernel_version",
|
"type": "min_kernel_version",
|
||||||
|
@ -42,7 +42,46 @@ namespace ams::fatal::srv {
|
|||||||
alignas(os::MemoryPageSize) constinit u8 g_nv_transfer_memory[0x40000];
|
alignas(os::MemoryPageSize) constinit u8 g_nv_transfer_memory[0x40000];
|
||||||
|
|
||||||
/* There should only be a single (1280*768) framebuffer. */
|
/* There should only be a single (1280*768) framebuffer. */
|
||||||
alignas(os::MemoryPageSize) constinit u8 g_framebuffer_memory[FatalScreenWidthAlignedBytes * util::AlignUp(FatalScreenHeight, 128)];
|
constexpr size_t FrameBufferRequiredSizeBytes = FatalScreenWidthAlignedBytes * util::AlignUp(FatalScreenHeight, 128);
|
||||||
|
constexpr size_t FrameBufferRequiredSizePageAligned = util::AlignUp(FrameBufferRequiredSizeBytes, os::MemoryPageSize);
|
||||||
|
constexpr size_t FrameBufferRequiredSizeHeapAligned = util::AlignUp(FrameBufferRequiredSizeBytes, os::MemoryHeapUnitSize);
|
||||||
|
|
||||||
|
constinit u8 *g_framebuffer_pointer = nullptr;
|
||||||
|
|
||||||
|
void InitializeFrameBufferPointer() {
|
||||||
|
/* Try to get a framebuffer from heap. */
|
||||||
|
{
|
||||||
|
if (R_SUCCEEDED(os::SetMemoryHeapSize(FrameBufferRequiredSizeHeapAligned))) {
|
||||||
|
g_framebuffer_pointer = reinterpret_cast<u8 *>(os::GetMemoryHeapAddress());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We couldn't use heap, so try insecure memory, from the application pool. */
|
||||||
|
{
|
||||||
|
uintptr_t address = 0;
|
||||||
|
if (R_SUCCEEDED(os::AllocateInsecureMemory(std::addressof(address), FrameBufferRequiredSizePageAligned))) {
|
||||||
|
g_framebuffer_pointer = reinterpret_cast<u8 *>(address);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Neither heap nor insecure is available, so we're going to have to try to raid the unsafe pool. */
|
||||||
|
{
|
||||||
|
/* First, increase the limit to an extremely high value. */
|
||||||
|
size_t large_size = std::max(64_MB, FrameBufferRequiredSizeHeapAligned);
|
||||||
|
while (svc::ResultLimitReached::Includes(svc::SetUnsafeLimit(large_size))) {
|
||||||
|
large_size *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Next, map some unsafe memory. */
|
||||||
|
uintptr_t address = 0;
|
||||||
|
if (R_SUCCEEDED(os::AllocateUnsafeMemory(std::addressof(address), FrameBufferRequiredSizePageAligned))) {
|
||||||
|
g_framebuffer_pointer = reinterpret_cast<u8 *>(address);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,8 +241,12 @@ namespace ams::fatal::srv {
|
|||||||
void ShowFatalTask::PreRenderFrameBuffer() {
|
void ShowFatalTask::PreRenderFrameBuffer() {
|
||||||
const FatalConfig &config = GetFatalConfig();
|
const FatalConfig &config = GetFatalConfig();
|
||||||
|
|
||||||
|
/* Allocate a frame buffer. */
|
||||||
|
InitializeFrameBufferPointer();
|
||||||
|
AMS_ABORT_UNLESS(g_framebuffer_pointer != nullptr);
|
||||||
|
|
||||||
/* Pre-render the image into the static framebuffer. */
|
/* Pre-render the image into the static framebuffer. */
|
||||||
u16 *tiled_buf = reinterpret_cast<u16 *>(g_framebuffer_memory);
|
u16 *tiled_buf = reinterpret_cast<u16 *>(g_framebuffer_pointer);
|
||||||
|
|
||||||
/* Temporarily use the NV transfer memory as font backing heap. */
|
/* Temporarily use the NV transfer memory as font backing heap. */
|
||||||
font::SetHeapMemory(g_nv_transfer_memory, sizeof(g_nv_transfer_memory));
|
font::SetHeapMemory(g_nv_transfer_memory, sizeof(g_nv_transfer_memory));
|
||||||
@ -214,7 +257,7 @@ namespace ams::fatal::srv {
|
|||||||
font::SetFontColor(0xFFFF);
|
font::SetFontColor(0xFFFF);
|
||||||
|
|
||||||
/* Draw a background. */
|
/* Draw a background. */
|
||||||
for (size_t i = 0; i < sizeof(g_framebuffer_memory) / sizeof(*tiled_buf); i++) {
|
for (size_t i = 0; i < FrameBufferRequiredSizeBytes / sizeof(*tiled_buf); i++) {
|
||||||
tiled_buf[i] = 0x39C9;
|
tiled_buf[i] = 0x39C9;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -439,7 +482,7 @@ namespace ams::fatal::srv {
|
|||||||
R_TRY(nvFenceInit());
|
R_TRY(nvFenceInit());
|
||||||
|
|
||||||
/* Create nvmap. */
|
/* Create nvmap. */
|
||||||
R_TRY(nvMapCreate(std::addressof(m_map), g_framebuffer_memory, sizeof(g_framebuffer_memory), 0x20000, NvKind_Pitch, true));
|
R_TRY(nvMapCreate(std::addressof(m_map), g_framebuffer_pointer, FrameBufferRequiredSizeBytes, 0x20000, NvKind_Pitch, true));
|
||||||
|
|
||||||
/* Setup graphics buffer. */
|
/* Setup graphics buffer. */
|
||||||
{
|
{
|
||||||
@ -460,9 +503,9 @@ namespace ams::fatal::srv {
|
|||||||
grbuf.planes[0].block_height_log2 = 4;
|
grbuf.planes[0].block_height_log2 = 4;
|
||||||
grbuf.nvmap_id = nvMapGetId(std::addressof(m_map));
|
grbuf.nvmap_id = nvMapGetId(std::addressof(m_map));
|
||||||
grbuf.stride = FatalScreenWidthAligned;
|
grbuf.stride = FatalScreenWidthAligned;
|
||||||
grbuf.total_size = sizeof(g_framebuffer_memory);
|
grbuf.total_size = FrameBufferRequiredSizeBytes;
|
||||||
grbuf.planes[0].pitch = FatalScreenWidthAlignedBytes;
|
grbuf.planes[0].pitch = FatalScreenWidthAlignedBytes;
|
||||||
grbuf.planes[0].size = sizeof(g_framebuffer_memory);
|
grbuf.planes[0].size = FrameBufferRequiredSizeBytes;
|
||||||
grbuf.planes[0].offset = 0;
|
grbuf.planes[0].offset = 0;
|
||||||
|
|
||||||
R_TRY(nwindowConfigureBuffer(std::addressof(m_win), 0, std::addressof(grbuf)));
|
R_TRY(nwindowConfigureBuffer(std::addressof(m_win), 0, std::addressof(grbuf)));
|
||||||
@ -474,7 +517,7 @@ namespace ams::fatal::srv {
|
|||||||
void ShowFatalTask::DisplayPreRenderedFrame() {
|
void ShowFatalTask::DisplayPreRenderedFrame() {
|
||||||
s32 slot;
|
s32 slot;
|
||||||
R_ABORT_UNLESS(nwindowDequeueBuffer(std::addressof(m_win), std::addressof(slot), nullptr));
|
R_ABORT_UNLESS(nwindowDequeueBuffer(std::addressof(m_win), std::addressof(slot), nullptr));
|
||||||
dd::FlushDataCache(g_framebuffer_memory, sizeof(g_framebuffer_memory));
|
dd::FlushDataCache(g_framebuffer_pointer, FrameBufferRequiredSizeBytes);
|
||||||
R_ABORT_UNLESS(nwindowQueueBuffer(std::addressof(m_win), m_win.cur_slot, NULL));
|
R_ABORT_UNLESS(nwindowQueueBuffer(std::addressof(m_win), m_win.cur_slot, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user