Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
85c23b5781 | ||
|
|
8e042f2262 | ||
|
|
81e9154a52 | ||
|
|
e9b9dbc2aa | ||
|
|
7e6c849ca4 | ||
|
|
8ec7c096d0 | ||
|
|
6e5b901a9b | ||
|
|
b800953d66 | ||
|
|
f0240db75a | ||
|
|
1f5ec68a5c | ||
|
|
ed9e60acb9 | ||
|
|
a7300b0fa4 | ||
|
|
8e2eca2004 | ||
|
|
9f83b3c838 |
@@ -1,4 +1,15 @@
|
||||
# Changelog
|
||||
## 1.5.3
|
||||
+ Support was added for 16.0.3.
|
||||
+ Atmosphère was updated to use GCC 13/newlib (latest devkitA64/devkitARM releases).
|
||||
+ **Please note**: This introduces a known issue, which is currently being worked on.
|
||||
+ As you may recall from the 1.4.1 changelog, Fire Emblem: Engage requires enormous amounts of memory to support using layeredfs mods with the game.
|
||||
+ Latest GCC/newlib slightly increases malloc overhead size, which makes the previous memory increase insufficient.
|
||||
+ A general-case solution to this is in the works, which should hopefully fix the problem in a way that doesn't jinx me for the future.
|
||||
+ A number of minor issues were fixed and improvements were made, including:
|
||||
+ An issue was fixed that caused system font replacement to not work on 16.0.0+.
|
||||
+ An minor accuracy issue was addressed in mesosphere's management of certain memory ranges; this issue would have had zero visible impact to the end-user.
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
## 1.5.2
|
||||
+ A homebrew application (`haze`) was added for performing USB file transfer (with thanks to @liamwhite for both design and implementation).
|
||||
+ `haze` is included with atmosphère, and provides access to the SD card via the PTP/MTP protocol.
|
||||
|
||||
4
emummc/.gitrepo
vendored
4
emummc/.gitrepo
vendored
@@ -6,7 +6,7 @@
|
||||
[subrepo]
|
||||
remote = https://github.com/m4xw/emummc
|
||||
branch = develop
|
||||
commit = bba1f1fb65f75721caf6d023a35d75d3c9aafd0f
|
||||
parent = 1ab8b234447864503e21c600681219a96962e6c1
|
||||
commit = 30205111ee375bef96f0f76cb6a3130a2f0fc85c
|
||||
parent = 81e9154a52a976f85317bddd0131426599d26a62
|
||||
method = merge
|
||||
cmdver = 0.4.1
|
||||
|
||||
2
emummc/README.md
vendored
2
emummc/README.md
vendored
@@ -2,7 +2,7 @@
|
||||
*A SDMMC driver replacement for Nintendo's Filesystem Services, by **m4xw***
|
||||
|
||||
### Supported Horizon Versions
|
||||
**1.0.0 - 16.0.0**
|
||||
**1.0.0 - 16.0.3**
|
||||
|
||||
## Features
|
||||
* Arbitrary SDMMC backend selection
|
||||
|
||||
8
emummc/source/FS/FS_offsets.c
vendored
8
emummc/source/FS/FS_offsets.c
vendored
@@ -65,6 +65,8 @@
|
||||
#include "offsets/1500_exfat.h"
|
||||
#include "offsets/1600.h"
|
||||
#include "offsets/1600_exfat.h"
|
||||
#include "offsets/1603.h"
|
||||
#include "offsets/1603_exfat.h"
|
||||
#include "../utils/fatal.h"
|
||||
|
||||
#define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers
|
||||
@@ -141,6 +143,8 @@ DEFINE_OFFSET_STRUCT(_1500);
|
||||
DEFINE_OFFSET_STRUCT(_1500_EXFAT);
|
||||
DEFINE_OFFSET_STRUCT(_1600);
|
||||
DEFINE_OFFSET_STRUCT(_1600_EXFAT);
|
||||
DEFINE_OFFSET_STRUCT(_1603);
|
||||
DEFINE_OFFSET_STRUCT(_1603_EXFAT);
|
||||
|
||||
const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
|
||||
switch (version) {
|
||||
@@ -242,6 +246,10 @@ const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
|
||||
return &(GET_OFFSET_STRUCT_NAME(_1600));
|
||||
case FS_VER_16_0_0_EXFAT:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_1600_EXFAT));
|
||||
case FS_VER_16_0_3:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_1603));
|
||||
case FS_VER_16_0_3_EXFAT:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_1603_EXFAT));
|
||||
default:
|
||||
fatal_abort(Fatal_UnknownVersion);
|
||||
}
|
||||
|
||||
3
emummc/source/FS/FS_versions.h
vendored
3
emummc/source/FS/FS_versions.h
vendored
@@ -95,6 +95,9 @@ enum FS_VER
|
||||
FS_VER_16_0_0,
|
||||
FS_VER_16_0_0_EXFAT,
|
||||
|
||||
FS_VER_16_0_3,
|
||||
FS_VER_16_0_3_EXFAT,
|
||||
|
||||
FS_VER_MAX,
|
||||
};
|
||||
|
||||
|
||||
59
emummc/source/FS/offsets/1603.h
vendored
Normal file
59
emummc/source/FS/offsets/1603.h
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-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/>.
|
||||
*/
|
||||
#ifndef __FS_1603_H__
|
||||
#define __FS_1603_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_1603_SDMMC_ACCESSOR_GC 0x1862F0
|
||||
#define FS_OFFSET_1603_SDMMC_ACCESSOR_SD 0x187F70
|
||||
#define FS_OFFSET_1603_SDMMC_ACCESSOR_NAND 0x1867B0
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_1603_SDMMC_WRAPPER_READ 0x182240
|
||||
#define FS_OFFSET_1603_SDMMC_WRAPPER_WRITE 0x1822A0
|
||||
#define FS_OFFSET_1603_RTLD 0x269B0
|
||||
#define FS_OFFSET_1603_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x3C)))
|
||||
|
||||
#define FS_OFFSET_1603_CLKRST_SET_MIN_V_CLK_RATE 0x1A2D80
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_1603_LOCK_MUTEX 0x17B780
|
||||
#define FS_OFFSET_1603_UNLOCK_MUTEX 0x17B7D0
|
||||
|
||||
#define FS_OFFSET_1603_SDMMC_WRAPPER_CONTROLLER_OPEN 0x182200
|
||||
#define FS_OFFSET_1603_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x182220
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_1603_SD_MUTEX 0xFFB3F0
|
||||
#define FS_OFFSET_1603_NAND_MUTEX 0xFF6B58
|
||||
#define FS_OFFSET_1603_ACTIVE_PARTITION 0xFF6B98
|
||||
#define FS_OFFSET_1603_SDMMC_DAS_HANDLE 0xFDC8B0
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_1603_SD_DAS_INIT 0x258D4
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_1603_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00063B98, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00070DBC, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x0007795C, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x0008A7A4, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_1603_H__
|
||||
59
emummc/source/FS/offsets/1603_exfat.h
vendored
Normal file
59
emummc/source/FS/offsets/1603_exfat.h
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-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/>.
|
||||
*/
|
||||
#ifndef __FS_1603_EXFAT_H__
|
||||
#define __FS_1603_EXFAT_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_1603_EXFAT_SDMMC_ACCESSOR_GC 0x190FD0
|
||||
#define FS_OFFSET_1603_EXFAT_SDMMC_ACCESSOR_SD 0x192C50
|
||||
#define FS_OFFSET_1603_EXFAT_SDMMC_ACCESSOR_NAND 0x191490
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_1603_EXFAT_SDMMC_WRAPPER_READ 0x18CF20
|
||||
#define FS_OFFSET_1603_EXFAT_SDMMC_WRAPPER_WRITE 0x18CF80
|
||||
#define FS_OFFSET_1603_EXFAT_RTLD 0x269B0
|
||||
#define FS_OFFSET_1603_EXFAT_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x3C)))
|
||||
|
||||
#define FS_OFFSET_1603_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x1ADA60
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_1603_EXFAT_LOCK_MUTEX 0x186460
|
||||
#define FS_OFFSET_1603_EXFAT_UNLOCK_MUTEX 0x1864B0
|
||||
|
||||
#define FS_OFFSET_1603_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x18CEE0
|
||||
#define FS_OFFSET_1603_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x18CF00
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_1603_EXFAT_SD_MUTEX 0x100D3F0
|
||||
#define FS_OFFSET_1603_EXFAT_NAND_MUTEX 0x1008B58
|
||||
#define FS_OFFSET_1603_EXFAT_ACTIVE_PARTITION 0x1008B98
|
||||
#define FS_OFFSET_1603_EXFAT_SDMMC_DAS_HANDLE 0xFE98B0
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_1603_EXFAT_SD_DAS_INIT 0x258D4
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_1603_EXFAT_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00063B98, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00070DBC, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x0007795C, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x0008A7A4, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_1603_EXFAT_H__
|
||||
@@ -162,6 +162,9 @@ namespace ams::nxboot {
|
||||
FsVersion_16_0_0,
|
||||
FsVersion_16_0_0_Exfat,
|
||||
|
||||
FsVersion_16_0_3,
|
||||
FsVersion_16_0_3_Exfat,
|
||||
|
||||
FsVersion_Count,
|
||||
};
|
||||
|
||||
@@ -239,6 +242,9 @@ namespace ams::nxboot {
|
||||
|
||||
{ 0x56, 0xE8, 0x56, 0x56, 0x6C, 0x38, 0xD8, 0xBE }, /* FsVersion_16_0_0 */
|
||||
{ 0xCF, 0xAB, 0x45, 0x0C, 0x2C, 0x53, 0x9D, 0xA9 }, /* FsVersion_16_0_0_Exfat */
|
||||
|
||||
{ 0x39, 0xEE, 0x1F, 0x1E, 0x0E, 0xA7, 0x32, 0x5D }, /* FsVersion_16_0_3 */
|
||||
{ 0x62, 0xC6, 0x5E, 0xFD, 0x9A, 0xBF, 0x7C, 0x43 }, /* FsVersion_16_0_3_Exfat */
|
||||
};
|
||||
|
||||
const InitialProcessBinaryHeader *FindInitialProcessBinary(const pkg2::Package2Header *header, const u8 *data, ams::TargetFirmware target_firmware) {
|
||||
@@ -656,6 +662,14 @@ namespace ams::nxboot {
|
||||
AddPatch(fs_meta, 0x1913B9, NogcPatch0, sizeof(NogcPatch0));
|
||||
AddPatch(fs_meta, 0x16B950, NogcPatch1, sizeof(NogcPatch1));
|
||||
break;
|
||||
case FsVersion_16_0_3:
|
||||
AddPatch(fs_meta, 0x186729, NogcPatch0, sizeof(NogcPatch0));
|
||||
AddPatch(fs_meta, 0x160CC0, NogcPatch1, sizeof(NogcPatch1));
|
||||
break;
|
||||
case FsVersion_16_0_3_Exfat:
|
||||
AddPatch(fs_meta, 0x191409, NogcPatch0, sizeof(NogcPatch0));
|
||||
AddPatch(fs_meta, 0x16B9A0, NogcPatch1, sizeof(NogcPatch1));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
[subrepo]
|
||||
remote = https://github.com/Atmosphere-NX/Atmosphere-libs
|
||||
branch = master
|
||||
commit = ecc8b18111730acef0a353f6f61c45c1f143a793
|
||||
parent = d8aed7de6d39dd29b75e34f24d376decfb77a5b4
|
||||
commit = cd0fc2c1d5728ec45414aaaa6efa28c269695992
|
||||
parent = 8ec7c096d04e6f9586be2cb785840cd482d4b900
|
||||
method = merge
|
||||
cmdver = 0.4.1
|
||||
|
||||
@@ -257,7 +257,7 @@ namespace ams::kern {
|
||||
class KScopedAutoObject {
|
||||
NON_COPYABLE(KScopedAutoObject);
|
||||
private:
|
||||
template<typename U>
|
||||
template<typename U> requires std::derived_from<U, KAutoObject>
|
||||
friend class KScopedAutoObject;
|
||||
private:
|
||||
T *m_obj;
|
||||
|
||||
@@ -57,11 +57,26 @@ namespace ams::kern {
|
||||
using TraversalEntry = KPageTableImpl::TraversalEntry;
|
||||
using TraversalContext = KPageTableImpl::TraversalContext;
|
||||
|
||||
struct MemoryRange {
|
||||
KPhysicalAddress address;
|
||||
size_t size;
|
||||
class MemoryRange {
|
||||
private:
|
||||
KPhysicalAddress m_address;
|
||||
size_t m_size;
|
||||
bool m_heap;
|
||||
public:
|
||||
constexpr MemoryRange() : m_address(Null<KPhysicalAddress>), m_size(0), m_heap(false) { /* ... */ }
|
||||
|
||||
void Close();
|
||||
void Set(KPhysicalAddress address, size_t size, bool heap) {
|
||||
m_address = address;
|
||||
m_size = size;
|
||||
m_heap = heap;
|
||||
}
|
||||
|
||||
constexpr KPhysicalAddress GetAddress() const { return m_address; }
|
||||
constexpr size_t GetSize() const { return m_size; }
|
||||
constexpr bool IsHeap() const { return m_heap; }
|
||||
|
||||
void Open();
|
||||
void Close();
|
||||
};
|
||||
protected:
|
||||
enum MemoryFillValue {
|
||||
|
||||
@@ -120,10 +120,6 @@ namespace ams::kern {
|
||||
return m_address == rhs;
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE bool operator!=(uintptr_t rhs) const {
|
||||
return m_address != rhs;
|
||||
}
|
||||
|
||||
/* Allow getting the address explicitly, for use in accessors. */
|
||||
constexpr ALWAYS_INLINE uintptr_t GetValue() const {
|
||||
return m_address;
|
||||
|
||||
@@ -164,8 +164,9 @@ namespace ams::kern {
|
||||
};
|
||||
|
||||
|
||||
template<typename Derived, typename Base, bool SupportDynamicExpansion = false> requires std::derived_from<Base, KAutoObjectWithList>
|
||||
template<typename Derived, typename Base, bool SupportDynamicExpansion = false>
|
||||
class KAutoObjectWithSlabHeapAndContainer : public KAutoObjectWithSlabHeapBase<Derived, Base, SupportDynamicExpansion> {
|
||||
static_assert(std::derived_from<Base, KAutoObjectWithList>);
|
||||
private:
|
||||
static constinit inline KAutoObjectWithListContainer<Derived> s_container;
|
||||
public:
|
||||
|
||||
@@ -1133,17 +1133,17 @@ namespace ams::kern::board::nintendo::nx {
|
||||
size_t cur_size;
|
||||
{
|
||||
/* Get the current contiguous range. */
|
||||
KPageTableBase::MemoryRange contig_range = { .address = Null<KPhysicalAddress>, .size = 0 };
|
||||
KPageTableBase::MemoryRange contig_range;
|
||||
R_TRY(page_table->OpenMemoryRangeForMapDeviceAddressSpace(std::addressof(contig_range), process_address + mapped_size, size - mapped_size, ConvertToKMemoryPermission(device_perm), is_aligned));
|
||||
|
||||
/* Ensure we close the range when we're done. */
|
||||
ON_SCOPE_EXIT { contig_range.Close(); };
|
||||
|
||||
/* Get the current size. */
|
||||
cur_size = contig_range.size;
|
||||
cur_size = contig_range.GetSize();
|
||||
|
||||
/* Map the device page. */
|
||||
R_TRY(this->MapDevicePage(contig_range.address, contig_range.size, cur_addr, device_perm));
|
||||
R_TRY(this->MapDevicePage(contig_range.GetAddress(), cur_size, cur_addr, device_perm));
|
||||
}
|
||||
|
||||
/* Advance. */
|
||||
@@ -1288,7 +1288,7 @@ namespace ams::kern::board::nintendo::nx {
|
||||
MESOSPHERE_ASSERT(((device_address + size - 1) & ~DeviceVirtualAddressMask) == 0);
|
||||
|
||||
/* We need to traverse the ranges that make up our mapping, to make sure they're all good. Start by getting a contiguous range. */
|
||||
KPageTableBase::MemoryRange contig_range = { .address = Null<KPhysicalAddress>, .size = 0 };
|
||||
KPageTableBase::MemoryRange contig_range;
|
||||
if (R_FAILED(page_table->OpenMemoryRangeForUnmapDeviceAddressSpace(std::addressof(contig_range), process_address, size))) {
|
||||
return false;
|
||||
}
|
||||
@@ -1300,8 +1300,8 @@ namespace ams::kern::board::nintendo::nx {
|
||||
/* Walk the directory. */
|
||||
KProcessAddress cur_process_address = process_address;
|
||||
size_t remaining_size = size;
|
||||
KPhysicalAddress cur_phys_address = contig_range.address;
|
||||
size_t remaining_in_range = contig_range.size;
|
||||
KPhysicalAddress cur_phys_address = contig_range.GetAddress();
|
||||
size_t remaining_in_range = contig_range.GetSize();
|
||||
bool first = true;
|
||||
u32 first_attr = 0;
|
||||
while (remaining_size > 0) {
|
||||
@@ -1347,8 +1347,8 @@ namespace ams::kern::board::nintendo::nx {
|
||||
}
|
||||
range_open = true;
|
||||
|
||||
cur_phys_address = contig_range.address;
|
||||
remaining_in_range = contig_range.size;
|
||||
cur_phys_address = contig_range.GetAddress();
|
||||
remaining_in_range = contig_range.GetSize();
|
||||
}
|
||||
|
||||
/* Check that the physical address is expected. */
|
||||
@@ -1390,8 +1390,8 @@ namespace ams::kern::board::nintendo::nx {
|
||||
}
|
||||
range_open = true;
|
||||
|
||||
cur_phys_address = contig_range.address;
|
||||
remaining_in_range = contig_range.size;
|
||||
cur_phys_address = contig_range.GetAddress();
|
||||
remaining_in_range = contig_range.GetSize();
|
||||
}
|
||||
|
||||
/* Check that the physical address is expected, and there's enough in the range. */
|
||||
|
||||
@@ -74,8 +74,18 @@ namespace ams::kern {
|
||||
|
||||
}
|
||||
|
||||
void KPageTableBase::MemoryRange::Open() {
|
||||
/* If the range contains heap pages, open them. */
|
||||
if (this->IsHeap()) {
|
||||
Kernel::GetMemoryManager().Open(this->GetAddress(), this->GetSize() / PageSize);
|
||||
}
|
||||
}
|
||||
|
||||
void KPageTableBase::MemoryRange::Close() {
|
||||
Kernel::GetMemoryManager().Close(address, size / PageSize);
|
||||
/* If the range contains heap pages, close them. */
|
||||
if (this->IsHeap()) {
|
||||
Kernel::GetMemoryManager().Close(this->GetAddress(), this->GetSize() / PageSize);
|
||||
}
|
||||
}
|
||||
|
||||
Result KPageTableBase::InitializeForKernel(bool is_64_bit, void *table, KVirtualAddress start, KVirtualAddress end) {
|
||||
@@ -1504,16 +1514,13 @@ namespace ams::kern {
|
||||
|
||||
/* Check that the memory is contiguous (modulo the reference count bit). */
|
||||
const u32 test_state_mask = state_mask | KMemoryState_FlagReferenceCounted;
|
||||
if (R_FAILED(this->CheckMemoryStateContiguous(address, size, test_state_mask, state | KMemoryState_FlagReferenceCounted, perm_mask, perm, attr_mask, attr))) {
|
||||
const bool is_heap = R_SUCCEEDED(this->CheckMemoryStateContiguous(address, size, test_state_mask, state | KMemoryState_FlagReferenceCounted, perm_mask, perm, attr_mask, attr));
|
||||
if (!is_heap) {
|
||||
R_TRY(this->CheckMemoryStateContiguous(address, size, test_state_mask, state, perm_mask, perm, attr_mask, attr));
|
||||
}
|
||||
|
||||
/* The memory is contiguous, so set the output range. */
|
||||
*out = {
|
||||
.address = phys_address,
|
||||
.size = size,
|
||||
};
|
||||
|
||||
out->Set(phys_address, size, is_heap);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
@@ -2932,7 +2939,7 @@ namespace ams::kern {
|
||||
KMemoryAttribute_IpcLocked | KMemoryAttribute_Locked, KMemoryAttribute_None));
|
||||
|
||||
/* We got the range, so open it. */
|
||||
Kernel::GetMemoryManager().Open(out->address, out->size / PageSize);
|
||||
out->Open();
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
@@ -2949,7 +2956,7 @@ namespace ams::kern {
|
||||
KMemoryAttribute_DeviceShared | KMemoryAttribute_Locked, KMemoryAttribute_DeviceShared));
|
||||
|
||||
/* We got the range, so open it. */
|
||||
Kernel::GetMemoryManager().Open(out->address, out->size / PageSize);
|
||||
out->Open();
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
@@ -3020,7 +3027,7 @@ namespace ams::kern {
|
||||
KMemoryAttribute_Uncached, KMemoryAttribute_None));
|
||||
|
||||
/* We got the range, so open it. */
|
||||
Kernel::GetMemoryManager().Open(out->address, out->size / PageSize);
|
||||
out->Open();
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
@@ -36,15 +36,15 @@ namespace ams::kern::svc {
|
||||
size_t remaining = size;
|
||||
while (remaining > 0) {
|
||||
/* Get a contiguous range to operate on. */
|
||||
KPageTableBase::MemoryRange contig_range = { .address = Null<KPhysicalAddress>, .size = 0 };
|
||||
KPageTableBase::MemoryRange contig_range;
|
||||
R_TRY(page_table.OpenMemoryRangeForProcessCacheOperation(std::addressof(contig_range), cur_address, aligned_end - cur_address));
|
||||
|
||||
/* Close the range when we're done operating on it. */
|
||||
ON_SCOPE_EXIT { contig_range.Close(); };
|
||||
|
||||
/* Adjust to remain within range. */
|
||||
KVirtualAddress operate_address = KMemoryLayout::GetLinearVirtualAddress(contig_range.address);
|
||||
size_t operate_size = contig_range.size;
|
||||
KVirtualAddress operate_address = KMemoryLayout::GetLinearVirtualAddress(contig_range.GetAddress());
|
||||
size_t operate_size = contig_range.GetSize();
|
||||
if (cur_address < address) {
|
||||
operate_address += (address - cur_address);
|
||||
operate_size -= (address - cur_address);
|
||||
@@ -57,7 +57,7 @@ namespace ams::kern::svc {
|
||||
operation.Operate(GetVoidPointer(operate_address), operate_size);
|
||||
|
||||
/* Advance. */
|
||||
cur_address += contig_range.size;
|
||||
cur_address += contig_range.GetSize();
|
||||
remaining -= operate_size;
|
||||
}
|
||||
MESOSPHERE_ASSERT(remaining == 0);
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace ams::kern::svc {
|
||||
R_UNLESS(size < ams::kern::MainMemorySizeMax, svc::ResultInvalidSize());
|
||||
|
||||
/* Set the heap size. */
|
||||
KProcessAddress address;
|
||||
KProcessAddress address = Null<KProcessAddress>;
|
||||
R_TRY(GetCurrentProcess().GetPageTable().SetHeapSize(std::addressof(address), size));
|
||||
|
||||
/* Set the output. */
|
||||
|
||||
@@ -78,6 +78,7 @@ namespace ams::hos {
|
||||
Version_16_0_0 = ::ams::TargetFirmware_16_0_0,
|
||||
Version_16_0_1 = ::ams::TargetFirmware_16_0_1,
|
||||
Version_16_0_2 = ::ams::TargetFirmware_16_0_2,
|
||||
Version_16_0_3 = ::ams::TargetFirmware_16_0_3,
|
||||
|
||||
Version_Current = ::ams::TargetFirmware_Current,
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace ams::sf::hipc {
|
||||
AMS_ABORT_UNLESS(ServerManagerBase::CanAnyManageMitmServers());
|
||||
|
||||
/* Clone the forward service. */
|
||||
std::shared_ptr<::Service> new_forward_service = std::move(ServerSession::CreateForwardService());
|
||||
std::shared_ptr<::Service> new_forward_service = ServerSession::CreateForwardService();
|
||||
R_ABORT_UNLESS(serviceClone(util::GetReference(m_session->m_forward_service).get(), new_forward_service.get()));
|
||||
R_ABORT_UNLESS(tagged_manager->RegisterMitmSession(server_handle, std::move(clone), std::move(new_forward_service)));
|
||||
}
|
||||
@@ -168,7 +168,7 @@ namespace ams::sf::hipc {
|
||||
R_ABORT_UNLESS(hipc::CreateSession(std::addressof(server_handle), std::addressof(client_handle)));
|
||||
|
||||
/* Register. */
|
||||
std::shared_ptr<::Service> new_forward_service = std::move(ServerSession::CreateForwardService());
|
||||
std::shared_ptr<::Service> new_forward_service = ServerSession::CreateForwardService();
|
||||
serviceCreate(new_forward_service.get(), new_forward_target);
|
||||
R_ABORT_UNLESS(m_manager->RegisterMitmSession(server_handle, std::move(object), std::move(new_forward_service)));
|
||||
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
|
||||
#define ATMOSPHERE_RELEASE_VERSION_MAJOR 1
|
||||
#define ATMOSPHERE_RELEASE_VERSION_MINOR 5
|
||||
#define ATMOSPHERE_RELEASE_VERSION_MICRO 2
|
||||
#define ATMOSPHERE_RELEASE_VERSION_MICRO 3
|
||||
|
||||
#define ATMOSPHERE_RELEASE_VERSION ATMOSPHERE_RELEASE_VERSION_MAJOR, ATMOSPHERE_RELEASE_VERSION_MINOR, ATMOSPHERE_RELEASE_VERSION_MICRO
|
||||
|
||||
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 16
|
||||
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 0
|
||||
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MICRO 1
|
||||
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MICRO 3
|
||||
|
||||
@@ -76,8 +76,9 @@
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_16_0_0 ATMOSPHERE_TARGET_FIRMWARE(16, 0, 0)
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_16_0_1 ATMOSPHERE_TARGET_FIRMWARE(16, 0, 1)
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_16_0_2 ATMOSPHERE_TARGET_FIRMWARE(16, 0, 2)
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_16_0_3 ATMOSPHERE_TARGET_FIRMWARE(16, 0, 3)
|
||||
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_16_0_2
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_16_0_3
|
||||
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_MIN ATMOSPHERE_TARGET_FIRMWARE(0, 0, 0)
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_MAX ATMOSPHERE_TARGET_FIRMWARE_CURRENT
|
||||
@@ -146,6 +147,7 @@ namespace ams {
|
||||
TargetFirmware_16_0_0 = ATMOSPHERE_TARGET_FIRMWARE_16_0_0,
|
||||
TargetFirmware_16_0_1 = ATMOSPHERE_TARGET_FIRMWARE_16_0_1,
|
||||
TargetFirmware_16_0_2 = ATMOSPHERE_TARGET_FIRMWARE_16_0_2,
|
||||
TargetFirmware_16_0_3 = ATMOSPHERE_TARGET_FIRMWARE_16_0_3,
|
||||
|
||||
TargetFirmware_Current = ATMOSPHERE_TARGET_FIRMWARE_CURRENT,
|
||||
|
||||
|
||||
@@ -144,10 +144,6 @@ namespace ams::util {
|
||||
return m_node == rhs.m_node;
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE bool operator!=(const Iterator &rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE pointer operator->() const {
|
||||
return m_node;
|
||||
}
|
||||
@@ -355,10 +351,6 @@ namespace ams::util {
|
||||
return m_iterator == rhs.m_iterator;
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE bool operator!=(const Iterator &rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE pointer operator->() const {
|
||||
return std::addressof(Traits::GetParent(*m_iterator));
|
||||
}
|
||||
|
||||
@@ -94,10 +94,6 @@ namespace ams::util {
|
||||
return m_node == rhs.m_node;
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE bool operator!=(const Iterator &rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE pointer operator->() const {
|
||||
return m_node;
|
||||
}
|
||||
@@ -304,10 +300,6 @@ namespace ams::util {
|
||||
return m_impl == rhs.m_impl;
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE bool operator!=(const Iterator &rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE pointer operator->() const {
|
||||
return Traits::GetParent(std::addressof(*m_impl));
|
||||
}
|
||||
|
||||
@@ -54,7 +54,8 @@ namespace ams::mitm::fs {
|
||||
}
|
||||
|
||||
/* We want to mitm sdb, to support sd-romfs redirection of common system archives (like system font, etc). */
|
||||
if (program_id == ncm::SystemProgramId::Sdb) {
|
||||
/* NOTE: In 16.0.0+, this was moved to glue. */
|
||||
if (program_id == ncm::SystemProgramId::Sdb || program_id == ncm::SystemProgramId::Glue) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -251,12 +251,11 @@ namespace ams::mitm::fs {
|
||||
using DirectoryTableWriter = TableWriter<DirectoryEntry>;
|
||||
using FileTableWriter = TableWriter<FileEntry>;
|
||||
|
||||
constexpr inline u32 CalculatePathHash(u32 parent, const char *_path, u32 start, size_t path_len) {
|
||||
const unsigned char *path = reinterpret_cast<const unsigned char *>(_path);
|
||||
constexpr inline u32 CalculatePathHash(u32 parent, const char *path, u32 start, size_t path_len) {
|
||||
u32 hash = parent ^ 123456789;
|
||||
for (size_t i = 0; i < path_len; i++) {
|
||||
hash = (hash >> 5) | (hash << 27);
|
||||
hash ^= path[start + i];
|
||||
hash ^= static_cast<unsigned char>(path[start + i]);
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include <haze/async_usb_server.hpp>
|
||||
#include <haze/common.hpp>
|
||||
#include <haze/device_properties.hpp>
|
||||
#include <haze/event_reactor.hpp>
|
||||
#include <haze/file_system_proxy.hpp>
|
||||
#include <haze/ptp.hpp>
|
||||
|
||||
26
troposphere/haze/include/haze/device_properties.hpp
Normal file
26
troposphere/haze/include/haze/device_properties.hpp
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace haze {
|
||||
|
||||
Result LoadDeviceProperties();
|
||||
|
||||
const char *GetSerialNumber();
|
||||
|
||||
const char *GetFirmwareVersion();
|
||||
|
||||
}
|
||||
50
troposphere/haze/source/device_properties.cpp
Normal file
50
troposphere/haze/source/device_properties.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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 <haze.hpp>
|
||||
|
||||
namespace haze {
|
||||
|
||||
namespace {
|
||||
|
||||
constinit SetSysSerialNumber g_serial_number = {};
|
||||
constinit SetSysFirmwareVersion g_firmware_version = {};
|
||||
|
||||
}
|
||||
|
||||
Result LoadDeviceProperties() {
|
||||
/* Initialize set:sys. */
|
||||
R_TRY(setsysInitialize());
|
||||
|
||||
/* Ensure we maintain a clean state on exit. */
|
||||
ON_SCOPE_EXIT { setsysExit(); };
|
||||
|
||||
/* Get the serial number and firmware version. */
|
||||
R_TRY(setsysGetSerialNumber(std::addressof(g_serial_number)));
|
||||
R_TRY(setsysGetFirmwareVersion(std::addressof(g_firmware_version)));
|
||||
|
||||
/* We succeeded. */
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
const char *GetSerialNumber() {
|
||||
return g_serial_number.number;
|
||||
}
|
||||
|
||||
const char *GetFirmwareVersion() {
|
||||
return g_firmware_version.display_version;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,6 +17,9 @@
|
||||
#include <haze/console_main_loop.hpp>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
/* Load device firmware version and serial number. */
|
||||
HAZE_R_ABORT_UNLESS(haze::LoadDeviceProperties());
|
||||
|
||||
/* Run the application. */
|
||||
haze::ConsoleMainLoop::RunApplication();
|
||||
|
||||
|
||||
@@ -304,16 +304,6 @@ namespace haze {
|
||||
Result PtpResponder::GetDeviceInfo(PtpDataParser &dp) {
|
||||
PtpDataBuilder db(g_bulk_write_buffer, std::addressof(m_usb_server));
|
||||
|
||||
/* Initialize set:sys, ensuring we clean up on exit. */
|
||||
R_TRY(setsysInitialize());
|
||||
ON_SCOPE_EXIT { setsysExit(); };
|
||||
|
||||
/* Get the device version and serial number. */
|
||||
SetSysFirmwareVersion version;
|
||||
SetSysSerialNumber serial;
|
||||
R_TRY(setsysGetFirmwareVersion(std::addressof(version)));
|
||||
R_TRY(setsysGetSerialNumber(std::addressof(serial)));
|
||||
|
||||
/* Write the device info data. */
|
||||
R_TRY(db.WriteVariableLengthData(m_request_header, [&] () {
|
||||
R_TRY(db.Add(MtpStandardVersion));
|
||||
@@ -328,8 +318,8 @@ namespace haze {
|
||||
R_TRY(db.AddArray(SupportedPlaybackFormats, util::size(SupportedPlaybackFormats)));
|
||||
R_TRY(db.AddString(MtpDeviceManufacturer));
|
||||
R_TRY(db.AddString(MtpDeviceModel));
|
||||
R_TRY(db.AddString(version.display_version));
|
||||
R_TRY(db.AddString(serial.number));
|
||||
R_TRY(db.AddString(GetFirmwareVersion()));
|
||||
R_TRY(db.AddString(GetSerialNumber()));
|
||||
|
||||
R_SUCCEED();
|
||||
}));
|
||||
@@ -732,7 +722,9 @@ namespace haze {
|
||||
R_TRY(m_fs.SetFileSize(std::addressof(file), 0));
|
||||
|
||||
/* Expand to the needed size. */
|
||||
R_TRY(m_fs.SetFileSize(std::addressof(file), data_header.length));
|
||||
if (data_header.length > sizeof(PtpUsbBulkContainer)) {
|
||||
R_TRY(m_fs.SetFileSize(std::addressof(file), data_header.length - sizeof(PtpUsbBulkContainer)));
|
||||
}
|
||||
|
||||
/* Begin writing to the filesystem. */
|
||||
while (true) {
|
||||
@@ -753,6 +745,9 @@ namespace haze {
|
||||
R_TRY(read_res);
|
||||
}
|
||||
|
||||
/* Truncate the file to the received size. */
|
||||
R_TRY(m_fs.SetFileSize(std::addressof(file), offset));
|
||||
|
||||
/* Write the success response. */
|
||||
R_RETURN(this->WriteResponse(PtpResponseCode_Ok));
|
||||
}
|
||||
|
||||
@@ -165,19 +165,11 @@ namespace haze {
|
||||
static const u16 supported_langs[1] = { 0x0409 };
|
||||
R_TRY(usbDsAddUsbLanguageStringDescriptor(nullptr, supported_langs, util::size(supported_langs)));
|
||||
|
||||
/* Initialize set:sys, ensuring we clean up on exit. */
|
||||
R_TRY(setsysInitialize());
|
||||
ON_SCOPE_EXIT { setsysExit(); };
|
||||
|
||||
/* Get the device serial number. */
|
||||
SetSysSerialNumber serial;
|
||||
R_TRY(setsysGetSerialNumber(std::addressof(serial)));
|
||||
|
||||
/* Report strings. */
|
||||
u8 iManufacturer, iProduct, iSerialNumber;
|
||||
R_TRY(usbDsAddUsbStringDescriptor(std::addressof(iManufacturer), "Nintendo"));
|
||||
R_TRY(usbDsAddUsbStringDescriptor(std::addressof(iProduct), "Nintendo Switch"));
|
||||
R_TRY(usbDsAddUsbStringDescriptor(std::addressof(iSerialNumber), serial.number));
|
||||
R_TRY(usbDsAddUsbStringDescriptor(std::addressof(iSerialNumber), GetSerialNumber()));
|
||||
|
||||
/* Send device descriptors */
|
||||
struct usb_device_descriptor device_descriptor = {
|
||||
|
||||
Reference in New Issue
Block a user