diff --git a/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_page_table.hpp b/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_page_table.hpp index 0eedb6d8..a0952347 100644 --- a/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_page_table.hpp +++ b/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_page_table.hpp @@ -23,6 +23,17 @@ namespace ams::kern::arch::arm64::init { + inline void ClearPhysicalMemory(KPhysicalAddress address, size_t size) { + MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(size, sizeof(u64))); + + /* This Physical Address -> void * conversion is valid, because this is init page table code. */ + /* The MMU is necessarily not yet turned on, if we are creating an initial page table. */ + volatile u64 *ptr = reinterpret_cast(GetInteger(address)); + for (size_t i = 0; i < size / sizeof(u64); ++i) { + ptr[i] = 0; + } + } + class KInitialPageTable { public: class IPageAllocator { @@ -61,9 +72,7 @@ namespace ams::kern::arch::arm64::init { } static ALWAYS_INLINE void ClearNewPageTable(KPhysicalAddress address) { - /* This Physical Address -> void * conversion is valid, because this is page table code. */ - /* The MMU is necessarily not yet turned on, if we are creating an initial page table. */ - std::memset(reinterpret_cast(GetInteger(address)), 0, PageSize); + ClearPhysicalMemory(address, PageSize); } private: size_t NOINLINE GetBlockCount(KVirtualAddress virt_addr, size_t size, size_t block_size) { @@ -705,7 +714,7 @@ namespace ams::kern::arch::arm64::init { this->state.next_address += PageSize; } - std::memset(reinterpret_cast(allocated), 0, PageSize); + ClearPhysicalMemory(allocated, PageSize); return allocated; } diff --git a/libmesosphere/source/libc/arch/arm64/memset.arch.arm64-broken.s b/libmesosphere/source/libc/arch/arm64/memset.arch.arm64.s similarity index 99% rename from libmesosphere/source/libc/arch/arm64/memset.arch.arm64-broken.s rename to libmesosphere/source/libc/arch/arm64/memset.arch.arm64.s index d8d27272..700f0e84 100644 --- a/libmesosphere/source/libc/arch/arm64/memset.arch.arm64-broken.s +++ b/libmesosphere/source/libc/arch/arm64/memset.arch.arm64.s @@ -76,11 +76,13 @@ L(set96): .p2align 4 L(set_long): stp val, val, [dstin] - bic dst, dstin, 15 #if DC_ZVA_THRESHOLD cmp count, DC_ZVA_THRESHOLD ccmp val, 0, 0, cs + bic dst, dstin, 15 b.eq L(zva_64) +#else + bic dst, dstin, 15 #endif /* Small-size or non-zero memset does not use DC ZVA. */ sub count, dstend, dst diff --git a/libmesosphere/source/libc/kern_libc_config.arch.arm64.h b/libmesosphere/source/libc/kern_libc_config.arch.arm64.h index 155b013e..5d01bc77 100644 --- a/libmesosphere/source/libc/kern_libc_config.arch.arm64.h +++ b/libmesosphere/source/libc/kern_libc_config.arch.arm64.h @@ -19,6 +19,6 @@ #define MESOSPHERE_LIBC_MEMCPY_GENERIC 0 #define MESOSPHERE_LIBC_MEMCMP_GENERIC 0 #define MESOSPHERE_LIBC_MEMMOVE_GENERIC 0 -#define MESOSPHERE_LIBC_MEMSET_GENERIC 1 +#define MESOSPHERE_LIBC_MEMSET_GENERIC 0 #define MESOSPHERE_LIBC_STRNCPY_GENERIC 1 -#define MESOSPHERE_LIBC_STRNCMP_GENERIC 1 \ No newline at end of file +#define MESOSPHERE_LIBC_STRNCMP_GENERIC 1 diff --git a/libmesosphere/source/libc/kern_libc_config.h b/libmesosphere/source/libc/kern_libc_config.h index b391b995..f79fb750 100644 --- a/libmesosphere/source/libc/kern_libc_config.h +++ b/libmesosphere/source/libc/kern_libc_config.h @@ -23,4 +23,4 @@ #error "Unknown architecture for libc" -#endif \ No newline at end of file +#endif