mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-06-01 15:28:21 -04:00
kern/test: add wip qemu-virt board support to mesosphere
This commit is contained in:
parent
10ed579c38
commit
0a58e803be
39 changed files with 19796 additions and 27 deletions
23
tests/Licensing/Catch2-LICENSE.txt
Normal file
23
tests/Licensing/Catch2-LICENSE.txt
Normal file
|
@ -0,0 +1,23 @@
|
|||
Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
Permission is hereby granted, free of charge, to any person or organization
|
||||
obtaining a copy of the software and accompanying documentation covered by
|
||||
this license (the "Software") to use, reproduce, display, distribute,
|
||||
execute, and transmit the Software, and to prepare derivative works of the
|
||||
Software, and to permit third-parties to whom the Software is furnished to
|
||||
do so, all subject to the following:
|
||||
|
||||
The copyright notices in the Software and this entire statement, including
|
||||
the above license grant, this restriction and the following disclaimer,
|
||||
must be included in all copies of the Software, in whole or in part, and
|
||||
all derivative works of the Software, unless such copies or derivative
|
||||
works are solely in the form of machine-executable object code generated by
|
||||
a source language processor.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
107
tests/TestSvc/Makefile
Normal file
107
tests/TestSvc/Makefile
Normal file
|
@ -0,0 +1,107 @@
|
|||
#---------------------------------------------------------------------------------
|
||||
# pull in common stratosphere sysmodule configuration
|
||||
#---------------------------------------------------------------------------------
|
||||
include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../../libraries/config/templates/stratosphere.mk
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# no real need to edit anything past this point unless you need to add additional
|
||||
# rules for different file extensions
|
||||
#---------------------------------------------------------------------------------
|
||||
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OUTPUT := $(CURDIR)/$(TARGET)
|
||||
export TOPDIR := $(CURDIR)
|
||||
|
||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
||||
|
||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||
|
||||
CFILES := $(call FIND_SOURCE_FILES,$(SOURCES),c)
|
||||
CPPFILES := $(call FIND_SOURCE_FILES,$(SOURCES),cpp)
|
||||
SFILES := $(call FIND_SOURCE_FILES,$(SOURCES),s)
|
||||
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# use CXX for linking C++ projects, CC for standard C
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(CPPFILES)),)
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CC)
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CXX)
|
||||
#---------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OFILES := $(addsuffix .o,$(BINFILES)) \
|
||||
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||
-I$(CURDIR)/$(BUILD)
|
||||
|
||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
||||
|
||||
export BUILD_EXEFS_SRC := $(TOPDIR)/$(EXEFS_SRC)
|
||||
|
||||
ifeq ($(strip $(CONFIG_JSON)),)
|
||||
jsons := $(wildcard *.json)
|
||||
ifneq (,$(findstring $(TARGET).json,$(jsons)))
|
||||
export APP_JSON := $(TOPDIR)/$(TARGET).json
|
||||
else
|
||||
ifneq (,$(findstring config.json,$(jsons)))
|
||||
export APP_JSON := $(TOPDIR)/config.json
|
||||
endif
|
||||
endif
|
||||
else
|
||||
export APP_JSON := $(TOPDIR)/$(CONFIG_JSON)
|
||||
endif
|
||||
|
||||
.PHONY: $(BUILD) clean all
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
all: $(BUILD)
|
||||
|
||||
$(BUILD):
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
@echo clean ...
|
||||
@rm -fr $(BUILD) $(TARGET).kip $(TARGET).elf
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
.PHONY: all
|
||||
|
||||
DEPENDS := $(OFILES:.o=.d)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
all : $(OUTPUT).kip
|
||||
|
||||
$(OUTPUT).kip : $(OUTPUT).elf
|
||||
|
||||
$(OUTPUT).elf : $(OFILES)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# you need a rule like this for each extension you use as binary data
|
||||
#---------------------------------------------------------------------------------
|
||||
%.bin.o : %.bin
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
-include $(DEPENDS)
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------------
|
128
tests/TestSvc/TestSvc.json
Normal file
128
tests/TestSvc/TestSvc.json
Normal file
|
@ -0,0 +1,128 @@
|
|||
{
|
||||
"name": "TestSvc",
|
||||
"title_id": "0x5555555555555555",
|
||||
"main_thread_stack_size": "0x8000",
|
||||
"main_thread_priority": 28,
|
||||
"default_cpu_id": 3,
|
||||
"process_category": 1,
|
||||
"use_secure_memory": true,
|
||||
"immortal": true,
|
||||
"kernel_capabilities": [
|
||||
{
|
||||
"type": "handle_table_size",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"type": "syscalls",
|
||||
"value": {
|
||||
"svcUnknown00": "0x00",
|
||||
"svcSetHeapSize": "0x01",
|
||||
"svcSetMemoryPermission": "0x02",
|
||||
"svcSetMemoryAttribute": "0x03",
|
||||
"svcMapMemory": "0x04",
|
||||
"svcUnmapMemory": "0x05",
|
||||
"svcQueryMemory": "0x06",
|
||||
"svcExitProcess": "0x07",
|
||||
"svcCreateThread": "0x08",
|
||||
"svcStartThread": "0x09",
|
||||
"svcExitThread": "0x0A",
|
||||
"svcSleepThread": "0x0B",
|
||||
"svcGetThreadPriority": "0x0C",
|
||||
"svcSetThreadPriority": "0x0D",
|
||||
"svcGetThreadCoreMask": "0x0E",
|
||||
"svcSetThreadCoreMask": "0x0F",
|
||||
"svcGetCurrentProcessorNumber": "0x10",
|
||||
"svcSignalEvent": "0x11",
|
||||
"svcClearEvent": "0x12",
|
||||
"svcMapSharedMemory": "0x13",
|
||||
"svcUnmapSharedMemory": "0x14",
|
||||
"svcCreateTransferMemory": "0x15",
|
||||
"svcCloseHandle": "0x16",
|
||||
"svcResetSignal": "0x17",
|
||||
"svcWaitSynchronization": "0x18",
|
||||
"svcCancelSynchronization": "0x19",
|
||||
"svcArbitrateLock": "0x1A",
|
||||
"svcArbitrateUnlock": "0x1B",
|
||||
"svcWaitProcessWideKeyAtomic": "0x1C",
|
||||
"svcSignalProcessWideKey": "0x1D",
|
||||
"svcGetSystemTick": "0x1E",
|
||||
"svcConnectToNamedPort": "0x1F",
|
||||
"svcSendSyncRequestLight": "0x20",
|
||||
"svcSendSyncRequest": "0x21",
|
||||
"svcSendSyncRequestWithUserBuffer": "0x22",
|
||||
"svcSendAsyncRequestWithUserBuffer": "0x23",
|
||||
"svcGetProcessId": "0x24",
|
||||
"svcGetThreadId": "0x25",
|
||||
"svcBreak": "0x26",
|
||||
"svcOutputDebugString": "0x27",
|
||||
"svcReturnFromException": "0x28",
|
||||
"svcGetInfo": "0x29",
|
||||
"svcFlushEntireDataCache": "0x2A",
|
||||
"svcFlushDataCache": "0x2B",
|
||||
"svcMapPhysicalMemory": "0x2C",
|
||||
"svcUnmapPhysicalMemory": "0x2D",
|
||||
"svcGetDebugFutureThreadInfo": "0x2E",
|
||||
"svcGetLastThreadInfo": "0x2F",
|
||||
"svcGetResourceLimitLimitValue": "0x30",
|
||||
"svcGetResourceLimitCurrentValue": "0x31",
|
||||
"svcSetThreadActivity": "0x32",
|
||||
"svcGetThreadContext3": "0x33",
|
||||
"svcWaitForAddress": "0x34",
|
||||
"svcSignalToAddress": "0x35",
|
||||
"svcSynchronizePreemptionState": "0x36",
|
||||
"svcGetResourceLimitPeakValue": "0x37",
|
||||
"svcUnknown38": "0x38",
|
||||
"svcUnknown39": "0x39",
|
||||
"svcUnknown3a": "0x3A",
|
||||
"svcUnknown3b": "0x3B",
|
||||
"svcKernelDebug": "0x3C",
|
||||
"svcChangeKernelTraceState": "0x3D",
|
||||
"svcUnknown3e": "0x3E",
|
||||
"svcUnknown3f": "0x3F",
|
||||
"svcCreateSession": "0x40",
|
||||
"svcAcceptSession": "0x41",
|
||||
"svcReplyAndReceiveLight": "0x42",
|
||||
"svcReplyAndReceive": "0x43",
|
||||
"svcReplyAndReceiveWithUserBuffer": "0x44",
|
||||
"svcCreateEvent": "0x45",
|
||||
"svcUnknown46": "0x46",
|
||||
"svcUnknown47": "0x47",
|
||||
"svcMapPhysicalMemoryUnsafe": "0x48",
|
||||
"svcUnmapPhysicalMemoryUnsafe": "0x49",
|
||||
"svcSetUnsafeLimit": "0x4A",
|
||||
"svcCreateCodeMemory": "0x4B",
|
||||
"svcControlCodeMemory": "0x4C",
|
||||
"svcSleepSystem": "0x4D",
|
||||
"svcReadWriteRegister": "0x4E",
|
||||
"svcSetProcessActivity": "0x4F",
|
||||
"svcCreateSharedMemory": "0x50",
|
||||
"svcMapTransferMemory": "0x51",
|
||||
"svcUnmapTransferMemory": "0x52",
|
||||
"svcQueryIoMapping": "0x55",
|
||||
"svcDebugActiveProcess": "0x60",
|
||||
"svcBreakDebugProcess": "0x61",
|
||||
"svcTerminateDebugProcess": "0x62",
|
||||
"svcGetDebugEvent": "0x63",
|
||||
"svcContinueDebugEvent": "0x64",
|
||||
"svcGetProcessList": "0x65",
|
||||
"svcGetThreadList": "0x66",
|
||||
"svcGetDebugThreadContext": "0x67",
|
||||
"svcSetDebugThreadContext": "0x68",
|
||||
"svcQueryDebugProcessMemory": "0x69",
|
||||
"svcReadDebugProcessMemory": "0x6A",
|
||||
"svcWriteDebugProcessMemory": "0x6B",
|
||||
"svcSetHardwareBreakPoint": "0x6C",
|
||||
"svcGetDebugThreadParam": "0x6D",
|
||||
"svcGetSystemInfo": "0x6F",
|
||||
"svcConnectToPort": "0x72",
|
||||
"svcSetProcessMemoryPermission": "0x73",
|
||||
"svcMapProcessMemory": "0x74",
|
||||
"svcUnmapProcessMemory": "0x75",
|
||||
"svcQueryProcessMemory": "0x76",
|
||||
"svcMapProcessCodeMemory": "0x77",
|
||||
"svcUnmapProcessCodeMemory": "0x78",
|
||||
"svcCallSecureMonitor": "0x7F"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
17959
tests/TestSvc/source/catch.hpp
Normal file
17959
tests/TestSvc/source/catch.hpp
Normal file
File diff suppressed because it is too large
Load diff
93
tests/TestSvc/source/test_main.cpp
Normal file
93
tests/TestSvc/source/test_main.cpp
Normal file
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright (c) Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
#define CATCH_CONFIG_NOSTDOUT
|
||||
#define CATCH_CONFIG_RUNNER
|
||||
#define CATCH_CONFIG_PREFIX_ALL
|
||||
#define CATCH_CONFIG_DISABLE_EXCEPTIONS
|
||||
#define CATCH_CONFIG_NO_POSIX_SIGNALS
|
||||
#include "catch.hpp"
|
||||
|
||||
namespace ams {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr size_t MallocBufferSize = 16_MB;
|
||||
alignas(os::MemoryPageSize) constinit u8 g_malloc_buffer[MallocBufferSize];
|
||||
|
||||
}
|
||||
|
||||
namespace init {
|
||||
|
||||
void InitializeSystemModuleBeforeConstructors() {
|
||||
/* Catch has global-ctors which allocate, so we need to do this earlier than normal. */
|
||||
init::InitializeAllocator(g_malloc_buffer, sizeof(g_malloc_buffer));
|
||||
}
|
||||
|
||||
void InitializeSystemModule() { /* ... */ }
|
||||
|
||||
void FinalizeSystemModule() { /* ... */ }
|
||||
|
||||
void Startup() { /* ... */ }
|
||||
|
||||
}
|
||||
|
||||
void NORETURN Exit(int rc) {
|
||||
AMS_UNUSED(rc);
|
||||
AMS_ABORT("Exit called by immortal process");
|
||||
}
|
||||
|
||||
void Main() {
|
||||
/* Run tests. */
|
||||
Catch::Session().run(os::GetHostArgc(), os::GetHostArgv());
|
||||
|
||||
AMS_INFINITE_LOOP();
|
||||
|
||||
/* This can never be reached. */
|
||||
AMS_ASSUME(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace Catch {
|
||||
|
||||
namespace {
|
||||
|
||||
class OutputDebugStringStream : public std::stringbuf {
|
||||
public:
|
||||
OutputDebugStringStream() = default;
|
||||
~OutputDebugStringStream() { pubsync(); }
|
||||
|
||||
int sync() override {
|
||||
const auto message = str();
|
||||
return R_SUCCEEDED(ams::svc::OutputDebugString(message.c_str(), message.length())) ? 0 : -1;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
std::ostream& cout() {
|
||||
static std::ostream ret(new OutputDebugStringStream);
|
||||
return ret;
|
||||
}
|
||||
std::ostream& clog() {
|
||||
return cout();
|
||||
}
|
||||
std::ostream& cerr() {
|
||||
return clog();
|
||||
}
|
||||
}
|
153
tests/TestSvc/source/test_set_heap_size.cpp
Normal file
153
tests/TestSvc/source/test_set_heap_size.cpp
Normal file
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* Copyright (c) Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
#define CATCH_CONFIG_NOSTDOUT
|
||||
#define CATCH_CONFIG_PREFIX_ALL
|
||||
#define CATCH_CONFIG_DISABLE_EXCEPTIONS
|
||||
#define CATCH_CONFIG_NO_POSIX_SIGNALS
|
||||
#include "catch.hpp"
|
||||
|
||||
namespace ams::test {
|
||||
|
||||
namespace {
|
||||
|
||||
size_t GetPhysicalMemorySizeMax() {
|
||||
u64 v;
|
||||
R_ABORT_UNLESS(svc::GetInfo(std::addressof(v), svc::InfoType_ResourceLimit, svc::InvalidHandle, 0));
|
||||
|
||||
const svc::Handle resource_limit = v;
|
||||
ON_SCOPE_EXIT { svc::CloseHandle(resource_limit); };
|
||||
|
||||
s64 size;
|
||||
R_ABORT_UNLESS(svc::GetResourceLimitLimitValue(std::addressof(size), resource_limit, svc::LimitableResource_PhysicalMemoryMax));
|
||||
|
||||
return static_cast<size_t>(size);
|
||||
}
|
||||
|
||||
size_t GetPhysicalMemorySizeAvailable() {
|
||||
u64 v;
|
||||
R_ABORT_UNLESS(svc::GetInfo(std::addressof(v), svc::InfoType_ResourceLimit, svc::InvalidHandle, 0));
|
||||
|
||||
const svc::Handle resource_limit = v;
|
||||
ON_SCOPE_EXIT { svc::CloseHandle(resource_limit); };
|
||||
|
||||
s64 total;
|
||||
R_ABORT_UNLESS(svc::GetResourceLimitLimitValue(std::addressof(total), resource_limit, svc::LimitableResource_PhysicalMemoryMax));
|
||||
|
||||
s64 current;
|
||||
R_ABORT_UNLESS(svc::GetResourceLimitCurrentValue(std::addressof(current), resource_limit, svc::LimitableResource_PhysicalMemoryMax));
|
||||
|
||||
return static_cast<size_t>(total - current);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
CATCH_TEST_CASE("svc::SetHeapSize") {
|
||||
svc::MemoryInfo mem_info;
|
||||
svc::PageInfo page_info;
|
||||
uintptr_t dummy;
|
||||
|
||||
/* Reset the heap. */
|
||||
uintptr_t addr;
|
||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetHeapSize(std::addressof(addr), 0)));
|
||||
|
||||
/* Ensure that we don't leak memory. */
|
||||
const size_t initial_memory = GetPhysicalMemorySizeAvailable();
|
||||
ON_SCOPE_EXIT { CATCH_REQUIRE(initial_memory == GetPhysicalMemorySizeAvailable()); };
|
||||
|
||||
CATCH_SECTION("Unaligned and too big sizes fail") {
|
||||
CATCH_REQUIRE(svc::ResultInvalidSize::Includes(svc::SetHeapSize(std::addressof(dummy), 5)));
|
||||
CATCH_REQUIRE(svc::ResultInvalidSize::Includes(svc::SetHeapSize(std::addressof(dummy), 64_GB)));
|
||||
}
|
||||
|
||||
CATCH_SECTION("Larger size than address space fails") {
|
||||
CATCH_REQUIRE(svc::ResultOutOfMemory::Includes(svc::SetHeapSize(std::addressof(dummy), util::AlignUp(svc::AddressMemoryRegionHeap39Size + 1, svc::HeapSizeAlignment))));
|
||||
}
|
||||
|
||||
CATCH_SECTION("Bounded by resource limit") {
|
||||
CATCH_REQUIRE(svc::ResultLimitReached::Includes(svc::SetHeapSize(std::addressof(dummy), util::AlignUp(GetPhysicalMemorySizeMax() + 1, svc::HeapSizeAlignment))));
|
||||
CATCH_REQUIRE(svc::ResultLimitReached::Includes(svc::SetHeapSize(std::addressof(dummy), util::AlignUp(GetPhysicalMemorySizeAvailable() + 1, svc::HeapSizeAlignment))));
|
||||
}
|
||||
|
||||
CATCH_SECTION("SetHeapSize gives heap memory") {
|
||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetHeapSize(std::addressof(addr), svc::HeapSizeAlignment)));
|
||||
|
||||
CATCH_REQUIRE(R_SUCCEEDED(svc::QueryMemory(std::addressof(mem_info), std::addressof(page_info), addr)));
|
||||
CATCH_REQUIRE(mem_info.base_address == addr);
|
||||
CATCH_REQUIRE(mem_info.size == svc::HeapSizeAlignment);
|
||||
CATCH_REQUIRE(mem_info.permission == svc::MemoryPermission_ReadWrite);
|
||||
CATCH_REQUIRE(mem_info.state == svc::MemoryState_Normal);
|
||||
|
||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetHeapSize(std::addressof(addr), 0)));
|
||||
}
|
||||
|
||||
CATCH_SECTION("SetHeapSize cannot remove read-only heap") {
|
||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetHeapSize(std::addressof(addr), svc::HeapSizeAlignment)));
|
||||
|
||||
CATCH_REQUIRE(R_SUCCEEDED(svc::QueryMemory(std::addressof(mem_info), std::addressof(page_info), addr)));
|
||||
CATCH_REQUIRE(mem_info.base_address == addr);
|
||||
CATCH_REQUIRE(mem_info.size == svc::HeapSizeAlignment);
|
||||
CATCH_REQUIRE(mem_info.permission == svc::MemoryPermission_ReadWrite);
|
||||
CATCH_REQUIRE(mem_info.state == svc::MemoryState_Normal);
|
||||
|
||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetMemoryPermission(addr, svc::HeapSizeAlignment, svc::MemoryPermission_Read)));
|
||||
|
||||
CATCH_REQUIRE(R_SUCCEEDED(svc::QueryMemory(std::addressof(mem_info), std::addressof(page_info), addr)));
|
||||
CATCH_REQUIRE(mem_info.base_address == addr);
|
||||
CATCH_REQUIRE(mem_info.size == svc::HeapSizeAlignment);
|
||||
CATCH_REQUIRE(mem_info.permission == svc::MemoryPermission_Read);
|
||||
CATCH_REQUIRE(mem_info.state == svc::MemoryState_Normal);
|
||||
|
||||
CATCH_REQUIRE(svc::ResultInvalidCurrentMemory::Includes(svc::SetHeapSize(std::addressof(dummy), 0)));
|
||||
|
||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetMemoryPermission(addr, svc::HeapSizeAlignment, svc::MemoryPermission_ReadWrite)));
|
||||
|
||||
CATCH_REQUIRE(R_SUCCEEDED(svc::QueryMemory(std::addressof(mem_info), std::addressof(page_info), addr)));
|
||||
CATCH_REQUIRE(mem_info.base_address == addr);
|
||||
CATCH_REQUIRE(mem_info.size == svc::HeapSizeAlignment);
|
||||
CATCH_REQUIRE(mem_info.permission == svc::MemoryPermission_ReadWrite);
|
||||
CATCH_REQUIRE(mem_info.state == svc::MemoryState_Normal);
|
||||
|
||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetHeapSize(std::addressof(addr), 0)));
|
||||
}
|
||||
|
||||
CATCH_SECTION("Heap memory does not survive unmap/re-map") {
|
||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetHeapSize(std::addressof(addr), 2 * svc::HeapSizeAlignment)));
|
||||
|
||||
u8 * const heap = reinterpret_cast<u8 *>(addr);
|
||||
|
||||
std::memset(heap, 0xAA, svc::HeapSizeAlignment);
|
||||
std::memset(heap + svc::HeapSizeAlignment, 0xBB, svc::HeapSizeAlignment);
|
||||
|
||||
CATCH_REQUIRE(heap[svc::HeapSizeAlignment] == 0xBB);
|
||||
CATCH_REQUIRE(std::memcmp(heap + svc::HeapSizeAlignment, heap + svc::HeapSizeAlignment + 1, svc::HeapSizeAlignment - 1) == 0);
|
||||
|
||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetHeapSize(std::addressof(addr), svc::HeapSizeAlignment)));
|
||||
|
||||
CATCH_REQUIRE(heap[0] == 0xAA);
|
||||
CATCH_REQUIRE(std::memcmp(heap, heap + 1, svc::HeapSizeAlignment - 1) == 0);
|
||||
|
||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetHeapSize(std::addressof(addr), 2 * svc::HeapSizeAlignment)));
|
||||
|
||||
CATCH_REQUIRE(heap[svc::HeapSizeAlignment] == 0x00);
|
||||
CATCH_REQUIRE(std::memcmp(heap + svc::HeapSizeAlignment, heap + svc::HeapSizeAlignment + 1, svc::HeapSizeAlignment - 1) == 0);
|
||||
|
||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetHeapSize(std::addressof(addr), 0)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
37
tests/TestSvc/source/test_sleep_thread.cpp
Normal file
37
tests/TestSvc/source/test_sleep_thread.cpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
#define CATCH_CONFIG_NOSTDOUT
|
||||
#define CATCH_CONFIG_PREFIX_ALL
|
||||
#define CATCH_CONFIG_DISABLE_EXCEPTIONS
|
||||
#define CATCH_CONFIG_NO_POSIX_SIGNALS
|
||||
#include "catch.hpp"
|
||||
|
||||
namespace ams::test {
|
||||
|
||||
CATCH_TEST_CASE( "svc::SleepThread: Thread sleeps for time specified" ) {
|
||||
for (s64 ns = 1; ns < TimeSpan::FromSeconds(1).GetNanoSeconds(); ns *= 2) {
|
||||
const auto start = os::GetSystemTickOrdered();
|
||||
svc::SleepThread(ns);
|
||||
const auto end = os::GetSystemTickOrdered();
|
||||
|
||||
const s64 taken_ns = (end - start).ToTimeSpan().GetNanoSeconds();
|
||||
CATCH_REQUIRE( taken_ns >= ns );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue