Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
32b590e7ab | ||
|
|
590f22933d | ||
|
|
0dd071b279 | ||
|
|
f1132fbf5a | ||
|
|
9cd57b6c61 | ||
|
|
bf66e40a7b | ||
|
|
77cc53227a | ||
|
|
59a295db79 | ||
|
|
e4b9930bf3 | ||
|
|
04c9004e05 | ||
|
|
1f8798ace7 | ||
|
|
ff7a80e592 | ||
|
|
e3ace4be15 |
@@ -38,7 +38,7 @@ In no particular order, we credit the following for their invaluable contributio
|
||||
|
||||
* __switchbrew__ for the [libnx](https://github.com/switchbrew/libnx) project and the extensive [documentation, research and tool development](http://switchbrew.org) pertaining to the Nintendo Switch.
|
||||
* __devkitPro__ for the [devkitA64](https://devkitpro.org/) toolchain and libnx support.
|
||||
* __ReSwitched Team__ for additional [documentation, research and tool development](https://reswitched.team/) pertaining to the Nintendo Switch.
|
||||
* __ReSwitched Team__ for additional [documentation, research and tool development](https://reswitched.github.io/) pertaining to the Nintendo Switch.
|
||||
* __ChaN__ for the [FatFs](http://elm-chan.org/fsw/ff/00index_e.html) module.
|
||||
* __Marcus Geelnard__ for the [bcl-1.2.0](https://sourceforge.net/projects/bcl/files/bcl/bcl-1.2.0) library.
|
||||
* __naehrwert__ and __st4rk__ for the original [hekate](https://github.com/nwert/hekate) project and its hwinit code base.
|
||||
|
||||
@@ -1,4 +1,17 @@
|
||||
# Changelog
|
||||
## 1.4.1
|
||||
+ A number of minor issues were fixed and improvements were made, including:
|
||||
+ `dmnt` cheat toggle files are no longer ignored when they are missing a trailing newline.
|
||||
+ The mechanism for automatically cleaning up `erpt_reports` added in 1.3.0 was fixed.
|
||||
+ This was actually just very fundamentally broken and has never worked, but it is verified working now.
|
||||
+ Minor fixes were made in `mesosphère` to match official kernel behavior (spin lock assembly was corrected, wrong result on failure in in GetProcessId was corrected).
|
||||
+ A missing call to GetSdStatus when initializing SD cards at non uhs-i mode was added in the sdmmc driver.
|
||||
+ `ams.mitm`'s memory usage was increased by 16 MB, to prevent crashing when building romfs for games with obscene file counts.
|
||||
+ To quote the changelog for 1.2.3: "Animal Crossing's 2.0.0 update contains >99000 files [...] It's really hard to imagine any game being worse than Animal Crossing".
|
||||
+ As it turns out, Fire Emblem: Engage has ~186000 files, and is approximately twice as bad as animal crossing.
|
||||
+ The additional memory here is taken from the applet pool; no issues are expected to arise from this, but please report anything you may run into.
|
||||
+ As usual, if you encounter a game that exhausts ams.mitm's memory (crashing it) when loading layeredfs mods, please contact `SciresM#0524`.
|
||||
+ I am jinxing myself by saying this, but it's really hard to imagine any game being worse than Fire Emblem: Engage, but if it happens again I will drop everything to fix it as usual.
|
||||
## 1.4.0
|
||||
+ Support was added for 15.0.0.
|
||||
+ `mesosphère` was updated to reflect the latest official kernel behavior.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
[subrepo]
|
||||
remote = https://github.com/Atmosphere-NX/Atmosphere-libs
|
||||
branch = master
|
||||
commit = b2232894f31953511d33bc665f68216badc3bb07
|
||||
parent = 8ce4f1961580a09381e486cc51c160a00fa86b88
|
||||
commit = b7711b8fbcec5013e1738218267d69b2cb44f85e
|
||||
parent = 590f22933db38f089ab2224f7fd86658a9533e8d
|
||||
method = merge
|
||||
cmdver = 0.4.1
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace ams::pkg1 {
|
||||
enum MemoryArrange {
|
||||
MemoryArrange_Normal = 1,
|
||||
MemoryArrange_AppletDev = 2,
|
||||
MemoryArrange_SystemDev = 2,
|
||||
MemoryArrange_SystemDev = 3,
|
||||
};
|
||||
|
||||
enum MemoryMode {
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace ams::kern::arch::arm64 {
|
||||
__asm__ __volatile__(
|
||||
" prfm pstl1keep, %[m_next_ticket]\n"
|
||||
"1:\n"
|
||||
" ldaxrh %w[tmp0], %[m_next_ticket]\n"
|
||||
" ldxrh %w[tmp0], %[m_next_ticket]\n"
|
||||
" add %w[tmp1], %w[tmp0], #0x1\n"
|
||||
" stxrh %w[got_lock], %w[tmp1], %[m_next_ticket]\n"
|
||||
" cbnz %w[got_lock], 1b\n"
|
||||
|
||||
@@ -361,7 +361,7 @@ namespace ams::kern::board::nintendo::nx {
|
||||
}();
|
||||
|
||||
/* Return (possibly) adjusted size. */
|
||||
constexpr size_t ExtraSystemMemoryForAtmosphere = 40_MB;
|
||||
constexpr size_t ExtraSystemMemoryForAtmosphere = 56_MB;
|
||||
return base_pool_size - ExtraSystemMemoryForAtmosphere - KTraceBufferSize;
|
||||
}
|
||||
|
||||
|
||||
@@ -63,6 +63,8 @@ namespace ams::kern::svc {
|
||||
|
||||
/* Get the process id. */
|
||||
*out_process_id = d->GetProcessUnsafe()->GetProcessId();
|
||||
} else {
|
||||
R_THROW(svc::ResultInvalidHandle());
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
namespace ams::erpt::srv {
|
||||
|
||||
constexpr inline const char ReportOnSdStoragePath[] = "ersd";
|
||||
constexpr inline const char ReportOnSdStorageRootDirectoryPath[] = "ersd:/";
|
||||
|
||||
constexpr inline const char ReportStoragePath[] = "save";
|
||||
constexpr inline const char JournalFileName[] = "save:/journal";
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace ams::erpt::srv {
|
||||
s64 report_count = MinimumReportCountForCleanup;
|
||||
|
||||
fs::DirectoryHandle dir;
|
||||
if (R_SUCCEEDED(fs::OpenDirectory(std::addressof(dir), ReportOnSdStoragePath, fs::OpenDirectoryMode_All))) {
|
||||
if (R_SUCCEEDED(fs::OpenDirectory(std::addressof(dir), ReportOnSdStorageRootDirectoryPath, fs::OpenDirectoryMode_All))) {
|
||||
ON_SCOPE_EXIT { fs::CloseDirectory(dir); };
|
||||
|
||||
if (R_FAILED(fs::GetDirectoryEntryCount(std::addressof(report_count), dir))) {
|
||||
@@ -97,7 +97,7 @@ namespace ams::erpt::srv {
|
||||
}
|
||||
|
||||
if (report_count >= MinimumReportCountForCleanup) {
|
||||
fs::CleanDirectoryRecursively(ReportOnSdStoragePath);
|
||||
fs::CleanDirectoryRecursively(ReportOnSdStorageRootDirectoryPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
|
||||
#define ATMOSPHERE_RELEASE_VERSION_MAJOR 1
|
||||
#define ATMOSPHERE_RELEASE_VERSION_MINOR 4
|
||||
#define ATMOSPHERE_RELEASE_VERSION_MICRO 0
|
||||
#define ATMOSPHERE_RELEASE_VERSION_MICRO 1
|
||||
|
||||
#define ATMOSPHERE_RELEASE_VERSION ATMOSPHERE_RELEASE_VERSION_MAJOR, ATMOSPHERE_RELEASE_VERSION_MINOR, ATMOSPHERE_RELEASE_VERSION_MICRO
|
||||
|
||||
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 15
|
||||
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 0
|
||||
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MICRO 0
|
||||
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MICRO 1
|
||||
|
||||
@@ -632,6 +632,8 @@ namespace ams::sdmmc::impl {
|
||||
R_TRY(this->ExtendBusSpeedAtUhsIMode(max_sm, wb, wb_size));
|
||||
} else {
|
||||
R_TRY(this->ExtendBusSpeedAtNonUhsIMode(max_sm, spec_under_1_1, wb, wb_size));
|
||||
|
||||
R_TRY(this->GetSdStatus(wb, wb_size));
|
||||
}
|
||||
|
||||
/* Enable power saving. */
|
||||
|
||||
@@ -388,12 +388,16 @@ namespace ams::sdmmc::impl {
|
||||
break;
|
||||
case SpeedMode_SdCardSdr50:
|
||||
case SpeedMode_SdCardSdr104:
|
||||
case SpeedMode_GcAsicFpgaSpeed:
|
||||
case SpeedMode_GcAsicSpeed:
|
||||
/* Set as SDR104, 1.8V. */
|
||||
reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.host_control2, SD_REG_BITS_ENUM(HOST_CONTROL2_UHS_MODE_SELECT, SDR104));
|
||||
reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.host_control2, SD_REG_BITS_ENUM(HOST_CONTROL2_1_8V_SIGNALING_ENABLE, 1_8V_SIGNALING));
|
||||
break;
|
||||
case SpeedMode_GcAsicFpgaSpeed:
|
||||
case SpeedMode_GcAsicSpeed:
|
||||
/* Set as HS200, 1.8V. */
|
||||
reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.host_control2, SD_REG_BITS_ENUM(HOST_CONTROL2_UHS_MODE_SELECT, HS200));
|
||||
reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.host_control2, SD_REG_BITS_ENUM(HOST_CONTROL2_1_8V_SIGNALING_ENABLE, 1_8V_SIGNALING));
|
||||
break;
|
||||
AMS_UNREACHABLE_DEFAULT_CASE();
|
||||
}
|
||||
SdHostStandardController::EnsureControl();
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace ams {
|
||||
namespace {
|
||||
|
||||
/* TODO: we really shouldn't be using malloc just to avoid dealing with real allocator separation. */
|
||||
constexpr size_t MallocBufferSize = 16_MB;
|
||||
constexpr size_t MallocBufferSize = 32_MB;
|
||||
alignas(os::MemoryPageSize) constinit u8 g_malloc_buffer[MallocBufferSize];
|
||||
|
||||
}
|
||||
|
||||
@@ -80,6 +80,7 @@ namespace ams::mitm::fs {
|
||||
while (m_cache == nullptr) {
|
||||
cache_size >>= 1;
|
||||
AMS_ABORT_UNLESS(cache_size >= 16_KB);
|
||||
m_cache = std::malloc(cache_size);
|
||||
}
|
||||
m_cache_bitsize = util::CountTrailingZeros(cache_size);
|
||||
}
|
||||
@@ -617,19 +618,42 @@ namespace ams::mitm::fs {
|
||||
}
|
||||
}
|
||||
|
||||
/* Replace sibling pointers with sibling entry_offsets, so that we can de-allocate as we go. */
|
||||
{
|
||||
/* Set all directories sibling and file pointers. */
|
||||
for (const auto &it : m_directories) {
|
||||
BuildDirectoryContext *cur_dir = it.get();
|
||||
|
||||
cur_dir->ClearHashMark();
|
||||
|
||||
cur_dir->sibling_offset = (cur_dir->sibling == nullptr) ? EmptyEntry : cur_dir->sibling->entry_offset;
|
||||
cur_dir->child_offset = (cur_dir->child == nullptr) ? EmptyEntry : cur_dir->child->entry_offset;
|
||||
cur_dir->file_offset = (cur_dir->file == nullptr) ? EmptyEntry : cur_dir->file->entry_offset;
|
||||
|
||||
cur_dir->parent_offset = cur_dir == m_root ? 0 : cur_dir->parent->entry_offset;
|
||||
}
|
||||
|
||||
/* Replace all files' sibling pointers. */
|
||||
for (const auto &it : m_files) {
|
||||
BuildFileContext *cur_file = it.get();
|
||||
|
||||
cur_file->ClearHashMark();
|
||||
|
||||
cur_file->sibling_offset = (cur_file->sibling == nullptr) ? EmptyEntry : cur_file->sibling->entry_offset;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the file table. */
|
||||
{
|
||||
FileTableWriter file_table(std::addressof(metadata_file), m_dir_hash_table_size + m_dir_table_size + m_file_hash_table_size, m_file_table_size);
|
||||
|
||||
for (const auto &it : m_files) {
|
||||
BuildFileContext *cur_file = it.get();
|
||||
for (auto it = m_files.begin(); it != m_files.end(); it = m_files.erase(it)) {
|
||||
BuildFileContext *cur_file = it->get();
|
||||
FileEntry *cur_entry = file_table.GetEntry(cur_file->entry_offset, cur_file->path_len);
|
||||
|
||||
cur_file->ClearHashMark();
|
||||
|
||||
/* Set entry fields. */
|
||||
cur_entry->parent = cur_file->parent->entry_offset;
|
||||
cur_entry->sibling = (cur_file->sibling == nullptr) ? EmptyEntry : cur_file->sibling->entry_offset;
|
||||
cur_entry->sibling = cur_file->sibling_offset;
|
||||
cur_entry->offset = cur_file->offset;
|
||||
cur_entry->size = cur_file->size;
|
||||
cur_entry->hash = cur_file->hash_value;
|
||||
@@ -660,8 +684,15 @@ namespace ams::mitm::fs {
|
||||
break;
|
||||
case DataSourceType::LooseSdFile:
|
||||
{
|
||||
char *new_path = new char[cur_file->GetPathLength() + 1];
|
||||
cur_file->GetPath(new_path);
|
||||
char full_path[fs::EntryNameLengthMax + 1];
|
||||
const size_t path_needed_size = cur_file->GetPathLength() + 1;
|
||||
AMS_ABORT_UNLESS(path_needed_size <= sizeof(full_path));
|
||||
cur_file->GetPath(full_path);
|
||||
|
||||
cur_file->path.reset();
|
||||
|
||||
char *new_path = new char[path_needed_size];
|
||||
std::memcpy(new_path, full_path, path_needed_size);
|
||||
out_infos->emplace_back(cur_file->offset + FilePartitionOffset, cur_file->size, cur_file->source_type, new_path);
|
||||
}
|
||||
break;
|
||||
@@ -674,17 +705,15 @@ namespace ams::mitm::fs {
|
||||
{
|
||||
DirectoryTableWriter dir_table(std::addressof(metadata_file), m_dir_hash_table_size, m_dir_table_size);
|
||||
|
||||
for (const auto &it : m_directories) {
|
||||
BuildDirectoryContext *cur_dir = it.get();
|
||||
for (auto it = m_directories.begin(); it != m_directories.end(); it = m_directories.erase(it)) {
|
||||
BuildDirectoryContext *cur_dir = it->get();
|
||||
DirectoryEntry *cur_entry = dir_table.GetEntry(cur_dir->entry_offset, cur_dir->path_len);
|
||||
|
||||
cur_dir->ClearHashMark();
|
||||
|
||||
/* Set entry fields. */
|
||||
cur_entry->parent = cur_dir == m_root ? 0 : cur_dir->parent->entry_offset;
|
||||
cur_entry->sibling = (cur_dir->sibling == nullptr) ? EmptyEntry : cur_dir->sibling->entry_offset;
|
||||
cur_entry->child = (cur_dir->child == nullptr) ? EmptyEntry : cur_dir->child->entry_offset;
|
||||
cur_entry->file = (cur_dir->file == nullptr) ? EmptyEntry : cur_dir->file->entry_offset;
|
||||
cur_entry->parent = cur_dir->parent_offset;
|
||||
cur_entry->sibling = cur_dir->sibling_offset;
|
||||
cur_entry->child = cur_dir->child_offset;
|
||||
cur_entry->file = cur_dir->file_offset;
|
||||
cur_entry->hash = cur_dir->hash_value;
|
||||
|
||||
/* Set name. */
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
#pragma once
|
||||
#include <stratosphere.hpp>
|
||||
#include "../dns_mitm/dnsmitm_debug.hpp"
|
||||
|
||||
namespace ams::mitm::fs::romfs {
|
||||
|
||||
@@ -115,10 +114,24 @@ namespace ams::mitm::fs::romfs {
|
||||
NON_MOVEABLE(BuildDirectoryContext);
|
||||
|
||||
std::unique_ptr<char[]> path;
|
||||
BuildDirectoryContext *parent;
|
||||
BuildDirectoryContext *child;
|
||||
BuildDirectoryContext *sibling;
|
||||
BuildFileContext *file;
|
||||
union {
|
||||
BuildDirectoryContext *parent;
|
||||
};
|
||||
union {
|
||||
BuildDirectoryContext *child;
|
||||
struct {
|
||||
u32 parent_offset;
|
||||
u32 child_offset;
|
||||
};
|
||||
};
|
||||
union {
|
||||
BuildDirectoryContext *sibling;
|
||||
u32 sibling_offset;
|
||||
};
|
||||
union {
|
||||
BuildFileContext *file;
|
||||
u32 file_offset;
|
||||
};
|
||||
u32 path_len;
|
||||
u32 entry_offset;
|
||||
u32 hash_value;
|
||||
@@ -176,7 +189,10 @@ namespace ams::mitm::fs::romfs {
|
||||
|
||||
std::unique_ptr<char[]> path;
|
||||
BuildDirectoryContext *parent;
|
||||
BuildFileContext *sibling;
|
||||
union {
|
||||
BuildFileContext *sibling;
|
||||
u32 sibling_offset;
|
||||
};
|
||||
s64 offset;
|
||||
s64 size;
|
||||
s64 orig_offset;
|
||||
|
||||
@@ -1025,13 +1025,16 @@ namespace ams::dmnt::cheat::impl {
|
||||
/* Skip whitespace. */
|
||||
while (std::isspace(static_cast<unsigned char>(s[i]))) {
|
||||
i++;
|
||||
if (i >= len) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse whether to toggle. */
|
||||
j = i + 1;
|
||||
while (!std::isspace(static_cast<unsigned char>(s[j]))) {
|
||||
while (j < len && !std::isspace(static_cast<unsigned char>(s[j]))) {
|
||||
j++;
|
||||
if (j >= len || (j - i) >= sizeof(toggle)) {
|
||||
if ((j - i) >= sizeof(toggle)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,12 +78,6 @@ namespace ams {
|
||||
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(erpt, Main));
|
||||
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(erpt, Main));
|
||||
|
||||
/* Set the memory heap for erpt::srv namespace. */
|
||||
R_ABORT_UNLESS(erpt::srv::Initialize(erpt::g_memory_heap, erpt::MemoryHeapSize));
|
||||
|
||||
/* Atmosphere always wants to redirect new reports to the SD card, to prevent them from being logged. */
|
||||
erpt::srv::SetRedirectNewReportsToSdCard(true);
|
||||
|
||||
/* Decide whether or not to clean up reports periodically. */
|
||||
{
|
||||
u8 disable_report_cleanup = 0;
|
||||
@@ -94,6 +88,12 @@ namespace ams {
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the memory heap for erpt::srv namespace, perform other service init/etc. */
|
||||
R_ABORT_UNLESS(erpt::srv::Initialize(erpt::g_memory_heap, erpt::MemoryHeapSize));
|
||||
|
||||
/* Atmosphere always wants to redirect new reports to the SD card, to prevent them from being logged. */
|
||||
erpt::srv::SetRedirectNewReportsToSdCard(true);
|
||||
|
||||
/* Configure the OS version. */
|
||||
{
|
||||
settings::system::FirmwareVersion firmware_version = {};
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace ams::pm::resource {
|
||||
constexpr size_t ReservedMemorySize600 = 5_MB;
|
||||
|
||||
/* Atmosphere always allocates extra memory for system usage. */
|
||||
constexpr size_t ExtraSystemMemorySizeAtmosphere = 24_MB;
|
||||
constexpr size_t ExtraSystemMemorySizeAtmosphere = 40_MB;
|
||||
|
||||
/* Desired extra threads. */
|
||||
constexpr u64 BaseApplicationThreads = 96;
|
||||
|
||||
Reference in New Issue
Block a user