Compare commits
68 Commits
mesosphere
...
mariko_boo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e6bddf8782 | ||
|
|
d8bd3d16bb | ||
|
|
80f567d46a | ||
|
|
b6580b3170 | ||
|
|
df8ceb9b06 | ||
|
|
c5656d39d2 | ||
|
|
62ff502979 | ||
|
|
f135ee74f8 | ||
|
|
8c3e536e94 | ||
|
|
35573c4d85 | ||
|
|
e6ef753bb6 | ||
|
|
eade15b34e | ||
|
|
b9c5dab18a | ||
|
|
d0a45b8f21 | ||
|
|
e0ce035323 | ||
|
|
2562700f34 | ||
|
|
e93c3cbf58 | ||
|
|
cd7d7894f1 | ||
|
|
aa63b1eab7 | ||
|
|
4cc4f5fdb0 | ||
|
|
22ae1d5bd3 | ||
|
|
43f7b10c0f | ||
|
|
48784da42a | ||
|
|
f27d6f2fd8 | ||
|
|
6f7502dfef | ||
|
|
2d2b11a2d2 | ||
|
|
2744a614de | ||
|
|
27be1a548c | ||
|
|
91b2a233c4 | ||
|
|
7636dd2d44 | ||
|
|
c867975eb8 | ||
|
|
5bc4abb92f | ||
|
|
e1dccef7d1 | ||
|
|
17fa05a789 | ||
|
|
5b617f4d2f | ||
|
|
d2e530c2aa | ||
|
|
166318ba77 | ||
|
|
ac04e02a08 | ||
|
|
1c71d12d9d | ||
|
|
37738699f2 | ||
|
|
e973ef7533 | ||
|
|
2ee2a4f1ac | ||
|
|
2a2bffeb35 | ||
|
|
d04046ecaf | ||
|
|
f24171dc41 | ||
|
|
5b02c77400 | ||
|
|
2e7214b6fa | ||
|
|
d52179c708 | ||
|
|
388f9e6455 | ||
|
|
c547c7f0e7 | ||
|
|
4138abbefa | ||
|
|
1275eb0bf3 | ||
|
|
5ac9e45d86 | ||
|
|
feba788bc6 | ||
|
|
f4d10a4481 | ||
|
|
ff310a0647 | ||
|
|
85505db9b7 | ||
|
|
48b4dd48a4 | ||
|
|
8d46d901d9 | ||
|
|
1930880270 | ||
|
|
fa0df994ba | ||
|
|
909a1767a6 | ||
|
|
dbe59fd041 | ||
|
|
9b65daf439 | ||
|
|
4acdc899f5 | ||
|
|
76957e502d | ||
|
|
909397233c | ||
|
|
211a828730 |
10
Makefile
10
Makefile
@@ -70,8 +70,8 @@ dist-no-debug: all
|
|||||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/config
|
mkdir -p atmosphere-$(AMSVER)/atmosphere/config
|
||||||
cp fusee/fusee-primary/fusee-primary.bin atmosphere-$(AMSVER)/atmosphere/reboot_payload.bin
|
cp fusee/fusee-primary/fusee-primary.bin atmosphere-$(AMSVER)/atmosphere/reboot_payload.bin
|
||||||
cp fusee/fusee-mtc/fusee-mtc.bin atmosphere-$(AMSVER)/atmosphere/fusee-mtc.bin
|
cp fusee/fusee-mtc/fusee-mtc.bin atmosphere-$(AMSVER)/atmosphere/fusee-mtc.bin
|
||||||
cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/atmosphere/fusee-secondary.bin
|
cp fusee/fusee-secondary/fusee-secondary-experimental.bin atmosphere-$(AMSVER)/atmosphere/fusee-secondary.bin
|
||||||
cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/sept/payload.bin
|
cp fusee/fusee-secondary/fusee-secondary-experimental.bin atmosphere-$(AMSVER)/sept/payload.bin
|
||||||
cp sept/sept-primary/sept-primary.bin atmosphere-$(AMSVER)/sept/sept-primary.bin
|
cp sept/sept-primary/sept-primary.bin atmosphere-$(AMSVER)/sept/sept-primary.bin
|
||||||
cp sept/sept-secondary/sept-secondary.bin atmosphere-$(AMSVER)/sept/sept-secondary.bin
|
cp sept/sept-secondary/sept-secondary.bin atmosphere-$(AMSVER)/sept/sept-secondary.bin
|
||||||
cp sept/sept-secondary/sept-secondary_00.enc atmosphere-$(AMSVER)/sept/sept-secondary_00.enc
|
cp sept/sept-secondary/sept-secondary_00.enc atmosphere-$(AMSVER)/sept/sept-secondary_00.enc
|
||||||
@@ -99,9 +99,13 @@ dist-no-debug: all
|
|||||||
touch atmosphere-$(AMSVER)/atmosphere/contents/0100000000000037/flags/boot2.flag
|
touch atmosphere-$(AMSVER)/atmosphere/contents/0100000000000037/flags/boot2.flag
|
||||||
cp troposphere/reboot_to_payload/reboot_to_payload.nro atmosphere-$(AMSVER)/switch/reboot_to_payload.nro
|
cp troposphere/reboot_to_payload/reboot_to_payload.nro atmosphere-$(AMSVER)/switch/reboot_to_payload.nro
|
||||||
cp troposphere/daybreak/daybreak.nro atmosphere-$(AMSVER)/switch/daybreak.nro
|
cp troposphere/daybreak/daybreak.nro atmosphere-$(AMSVER)/switch/daybreak.nro
|
||||||
|
cd atmosphere-$(AMSVER); zip -r ../atmosphere-EXPERIMENTAL-$(AMSVER).zip ./*; cd ../;
|
||||||
|
cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/atmosphere/fusee-secondary.bin
|
||||||
|
cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/sept/payload.bin
|
||||||
cd atmosphere-$(AMSVER); zip -r ../atmosphere-$(AMSVER).zip ./*; cd ../;
|
cd atmosphere-$(AMSVER); zip -r ../atmosphere-$(AMSVER).zip ./*; cd ../;
|
||||||
rm -r atmosphere-$(AMSVER)
|
rm -r atmosphere-$(AMSVER)
|
||||||
mkdir out
|
mkdir out
|
||||||
|
mv atmosphere-EXPERIMENTAL-$(AMSVER).zip out/atmosphere-EXPERIMENTAL-$(AMSVER).zip
|
||||||
mv atmosphere-$(AMSVER).zip out/atmosphere-$(AMSVER).zip
|
mv atmosphere-$(AMSVER).zip out/atmosphere-$(AMSVER).zip
|
||||||
cp fusee/fusee-primary/fusee-primary.bin out/fusee-primary.bin
|
cp fusee/fusee-primary/fusee-primary.bin out/fusee-primary.bin
|
||||||
|
|
||||||
@@ -120,7 +124,7 @@ dist: dist-no-debug
|
|||||||
mkdir atmosphere-$(AMSVER)-debug
|
mkdir atmosphere-$(AMSVER)-debug
|
||||||
cp fusee/fusee-primary/fusee-primary.elf atmosphere-$(AMSVER)-debug/fusee-primary.elf
|
cp fusee/fusee-primary/fusee-primary.elf atmosphere-$(AMSVER)-debug/fusee-primary.elf
|
||||||
cp fusee/fusee-mtc/fusee-mtc.elf atmosphere-$(AMSVER)-debug/fusee-mtc.elf
|
cp fusee/fusee-mtc/fusee-mtc.elf atmosphere-$(AMSVER)-debug/fusee-mtc.elf
|
||||||
cp fusee/fusee-secondary/fusee-secondary.elf atmosphere-$(AMSVER)-debug/fusee-secondary.elf
|
cp fusee/fusee-secondary/fusee-secondary-experimental.elf atmosphere-$(AMSVER)-debug/fusee-secondary.elf
|
||||||
cp sept/sept-primary/sept-primary.elf atmosphere-$(AMSVER)-debug/sept-primary.elf
|
cp sept/sept-primary/sept-primary.elf atmosphere-$(AMSVER)-debug/sept-primary.elf
|
||||||
cp sept/sept-secondary/sept-secondary.elf atmosphere-$(AMSVER)-debug/sept-secondary.elf
|
cp sept/sept-secondary/sept-secondary.elf atmosphere-$(AMSVER)-debug/sept-secondary.elf
|
||||||
cp sept/sept-secondary/key_derivation/key_derivation.elf atmosphere-$(AMSVER)-debug/sept-secondary-key-derivation.elf
|
cp sept/sept-secondary/key_derivation/key_derivation.elf atmosphere-$(AMSVER)-debug/sept-secondary-key-derivation.elf
|
||||||
|
|||||||
@@ -9,4 +9,4 @@ stage2_entrypoint = 0xF0000000
|
|||||||
; To force-enable nogc, add nogc = 1
|
; To force-enable nogc, add nogc = 1
|
||||||
; To force-disable nogc, add nogc = 0
|
; To force-disable nogc, add nogc = 0
|
||||||
|
|
||||||
; To opt in to using Atmosphere's NCM reimplementation, add enable_ncm = 1
|
; To opt out of using Atmosphere's NCM reimplementation, add disable_ncm = 1
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ Building Atmosphère is a very straightforward process that relies almost exclus
|
|||||||
## Dependencies
|
## Dependencies
|
||||||
+ [devkitA64](https://devkitpro.org)
|
+ [devkitA64](https://devkitpro.org)
|
||||||
+ [devkitARM](https://devkitpro.org)
|
+ [devkitARM](https://devkitpro.org)
|
||||||
+ [Python 2 or 3](https://www.python.org) (optional)
|
+ [Python 2](https://www.python.org) (Python 3 may work as well, but this is not guaranteed)
|
||||||
+ [PyCryptodome](https://pypi.org/project/pycryptodome) (optional)
|
+ [PyCryptodome](https://pypi.org/project/pycryptodome) (optional)
|
||||||
|
|
||||||
## Instructions
|
## Instructions
|
||||||
|
|||||||
@@ -1,4 +1,39 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
## 0.15.0
|
||||||
|
+ fusee-primary's panic display was updated to automatically identify and give suggestions to resolve many of the most common errors users encounter.
|
||||||
|
+ Having been tested as well as I can alone, `mesosphere` (atmosphère's reimplementation of the Nintendo Switch kernel) is now available for users interested in trying it.
|
||||||
|
+ Beginning in this release and until it is stable and well-tested, atmosphère will distribute two zips.
|
||||||
|
+ Users who wish to opt-in to mesosphere should download and extract the "cool kids" zip ("atmosphere-EXPERIMENTAL-").
|
||||||
|
+ Users who do not wish to use mesosphere should continue using the normal zip ("atmosphere-").
|
||||||
|
+ Users may detect whether mesosphere is active in system settings.
|
||||||
|
+ When mesosphere is active, the system version string will display "M.15.0" rather than "0.15.0", and so on for future releases.
|
||||||
|
+ Crash reports and the like will contain information on whether or not the user is using mesosphere, as well.
|
||||||
|
+ There are "probably" no material user-facing benefits to using mesosphere at this time.
|
||||||
|
+ Developers may be interested in the fact that mesosphere provides many newer SVC APIs even when on lower firmware versions.
|
||||||
|
+ The primary benefit to using mesosphere is that any issues you may encounter and report to me will be fixed.
|
||||||
|
+ All users who choose to opt in to using mesosphere have my deepest gratitude.
|
||||||
|
+ **Note:** If using hekate instead of fusee-primary, you will have to wait for the next hekate release for mesosphere to function, as hekate's support has not yet been included in an official release build.
|
||||||
|
+ This will be updated in the release notes when hekate provides a new release.
|
||||||
|
+ As mentioned in previous release notes, when mesosphere is stable and well-tested, it will be enabled by default and atmosphère's version will transition to 1.0.0.
|
||||||
|
+ Having been tested sufficiently over the last half-year, Atmosphere's NCM implementation is now opt-out, rather than opt in.
|
||||||
|
+ In the unlikely event that any issues are encountered, please report them to @SciresM.
|
||||||
|
+ Users interested in opting out of using our implementation should set `stratosphere!disable_ncm = 1` in BCT.ini.
|
||||||
|
+ The NCM implementation will stop being opt-out in a future update, probably around the same time that mesosphere becomes opt-out instead of opt-in.
|
||||||
|
+ Several bugs were fixed, including:
|
||||||
|
+ Loader now sets HBL's thread priority to a higher value when loading it in applet mode.
|
||||||
|
+ This fixes an extremely-slow launch ("hang") when using applet-HBL with certain games that do not suspend while inactive (e.g. Super Mario Sunshine).
|
||||||
|
+ set.mitm now caches user language configuration much more heavily.
|
||||||
|
+ This severely reduces lag in certain games which misuse the "nn::oe::GetDesiredLanguage()" API.
|
||||||
|
+ A bug was fixed that could cause erpt to fatal when loading an official save file that had error report attachments in it.
|
||||||
|
+ General system stability improvements to enhance the user's experience.
|
||||||
|
## 0.14.4
|
||||||
|
+ Several bugs were fixed involving the official jit sysmodule added in 10.0.0.
|
||||||
|
+ A Process handle leak was fixed when JitPlugin NRRs were registered with the `ro` sysmodule.
|
||||||
|
+ This prevented processes using jit from being able to exit, causing a full system freeze.
|
||||||
|
+ The `sm` atmosphere extension to not unregister services when the server's connection is closed was special-case disabled for `jit:u`.
|
||||||
|
+ This extension is normally desirable in order to allow more concurrent processes to exist (as only 0x40 sm connections may ever be concurrently open), but official jit sysmodule relies on the behavior.
|
||||||
|
+ This would cause crashes on attempts to launch a program using jit services more than once per reboot.
|
||||||
|
+ General system stability improvements to enhance the user's experience.
|
||||||
## 0.14.3
|
## 0.14.3
|
||||||
+ Support was added for 10.2.0.
|
+ Support was added for 10.2.0.
|
||||||
+ General system stability improvements to enhance the user's experience.
|
+ General system stability improvements to enhance the user's experience.
|
||||||
|
|||||||
@@ -29,11 +29,11 @@ nogc = X
|
|||||||
0 = force-disable nogc, so Atmosphère will always enable the Game Card reader.
|
0 = force-disable nogc, so Atmosphère will always enable the Game Card reader.
|
||||||
```
|
```
|
||||||
|
|
||||||
### NCM opt-in
|
### NCM opt-out
|
||||||
Atmosphère provides a reimplementation of the [ncm](../components/modules/ncm.md) system module, but currently this is not enabled by default. If you wish to enable this reimplementation add the following line to the `stratosphere` section:
|
Atmosphère provides a reimplementation of the [ncm](../components/modules/ncm.md) system module. If you wish to disable this reimplementation add the following line to the `stratosphere` section:
|
||||||
```
|
```
|
||||||
[stratosphere]
|
[stratosphere]
|
||||||
enable_ncm = 1
|
disable_ncm = 1
|
||||||
```
|
```
|
||||||
|
|
||||||
### Logging
|
### Logging
|
||||||
|
|||||||
@@ -96,10 +96,6 @@ namespace ams::secmon {
|
|||||||
util::ClearMemory(reinterpret_cast<void *>(address + size / 2), size / 2);
|
util::ClearMemory(reinterpret_cast<void *>(address + size / 2), size / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsPhysicalMemoryAddress(uintptr_t address) {
|
|
||||||
return (address - MemoryRegionDram.GetAddress()) < GetPhysicalMemorySize();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClearBootCodeHigh() {
|
void ClearBootCodeHigh() {
|
||||||
@@ -130,6 +126,10 @@ namespace ams::secmon {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsPhysicalMemoryAddress(uintptr_t address) {
|
||||||
|
return (address - MemoryRegionDram.GetAddress()) < GetPhysicalMemorySize();
|
||||||
|
}
|
||||||
|
|
||||||
void UnmapTzram() {
|
void UnmapTzram() {
|
||||||
/* Get the tables. */
|
/* Get the tables. */
|
||||||
u64 * const l1 = MemoryRegionVirtualTzramL1PageTable.GetPointer<u64>();
|
u64 * const l1 = MemoryRegionVirtualTzramL1PageTable.GetPointer<u64>();
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
namespace ams::secmon {
|
namespace ams::secmon {
|
||||||
|
|
||||||
|
bool IsPhysicalMemoryAddress(uintptr_t address);
|
||||||
size_t GetPhysicalMemorySize();
|
size_t GetPhysicalMemorySize();
|
||||||
|
|
||||||
void UnmapTzram();
|
void UnmapTzram();
|
||||||
|
|||||||
@@ -648,7 +648,7 @@ namespace ams::secmon {
|
|||||||
reg::Read (MC + MC_SMMU_TLB_CONFIG);
|
reg::Read (MC + MC_SMMU_TLB_CONFIG);
|
||||||
|
|
||||||
/* Flush the entire page table cache, and read TLB_CONFIG to ensure the flush takes. */
|
/* Flush the entire page table cache, and read TLB_CONFIG to ensure the flush takes. */
|
||||||
reg::Write(MC + MC_SMMU_PTC_FLUSH, 0);
|
reg::Write(MC + MC_SMMU_PTC_FLUSH_0, 0);
|
||||||
reg::Read (MC + MC_SMMU_TLB_CONFIG);
|
reg::Read (MC + MC_SMMU_TLB_CONFIG);
|
||||||
|
|
||||||
/* Flush the entire translation lookaside buffer, and read TLB_CONFIG to ensure the flush takes. */
|
/* Flush the entire translation lookaside buffer, and read TLB_CONFIG to ensure the flush takes. */
|
||||||
@@ -907,7 +907,7 @@ namespace ams::secmon {
|
|||||||
reg::Write(MC + MC_SMMU_PPCS1_ASID, MC_REG_BITS_ENUM(SMMU_PPCS1_ASID_PPCS1_SMMU_ENABLE, ENABLE), MC_REG_BITS_VALUE(SMMU_PPCS1_ASID_PPCS1_ASID, BpmpAsid));
|
reg::Write(MC + MC_SMMU_PPCS1_ASID, MC_REG_BITS_ENUM(SMMU_PPCS1_ASID_PPCS1_SMMU_ENABLE, ENABLE), MC_REG_BITS_VALUE(SMMU_PPCS1_ASID_PPCS1_ASID, BpmpAsid));
|
||||||
|
|
||||||
/* Flush the entire page table cache, and read TLB_CONFIG to ensure the flush takes. */
|
/* Flush the entire page table cache, and read TLB_CONFIG to ensure the flush takes. */
|
||||||
reg::Write(MC + MC_SMMU_PTC_FLUSH, 0);
|
reg::Write(MC + MC_SMMU_PTC_FLUSH_0, 0);
|
||||||
reg::Read (MC + MC_SMMU_TLB_CONFIG);
|
reg::Read (MC + MC_SMMU_TLB_CONFIG);
|
||||||
|
|
||||||
/* Flush the entire translation lookaside buffer, and read TLB_CONFIG to ensure the flush takes. */
|
/* Flush the entire translation lookaside buffer, and read TLB_CONFIG to ensure the flush takes. */
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ SetRegisterAllowed(MC_SMMU_CONFIG); /* 0x010 */
|
|||||||
SetRegisterAllowed(MC_SMMU_PTB_ASID); /* 0x01C */
|
SetRegisterAllowed(MC_SMMU_PTB_ASID); /* 0x01C */
|
||||||
SetRegisterAllowed(MC_SMMU_PTB_DATA); /* 0x020 */
|
SetRegisterAllowed(MC_SMMU_PTB_DATA); /* 0x020 */
|
||||||
SetRegisterAllowed(MC_SMMU_TLB_FLUSH); /* 0x030 */
|
SetRegisterAllowed(MC_SMMU_TLB_FLUSH); /* 0x030 */
|
||||||
SetRegisterAllowed(MC_SMMU_PTC_FLUSH); /* 0x034 */
|
SetRegisterAllowed(MC_SMMU_PTC_FLUSH_0); /* 0x034 */
|
||||||
SetRegisterAllowed(MC_EMEM_CFG); /* 0x050 */
|
SetRegisterAllowed(MC_EMEM_CFG); /* 0x050 */
|
||||||
SetRegisterAllowed(MC_EMEM_ADR_CFG); /* 0x054 */
|
SetRegisterAllowed(MC_EMEM_ADR_CFG); /* 0x054 */
|
||||||
SetRegisterAllowed(MC_EMEM_ARB_CFG); /* 0x090 */
|
SetRegisterAllowed(MC_EMEM_ARB_CFG); /* 0x090 */
|
||||||
@@ -53,7 +53,7 @@ SetRegisterAllowed(MC_SMMU_DCB_ASID); /* 0x244 */
|
|||||||
SetRegisterAllowed(MC_SMMU_HC_ASID); /* 0x250 */
|
SetRegisterAllowed(MC_SMMU_HC_ASID); /* 0x250 */
|
||||||
SetRegisterAllowed(MC_SMMU_HDA_ASID); /* 0x254 */
|
SetRegisterAllowed(MC_SMMU_HDA_ASID); /* 0x254 */
|
||||||
SetRegisterAllowed(MC_SMMU_ISP2_ASID); /* 0x258 */
|
SetRegisterAllowed(MC_SMMU_ISP2_ASID); /* 0x258 */
|
||||||
SetRegisterAllowed(MC_SMMU_NVENC_ASID); /* 0x264 */
|
SetRegisterAllowed(MC_SMMU_MSENC_NVENC_ASID); /* 0x264 */
|
||||||
SetRegisterAllowed(MC_SMMU_NV_ASID); /* 0x268 */
|
SetRegisterAllowed(MC_SMMU_NV_ASID); /* 0x268 */
|
||||||
SetRegisterAllowed(MC_SMMU_NV2_ASID); /* 0x26C */
|
SetRegisterAllowed(MC_SMMU_NV2_ASID); /* 0x26C */
|
||||||
SetRegisterAllowed(MC_SMMU_PPCS_ASID); /* 0x270 */
|
SetRegisterAllowed(MC_SMMU_PPCS_ASID); /* 0x270 */
|
||||||
|
|||||||
@@ -141,6 +141,9 @@ namespace ams::secmon::smc {
|
|||||||
{ 0xC3000006, Restriction_Normal, SmcShowError },
|
{ 0xC3000006, Restriction_Normal, SmcShowError },
|
||||||
{ 0xC3000007, Restriction_Normal, SmcSetKernelCarveoutRegion },
|
{ 0xC3000007, Restriction_Normal, SmcSetKernelCarveoutRegion },
|
||||||
{ 0xC3000008, Restriction_Normal, SmcReadWriteRegister },
|
{ 0xC3000008, Restriction_Normal, SmcReadWriteRegister },
|
||||||
|
|
||||||
|
/* NOTE: Atmosphere extension for mesosphere. This ID is subject to change at any time. */
|
||||||
|
{ 0xC3000409, Restriction_Normal, SmcSetConfig },
|
||||||
};
|
};
|
||||||
|
|
||||||
constinit HandlerInfo g_ams_handlers[] = {
|
constinit HandlerInfo g_ams_handlers[] = {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
#include <exosphere.hpp>
|
#include <exosphere.hpp>
|
||||||
#include "../secmon_error.hpp"
|
#include "../secmon_error.hpp"
|
||||||
|
#include "../secmon_map.hpp"
|
||||||
#include "../secmon_misc.hpp"
|
#include "../secmon_misc.hpp"
|
||||||
#include "../secmon_page_mapper.hpp"
|
#include "../secmon_page_mapper.hpp"
|
||||||
#include "../secmon_user_power_management.hpp"
|
#include "../secmon_user_power_management.hpp"
|
||||||
@@ -157,6 +158,8 @@ namespace ams::secmon::smc {
|
|||||||
return value.value;
|
return value.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constinit u64 g_payload_address = 0;
|
||||||
|
|
||||||
SmcResult GetConfig(SmcArguments &args, bool kern) {
|
SmcResult GetConfig(SmcArguments &args, bool kern) {
|
||||||
switch (static_cast<ConfigItem>(args.r[1])) {
|
switch (static_cast<ConfigItem>(args.r[1])) {
|
||||||
case ConfigItem::DisableProgramVerification:
|
case ConfigItem::DisableProgramVerification:
|
||||||
@@ -267,6 +270,14 @@ namespace ams::secmon::smc {
|
|||||||
/* NOTE: This may return values other than 1 in the future. */
|
/* NOTE: This may return values other than 1 in the future. */
|
||||||
args.r[1] = (GetEmummcConfiguration().IsEmummcActive() ? 1 : 0);
|
args.r[1] = (GetEmummcConfiguration().IsEmummcActive() ? 1 : 0);
|
||||||
break;
|
break;
|
||||||
|
case ConfigItem::ExospherePayloadAddress:
|
||||||
|
/* Gets the physical address of the reboot payload buffer, if one exists. */
|
||||||
|
if (g_payload_address != 0) {
|
||||||
|
args.r[1] = g_payload_address;
|
||||||
|
} else {
|
||||||
|
return SmcResult::NotInitialized;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return SmcResult::InvalidArgument;
|
return SmcResult::InvalidArgument;
|
||||||
}
|
}
|
||||||
@@ -309,6 +320,17 @@ namespace ams::secmon::smc {
|
|||||||
return SmcResult::NotImplemented;
|
return SmcResult::NotImplemented;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ConfigItem::ExospherePayloadAddress:
|
||||||
|
if (g_payload_address == 0) {
|
||||||
|
if (secmon::IsPhysicalMemoryAddress(args.r[2])) {
|
||||||
|
g_payload_address = args.r[2];
|
||||||
|
} else {
|
||||||
|
return SmcResult::InvalidArgument;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return SmcResult::Busy;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return SmcResult::InvalidArgument;
|
return SmcResult::InvalidArgument;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ namespace ams::secmon::smc {
|
|||||||
ExosphereBlankProdInfo = 65005,
|
ExosphereBlankProdInfo = 65005,
|
||||||
ExosphereAllowCalWrites = 65006,
|
ExosphereAllowCalWrites = 65006,
|
||||||
ExosphereEmummcType = 65007,
|
ExosphereEmummcType = 65007,
|
||||||
|
ExospherePayloadAddress = 65008,
|
||||||
};
|
};
|
||||||
|
|
||||||
SmcResult SmcGetConfigUser(SmcArguments &args);
|
SmcResult SmcGetConfigUser(SmcArguments &args);
|
||||||
|
|||||||
108
exosphere/sdmmc_test/Makefile
Normal file
108
exosphere/sdmmc_test/Makefile
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# Define the atmosphere board and cpu
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
export ATMOSPHERE_BOARD := nx-hac-001
|
||||||
|
export ATMOSPHERE_CPU := arm7tdmi
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# pull in common atmosphere configuration
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../../libraries/config/templates/exosphere.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 DEPSDIR := $(CURDIR)/$(BUILD)
|
||||||
|
|
||||||
|
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||||
|
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
||||||
|
|
||||||
|
CFILES := $(call FIND_SOURCE_FILES,$(SOURCES),c)
|
||||||
|
CPPFILES := $(call FIND_SOURCE_FILES,$(SOURCES),cpp)
|
||||||
|
SFILES := $(call FIND_SOURCE_FILES,$(SOURCES),s)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# use CXX for linking C++ projects, CC for standard C
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
ifeq ($(strip $(CPPFILES)),)
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
export LD := $(CC)
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
else
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
export LD := $(CXX)
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
endif
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
|
||||||
|
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||||
|
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
|
||||||
|
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(subst -,_,$(BINFILES))))
|
||||||
|
|
||||||
|
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||||
|
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||||
|
-I.
|
||||||
|
|
||||||
|
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib -L$(dir)/$(ATMOSPHERE_LIBRARY_DIR))
|
||||||
|
|
||||||
|
.PHONY: $(BUILD) clean all
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
all: $(BUILD) check_libexo
|
||||||
|
|
||||||
|
$(BUILD): check_libexo
|
||||||
|
@[ -d $@ ] || mkdir -p $@
|
||||||
|
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||||
|
|
||||||
|
check_libexo:
|
||||||
|
@$(MAKE) --no-print-directory -C ../../libraries/libexosphere arm
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
clean:
|
||||||
|
@echo clean ...
|
||||||
|
@rm -fr $(BUILD) $(OUTPUT).bin $(OUTPUT).elf *.lz4
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
else
|
||||||
|
.PHONY: all
|
||||||
|
|
||||||
|
DEPENDS := $(OFILES:.o=.d)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# main targets
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
all : $(OUTPUT).bin
|
||||||
|
|
||||||
|
$(OUTPUT).bin : $(OUTPUT).elf
|
||||||
|
$(OBJCOPY) -S -O binary --set-section-flags .bss=alloc,load,contents $< $@
|
||||||
|
@echo built ... $(notdir $@)
|
||||||
|
|
||||||
|
$(OUTPUT).elf : $(OFILES) ../../../libraries/libexosphere/$(ATMOSPHERE_LIBRARY_DIR)/libexosphere.a
|
||||||
|
|
||||||
|
%.elf:
|
||||||
|
@echo linking $(notdir $@)
|
||||||
|
$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@
|
||||||
|
@$(NM) -CSn $@ > $(notdir $*.lst)
|
||||||
|
|
||||||
|
$(OFILES_SRC) : $(HFILES_BIN)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# you need a rule like this for each extension you use as binary data
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
%.bin.o %_bin.h: %.bin
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
@echo $(notdir $<)
|
||||||
|
@$(bin2o)
|
||||||
|
|
||||||
|
-include $(DEPENDS)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------------
|
||||||
|
endif
|
||||||
|
#---------------------------------------------------------------------------------------
|
||||||
194
exosphere/sdmmc_test/sdmmc_test.ld
Normal file
194
exosphere/sdmmc_test/sdmmc_test.ld
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
OUTPUT_ARCH(arm)
|
||||||
|
ENTRY(_ZN3ams10sdmmc_test5StartEv)
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
NULL : ORIGIN = 0, LENGTH = 4K
|
||||||
|
test_fw : ORIGIN = 0x40010000, LENGTH = 32K
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
/* =========== CODE section =========== */
|
||||||
|
PROVIDE(__start__ = ORIGIN(test_fw));
|
||||||
|
. = __start__;
|
||||||
|
__code_start = . ;
|
||||||
|
|
||||||
|
.crt0 :
|
||||||
|
{
|
||||||
|
KEEP (*(.crt0 .crt0.*))
|
||||||
|
. = ALIGN(8);
|
||||||
|
} >test_fw
|
||||||
|
|
||||||
|
.vectors :
|
||||||
|
{
|
||||||
|
KEEP (*(.vectors .vectors.*))
|
||||||
|
. = ALIGN(8);
|
||||||
|
} >test_fw
|
||||||
|
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
|
||||||
|
*(.text.exit .text.exit.*)
|
||||||
|
*(.text.startup .text.startup.*)
|
||||||
|
*(.text.hot .text.hot.*)
|
||||||
|
*(.text .stub .text.* .gnu.linkonce.t.*)
|
||||||
|
. = ALIGN(8);
|
||||||
|
} >test_fw
|
||||||
|
|
||||||
|
.init :
|
||||||
|
{
|
||||||
|
KEEP( *(.init) )
|
||||||
|
. = ALIGN(8);
|
||||||
|
} >test_fw
|
||||||
|
|
||||||
|
.plt :
|
||||||
|
{
|
||||||
|
*(.plt)
|
||||||
|
*(.iplt)
|
||||||
|
. = ALIGN(8);
|
||||||
|
} >test_fw
|
||||||
|
|
||||||
|
.fini :
|
||||||
|
{
|
||||||
|
KEEP( *(.fini) )
|
||||||
|
. = ALIGN(8);
|
||||||
|
} >test_fw
|
||||||
|
|
||||||
|
|
||||||
|
/* =========== RODATA section =========== */
|
||||||
|
. = ALIGN(8);
|
||||||
|
__rodata_start = . ;
|
||||||
|
|
||||||
|
.rodata :
|
||||||
|
{
|
||||||
|
*(.rodata .rodata.* .gnu.linkonce.r.*)
|
||||||
|
. = ALIGN(8);
|
||||||
|
} >test_fw
|
||||||
|
|
||||||
|
.eh_frame_hdr : { __eh_frame_hdr_start = .; *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) __eh_frame_hdr_end = .; } >test_fw
|
||||||
|
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) } >test_fw
|
||||||
|
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } >test_fw
|
||||||
|
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } >test_fw
|
||||||
|
|
||||||
|
.hash : { *(.hash) } >test_fw
|
||||||
|
|
||||||
|
/* =========== DATA section =========== */
|
||||||
|
. = ALIGN(8);
|
||||||
|
__data_start = . ;
|
||||||
|
|
||||||
|
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) } >test_fw
|
||||||
|
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } >test_fw
|
||||||
|
.gnu_extab : ONLY_IF_RW { *(.gnu_extab*) } >test_fw
|
||||||
|
.exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) } >test_fw
|
||||||
|
|
||||||
|
.preinit_array ALIGN(8) :
|
||||||
|
{
|
||||||
|
PROVIDE (__preinit_array_start = .);
|
||||||
|
KEEP (*(.preinit_array))
|
||||||
|
PROVIDE (__preinit_array_end = .);
|
||||||
|
} >test_fw
|
||||||
|
|
||||||
|
.init_array ALIGN(8) :
|
||||||
|
{
|
||||||
|
PROVIDE (__init_array_start = .);
|
||||||
|
KEEP (*(SORT(.init_array.*)))
|
||||||
|
KEEP (*(.init_array))
|
||||||
|
PROVIDE (__init_array_end = .);
|
||||||
|
} >test_fw
|
||||||
|
|
||||||
|
.fini_array ALIGN(8) :
|
||||||
|
{
|
||||||
|
PROVIDE (__fini_array_start = .);
|
||||||
|
KEEP (*(.fini_array))
|
||||||
|
KEEP (*(SORT(.fini_array.*)))
|
||||||
|
PROVIDE (__fini_array_end = .);
|
||||||
|
} >test_fw
|
||||||
|
|
||||||
|
.ctors ALIGN(8) :
|
||||||
|
{
|
||||||
|
KEEP (*crtbegin.o(.ctors)) /* MUST be first -- GCC requires it */
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||||
|
KEEP (*(SORT(.ctors.*)))
|
||||||
|
KEEP (*(.ctors))
|
||||||
|
} >test_fw
|
||||||
|
|
||||||
|
.dtors ALIGN(8) :
|
||||||
|
{
|
||||||
|
KEEP (*crtbegin.o(.dtors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||||
|
KEEP (*(SORT(.dtors.*)))
|
||||||
|
KEEP (*(.dtors))
|
||||||
|
} >test_fw
|
||||||
|
|
||||||
|
__got_start__ = .;
|
||||||
|
|
||||||
|
.got : { *(.got) *(.igot) } >test_fw
|
||||||
|
.got.plt : { *(.got.plt) *(.igot.plt) } >test_fw
|
||||||
|
|
||||||
|
__got_end__ = .;
|
||||||
|
|
||||||
|
.data ALIGN(8) :
|
||||||
|
{
|
||||||
|
*(.data .data.* .gnu.linkonce.d.*)
|
||||||
|
SORT(CONSTRUCTORS)
|
||||||
|
} >test_fw
|
||||||
|
|
||||||
|
__bss_start__ = .;
|
||||||
|
.bss ALIGN(8) :
|
||||||
|
{
|
||||||
|
*(.dynbss)
|
||||||
|
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(16);
|
||||||
|
} >test_fw
|
||||||
|
__bss_end__ = .;
|
||||||
|
|
||||||
|
__end__ = ABSOLUTE(.) ;
|
||||||
|
|
||||||
|
__total_size__ = (__end__ - __start__);
|
||||||
|
|
||||||
|
__stack_top__ = 0x40031000;
|
||||||
|
__stack_bottom__ = 0x40030000;
|
||||||
|
|
||||||
|
/* ==================
|
||||||
|
==== Metadata ====
|
||||||
|
================== */
|
||||||
|
|
||||||
|
/* Discard sections that difficult post-processing */
|
||||||
|
/DISCARD/ : { *(.group .comment .note .interp) }
|
||||||
|
|
||||||
|
/* Stabs debugging sections. */
|
||||||
|
.stab 0 : { *(.stab) }
|
||||||
|
.stabstr 0 : { *(.stabstr) }
|
||||||
|
.stab.excl 0 : { *(.stab.excl) }
|
||||||
|
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||||
|
.stab.index 0 : { *(.stab.index) }
|
||||||
|
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||||
|
|
||||||
|
/* DWARF debug sections.
|
||||||
|
Symbols in the DWARF debugging sections are relative to the beginning
|
||||||
|
of the section so we begin them at 0. */
|
||||||
|
|
||||||
|
/* DWARF 1 */
|
||||||
|
.debug 0 : { *(.debug) }
|
||||||
|
.line 0 : { *(.line) }
|
||||||
|
|
||||||
|
/* GNU DWARF 1 extensions */
|
||||||
|
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||||
|
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||||
|
|
||||||
|
/* DWARF 1.1 and DWARF 2 */
|
||||||
|
.debug_aranges 0 : { *(.debug_aranges) }
|
||||||
|
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||||
|
|
||||||
|
/* DWARF 2 */
|
||||||
|
.debug_info 0 : { *(.debug_info) }
|
||||||
|
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||||
|
.debug_line 0 : { *(.debug_line) }
|
||||||
|
.debug_frame 0 : { *(.debug_frame) }
|
||||||
|
.debug_str 0 : { *(.debug_str) }
|
||||||
|
.debug_loc 0 : { *(.debug_loc) }
|
||||||
|
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||||
|
}
|
||||||
7
exosphere/sdmmc_test/sdmmc_test.specs
Normal file
7
exosphere/sdmmc_test/sdmmc_test.specs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
%rename link old_link
|
||||||
|
|
||||||
|
*link:
|
||||||
|
%(old_link) -T %:getenv(TOPDIR /sdmmc_test.ld) --gc-sections --nmagic -nostdlib -nostartfiles
|
||||||
|
|
||||||
|
*startfile:
|
||||||
|
crti%O%s crtbegin%O%s
|
||||||
146
exosphere/sdmmc_test/source/sdmmc_test_main.cpp
Normal file
146
exosphere/sdmmc_test/source/sdmmc_test_main.cpp
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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 <exosphere.hpp>
|
||||||
|
|
||||||
|
namespace ams::sdmmc_test {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constexpr inline const uintptr_t PMC = secmon::MemoryRegionPhysicalDevicePmc.GetAddress();
|
||||||
|
|
||||||
|
constexpr inline auto Port = sdmmc::Port_SdCard0;
|
||||||
|
alignas(8) constinit u8 g_sd_work_buffer[sdmmc::SdCardWorkBufferSize];
|
||||||
|
|
||||||
|
constexpr inline u32 SectorIndex = 0;
|
||||||
|
constexpr inline u32 SectorCount = 2;
|
||||||
|
|
||||||
|
NORETURN void PmcMainReboot() {
|
||||||
|
/* Write enable to MAIN_RESET. */
|
||||||
|
reg::Write(PMC + APBDEV_PMC_CNTRL, PMC_REG_BITS_ENUM(CNTRL_MAIN_RESET, ENABLE));
|
||||||
|
|
||||||
|
/* Wait forever until we're reset. */
|
||||||
|
AMS_INFINITE_LOOP();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckResult(const Result result) {
|
||||||
|
volatile u32 * const DEBUG = reinterpret_cast<volatile u32 *>(0x4003C000);
|
||||||
|
if (R_FAILED(result)) {
|
||||||
|
DEBUG[1] = result.GetValue();
|
||||||
|
PmcMainReboot();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Main() {
|
||||||
|
/* Perform butchered hwinit. */
|
||||||
|
/* TODO: replace with simpler, non-C logic. */
|
||||||
|
/* nx_hwinit(); */
|
||||||
|
|
||||||
|
/* Clear output buffer for debug. */
|
||||||
|
std::memset((void *)0x40038000, 0xAA, 0x400);
|
||||||
|
|
||||||
|
/* Normally, these pins get configured by boot sysmodule during initial pinmux config. */
|
||||||
|
/* However, they're required to access the SD card. */
|
||||||
|
{
|
||||||
|
const uintptr_t apb_misc = dd::QueryIoMapping(0x70000000, 0x4000);
|
||||||
|
|
||||||
|
reg::ReadWrite(apb_misc + PINMUX_AUX_SDMMC1_CLK, PINMUX_REG_BITS_ENUM(AUX_E_INPUT, ENABLE),
|
||||||
|
PINMUX_REG_BITS_ENUM(AUX_TRISTATE, PASSTHROUGH),
|
||||||
|
PINMUX_REG_BITS_ENUM(AUX_PUPD, PULL_DOWN),
|
||||||
|
PINMUX_REG_BITS_ENUM(AUX_SDMMC1_CLK_PM, SDMMC1));
|
||||||
|
|
||||||
|
reg::ReadWrite(apb_misc + PINMUX_AUX_SDMMC1_CMD, PINMUX_REG_BITS_ENUM(AUX_E_INPUT, ENABLE),
|
||||||
|
PINMUX_REG_BITS_ENUM(AUX_TRISTATE, PASSTHROUGH),
|
||||||
|
PINMUX_REG_BITS_ENUM(AUX_PUPD, PULL_UP),
|
||||||
|
PINMUX_REG_BITS_ENUM(AUX_SDMMC1_CMD_PM, SDMMC1));
|
||||||
|
|
||||||
|
reg::ReadWrite(apb_misc + PINMUX_AUX_SDMMC1_DAT3, PINMUX_REG_BITS_ENUM(AUX_E_INPUT, ENABLE),
|
||||||
|
PINMUX_REG_BITS_ENUM(AUX_TRISTATE, PASSTHROUGH),
|
||||||
|
PINMUX_REG_BITS_ENUM(AUX_PUPD, PULL_UP),
|
||||||
|
PINMUX_REG_BITS_ENUM(AUX_SDMMC1_DAT3_PM, SDMMC1));
|
||||||
|
|
||||||
|
reg::ReadWrite(apb_misc + PINMUX_AUX_SDMMC1_DAT2, PINMUX_REG_BITS_ENUM(AUX_E_INPUT, ENABLE),
|
||||||
|
PINMUX_REG_BITS_ENUM(AUX_TRISTATE, PASSTHROUGH),
|
||||||
|
PINMUX_REG_BITS_ENUM(AUX_PUPD, PULL_UP),
|
||||||
|
PINMUX_REG_BITS_ENUM(AUX_SDMMC1_DAT2_PM, SDMMC1));
|
||||||
|
|
||||||
|
reg::ReadWrite(apb_misc + PINMUX_AUX_SDMMC1_DAT1, PINMUX_REG_BITS_ENUM(AUX_E_INPUT, ENABLE),
|
||||||
|
PINMUX_REG_BITS_ENUM(AUX_TRISTATE, PASSTHROUGH),
|
||||||
|
PINMUX_REG_BITS_ENUM(AUX_PUPD, PULL_UP),
|
||||||
|
PINMUX_REG_BITS_ENUM(AUX_SDMMC1_DAT1_PM, SDMMC1));
|
||||||
|
|
||||||
|
reg::ReadWrite(apb_misc + PINMUX_AUX_SDMMC1_DAT0, PINMUX_REG_BITS_ENUM(AUX_E_INPUT, ENABLE),
|
||||||
|
PINMUX_REG_BITS_ENUM(AUX_TRISTATE, PASSTHROUGH),
|
||||||
|
PINMUX_REG_BITS_ENUM(AUX_PUPD, PULL_UP),
|
||||||
|
PINMUX_REG_BITS_ENUM(AUX_SDMMC1_DAT0_PM, SDMMC1));
|
||||||
|
|
||||||
|
reg::ReadWrite(apb_misc + PINMUX_AUX_DMIC3_CLK, PINMUX_REG_BITS_ENUM(AUX_E_OD, DISABLE),
|
||||||
|
PINMUX_REG_BITS_ENUM(AUX_E_INPUT, DISABLE),
|
||||||
|
PINMUX_REG_BITS_ENUM(AUX_TRISTATE, PASSTHROUGH),
|
||||||
|
PINMUX_REG_BITS_ENUM(AUX_SDMMC1_DAT0_PM, RSVD2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Debug signaler. */
|
||||||
|
volatile u32 * const DEBUG = reinterpret_cast<volatile u32 *>(0x4003C000);
|
||||||
|
DEBUG[0] = 0;
|
||||||
|
DEBUG[1] = 0xAAAAAAAA;
|
||||||
|
|
||||||
|
/* Initialize sdmmc library. */
|
||||||
|
sdmmc::Initialize(Port);
|
||||||
|
DEBUG[0] = 1;
|
||||||
|
|
||||||
|
sdmmc::SetSdCardWorkBuffer(Port, g_sd_work_buffer, sizeof(g_sd_work_buffer));
|
||||||
|
DEBUG[0] = 2;
|
||||||
|
|
||||||
|
Result result = sdmmc::Activate(Port);
|
||||||
|
DEBUG[0] = 3;
|
||||||
|
CheckResult(result);
|
||||||
|
|
||||||
|
/* Read the first two sectors from disk. */
|
||||||
|
void * const sector_dst = reinterpret_cast<void *>(0x40038000);
|
||||||
|
result = sdmmc::Read(sector_dst, SectorCount * sdmmc::SectorSize, Port, SectorIndex, SectorCount);
|
||||||
|
DEBUG[0] = 4;
|
||||||
|
CheckResult(result);
|
||||||
|
|
||||||
|
/* Get the connection status. */
|
||||||
|
sdmmc::SpeedMode speed_mode;
|
||||||
|
sdmmc::BusWidth bus_width;
|
||||||
|
result = sdmmc::CheckSdCardConnection(std::addressof(speed_mode), std::addressof(bus_width), Port);
|
||||||
|
|
||||||
|
/* Save status for debug. */
|
||||||
|
DEBUG[0] = 5;
|
||||||
|
DEBUG[1] = result.GetValue();
|
||||||
|
DEBUG[2] = static_cast<u32>(speed_mode);
|
||||||
|
DEBUG[3] = static_cast<u32>(bus_width);
|
||||||
|
|
||||||
|
/* Perform a reboot. */
|
||||||
|
PmcMainReboot();
|
||||||
|
}
|
||||||
|
|
||||||
|
NORETURN void ExceptionHandler() {
|
||||||
|
PmcMainReboot();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace ams::diag {
|
||||||
|
|
||||||
|
void AbortImpl() {
|
||||||
|
sdmmc_test::ExceptionHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
37
exosphere/sdmmc_test/source/sdmmc_test_start.s
Normal file
37
exosphere/sdmmc_test/source/sdmmc_test_start.s
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.section .crt0.text._ZN3ams10sdmmc_test5StartEv, "ax", %progbits
|
||||||
|
.align 3
|
||||||
|
.global _ZN3ams10sdmmc_test5StartEv
|
||||||
|
_ZN3ams10sdmmc_test5StartEv:
|
||||||
|
/* Switch to system mode, mask all interrupts, clear all flags */
|
||||||
|
msr cpsr_cxsf, #0xDF
|
||||||
|
|
||||||
|
/* Set the stack pointer. */
|
||||||
|
ldr sp, =__stack_top__
|
||||||
|
|
||||||
|
/* Set our link register to the exception handler. */
|
||||||
|
ldr lr, =_ZN3ams10sdmmc_test16ExceptionHandlerEv
|
||||||
|
|
||||||
|
/* Call init array functions. */
|
||||||
|
bl __libc_init_array
|
||||||
|
|
||||||
|
/* Invoke main. */
|
||||||
|
b _ZN3ams10sdmmc_test4MainEv
|
||||||
|
|
||||||
|
/* Infinite loop. */
|
||||||
|
2: b 2b
|
||||||
@@ -30,7 +30,7 @@ _ZN3ams8warmboot5StartEv:
|
|||||||
|
|
||||||
/* Invoke main. */
|
/* Invoke main. */
|
||||||
ldr r0, =_metadata
|
ldr r0, =_metadata
|
||||||
bl _ZN3ams8warmboot4MainEPKNS0_8MetadataE
|
b _ZN3ams8warmboot4MainEPKNS0_8MetadataE
|
||||||
|
|
||||||
/* Infinite loop. */
|
/* Infinite loop. */
|
||||||
1: b 1b
|
1: b 1b
|
||||||
@@ -24,6 +24,9 @@
|
|||||||
#include "lib/log.h"
|
#include "lib/log.h"
|
||||||
#include "display/video_fb.h"
|
#include "display/video_fb.h"
|
||||||
|
|
||||||
|
#define PROGRAM_ID_AMS_MITM 0x010041544D530000ull
|
||||||
|
#define PROGRAM_ID_BOOT 0x0100000000000005ull
|
||||||
|
|
||||||
static uint32_t g_panic_code = 0;
|
static uint32_t g_panic_code = 0;
|
||||||
|
|
||||||
static const char *get_error_desc_str(uint32_t error_desc) {
|
static const char *get_error_desc_str(uint32_t error_desc) {
|
||||||
@@ -53,6 +56,61 @@ static const char *get_error_desc_str(uint32_t error_desc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _try_suggest_fix(const atmosphere_fatal_error_ctx *ctx) {
|
||||||
|
/* Try to recognize certain errors automatically, and suggest fixes for them. */
|
||||||
|
const char *suggestion = NULL;
|
||||||
|
|
||||||
|
if (ctx->error_desc == 0xFFE) {
|
||||||
|
if (ctx->program_id == PROGRAM_ID_AMS_MITM) {
|
||||||
|
/* When a user has archive bits set improperly, attempting to create an automatic backup will fail */
|
||||||
|
/* to create the file path with error 0x202 (fs::ResultPathNotFound()) */
|
||||||
|
if (ctx->gprs[0] == 0x202) {
|
||||||
|
/* When the archive bit error is occurring, it manifests as failure to create automatic backup. */
|
||||||
|
/* Thus, we can search the stack for the automatic backups path. */
|
||||||
|
const char * const automatic_backups_prefix = "automatic_backups/X" /* ..... */;
|
||||||
|
const int prefix_len = strlen(automatic_backups_prefix);
|
||||||
|
|
||||||
|
for (size_t i = 0; i + prefix_len < ctx->stack_dump_size; ++i) {
|
||||||
|
if (memcmp(&ctx->stack_dump[i], automatic_backups_prefix, prefix_len) == 0) {
|
||||||
|
suggestion = "The atmosphere directory may improperly have archive\n"
|
||||||
|
"bits set. Please try running an archive bit fixer tool\n"
|
||||||
|
"(for example, the one in Hekate).\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (ctx->gprs[0] == 0x249A02) { /* fs::ResultResultExFatUnavailable() */
|
||||||
|
/* When a user installs non-exFAT firm but has an exFAT formatted SD card, this error will */
|
||||||
|
/* be returned on attempt to access the SD card. */
|
||||||
|
suggestion = "Your console has non-exFAT firmware installed, but your SD card\n"
|
||||||
|
"is formatted as exFAT. Format your SD card as FAT32, or manually\n"
|
||||||
|
"flash exFAT firmware to package2.\n";
|
||||||
|
}
|
||||||
|
} else if (ctx->program_id == PROGRAM_ID_BOOT) {
|
||||||
|
/* 9.x -> 10.x updated the API for SvcQueryIoMapping. */
|
||||||
|
/* This can cause the kernel to reject incorrect-ABI calls by boot when a partial update is applied */
|
||||||
|
/* (older kernel in package2, for some reason). */
|
||||||
|
for (size_t i = 0; i < 8; ++i) {
|
||||||
|
if (ctx->gprs[i] == 0xF201) {
|
||||||
|
suggestion = "A partial update may have been improperly performed.\n"
|
||||||
|
"To fix, try manually flashing latest package2 to MMC.\n"
|
||||||
|
"\n"
|
||||||
|
"For help doing this, seek support in the ReSwitched or\n"
|
||||||
|
"Nintendo Homebrew discord servers.\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (ctx->error_desc == 0xF00) { /* Kernel Panic */
|
||||||
|
suggestion = "Please contact SciresM#0524 on Discord, or create an issue\n"
|
||||||
|
"on the Atmosphere GitHub issue tracker. Thank you very much\n"
|
||||||
|
"for helping to test mesosphere.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (suggestion != NULL) {
|
||||||
|
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "\n%s", suggestion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void _check_and_display_atmosphere_fatal_error(void) {
|
static void _check_and_display_atmosphere_fatal_error(void) {
|
||||||
/* Check for valid magic. */
|
/* Check for valid magic. */
|
||||||
if (ATMOSPHERE_FATAL_ERROR_CONTEXT->magic != ATMOSPHERE_REBOOT_TO_FATAL_MAGIC &&
|
if (ATMOSPHERE_FATAL_ERROR_CONTEXT->magic != ATMOSPHERE_REBOOT_TO_FATAL_MAGIC &&
|
||||||
@@ -86,7 +144,7 @@ static void _check_and_display_atmosphere_fatal_error(void) {
|
|||||||
ATMOSPHERE_FATAL_ERROR_CONTEXT->magic = 0xCCCCCCCC;
|
ATMOSPHERE_FATAL_ERROR_CONTEXT->magic = 0xCCCCCCCC;
|
||||||
|
|
||||||
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "A fatal error occurred when running Atmosph\xe8re.\n");
|
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "A fatal error occurred when running Atmosph\xe8re.\n");
|
||||||
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "Title ID: %016llx\n", ctx.title_id);
|
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "Program ID: %016llx\n", ctx.program_id);
|
||||||
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "Error Desc: %s (0x%x)\n", get_error_desc_str(ctx.error_desc), ctx.error_desc);
|
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "Error Desc: %s (0x%x)\n", get_error_desc_str(ctx.error_desc), ctx.error_desc);
|
||||||
|
|
||||||
/* Save context to the SD card. */
|
/* Save context to the SD card. */
|
||||||
@@ -101,6 +159,9 @@ static void _check_and_display_atmosphere_fatal_error(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Try to print a fix suggestion via automatic error detection. */
|
||||||
|
_try_suggest_fix(&ctx);
|
||||||
|
|
||||||
/* Display error. */
|
/* Display error. */
|
||||||
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "\nPress POWER to reboot\n");
|
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "\nPress POWER to reboot\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t magic;
|
uint32_t magic;
|
||||||
uint32_t error_desc;
|
uint32_t error_desc;
|
||||||
uint64_t title_id;
|
uint64_t program_id;
|
||||||
union {
|
union {
|
||||||
uint64_t gprs[32];
|
uint64_t gprs[32];
|
||||||
struct {
|
struct {
|
||||||
|
|||||||
@@ -186,11 +186,15 @@ DEPENDS := $(OFILES:.o=.d)
|
|||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
all : $(OUTPUT).bin
|
all : $(OUTPUT).bin
|
||||||
|
|
||||||
$(OUTPUT).bin : $(OUTPUT).elf
|
$(OUTPUT).bin : $(OUTPUT)-experimental.bin
|
||||||
|
@python $(TOPDIR)/fusee_make_standard.py $(OUTPUT)-experimental.bin $(OUTPUT).bin
|
||||||
|
@echo built ... $(notdir $@)
|
||||||
|
|
||||||
|
$(OUTPUT)-experimental.bin : $(OUTPUT)-experimental.elf
|
||||||
$(OBJCOPY) -S -O binary $< $@
|
$(OBJCOPY) -S -O binary $< $@
|
||||||
@echo built ... $(notdir $@)
|
@echo built ... $(notdir $@)
|
||||||
|
|
||||||
$(OUTPUT).elf : $(OFILES)
|
$(OUTPUT)-experimental.elf : $(OFILES)
|
||||||
|
|
||||||
%.elf: $(OFILES)
|
%.elf: $(OFILES)
|
||||||
@echo linking $(notdir $@)
|
@echo linking $(notdir $@)
|
||||||
|
|||||||
37
fusee/fusee-secondary/fusee_make_standard.py
Normal file
37
fusee/fusee-secondary/fusee_make_standard.py
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
import sys, os
|
||||||
|
from struct import pack as pk, unpack as up
|
||||||
|
|
||||||
|
def make_standard(exp):
|
||||||
|
std = exp[:]
|
||||||
|
_, metadata_offset, is_exp = up('<III', exp[:12])
|
||||||
|
assert is_exp == 1
|
||||||
|
|
||||||
|
# Patch the experimental flag to zero.
|
||||||
|
std = std[:8] + pk('<I', 0) + std[12:]
|
||||||
|
|
||||||
|
# Locate the mesosphere content header, patch to be experimental.
|
||||||
|
magic, size, code_ofs, content_ofs, num_contents, ver, sup_ver, rev = up('<IIIIIIII', exp[metadata_offset:metadata_offset + 0x20])
|
||||||
|
for i in range(num_contents):
|
||||||
|
start, size, cnt_type, flag0, flag1, flag2, pad = up('<IIBBBBI', exp[content_ofs + 0x20 * i:content_ofs + 0x20 * i + 0x10])
|
||||||
|
if cnt_type == 10: # CONTENT_TYPE_KRN
|
||||||
|
assert exp[content_ofs + 0x20 * i + 0x10:content_ofs + 0x20 * i + 0x10 + len(b'mesosphere') + 1] == (b'mesosphere\x00')
|
||||||
|
assert flag0 == 0 and flag1 == 0 and flag2 == 0
|
||||||
|
std = std[:content_ofs + 0x20 * i] + pk('<IIBBBBI', start, size, cnt_type, flag0 | 0x1, flag1, flag2, pad) + std[content_ofs + 0x20 * i + 0x10:]
|
||||||
|
|
||||||
|
return std
|
||||||
|
|
||||||
|
|
||||||
|
def main(argc, argv):
|
||||||
|
if argc != 3:
|
||||||
|
print('Usage: %s input output' % argv[0])
|
||||||
|
return 1
|
||||||
|
with open(argv[1], 'rb') as f:
|
||||||
|
experimental = f.read()
|
||||||
|
with open(argv[2], 'wb') as f:
|
||||||
|
f.write(make_standard(experimental))
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.exit(main(len(sys.argv), sys.argv))
|
||||||
@@ -254,4 +254,6 @@ SECTIONS
|
|||||||
PROVIDE(__emummc_kip_size__ = emummc_kip_end - emummc_kip);
|
PROVIDE(__emummc_kip_size__ = emummc_kip_end - emummc_kip);
|
||||||
PROVIDE(__kernel_ldr_bin_start__ = kernel_ldr_bin - __start__);
|
PROVIDE(__kernel_ldr_bin_start__ = kernel_ldr_bin - __start__);
|
||||||
PROVIDE(__kernel_ldr_bin_size__ = kernel_ldr_bin_end - kernel_ldr_bin);
|
PROVIDE(__kernel_ldr_bin_size__ = kernel_ldr_bin_end - kernel_ldr_bin);
|
||||||
|
PROVIDE(__mesosphere_bin_start__ = mesosphere_bin - __start__);
|
||||||
|
PROVIDE(__mesosphere_bin_size__ = mesosphere_bin_end - mesosphere_bin);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,6 +55,7 @@
|
|||||||
#define u8 uint8_t
|
#define u8 uint8_t
|
||||||
#define u32 uint32_t
|
#define u32 uint32_t
|
||||||
#include "exosphere_bin.h"
|
#include "exosphere_bin.h"
|
||||||
|
#include "mesosphere_bin.h"
|
||||||
#include "sept_secondary_00_enc.h"
|
#include "sept_secondary_00_enc.h"
|
||||||
#include "sept_secondary_01_enc.h"
|
#include "sept_secondary_01_enc.h"
|
||||||
#include "sept_secondary_dev_00_enc.h"
|
#include "sept_secondary_dev_00_enc.h"
|
||||||
@@ -66,6 +67,8 @@
|
|||||||
|
|
||||||
extern const uint8_t warmboot_bin[];
|
extern const uint8_t warmboot_bin[];
|
||||||
|
|
||||||
|
extern int fusee_is_experimental(void);
|
||||||
|
|
||||||
static const uint8_t retail_pkc_modulus[0x100] = {
|
static const uint8_t retail_pkc_modulus[0x100] = {
|
||||||
0xF7, 0x86, 0x47, 0xAB, 0x71, 0x89, 0x81, 0xB5, 0xCF, 0x0C, 0xB0, 0xE8, 0x48, 0xA7, 0xFD, 0xAD,
|
0xF7, 0x86, 0x47, 0xAB, 0x71, 0x89, 0x81, 0xB5, 0xCF, 0x0C, 0xB0, 0xE8, 0x48, 0xA7, 0xFD, 0xAD,
|
||||||
0xCB, 0x4E, 0x4A, 0x52, 0x0B, 0x1A, 0x8E, 0xDE, 0x41, 0x87, 0x6F, 0xB7, 0x31, 0x05, 0x5F, 0xAA,
|
0xCB, 0x4E, 0x4A, 0x52, 0x0B, 0x1A, 0x8E, 0xDE, 0x41, 0x87, 0x6F, 0xB7, 0x31, 0x05, 0x5F, 0xAA,
|
||||||
@@ -209,11 +212,11 @@ static int stratosphere_ini_handler(void *user, const char *section, const char
|
|||||||
strat_cfg->has_nogc_config = true;
|
strat_cfg->has_nogc_config = true;
|
||||||
sscanf(value, "%d", &tmp);
|
sscanf(value, "%d", &tmp);
|
||||||
strat_cfg->enable_nogc = tmp != 0;
|
strat_cfg->enable_nogc = tmp != 0;
|
||||||
} else if (strcmp(name, STRATOSPHERE_ENABLE_NCM_KEY) == 0) {
|
} else if (strcmp(name, STRATOSPHERE_DISABLE_NCM_KEY) == 0) {
|
||||||
sscanf(value, "%d", &tmp);
|
sscanf(value, "%d", &tmp);
|
||||||
strat_cfg->ncm_enabled = tmp != 0;
|
strat_cfg->ncm_disabled = tmp != 0;
|
||||||
if (strat_cfg->ncm_enabled) {
|
if (strat_cfg->ncm_disabled) {
|
||||||
stratosphere_enable_ncm();
|
stratosphere_disable_ncm();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -624,6 +627,7 @@ static nx_keyblob_t __attribute__((aligned(16))) g_keyblobs[32];
|
|||||||
uint32_t nxboot_main(void) {
|
uint32_t nxboot_main(void) {
|
||||||
volatile tegra_pmc_t *pmc = pmc_get_regs();
|
volatile tegra_pmc_t *pmc = pmc_get_regs();
|
||||||
loader_ctx_t *loader_ctx = get_loader_ctx();
|
loader_ctx_t *loader_ctx = get_loader_ctx();
|
||||||
|
const bool is_experimental = fusee_is_experimental();
|
||||||
package2_header_t *package2;
|
package2_header_t *package2;
|
||||||
size_t package2_size;
|
size_t package2_size;
|
||||||
void *tsec_fw;
|
void *tsec_fw;
|
||||||
@@ -933,7 +937,6 @@ uint32_t nxboot_main(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Configure mesosphere. */
|
/* Configure mesosphere. */
|
||||||
/* TODO: Support non-SD/embedded mesosphere. */
|
|
||||||
{
|
{
|
||||||
size_t sd_meso_size = get_file_size("atmosphere/mesosphere.bin");
|
size_t sd_meso_size = get_file_size("atmosphere/mesosphere.bin");
|
||||||
if (sd_meso_size != 0) {
|
if (sd_meso_size != 0) {
|
||||||
@@ -948,6 +951,20 @@ uint32_t nxboot_main(void) {
|
|||||||
fatal_error("Error: failed to read atmosphere/mesosphere.bin!\n");
|
fatal_error("Error: failed to read atmosphere/mesosphere.bin!\n");
|
||||||
}
|
}
|
||||||
mesosphere_size = sd_meso_size;
|
mesosphere_size = sd_meso_size;
|
||||||
|
} else if (is_experimental) {
|
||||||
|
mesosphere_size = mesosphere_bin_size;
|
||||||
|
|
||||||
|
mesosphere = malloc(mesosphere_size);
|
||||||
|
|
||||||
|
if (mesosphere == NULL) {
|
||||||
|
fatal_error("[NXBOOT] Out of memory!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(mesosphere, mesosphere_bin, mesosphere_size);
|
||||||
|
|
||||||
|
if (mesosphere_size == 0) {
|
||||||
|
fatal_error("[NXBOOT] Could not read embedded mesosphere!\n");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
mesosphere = NULL;
|
mesosphere = NULL;
|
||||||
mesosphere_size = 0;
|
mesosphere_size = 0;
|
||||||
|
|||||||
@@ -30,6 +30,9 @@ _start:
|
|||||||
|
|
||||||
.word (_metadata - _start)
|
.word (_metadata - _start)
|
||||||
|
|
||||||
|
_is_experimental:
|
||||||
|
.word 0x00000001 /* is experimental */
|
||||||
|
|
||||||
_crt0:
|
_crt0:
|
||||||
/* Switch to system mode, mask all interrupts, clear all flags */
|
/* Switch to system mode, mask all interrupts, clear all flags */
|
||||||
msr cpsr_cxsf, #0xDF
|
msr cpsr_cxsf, #0xDF
|
||||||
@@ -68,6 +71,14 @@ _crt0:
|
|||||||
ldr r1, [r1]
|
ldr r1, [r1]
|
||||||
b main
|
b main
|
||||||
|
|
||||||
|
.arm
|
||||||
|
.global fusee_is_experimental
|
||||||
|
.type fusee_is_experimental, %function
|
||||||
|
fusee_is_experimental:
|
||||||
|
ldr r0, =_is_experimental
|
||||||
|
ldr r0, [r0]
|
||||||
|
bx lr
|
||||||
|
|
||||||
/* Fusee-secondary header. */
|
/* Fusee-secondary header. */
|
||||||
.align 5
|
.align 5
|
||||||
_metadata:
|
_metadata:
|
||||||
@@ -135,6 +146,17 @@ _content_headers:
|
|||||||
.asciz "exosphere"
|
.asciz "exosphere"
|
||||||
.align 5
|
.align 5
|
||||||
|
|
||||||
|
/* mesosphere content header */
|
||||||
|
.word __mesosphere_bin_start__
|
||||||
|
.word __mesosphere_bin_size__
|
||||||
|
.byte CONTENT_TYPE_KRN
|
||||||
|
.byte CONTENT_FLAG_NONE
|
||||||
|
.byte CONTENT_FLAG_NONE
|
||||||
|
.byte CONTENT_FLAG_NONE
|
||||||
|
.word 0xCCCCCCCC
|
||||||
|
.asciz "mesosphere"
|
||||||
|
.align 5
|
||||||
|
|
||||||
/* fusee_primary content header */
|
/* fusee_primary content header */
|
||||||
.word __fusee_primary_bin_start__
|
.word __fusee_primary_bin_start__
|
||||||
.word __fusee_primary_bin_size__
|
.word __fusee_primary_bin_size__
|
||||||
@@ -249,7 +271,7 @@ _content_headers:
|
|||||||
.word __ncm_kip_start__
|
.word __ncm_kip_start__
|
||||||
.word __ncm_kip_size__
|
.word __ncm_kip_size__
|
||||||
.byte CONTENT_TYPE_KIP
|
.byte CONTENT_TYPE_KIP
|
||||||
.byte CONTENT_FLAG0_EXPERIMENTAL
|
.byte CONTENT_FLAG_NONE
|
||||||
.byte CONTENT_FLAG_NONE
|
.byte CONTENT_FLAG_NONE
|
||||||
.byte CONTENT_FLAG_NONE
|
.byte CONTENT_FLAG_NONE
|
||||||
.word 0xCCCCCCCC
|
.word 0xCCCCCCCC
|
||||||
@@ -267,17 +289,6 @@ _content_headers:
|
|||||||
.asciz "emummc"
|
.asciz "emummc"
|
||||||
.align 5
|
.align 5
|
||||||
|
|
||||||
/* kernel_ldr content header */
|
|
||||||
.word __kernel_ldr_bin_start__
|
|
||||||
.word __kernel_ldr_bin_size__
|
|
||||||
.byte CONTENT_TYPE_KLD
|
|
||||||
.byte CONTENT_FLAG_NONE
|
|
||||||
.byte CONTENT_FLAG_NONE
|
|
||||||
.byte CONTENT_FLAG_NONE
|
|
||||||
.word 0xCCCCCCCC
|
|
||||||
.asciz "kernel_ldr"
|
|
||||||
.align 5
|
|
||||||
|
|
||||||
/* splash_screen content header */
|
/* splash_screen content header */
|
||||||
.word __splash_screen_bmp_start__
|
.word __splash_screen_bmp_start__
|
||||||
.word __splash_screen_bmp_size__
|
.word __splash_screen_bmp_size__
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ static bool g_stratosphere_pm_enabled = true;
|
|||||||
static bool g_stratosphere_ams_mitm_enabled = true;
|
static bool g_stratosphere_ams_mitm_enabled = true;
|
||||||
static bool g_stratosphere_spl_enabled = true;
|
static bool g_stratosphere_spl_enabled = true;
|
||||||
static bool g_stratosphere_boot_enabled = true;
|
static bool g_stratosphere_boot_enabled = true;
|
||||||
static bool g_stratosphere_ncm_enabled = false;
|
static bool g_stratosphere_ncm_enabled = true;
|
||||||
|
|
||||||
extern const uint8_t loader_kip[], pm_kip[], sm_kip[], spl_kip[], boot_kip[], ncm_kip[], ams_mitm_kip[];
|
extern const uint8_t loader_kip[], pm_kip[], sm_kip[], spl_kip[], boot_kip[], ncm_kip[], ams_mitm_kip[];
|
||||||
|
|
||||||
@@ -58,17 +58,17 @@ emummc_fs_ver_t stratosphere_get_fs_version(void) {
|
|||||||
return g_fs_ver;
|
return g_fs_ver;
|
||||||
}
|
}
|
||||||
|
|
||||||
void stratosphere_enable_ncm(void) {
|
void stratosphere_disable_ncm(void) {
|
||||||
/* The Atmosphere team believes our implementation of NCM to be extremely accurate, */
|
/* The Atmosphere team believes our implementation of NCM to be extremely accurate, */
|
||||||
/* and does not think it likely there is any possibility of undesirable behavior */
|
/* and does not think it likely there is any possibility of undesirable behavior */
|
||||||
/* when using the NCM reimplementation. However, because NCM manages critical save games */
|
/* when using the NCM reimplementation. However, because NCM manages critical save games */
|
||||||
/* the implementation will default to off for some time, until the code has been thoroughly */
|
/* the implementation may be optionally disabled for those not comfortable using it. */
|
||||||
/* tested in practice. */
|
|
||||||
|
|
||||||
/* PLEASE NOTE: The default behavior will be NCM on in a future atmosphere release, */
|
|
||||||
/* and this opt-in functionality will be removed at that time. */
|
|
||||||
|
|
||||||
g_stratosphere_ncm_enabled = true;
|
/* PLEASE NOTE: The NCM reimplementation has been well-tested, and correspondingly opt-out */
|
||||||
|
/* functionality will be removed in Atmosphere 1.0.0. */
|
||||||
|
|
||||||
|
g_stratosphere_ncm_enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* GCC doesn't consider the size as const... we have to write it ourselves. */
|
/* GCC doesn't consider the size as const... we have to write it ourselves. */
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ ini1_header_t *stratosphere_get_ini1(uint32_t target_firmware);
|
|||||||
ini1_header_t *stratosphere_get_sd_files_ini1(void);
|
ini1_header_t *stratosphere_get_sd_files_ini1(void);
|
||||||
void stratosphere_free_ini1(void);
|
void stratosphere_free_ini1(void);
|
||||||
|
|
||||||
void stratosphere_enable_ncm(void);
|
void stratosphere_disable_ncm(void);
|
||||||
|
|
||||||
emummc_fs_ver_t stratosphere_get_fs_version(void);
|
emummc_fs_ver_t stratosphere_get_fs_version(void);
|
||||||
|
|
||||||
@@ -39,10 +39,10 @@ ini1_header_t *stratosphere_merge_inis(ini1_header_t **inis, unsigned int num_in
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
bool has_nogc_config;
|
bool has_nogc_config;
|
||||||
bool enable_nogc;
|
bool enable_nogc;
|
||||||
bool ncm_enabled;
|
bool ncm_disabled;
|
||||||
} stratosphere_cfg_t;
|
} stratosphere_cfg_t;
|
||||||
|
|
||||||
#define STRATOSPHERE_NOGC_KEY "nogc"
|
#define STRATOSPHERE_NOGC_KEY "nogc"
|
||||||
#define STRATOSPHERE_ENABLE_NCM_KEY "enable_ncm"
|
#define STRATOSPHERE_DISABLE_NCM_KEY "disable_ncm"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
[subrepo]
|
[subrepo]
|
||||||
remote = https://github.com/Atmosphere-NX/Atmosphere-libs
|
remote = https://github.com/Atmosphere-NX/Atmosphere-libs
|
||||||
branch = master
|
branch = master
|
||||||
commit = 48dbf4808f4f2042de8c45e9ec471a8f60d5d621
|
commit = 10e9e0e8f926b11c2c7de16ffe15bea7d7ec2cdf
|
||||||
parent = 47d0d5c6abc1c9957cd05c63b02ee5e712179b80
|
parent = 2ee2a4f1ac04bc7f15de8be8d57ad04d7e73f735
|
||||||
method = merge
|
method = merge
|
||||||
cmdver = 0.4.1
|
cmdver = 0.4.1
|
||||||
|
|||||||
@@ -15,8 +15,10 @@ endif
|
|||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ATMOSPHERE_BUILD_SETTINGS ?=
|
||||||
|
|
||||||
export ATMOSPHERE_DEFINES := -DATMOSPHERE
|
export ATMOSPHERE_DEFINES := -DATMOSPHERE
|
||||||
export ATMOSPHERE_SETTINGS := -fPIE -g
|
export ATMOSPHERE_SETTINGS := -fPIE -g $(ATMOSPHERE_BUILD_SETTINGS)
|
||||||
export ATMOSPHERE_CFLAGS := -Wall -ffunction-sections -fdata-sections -fno-strict-aliasing -fwrapv \
|
export ATMOSPHERE_CFLAGS := -Wall -ffunction-sections -fdata-sections -fno-strict-aliasing -fwrapv \
|
||||||
-fno-asynchronous-unwind-tables -fno-unwind-tables -fno-stack-protector \
|
-fno-asynchronous-unwind-tables -fno-unwind-tables -fno-stack-protector \
|
||||||
-Wno-format-truncation -Wno-format-zero-length -Wno-stringop-truncation
|
-Wno-format-truncation -Wno-format-zero-length -Wno-stringop-truncation
|
||||||
@@ -132,10 +134,15 @@ FIND_SOURCE_FILES=$(foreach dir,$1,$(filter-out $(notdir $(wildcard $(dir)/*.arc
|
|||||||
$(foreach dir,$1,$(call FIND_SPECIFIC_SOURCE_FILES,$(dir),os,$(ATMOSPHERE_OS_NAME),$2)) \
|
$(foreach dir,$1,$(call FIND_SPECIFIC_SOURCE_FILES,$(dir),os,$(ATMOSPHERE_OS_NAME),$2)) \
|
||||||
$(foreach dir,$1,$(call FIND_SPECIFIC_SOURCE_FILES_EX,$(dir),cpu,$(ATMOSPHERE_CPU_NAME) $(ATMOSPHERE_CPU_EXTENSIONS),$2))
|
$(foreach dir,$1,$(call FIND_SPECIFIC_SOURCE_FILES_EX,$(dir),cpu,$(ATMOSPHERE_CPU_NAME) $(ATMOSPHERE_CPU_EXTENSIONS),$2))
|
||||||
|
|
||||||
|
ATMOSPHERE_GCH_IDENTIFIER ?= ams_placeholder_gch_identifier
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# Rules for compiling pre-compiled headers
|
# Rules for compiling pre-compiled headers
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
%.gch: %.hpp
|
%.hpp.gch/$(ATMOSPHERE_GCH_IDENTIFIER): %.hpp | %.hpp.gch
|
||||||
@echo $<
|
@echo Precompiling $(notdir $<) for $(ATMOSPHERE_GCH_IDENTIFIER)
|
||||||
$(CXX) -w -x c++-header -MMD -MP -MF $(DEPSDIR)/$*.d $(CXXFLAGS) -c $< -o $@ $(ERROR_FILTER)
|
$(SILENTCMD)$(CXX) -w -x c++-header -MMD -MP -MQ$@ -MF $(DEPSDIR)/$(notdir $*).d $(CXXFLAGS) -c $< -o $@ $(ERROR_FILTER)
|
||||||
@cp $@ $(<).gch
|
|
||||||
|
%.hpp.gch: %.hpp
|
||||||
|
@echo Precompiling $(notdir $<)
|
||||||
|
$(SILENTCMD)$(CXX) -w -x c++-header -MMD -MP -MQ$@ -MF $(DEPSDIR)/$(notdir $*).d $(CXXFLAGS) -c $< -o $@ $(ERROR_FILTER)
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \
|
|||||||
-Wl,--wrap,_ZSt20__throw_length_errorPKc \
|
-Wl,--wrap,_ZSt20__throw_length_errorPKc \
|
||||||
-Wl,--wrap,_ZNSt11logic_errorC2EPKc
|
-Wl,--wrap,_ZNSt11logic_errorC2EPKc
|
||||||
|
|
||||||
export LIBS := -lmesosphere
|
export LIBS := -l$(LIBMESOSPHERE_NAME)
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# list of directories containing libraries, this must be the top level containing
|
# list of directories containing libraries, this must be the top level containing
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ $(OFILES) : $(GCH_FILES)
|
|||||||
$(OFILES_SRC) : $(HFILES_BIN)
|
$(OFILES_SRC) : $(HFILES_BIN)
|
||||||
|
|
||||||
libc.o: CFLAGS += -fno-builtin -fno-lto
|
libc.o: CFLAGS += -fno-builtin -fno-lto
|
||||||
|
libgcc_division.arch.arm.o: CFLAGS += -fno-builtin -fno-lto
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
%_bin.h %.bin.o : %.bin
|
%_bin.h %.bin.o : %.bin
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
#include <vapours.hpp>
|
#include <vapours.hpp>
|
||||||
|
|
||||||
#include <exosphere/common.hpp>
|
#include <exosphere/common.hpp>
|
||||||
#include <exosphere/reg.hpp>
|
|
||||||
#include <exosphere/hw.hpp>
|
#include <exosphere/hw.hpp>
|
||||||
#include <exosphere/util.hpp>
|
#include <exosphere/util.hpp>
|
||||||
#include <exosphere/mmu.hpp>
|
#include <exosphere/mmu.hpp>
|
||||||
@@ -41,4 +40,3 @@
|
|||||||
#include <exosphere/actmon.hpp>
|
#include <exosphere/actmon.hpp>
|
||||||
#include <exosphere/pmc.hpp>
|
#include <exosphere/pmc.hpp>
|
||||||
#include <exosphere/secmon.hpp>
|
#include <exosphere/secmon.hpp>
|
||||||
#include <exosphere/tegra.hpp>
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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
|
|
||||||
#include <vapours.hpp>
|
|
||||||
|
|
||||||
#include <exosphere/tegra/tegra_ahb_arbc.hpp>
|
|
||||||
#include <exosphere/tegra/tegra_apb_misc.hpp>
|
|
||||||
#include <exosphere/tegra/tegra_avp_cache.hpp>
|
|
||||||
#include <exosphere/tegra/tegra_clkrst.hpp>
|
|
||||||
#include <exosphere/tegra/tegra_emc.hpp>
|
|
||||||
#include <exosphere/tegra/tegra_evp.hpp>
|
|
||||||
#include <exosphere/tegra/tegra_flow_ctlr.hpp>
|
|
||||||
#include <exosphere/tegra/tegra_ictlr.hpp>
|
|
||||||
#include <exosphere/tegra/tegra_mc.hpp>
|
|
||||||
#include <exosphere/tegra/tegra_mselect.hpp>
|
|
||||||
#include <exosphere/tegra/tegra_pinmux.hpp>
|
|
||||||
#include <exosphere/tegra/tegra_pg_up.hpp>
|
|
||||||
#include <exosphere/tegra/tegra_pmc.hpp>
|
|
||||||
#include <exosphere/tegra/tegra_sb.hpp>
|
|
||||||
#include <exosphere/tegra/tegra_sysctr0.hpp>
|
|
||||||
#include <exosphere/tegra/tegra_timer.hpp>
|
|
||||||
@@ -20,14 +20,6 @@ namespace ams::util {
|
|||||||
|
|
||||||
void SetRegisterAddress(uintptr_t address);
|
void SetRegisterAddress(uintptr_t address);
|
||||||
|
|
||||||
u32 GetMicroSeconds();
|
|
||||||
void WaitMicroSeconds(int us);
|
|
||||||
|
|
||||||
void ClearMemory(void *ptr, size_t size);
|
void ClearMemory(void *ptr, size_t size);
|
||||||
|
|
||||||
template<typename T, typename U> requires std::integral<T> && std::integral<U>
|
|
||||||
constexpr T DivideUp(T x, U y) {
|
|
||||||
return (x + (y - 1)) / y;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -14,7 +14,6 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include <exosphere.hpp>
|
#include <exosphere.hpp>
|
||||||
#include "i2c_registers.hpp"
|
|
||||||
|
|
||||||
namespace ams::i2c {
|
namespace ams::i2c {
|
||||||
|
|
||||||
|
|||||||
@@ -1,77 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <exosphere.hpp>
|
|
||||||
|
|
||||||
namespace ams::i2c {
|
|
||||||
|
|
||||||
#define I2C_I2C_CNFG (0x000)
|
|
||||||
#define I2C_I2C_CMD_ADDR0 (0x004)
|
|
||||||
#define I2C_I2C_CMD_DATA1 (0x00C)
|
|
||||||
#define I2C_I2C_STATUS (0x01C)
|
|
||||||
#define I2C_INTERRUPT_STATUS_REGISTER (0x068)
|
|
||||||
#define I2C_CLK_DIVISOR_REGISTER (0x06C)
|
|
||||||
#define I2C_BUS_CLEAR_CONFIG (0x084)
|
|
||||||
#define I2C_BUS_CLEAR_STATUS (0x088)
|
|
||||||
#define I2C_CONFIG_LOAD (0x08C)
|
|
||||||
|
|
||||||
#define I2C_REG_BITS_MASK(NAME) REG_NAMED_BITS_MASK (I2C, NAME)
|
|
||||||
#define I2C_REG_BITS_VALUE(NAME, VALUE) REG_NAMED_BITS_VALUE (I2C, NAME, VALUE)
|
|
||||||
#define I2C_REG_BITS_ENUM(NAME, ENUM) REG_NAMED_BITS_ENUM (I2C, NAME, ENUM)
|
|
||||||
#define I2C_REG_BITS_ENUM_SEL(NAME, __COND__, TRUE_ENUM, FALSE_ENUM) REG_NAMED_BITS_ENUM_SEL(I2C, NAME, __COND__, TRUE_ENUM, FALSE_ENUM)
|
|
||||||
|
|
||||||
#define DEFINE_I2C_REG(NAME, __OFFSET__, __WIDTH__) REG_DEFINE_NAMED_REG (I2C, NAME, __OFFSET__, __WIDTH__)
|
|
||||||
#define DEFINE_I2C_REG_BIT_ENUM(NAME, __OFFSET__, ZERO, ONE) REG_DEFINE_NAMED_BIT_ENUM (I2C, NAME, __OFFSET__, ZERO, ONE)
|
|
||||||
#define DEFINE_I2C_REG_TWO_BIT_ENUM(NAME, __OFFSET__, ZERO, ONE, TWO, THREE) REG_DEFINE_NAMED_TWO_BIT_ENUM (I2C, NAME, __OFFSET__, ZERO, ONE, TWO, THREE)
|
|
||||||
#define DEFINE_I2C_REG_THREE_BIT_ENUM(NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN) REG_DEFINE_NAMED_THREE_BIT_ENUM(I2C, NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN)
|
|
||||||
#define DEFINE_I2C_REG_FOUR_BIT_ENUM(NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, ELEVEN, TWELVE, THIRTEEN, FOURTEEN, FIFTEEN) REG_DEFINE_NAMED_FOUR_BIT_ENUM (I2C, NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, ELEVEN, TWELVE, THIRTEEN, FOURTEEN, FIFTEEN)
|
|
||||||
|
|
||||||
/* I2C_CNFG */
|
|
||||||
DEFINE_I2C_REG(I2C_CNFG_LENGTH, 1, 3);
|
|
||||||
DEFINE_I2C_REG_BIT_ENUM(I2C_CNFG_CMD1, 6, WRITE, READ);
|
|
||||||
DEFINE_I2C_REG_BIT_ENUM(I2C_CNFG_SEND, 9, NOP, GO);
|
|
||||||
DEFINE_I2C_REG_BIT_ENUM(I2C_CNFG_NEW_MASTER_FSM, 11, DISABLE, ENABLE);
|
|
||||||
DEFINE_I2C_REG_THREE_BIT_ENUM(I2C_CNFG_DEBOUNCE_CNT, 12, NO_DEBOUNCE, DEBOUNCE_2T, DEBOUNCE_4T, DEBOUNCE_6T, DEBOUNCE_8T, DEBOUNCE_10T, DEBOUNCE_12T, DEBOUNCE_14T);
|
|
||||||
|
|
||||||
/* I2C_CMD_ADDR0 */
|
|
||||||
DEFINE_I2C_REG_BIT_ENUM(I2C_CMD_ADDR0_7BIT_RW, 0, WRITE, READ);
|
|
||||||
DEFINE_I2C_REG(I2C_CMD_ADDR0_7BIT_ADDR, 1, 7);
|
|
||||||
|
|
||||||
/* I2C_STATUS */
|
|
||||||
DEFINE_I2C_REG_FOUR_BIT_ENUM(I2C_STATUS_CMD1_STAT, 0, SL1_XFER_SUCCESSFUL, SL1_NOACK_FOR_BYTE1, SL1_NOACK_FOR_BYTE2, SL1_NOACK_FOR_BYTE3, SL1_NOACK_FOR_BYTE4, SL1_NOACK_FOR_BYTE5, SL1_NOACK_FOR_BYTE6, SL1_NOACK_FOR_BYTE7, SL1_NOACK_FOR_BYTE8, SL1_NOACK_FOR_BYTE9, SL1_NOACK_FOR_BYTE10, RESERVED11, RESERVED12, RESERVED13, RESERVED14, RESERVED15);
|
|
||||||
DEFINE_I2C_REG_FOUR_BIT_ENUM(I2C_STATUS_CMD2_STAT, 4, SL2_XFER_SUCCESSFUL, SL2_NOACK_FOR_BYTE1, SL2_NOACK_FOR_BYTE2, SL2_NOACK_FOR_BYTE3, SL2_NOACK_FOR_BYTE4, SL2_NOACK_FOR_BYTE5, SL2_NOACK_FOR_BYTE6, SL2_NOACK_FOR_BYTE7, SL2_NOACK_FOR_BYTE8, SL2_NOACK_FOR_BYTE9, SL2_NOACK_FOR_BYTE10, RESERVED11, RESERVED12, RESERVED13, RESERVED14, RESERVED15);
|
|
||||||
DEFINE_I2C_REG_BIT_ENUM(I2C_STATUS_BUSY, 8, NOT_BUSY, BUSY);
|
|
||||||
|
|
||||||
/* INTERRUPT_STATUS_REGISTER */
|
|
||||||
DEFINE_I2C_REG_BIT_ENUM(INTERRUPT_STATUS_REGISTER_BUS_CLEAR_DONE, 11, UNSET, SET);
|
|
||||||
|
|
||||||
/* CLK_DIVISOR_REGISTER */
|
|
||||||
DEFINE_I2C_REG(CLK_DIVISOR_REGISTER_HSMODE, 0, 16);
|
|
||||||
DEFINE_I2C_REG(CLK_DIVISOR_REGISTER_STD_FAST_MODE, 16, 16);
|
|
||||||
|
|
||||||
/* BUS_CLEAR_CONFIG */
|
|
||||||
DEFINE_I2C_REG_BIT_ENUM(BUS_CLEAR_CONFIG_BC_ENABLE, 0, DISABLE, ENABLE);
|
|
||||||
DEFINE_I2C_REG_BIT_ENUM(BUS_CLEAR_CONFIG_BC_TERMINATE, 1, THRESHOLD, IMMEDIATE);
|
|
||||||
DEFINE_I2C_REG_BIT_ENUM(BUS_CLEAR_CONFIG_BC_STOP_COND, 2, NO_STOP, STOP);
|
|
||||||
DEFINE_I2C_REG(BUS_CLEAR_CONFIG_BC_SCLK_THRESHOLD, 16, 8);
|
|
||||||
|
|
||||||
/* CONFIG_LOAD */
|
|
||||||
DEFINE_I2C_REG_BIT_ENUM(CONFIG_LOAD_MSTR_CONFIG_LOAD, 0, DISABLE, ENABLE);
|
|
||||||
DEFINE_I2C_REG_BIT_ENUM(CONFIG_LOAD_SLV_CONFIG_LOAD, 1, DISABLE, ENABLE);
|
|
||||||
DEFINE_I2C_REG_BIT_ENUM(CONFIG_LOAD_TIMEOUT_CONFIG_LOAD, 2, DISABLE, ENABLE);
|
|
||||||
DEFINE_I2C_REG(CONFIG_LOAD_RESERVED_BIT_5, 5, 1);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
27
libraries/libexosphere/source/libc/libexo_cxx.cpp
Normal file
27
libraries/libexosphere/source/libc/libexo_cxx.cpp
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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 <exosphere.hpp>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* cxx implementation details to be stubbed here, as needed. */
|
||||||
|
void __cxa_pure_virtual() { AMS_ABORT("pure virtual function call"); }
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
160
libraries/libexosphere/source/libc/libgcc_division.arch.arm.c
Normal file
160
libraries/libexosphere/source/libc/libgcc_division.arch.arm.c
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, STMicroelectronics International N.V.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Form ABI specifications:
|
||||||
|
* int __aeabi_idiv(int numerator, int denominator);
|
||||||
|
* unsigned __aeabi_uidiv(unsigned numerator, unsigned denominator);
|
||||||
|
*
|
||||||
|
* typedef struct { int quot; int rem; } idiv_return;
|
||||||
|
* typedef struct { unsigned quot; unsigned rem; } uidiv_return;
|
||||||
|
*
|
||||||
|
* __value_in_regs idiv_return __aeabi_idivmod(int numerator,
|
||||||
|
* int *denominator);
|
||||||
|
* __value_in_regs uidiv_return __aeabi_uidivmod(unsigned *numerator,
|
||||||
|
* unsigned denominator);
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* struct qr - stores qutient/remainder to handle divmod EABI interfaces. */
|
||||||
|
struct qr {
|
||||||
|
unsigned q; /* computed quotient */
|
||||||
|
unsigned r; /* computed remainder */
|
||||||
|
unsigned q_n; /* specficies if quotient shall be negative */
|
||||||
|
unsigned r_n; /* specficies if remainder shall be negative */
|
||||||
|
};
|
||||||
|
|
||||||
|
static void uint_div_qr(unsigned numerator, unsigned denominator,
|
||||||
|
struct qr *qr);
|
||||||
|
|
||||||
|
/* returns in R0 and R1 by tail calling an asm function */
|
||||||
|
unsigned __aeabi_uidivmod(unsigned numerator, unsigned denominator);
|
||||||
|
|
||||||
|
unsigned __aeabi_uidiv(unsigned numerator, unsigned denominator);
|
||||||
|
|
||||||
|
/* returns in R0 and R1 by tail calling an asm function */
|
||||||
|
signed __aeabi_idivmod(signed numerator, signed denominator);
|
||||||
|
|
||||||
|
signed __aeabi_idiv(signed numerator, signed denominator);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* __ste_idivmod_ret_t __aeabi_idivmod(signed numerator, signed denominator)
|
||||||
|
* Numerator and Denominator are received in R0 and R1.
|
||||||
|
* Where __ste_idivmod_ret_t is returned in R0 and R1.
|
||||||
|
*
|
||||||
|
* __ste_uidivmod_ret_t __aeabi_uidivmod(unsigned numerator,
|
||||||
|
* unsigned denominator)
|
||||||
|
* Numerator and Denominator are received in R0 and R1.
|
||||||
|
* Where __ste_uidivmod_ret_t is returned in R0 and R1.
|
||||||
|
*/
|
||||||
|
#ifdef __GNUC__
|
||||||
|
signed ret_idivmod_values(signed quotient, signed remainder);
|
||||||
|
unsigned ret_uidivmod_values(unsigned quotient, unsigned remainder);
|
||||||
|
#else
|
||||||
|
#error "Compiler not supported"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void division_qr(unsigned n, unsigned p, struct qr *qr)
|
||||||
|
{
|
||||||
|
unsigned i = 1, q = 0;
|
||||||
|
if (p == 0) {
|
||||||
|
qr->r = 0xFFFFFFFF; /* division by 0 */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((p >> 31) == 0) {
|
||||||
|
i = i << 1; /* count the max division steps */
|
||||||
|
p = p << 1; /* increase p until it has maximum size*/
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i > 0) {
|
||||||
|
q = q << 1; /* write bit in q at index (size-1) */
|
||||||
|
if (n >= p)
|
||||||
|
{
|
||||||
|
n -= p;
|
||||||
|
q++;
|
||||||
|
}
|
||||||
|
p = p >> 1; /* decrease p */
|
||||||
|
i = i >> 1; /* decrease remaining size in q */
|
||||||
|
}
|
||||||
|
qr->r = n;
|
||||||
|
qr->q = q;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void uint_div_qr(unsigned numerator, unsigned denominator, struct qr *qr)
|
||||||
|
{
|
||||||
|
|
||||||
|
division_qr(numerator, denominator, qr);
|
||||||
|
|
||||||
|
/* negate quotient and/or remainder according to requester */
|
||||||
|
if (qr->q_n)
|
||||||
|
qr->q = -qr->q;
|
||||||
|
if (qr->r_n)
|
||||||
|
qr->r = -qr->r;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned __aeabi_uidiv(unsigned numerator, unsigned denominator)
|
||||||
|
{
|
||||||
|
struct qr qr = { .q_n = 0, .r_n = 0 };
|
||||||
|
|
||||||
|
uint_div_qr(numerator, denominator, &qr);
|
||||||
|
|
||||||
|
return qr.q;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned __aeabi_uidivmod(unsigned numerator, unsigned denominator)
|
||||||
|
{
|
||||||
|
struct qr qr = { .q_n = 0, .r_n = 0 };
|
||||||
|
|
||||||
|
uint_div_qr(numerator, denominator, &qr);
|
||||||
|
|
||||||
|
return ret_uidivmod_values(qr.q, qr.r);
|
||||||
|
}
|
||||||
|
|
||||||
|
signed __aeabi_idiv(signed numerator, signed denominator)
|
||||||
|
{
|
||||||
|
struct qr qr = { .q_n = 0, .r_n = 0 };
|
||||||
|
|
||||||
|
if (((numerator < 0) && (denominator > 0)) ||
|
||||||
|
((numerator > 0) && (denominator < 0)))
|
||||||
|
qr.q_n = 1; /* quotient shall be negate */
|
||||||
|
if (numerator < 0) {
|
||||||
|
numerator = -numerator;
|
||||||
|
qr.r_n = 1; /* remainder shall be negate */
|
||||||
|
}
|
||||||
|
if (denominator < 0)
|
||||||
|
denominator = -denominator;
|
||||||
|
|
||||||
|
uint_div_qr(numerator, denominator, &qr);
|
||||||
|
|
||||||
|
return qr.q;
|
||||||
|
}
|
||||||
|
|
||||||
|
signed __aeabi_idivmod(signed numerator, signed denominator)
|
||||||
|
{
|
||||||
|
struct qr qr = { .q_n = 0, .r_n = 0 };
|
||||||
|
|
||||||
|
if (((numerator < 0) && (denominator > 0)) ||
|
||||||
|
((numerator > 0) && (denominator < 0)))
|
||||||
|
qr.q_n = 1; /* quotient shall be negate */
|
||||||
|
if (numerator < 0) {
|
||||||
|
numerator = -numerator;
|
||||||
|
qr.r_n = 1; /* remainder shall be negate */
|
||||||
|
}
|
||||||
|
if (denominator < 0)
|
||||||
|
denominator = -denominator;
|
||||||
|
|
||||||
|
uint_div_qr(numerator, denominator, &qr);
|
||||||
|
|
||||||
|
return ret_idivmod_values(qr.q, qr.r);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/* SPDX-License-Identifier: BSD-2-Clause */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, STMicroelectronics International N.V.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* signed ret_idivmod_values(signed quot, signed rem);
|
||||||
|
* return quotient and remaining the EABI way (regs r0,r1)
|
||||||
|
*/
|
||||||
|
.section .text.ret_idivmod_values, "ax", %progbits
|
||||||
|
.globl ret_idivmod_values
|
||||||
|
.align 0
|
||||||
|
.syntax unified
|
||||||
|
ret_idivmod_values:
|
||||||
|
bx lr
|
||||||
|
.type ret_idivmod_values, %function
|
||||||
|
.size ret_idivmod_values, .-ret_idivmod_values
|
||||||
|
|
||||||
|
/*
|
||||||
|
* unsigned ret_uidivmod_values(unsigned quot, unsigned rem);
|
||||||
|
* return quotient and remaining the EABI way (regs r0,r1)
|
||||||
|
*/
|
||||||
|
.section .text.ret_uidivmod_values, "ax", %progbits
|
||||||
|
.globl ret_uidivmod_values
|
||||||
|
.align 0
|
||||||
|
.syntax unified
|
||||||
|
ret_uidivmod_values:
|
||||||
|
bx lr
|
||||||
|
.type ret_uidivmod_values, %function
|
||||||
|
.size ret_uidivmod_values, .-ret_uidivmod_values
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/* Copyright (C) 1995-2018 Free Software Foundation, Inc.
|
||||||
|
This file is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by the
|
||||||
|
Free Software Foundation; either version 3, or (at your option) any
|
||||||
|
later version.
|
||||||
|
This file is distributed in the hope that 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.
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
|
||||||
|
.section .text.__gnu_thumb1_case_uqi, "ax", %progbits
|
||||||
|
.globl __gnu_thumb1_case_uqi
|
||||||
|
.align 0
|
||||||
|
.thumb_func
|
||||||
|
.syntax unified
|
||||||
|
__gnu_thumb1_case_uqi:
|
||||||
|
push {r1}
|
||||||
|
mov r1, lr
|
||||||
|
lsrs r1, r1, #1
|
||||||
|
lsls r1, r1, #1
|
||||||
|
ldrb r1, [r1, r0]
|
||||||
|
lsls r1, r1, #1
|
||||||
|
add lr, lr, r1
|
||||||
|
pop {r1}
|
||||||
|
bx lr
|
||||||
|
.type __gnu_thumb1_case_uqi, %function
|
||||||
|
.size __gnu_thumb1_case_uqi, .-__gnu_thumb1_case_uqi
|
||||||
@@ -1,12 +1,14 @@
|
|||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# pull in common atmosphere configuration
|
# pull in common atmosphere configuration
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../config/common.mk
|
THIS_MAKEFILE := $(abspath $(lastword $(MAKEFILE_LIST)))
|
||||||
|
CURRENT_DIRECTORY := $(abspath $(dir $(THIS_MAKEFILE)))
|
||||||
|
include $(CURRENT_DIRECTORY)/../config/common.mk
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# options for code generation
|
# options for code generation
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
PRECOMPILED_HEADERS := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/include/mesosphere.hpp
|
PRECOMPILED_HEADERS := include/mesosphere.hpp
|
||||||
|
|
||||||
DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_MESOSPHERE
|
DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_MESOSPHERE
|
||||||
SETTINGS := $(ATMOSPHERE_SETTINGS) -O2 -mgeneral-regs-only -ffixed-x18 -Wextra -Werror -fno-non-call-exceptions
|
SETTINGS := $(ATMOSPHERE_SETTINGS) -O2 -mgeneral-regs-only -ffixed-x18 -Wextra -Werror -fno-non-call-exceptions
|
||||||
@@ -28,7 +30,7 @@ LIBDIRS := $(ATMOSPHERE_LIBRARIES_DIR)/libvapours
|
|||||||
# no real need to edit anything past this point unless you need to add additional
|
# no real need to edit anything past this point unless you need to add additional
|
||||||
# rules for different file extensions
|
# rules for different file extensions
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
ifneq ($(__RECURSIVE__),1)
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
|
|
||||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) $(CURDIR)/include \
|
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) $(CURDIR)/include \
|
||||||
@@ -54,7 +56,7 @@ endif
|
|||||||
|
|
||||||
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
|
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
|
||||||
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||||
export GCH_FILES := $(foreach hdr,$(PRECOMPILED_HEADERS:.hpp=.gch),$(notdir $(hdr)))
|
export GCH_DIRS := $(PRECOMPILED_HEADERS:.hpp=.hpp.gch)
|
||||||
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
|
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
|
||||||
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
|
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
|
||||||
|
|
||||||
@@ -62,41 +64,70 @@ export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
|||||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||||
-I.
|
-I.
|
||||||
|
|
||||||
.PHONY: clean all
|
#---------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ATMOSPHERE_BUILD_CONFIGS :=
|
||||||
|
all: release
|
||||||
|
|
||||||
|
define ATMOSPHERE_ADD_TARGET
|
||||||
|
|
||||||
|
ATMOSPHERE_BUILD_CONFIGS += $(strip $1)
|
||||||
|
|
||||||
|
$(strip $1): $$(ATMOSPHERE_LIBRARY_DIR)/$(strip $2)
|
||||||
|
|
||||||
|
$$(ATMOSPHERE_LIBRARY_DIR)/$(strip $2) : $$(ATMOSPHERE_LIBRARY_DIR) $$(ATMOSPHERE_BUILD_DIR)/$(strip $1) $$(SOURCES) $$(INCLUDES) $$(GCH_DIRS)
|
||||||
|
@$$(MAKE) __RECURSIVE__=1 OUTPUT=$$(CURDIR)/$$@ $(3) \
|
||||||
|
ATMOSPHERE_GCH_IDENTIFIER="$$(ATMOSPHERE_BOARD_NAME)_$$(ATMOSPHERE_ARCH_NAME)_$(strip $1)" \
|
||||||
|
DEPSDIR=$$(CURDIR)/$$(ATMOSPHERE_BUILD_DIR)/$(strip $1) \
|
||||||
|
--no-print-directory -C $$(ATMOSPHERE_BUILD_DIR)/$(strip $1) \
|
||||||
|
-f $$(THIS_MAKEFILE)
|
||||||
|
|
||||||
|
clean-$(strip $1):
|
||||||
|
@echo clean $(strip $1) ...
|
||||||
|
@rm -fr $$(ATMOSPHERE_BUILD_DIR)/$(strip $1) $$(ATMOSPHERE_LIBRARY_DIR)/$(strip $2)
|
||||||
|
@rm -fr $$(foreach hdr,$$(GCH_DIRS),$$(hdr)/$$(ATMOSPHERE_BOARD_NAME)_$$(ATMOSPHERE_ARCH_NAME)_$(strip $1))
|
||||||
|
@for i in $$(GCH_DIRS) $$(ATMOSPHERE_BUILD_DIR) $$(ATMOSPHERE_LIBRARY_DIR); do [ -d $$$$i ] && rmdir --ignore-fail-on-non-empty $$$$i || true; done
|
||||||
|
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(eval $(call ATMOSPHERE_ADD_TARGET, release, $(TARGET).a, \
|
||||||
|
ATMOSPHERE_BUILD_SETTINGS="" \
|
||||||
|
))
|
||||||
|
|
||||||
|
$(eval $(call ATMOSPHERE_ADD_TARGET, debug, $(TARGET)_debug.a, \
|
||||||
|
ATMOSPHERE_BUILD_SETTINGS="-DMESOSPHERE_BUILD_FOR_DEBUGGING" \
|
||||||
|
))
|
||||||
|
|
||||||
|
$(eval $(call ATMOSPHERE_ADD_TARGET, audit, $(TARGET)_audit.a, \
|
||||||
|
ATMOSPHERE_BUILD_SETTINGS="-DMESOSPHERE_BUILD_FOR_AUDITING" \
|
||||||
|
))
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
all: lib/$(TARGET).a
|
|
||||||
|
|
||||||
lib:
|
-include $(ATMOSPHERE_BOARD_NAME)_$(ATMOSPHERE_ARCH_NAME).mk
|
||||||
|
|
||||||
|
ALL_GCH_IDENTIFIERS := $(foreach config,$(ATMOSPHERE_BUILD_CONFIGS),$(ATMOSPHERE_BOARD_NAME)_$(ATMOSPHERE_ARCH_NAME)_$(config))
|
||||||
|
ALL_GCH_FILES := $(foreach hdr,$(PRECOMPILED_HEADERS:.hpp=.hpp.gch),$(foreach id,$(ALL_GCH_IDENTIFIERS),$(hdr)/$(id)))
|
||||||
|
|
||||||
|
.PHONY: clean all $(foreach config,$(ATMOSPHERE_BUILD_CONFIGS),$(config) clean-$(config))
|
||||||
|
|
||||||
|
$(ATMOSPHERE_LIBRARY_DIR) $(GCH_DIRS):
|
||||||
@[ -d $@ ] || mkdir -p $@
|
@[ -d $@ ] || mkdir -p $@
|
||||||
|
|
||||||
release:
|
$(ATMOSPHERE_BUILD_DIR)/%:
|
||||||
@[ -d $@ ] || mkdir -p $@
|
@[ -d $@ ] || mkdir -p $@
|
||||||
|
|
||||||
lib/$(TARGET).a : lib release $(SOURCES) $(INCLUDES)
|
|
||||||
@$(MAKE) BUILD=release OUTPUT=$(CURDIR)/$@ \
|
|
||||||
BUILD_CFLAGS="-DNDEBUG=1 -O2" \
|
|
||||||
DEPSDIR=$(CURDIR)/release \
|
|
||||||
--no-print-directory -C release \
|
|
||||||
-f $(CURDIR)/Makefile
|
|
||||||
|
|
||||||
dist-bin: all
|
|
||||||
@tar --exclude=*~ -cjf $(TARGET).tar.bz2 include lib
|
|
||||||
|
|
||||||
dist-src:
|
|
||||||
@tar --exclude=*~ -cjf $(TARGET)-src.tar.bz2 include source Makefile
|
|
||||||
|
|
||||||
dist: dist-src dist-bin
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
clean:
|
clean:
|
||||||
@echo clean ...
|
@echo clean ...
|
||||||
@rm -fr release lib *.bz2
|
@rm -fr $(ATMOSPHERE_BUILD_DIR) $(ATMOSPHERE_LIBRARY_DIR) *.bz2 $(ALL_GCH_FILES)
|
||||||
|
@for i in $(GCH_DIRS); do [ -d $$i ] && rmdir --ignore-fail-on-non-empty $$i || true; done
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
else
|
else
|
||||||
|
|
||||||
DEPENDS := $(OFILES:.o=.d) $(GCH_FILES:.gch=.d)
|
GCH_FILES := $(foreach hdr,$(PRECOMPILED_HEADERS:.hpp=.hpp.gch),$(CURRENT_DIRECTORY)/$(hdr)/$(ATMOSPHERE_GCH_IDENTIFIER))
|
||||||
|
DEPENDS := $(OFILES:.o=.d) $(foreach hdr,$(GCH_FILES),$(notdir $(patsubst %.hpp.gch/,%.d,$(dir $(hdr)))))
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# main targets
|
# main targets
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ namespace ams::kern {
|
|||||||
private:
|
private:
|
||||||
friend class KScopedSchedulerLock;
|
friend class KScopedSchedulerLock;
|
||||||
friend class KScopedSchedulerLockAndSleep;
|
friend class KScopedSchedulerLockAndSleep;
|
||||||
|
friend class KScopedDisableDispatch;
|
||||||
private:
|
private:
|
||||||
SchedulingState state;
|
SchedulingState state;
|
||||||
bool is_active;
|
bool is_active;
|
||||||
@@ -161,8 +162,9 @@ namespace ams::kern {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE void ScheduleOnInterrupt() {
|
ALWAYS_INLINE void ScheduleOnInterrupt() {
|
||||||
KScopedDisableDispatch dd;
|
GetCurrentThread().DisableDispatch();
|
||||||
this->Schedule();
|
this->Schedule();
|
||||||
|
GetCurrentThread().EnableDispatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RescheduleOtherCores(u64 cores_needing_scheduling);
|
void RescheduleOtherCores(u64 cores_needing_scheduling);
|
||||||
|
|||||||
@@ -559,20 +559,7 @@ namespace ams::kern {
|
|||||||
GetCurrentThread().DisableDispatch();
|
GetCurrentThread().DisableDispatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE ~KScopedDisableDispatch() {
|
~KScopedDisableDispatch();
|
||||||
GetCurrentThread().EnableDispatch();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class KScopedEnableDispatch {
|
|
||||||
public:
|
|
||||||
explicit ALWAYS_INLINE KScopedEnableDispatch() {
|
|
||||||
GetCurrentThread().EnableDispatch();
|
|
||||||
}
|
|
||||||
|
|
||||||
ALWAYS_INLINE ~KScopedEnableDispatch() {
|
|
||||||
GetCurrentThread().DisableDispatch();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ALWAYS_INLINE KExceptionContext *GetExceptionContext(KThread *thread) {
|
ALWAYS_INLINE KExceptionContext *GetExceptionContext(KThread *thread) {
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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
|
|
||||||
|
|
||||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_CSITE 0x1D4
|
|
||||||
#define CLK_RST_CONTROLLER_RST_DEV_L_SET 0x300
|
|
||||||
#define CLK_RST_CONTROLLER_RST_DEV_L_CLR 0x304
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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
|
|
||||||
|
|
||||||
#define FLOW_CTLR_HALT_COP_EVENTS 0x004
|
|
||||||
#define FLOW_CTLR_CC4_HVC_CONTROL 0x060
|
|
||||||
#define FLOW_CTLR_CC4_RETENTION_CONTROL 0x064
|
|
||||||
#define FLOW_CTLR_CC4_HVC_RETRY 0x08C
|
|
||||||
@@ -14,7 +14,6 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include <mesosphere.hpp>
|
#include <mesosphere.hpp>
|
||||||
#include "kern_mc_registers.hpp"
|
|
||||||
|
|
||||||
#if defined(MESOSPHERE_BUILD_FOR_DEBUGGING) || defined(MESOSPHERE_BUILD_FOR_AUDITING)
|
#if defined(MESOSPHERE_BUILD_FOR_DEBUGGING) || defined(MESOSPHERE_BUILD_FOR_AUDITING)
|
||||||
#define MESOSPHERE_ENABLE_MEMORY_CONTROLLER_INTERRUPT
|
#define MESOSPHERE_ENABLE_MEMORY_CONTROLLER_INTERRUPT
|
||||||
|
|||||||
@@ -78,13 +78,11 @@ namespace ams::kern::board::nintendo::nx {
|
|||||||
|
|
||||||
void WaitOtherCpuPowerOff() {
|
void WaitOtherCpuPowerOff() {
|
||||||
constexpr u64 PmcPhysicalAddress = 0x7000E400;
|
constexpr u64 PmcPhysicalAddress = 0x7000E400;
|
||||||
constexpr u64 APBDEV_PMC_PWRGATE_STATUS = PmcPhysicalAddress + 0x38;
|
|
||||||
|
|
||||||
constexpr u32 PWRGATE_STATUS_CE123_MASK = ((1u << 3) - 1) << 9;
|
constexpr u32 PWRGATE_STATUS_CE123_MASK = ((1u << 3) - 1) << 9;
|
||||||
|
|
||||||
u32 value;
|
u32 value;
|
||||||
do {
|
do {
|
||||||
bool res = smc::ReadWriteRegister(std::addressof(value), APBDEV_PMC_PWRGATE_STATUS, 0, 0);
|
bool res = smc::ReadWriteRegister(std::addressof(value), PmcPhysicalAddress + APBDEV_PMC_PWRGATE_STATUS, 0, 0);
|
||||||
MESOSPHERE_ASSERT(res);
|
MESOSPHERE_ASSERT(res);
|
||||||
} while ((value & PWRGATE_STATUS_CE123_MASK) != 0);
|
} while ((value & PWRGATE_STATUS_CE123_MASK) != 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -308,6 +308,15 @@ namespace ams::kern::board::nintendo::nx {
|
|||||||
g_secure_applet_memory_used = false;
|
g_secure_applet_memory_used = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u64 GetVersionIdentifier() {
|
||||||
|
u64 value = kern::GetTargetFirmware();
|
||||||
|
value |= static_cast<u64>(ATMOSPHERE_RELEASE_VERSION_MICRO) << 32;
|
||||||
|
value |= static_cast<u64>(ATMOSPHERE_RELEASE_VERSION_MINOR) << 40;
|
||||||
|
value |= static_cast<u64>(ATMOSPHERE_RELEASE_VERSION_MAJOR) << 48;
|
||||||
|
value |= static_cast<u64>('M') << 56;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialization. */
|
/* Initialization. */
|
||||||
@@ -534,10 +543,14 @@ namespace ams::kern::board::nintendo::nx {
|
|||||||
|
|
||||||
void KSystemControl::StopSystem(void *arg) {
|
void KSystemControl::StopSystem(void *arg) {
|
||||||
if (arg != nullptr) {
|
if (arg != nullptr) {
|
||||||
|
/* Get the address of the legacy IRAM region. */
|
||||||
|
const KVirtualAddress iram_address = KMemoryLayout::GetDeviceVirtualAddress(KMemoryRegionType_LegacyLpsIram) + 64_KB;
|
||||||
|
constexpr size_t RebootPayloadSize = 0x2E000;
|
||||||
|
|
||||||
/* NOTE: Atmosphere extension; if we received an exception context from Panic(), */
|
/* NOTE: Atmosphere extension; if we received an exception context from Panic(), */
|
||||||
/* generate a fatal error report using it. */
|
/* generate a fatal error report using it. */
|
||||||
const KExceptionContext *e_ctx = static_cast<const KExceptionContext *>(arg);
|
const KExceptionContext *e_ctx = static_cast<const KExceptionContext *>(arg);
|
||||||
auto *f_ctx = GetPointer<::ams::impl::FatalErrorContext>(KMemoryLayout::GetDeviceVirtualAddress(KMemoryRegionType_LegacyLpsIram) + 0x3E000);
|
auto *f_ctx = GetPointer<::ams::impl::FatalErrorContext>(iram_address + RebootPayloadSize);
|
||||||
|
|
||||||
/* Clear the fatal context. */
|
/* Clear the fatal context. */
|
||||||
std::memset(f_ctx, 0xCC, sizeof(*f_ctx));
|
std::memset(f_ctx, 0xCC, sizeof(*f_ctx));
|
||||||
@@ -553,6 +566,10 @@ namespace ams::kern::board::nintendo::nx {
|
|||||||
/* Set module base. */
|
/* Set module base. */
|
||||||
f_ctx->module_base = KMemoryLayout::GetKernelCodeRegionExtents().GetAddress();
|
f_ctx->module_base = KMemoryLayout::GetKernelCodeRegionExtents().GetAddress();
|
||||||
|
|
||||||
|
/* Set afsr1. */
|
||||||
|
f_ctx->afsr0 = 0;
|
||||||
|
f_ctx->afsr1 = GetVersionIdentifier();
|
||||||
|
|
||||||
/* Copy registers. */
|
/* Copy registers. */
|
||||||
for (size_t i = 0; i < util::size(e_ctx->x); ++i) {
|
for (size_t i = 0; i < util::size(e_ctx->x); ++i) {
|
||||||
f_ctx->gprs[i] = e_ctx->x[i];
|
f_ctx->gprs[i] = e_ctx->x[i];
|
||||||
@@ -581,8 +598,27 @@ namespace ams::kern::board::nintendo::nx {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Trigger a reboot to rcm. */
|
/* Try to get a payload address. */
|
||||||
smc::init::SetConfig(smc::ConfigItem::ExosphereNeedsReboot, smc::UserRebootType_ToRcm);
|
const KMemoryRegion *cached_region = nullptr;
|
||||||
|
u64 reboot_payload_paddr = 0;
|
||||||
|
if (smc::TryGetConfig(std::addressof(reboot_payload_paddr), 1, smc::ConfigItem::ExospherePayloadAddress) && KMemoryLayout::IsLinearMappedPhysicalAddress(cached_region, reboot_payload_paddr, RebootPayloadSize)) {
|
||||||
|
/* If we have a payload, reboot to it. */
|
||||||
|
const KVirtualAddress reboot_payload = KMemoryLayout::GetLinearVirtualAddress(KPhysicalAddress(reboot_payload_paddr));
|
||||||
|
|
||||||
|
/* Clear IRAM. */
|
||||||
|
std::memset(GetVoidPointer(iram_address), 0xCC, RebootPayloadSize);
|
||||||
|
|
||||||
|
/* Copy the payload to iram. */
|
||||||
|
for (size_t i = 0; i < RebootPayloadSize / sizeof(u32); ++i) {
|
||||||
|
GetPointer<volatile u32>(iram_address)[i] = GetPointer<volatile u32>(reboot_payload)[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reboot. */
|
||||||
|
smc::SetConfig(smc::ConfigItem::ExosphereNeedsReboot, smc::UserRebootType_ToPayload);
|
||||||
|
} else {
|
||||||
|
/* If we don't have a payload, reboot to rcm. */
|
||||||
|
smc::SetConfig(smc::ConfigItem::ExosphereNeedsReboot, smc::UserRebootType_ToRcm);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_call_smc_on_panic) {
|
if (g_call_smc_on_panic) {
|
||||||
|
|||||||
@@ -19,11 +19,7 @@
|
|||||||
|
|
||||||
#include "kern_bpmp_api.hpp"
|
#include "kern_bpmp_api.hpp"
|
||||||
#include "kern_atomics_registers.hpp"
|
#include "kern_atomics_registers.hpp"
|
||||||
#include "kern_clkrst_registers.hpp"
|
|
||||||
#include "kern_evp_registers.hpp"
|
|
||||||
#include "kern_flow_registers.hpp"
|
|
||||||
#include "kern_ictlr_registers.hpp"
|
#include "kern_ictlr_registers.hpp"
|
||||||
#include "kern_pmc_registers.hpp"
|
|
||||||
#include "kern_sema_registers.hpp"
|
#include "kern_sema_registers.hpp"
|
||||||
|
|
||||||
namespace ams::kern::board::nintendo::nx::lps {
|
namespace ams::kern::board::nintendo::nx::lps {
|
||||||
|
|||||||
@@ -1,526 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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
|
|
||||||
|
|
||||||
#define MC_INTSTATUS 0x0
|
|
||||||
#define MC_INTMASK 0x4
|
|
||||||
#define MC_ERR_STATUS 0x8
|
|
||||||
#define MC_ERR_ADR 0xc
|
|
||||||
#define MC_SMMU_CONFIG 0x10
|
|
||||||
#define MC_SMMU_TLB_CONFIG 0x14
|
|
||||||
#define MC_SMMU_PTC_CONFIG 0x18
|
|
||||||
#define MC_SMMU_PTB_ASID 0x1c
|
|
||||||
#define MC_SMMU_PTB_DATA 0x20
|
|
||||||
#define MC_SMMU_TLB_FLUSH 0x30
|
|
||||||
#define MC_SMMU_PTC_FLUSH_0 0x34
|
|
||||||
#define MC_SMMU_PTC_FLUSH_1 0x9b8
|
|
||||||
#define MC_SMMU_ASID_SECURITY 0x38
|
|
||||||
#define MC_SMMU_ASID_SECURITY_1 0x3c
|
|
||||||
#define MC_SMMU_ASID_SECURITY_2 0x9e0
|
|
||||||
#define MC_SMMU_ASID_SECURITY_3 0x9e4
|
|
||||||
#define MC_SMMU_ASID_SECURITY_4 0x9e8
|
|
||||||
#define MC_SMMU_ASID_SECURITY_5 0x9ec
|
|
||||||
#define MC_SMMU_ASID_SECURITY_6 0x9f0
|
|
||||||
#define MC_SMMU_ASID_SECURITY_7 0x9f4
|
|
||||||
#define MC_SMMU_AFI_ASID 0x238
|
|
||||||
#define MC_SMMU_AVPC_ASID 0x23c
|
|
||||||
#define MC_SMMU_DC_ASID 0x240
|
|
||||||
#define MC_SMMU_DCB_ASID 0x244
|
|
||||||
#define MC_SMMU_HC_ASID 0x250
|
|
||||||
#define MC_SMMU_HDA_ASID 0x254
|
|
||||||
#define MC_SMMU_ISP2_ASID 0x258
|
|
||||||
#define MC_SMMU_MSENC_NVENC_ASID 0x264
|
|
||||||
#define MC_SMMU_NV_ASID 0x268
|
|
||||||
#define MC_SMMU_NV2_ASID 0x26c
|
|
||||||
#define MC_SMMU_PPCS_ASID 0x270
|
|
||||||
#define MC_SMMU_SATA_ASID 0x274
|
|
||||||
#define MC_SMMU_VDE_ASID 0x27c
|
|
||||||
#define MC_SMMU_VI_ASID 0x280
|
|
||||||
#define MC_SMMU_VIC_ASID 0x284
|
|
||||||
#define MC_SMMU_XUSB_HOST_ASID 0x288
|
|
||||||
#define MC_SMMU_XUSB_DEV_ASID 0x28c
|
|
||||||
#define MC_SMMU_TSEC_ASID 0x294
|
|
||||||
#define MC_SMMU_PPCS1_ASID 0x298
|
|
||||||
#define MC_SMMU_DC1_ASID 0xa88
|
|
||||||
#define MC_SMMU_SDMMC1A_ASID 0xa94
|
|
||||||
#define MC_SMMU_SDMMC2A_ASID 0xa98
|
|
||||||
#define MC_SMMU_SDMMC3A_ASID 0xa9c
|
|
||||||
#define MC_SMMU_SDMMC4A_ASID 0xaa0
|
|
||||||
#define MC_SMMU_ISP2B_ASID 0xaa4
|
|
||||||
#define MC_SMMU_GPU_ASID 0xaa8
|
|
||||||
#define MC_SMMU_GPUB_ASID 0xaac
|
|
||||||
#define MC_SMMU_PPCS2_ASID 0xab0
|
|
||||||
#define MC_SMMU_NVDEC_ASID 0xab4
|
|
||||||
#define MC_SMMU_APE_ASID 0xab8
|
|
||||||
#define MC_SMMU_SE_ASID 0xabc
|
|
||||||
#define MC_SMMU_NVJPG_ASID 0xac0
|
|
||||||
#define MC_SMMU_HC1_ASID 0xac4
|
|
||||||
#define MC_SMMU_SE1_ASID 0xac8
|
|
||||||
#define MC_SMMU_AXIAP_ASID 0xacc
|
|
||||||
#define MC_SMMU_ETR_ASID 0xad0
|
|
||||||
#define MC_SMMU_TSECB_ASID 0xad4
|
|
||||||
#define MC_SMMU_TSEC1_ASID 0xad8
|
|
||||||
#define MC_SMMU_TSECB1_ASID 0xadc
|
|
||||||
#define MC_SMMU_NVDEC1_ASID 0xae0
|
|
||||||
#define MC_SMMU_TRANSLATION_ENABLE_0 0x228
|
|
||||||
#define MC_SMMU_TRANSLATION_ENABLE_1 0x22c
|
|
||||||
#define MC_SMMU_TRANSLATION_ENABLE_2 0x230
|
|
||||||
#define MC_SMMU_TRANSLATION_ENABLE_3 0x234
|
|
||||||
#define MC_SMMU_TRANSLATION_ENABLE_4 0xb98
|
|
||||||
#define MC_PCFIFO_CLIENT_CONFIG0 0xdd0
|
|
||||||
#define MC_PCFIFO_CLIENT_CONFIG1 0xdd4
|
|
||||||
#define MC_PCFIFO_CLIENT_CONFIG2 0xdd8
|
|
||||||
#define MC_PCFIFO_CLIENT_CONFIG3 0xddc
|
|
||||||
#define MC_PCFIFO_CLIENT_CONFIG4 0xde0
|
|
||||||
#define MC_EMEM_CFG 0x50
|
|
||||||
#define MC_EMEM_ADR_CFG 0x54
|
|
||||||
#define MC_EMEM_ADR_CFG_DEV0 0x58
|
|
||||||
#define MC_EMEM_ADR_CFG_DEV1 0x5c
|
|
||||||
#define MC_EMEM_ADR_CFG_CHANNEL_MASK 0x60
|
|
||||||
#define MC_EMEM_ADR_CFG_BANK_MASK_0 0x64
|
|
||||||
#define MC_EMEM_ADR_CFG_BANK_MASK_1 0x68
|
|
||||||
#define MC_EMEM_ADR_CFG_BANK_MASK_2 0x6c
|
|
||||||
#define MC_SECURITY_CFG0 0x70
|
|
||||||
#define MC_SECURITY_CFG1 0x74
|
|
||||||
#define MC_SECURITY_CFG3 0x9bc
|
|
||||||
#define MC_SECURITY_RSV 0x7c
|
|
||||||
#define MC_EMEM_ARB_CFG 0x90
|
|
||||||
#define MC_EMEM_ARB_OUTSTANDING_REQ 0x94
|
|
||||||
#define MC_EMEM_ARB_TIMING_RCD 0x98
|
|
||||||
#define MC_EMEM_ARB_TIMING_RP 0x9c
|
|
||||||
#define MC_EMEM_ARB_TIMING_RC 0xa0
|
|
||||||
#define MC_EMEM_ARB_TIMING_RAS 0xa4
|
|
||||||
#define MC_EMEM_ARB_TIMING_FAW 0xa8
|
|
||||||
#define MC_EMEM_ARB_TIMING_RRD 0xac
|
|
||||||
#define MC_EMEM_ARB_TIMING_RAP2PRE 0xb0
|
|
||||||
#define MC_EMEM_ARB_TIMING_WAP2PRE 0xb4
|
|
||||||
#define MC_EMEM_ARB_TIMING_R2R 0xb8
|
|
||||||
#define MC_EMEM_ARB_TIMING_W2W 0xbc
|
|
||||||
#define MC_EMEM_ARB_TIMING_R2W 0xc0
|
|
||||||
#define MC_EMEM_ARB_TIMING_W2R 0xc4
|
|
||||||
#define MC_EMEM_ARB_TIMING_RFCPB 0x6c0
|
|
||||||
#define MC_EMEM_ARB_TIMING_CCDMW 0x6c4
|
|
||||||
#define MC_EMEM_ARB_REFPB_HP_CTRL 0x6f0
|
|
||||||
#define MC_EMEM_ARB_REFPB_BANK_CTRL 0x6f4
|
|
||||||
#define MC_EMEM_ARB_DA_TURNS 0xd0
|
|
||||||
#define MC_EMEM_ARB_DA_COVERS 0xd4
|
|
||||||
#define MC_EMEM_ARB_MISC0 0xd8
|
|
||||||
#define MC_EMEM_ARB_MISC1 0xdc
|
|
||||||
#define MC_EMEM_ARB_MISC2 0xc8
|
|
||||||
#define MC_EMEM_ARB_RING1_THROTTLE 0xe0
|
|
||||||
#define MC_EMEM_ARB_RING3_THROTTLE 0xe4
|
|
||||||
#define MC_EMEM_ARB_NISO_THROTTLE 0x6b0
|
|
||||||
#define MC_EMEM_ARB_OVERRIDE 0xe8
|
|
||||||
#define MC_EMEM_ARB_RSV 0xec
|
|
||||||
#define MC_CLKEN_OVERRIDE 0xf4
|
|
||||||
#define MC_TIMING_CONTROL_DBG 0xf8
|
|
||||||
#define MC_TIMING_CONTROL 0xfc
|
|
||||||
#define MC_STAT_CONTROL 0x100
|
|
||||||
#define MC_STAT_STATUS 0x104
|
|
||||||
#define MC_STAT_EMC_CLOCK_LIMIT 0x108
|
|
||||||
#define MC_STAT_EMC_CLOCK_LIMIT_MSBS 0x10c
|
|
||||||
#define MC_STAT_EMC_CLOCKS 0x110
|
|
||||||
#define MC_STAT_EMC_CLOCKS_MSBS 0x114
|
|
||||||
#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_LO 0x118
|
|
||||||
#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_LO 0x158
|
|
||||||
#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_HI 0x11c
|
|
||||||
#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_HI 0x15c
|
|
||||||
#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_UPPER 0xa20
|
|
||||||
#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_UPPER 0xa24
|
|
||||||
#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_LO 0x198
|
|
||||||
#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_LO 0x1a8
|
|
||||||
#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_HI 0x19c
|
|
||||||
#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_HI 0x1ac
|
|
||||||
#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_UPPER 0xa28
|
|
||||||
#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_UPPER 0xa2c
|
|
||||||
#define MC_STAT_EMC_FILTER_SET0_ASID 0x1a0
|
|
||||||
#define MC_STAT_EMC_FILTER_SET1_ASID 0x1b0
|
|
||||||
#define MC_STAT_EMC_FILTER_SET0_SLACK_LIMIT 0x120
|
|
||||||
#define MC_STAT_EMC_FILTER_SET1_SLACK_LIMIT 0x160
|
|
||||||
#define MC_STAT_EMC_FILTER_SET0_CLIENT_0 0x128
|
|
||||||
#define MC_STAT_EMC_FILTER_SET1_CLIENT_0 0x168
|
|
||||||
#define MC_STAT_EMC_FILTER_SET0_CLIENT_1 0x12c
|
|
||||||
#define MC_STAT_EMC_FILTER_SET1_CLIENT_1 0x16c
|
|
||||||
#define MC_STAT_EMC_FILTER_SET0_CLIENT_2 0x130
|
|
||||||
#define MC_STAT_EMC_FILTER_SET1_CLIENT_2 0x170
|
|
||||||
#define MC_STAT_EMC_FILTER_SET0_CLIENT_3 0x134
|
|
||||||
#define MC_STAT_EMC_FILTER_SET0_CLIENT_4 0xb88
|
|
||||||
#define MC_STAT_EMC_FILTER_SET1_CLIENT_3 0x174
|
|
||||||
#define MC_STAT_EMC_FILTER_SET1_CLIENT_4 0xb8c
|
|
||||||
#define MC_STAT_EMC_SET0_COUNT 0x138
|
|
||||||
#define MC_STAT_EMC_SET0_COUNT_MSBS 0x13c
|
|
||||||
#define MC_STAT_EMC_SET1_COUNT 0x178
|
|
||||||
#define MC_STAT_EMC_SET1_COUNT_MSBS 0x17c
|
|
||||||
#define MC_STAT_EMC_SET0_SLACK_ACCUM 0x140
|
|
||||||
#define MC_STAT_EMC_SET0_SLACK_ACCUM_MSBS 0x144
|
|
||||||
#define MC_STAT_EMC_SET1_SLACK_ACCUM 0x180
|
|
||||||
#define MC_STAT_EMC_SET1_SLACK_ACCUM_MSBS 0x184
|
|
||||||
#define MC_STAT_EMC_SET0_HISTO_COUNT 0x148
|
|
||||||
#define MC_STAT_EMC_SET0_HISTO_COUNT_MSBS 0x14c
|
|
||||||
#define MC_STAT_EMC_SET1_HISTO_COUNT 0x188
|
|
||||||
#define MC_STAT_EMC_SET1_HISTO_COUNT_MSBS 0x18c
|
|
||||||
#define MC_STAT_EMC_SET0_MINIMUM_SLACK_OBSERVED 0x150
|
|
||||||
#define MC_STAT_EMC_SET1_MINIMUM_SLACK_OBSERVED 0x190
|
|
||||||
#define MC_STAT_EMC_SET0_IDLE_CYCLE_COUNT 0x1b8
|
|
||||||
#define MC_STAT_EMC_SET0_IDLE_CYCL_COUNT_MSBS 0x1bc
|
|
||||||
#define MC_STAT_EMC_SET1_IDLE_CYCLE_COUNT 0x1c8
|
|
||||||
#define MC_STAT_EMC_SET1_IDLE_CYCL_COUNT_MSBS 0x1cc
|
|
||||||
#define MC_STAT_EMC_SET0_IDLE_CYCLE_PARTITION_SELECT 0x1c0
|
|
||||||
#define MC_STAT_EMC_SET1_IDLE_CYCLE_PARTITION_SELECT 0x1d0
|
|
||||||
#define MC_CLIENT_HOTRESET_CTRL 0x200
|
|
||||||
#define MC_CLIENT_HOTRESET_CTRL_1 0x970
|
|
||||||
#define MC_CLIENT_HOTRESET_STATUS 0x204
|
|
||||||
#define MC_CLIENT_HOTRESET_STATUS_1 0x974
|
|
||||||
#define MC_EMEM_ARB_ISOCHRONOUS_0 0x208
|
|
||||||
#define MC_EMEM_ARB_ISOCHRONOUS_1 0x20c
|
|
||||||
#define MC_EMEM_ARB_ISOCHRONOUS_2 0x210
|
|
||||||
#define MC_EMEM_ARB_ISOCHRONOUS_3 0x214
|
|
||||||
#define MC_EMEM_ARB_ISOCHRONOUS_4 0xb94
|
|
||||||
#define MC_EMEM_ARB_HYSTERESIS_0 0x218
|
|
||||||
#define MC_EMEM_ARB_HYSTERESIS_1 0x21c
|
|
||||||
#define MC_EMEM_ARB_HYSTERESIS_2 0x220
|
|
||||||
#define MC_EMEM_ARB_HYSTERESIS_3 0x224
|
|
||||||
#define MC_EMEM_ARB_HYSTERESIS_4 0xb84
|
|
||||||
#define MC_EMEM_ARB_DHYSTERESIS_0 0xbb0
|
|
||||||
#define MC_EMEM_ARB_DHYSTERESIS_1 0xbb4
|
|
||||||
#define MC_EMEM_ARB_DHYSTERESIS_2 0xbb8
|
|
||||||
#define MC_EMEM_ARB_DHYSTERESIS_3 0xbbc
|
|
||||||
#define MC_EMEM_ARB_DHYSTERESIS_4 0xbc0
|
|
||||||
#define MC_EMEM_ARB_DHYST_CTRL 0xbcc
|
|
||||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_0 0xbd0
|
|
||||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_1 0xbd4
|
|
||||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_2 0xbd8
|
|
||||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_3 0xbdc
|
|
||||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_4 0xbe0
|
|
||||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_5 0xbe4
|
|
||||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_6 0xbe8
|
|
||||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_7 0xbec
|
|
||||||
#define MC_RESERVED_RSV 0x3fc
|
|
||||||
#define MC_DISB_EXTRA_SNAP_LEVELS 0x408
|
|
||||||
#define MC_APB_EXTRA_SNAP_LEVELS 0x2a4
|
|
||||||
#define MC_AHB_EXTRA_SNAP_LEVELS 0x2a0
|
|
||||||
#define MC_USBD_EXTRA_SNAP_LEVELS 0xa18
|
|
||||||
#define MC_ISP_EXTRA_SNAP_LEVELS 0xa08
|
|
||||||
#define MC_AUD_EXTRA_SNAP_LEVELS 0xa10
|
|
||||||
#define MC_MSE_EXTRA_SNAP_LEVELS 0x40c
|
|
||||||
#define MC_GK2_EXTRA_SNAP_LEVELS 0xa40
|
|
||||||
#define MC_A9AVPPC_EXTRA_SNAP_LEVELS 0x414
|
|
||||||
#define MC_FTOP_EXTRA_SNAP_LEVELS 0x2bc
|
|
||||||
#define MC_JPG_EXTRA_SNAP_LEVELS 0xa3c
|
|
||||||
#define MC_HOST_EXTRA_SNAP_LEVELS 0xa14
|
|
||||||
#define MC_SAX_EXTRA_SNAP_LEVELS 0x2c0
|
|
||||||
#define MC_DIS_EXTRA_SNAP_LEVELS 0x2ac
|
|
||||||
#define MC_VICPC_EXTRA_SNAP_LEVELS 0xa1c
|
|
||||||
#define MC_HDAPC_EXTRA_SNAP_LEVELS 0xa48
|
|
||||||
#define MC_AVP_EXTRA_SNAP_LEVELS 0x2a8
|
|
||||||
#define MC_USBX_EXTRA_SNAP_LEVELS 0x404
|
|
||||||
#define MC_PCX_EXTRA_SNAP_LEVELS 0x2b8
|
|
||||||
#define MC_SD_EXTRA_SNAP_LEVELS 0xa04
|
|
||||||
#define MC_DFD_EXTRA_SNAP_LEVELS 0xa4c
|
|
||||||
#define MC_VE_EXTRA_SNAP_LEVELS 0x2d8
|
|
||||||
#define MC_GK_EXTRA_SNAP_LEVELS 0xa00
|
|
||||||
#define MC_VE2_EXTRA_SNAP_LEVELS 0x410
|
|
||||||
#define MC_SDM_EXTRA_SNAP_LEVELS 0xa44
|
|
||||||
#define MC_VIDEO_PROTECT_BOM 0x648
|
|
||||||
#define MC_VIDEO_PROTECT_SIZE_MB 0x64c
|
|
||||||
#define MC_VIDEO_PROTECT_BOM_ADR_HI 0x978
|
|
||||||
#define MC_VIDEO_PROTECT_REG_CTRL 0x650
|
|
||||||
#define MC_ERR_VPR_STATUS 0x654
|
|
||||||
#define MC_ERR_VPR_ADR 0x658
|
|
||||||
#define MC_VIDEO_PROTECT_VPR_OVERRIDE 0x418
|
|
||||||
#define MC_VIDEO_PROTECT_VPR_OVERRIDE1 0x590
|
|
||||||
#define MC_IRAM_BOM 0x65c
|
|
||||||
#define MC_IRAM_TOM 0x660
|
|
||||||
#define MC_IRAM_ADR_HI 0x980
|
|
||||||
#define MC_IRAM_REG_CTRL 0x964
|
|
||||||
#define MC_EMEM_CFG_ACCESS_CTRL 0x664
|
|
||||||
#define MC_TZ_SECURITY_CTRL 0x668
|
|
||||||
#define MC_EMEM_ARB_OUTSTANDING_REQ_RING3 0x66c
|
|
||||||
#define MC_EMEM_ARB_OUTSTANDING_REQ_NISO 0x6b4
|
|
||||||
#define MC_EMEM_ARB_RING0_THROTTLE_MASK 0x6bc
|
|
||||||
#define MC_EMEM_ARB_NISO_THROTTLE_MASK 0x6b8
|
|
||||||
#define MC_EMEM_ARB_NISO_THROTTLE_MASK_1 0xb80
|
|
||||||
#define MC_SEC_CARVEOUT_BOM 0x670
|
|
||||||
#define MC_SEC_CARVEOUT_SIZE_MB 0x674
|
|
||||||
#define MC_SEC_CARVEOUT_ADR_HI 0x9d4
|
|
||||||
#define MC_SEC_CARVEOUT_REG_CTRL 0x678
|
|
||||||
#define MC_ERR_SEC_STATUS 0x67c
|
|
||||||
#define MC_ERR_SEC_ADR 0x680
|
|
||||||
#define MC_PC_IDLE_CLOCK_GATE_CONFIG 0x684
|
|
||||||
#define MC_STUTTER_CONTROL 0x688
|
|
||||||
#define MC_RESERVED_RSV_1 0x958
|
|
||||||
#define MC_DVFS_PIPE_SELECT 0x95c
|
|
||||||
#define MC_AHB_PTSA_MIN 0x4e0
|
|
||||||
#define MC_AUD_PTSA_MIN 0x54c
|
|
||||||
#define MC_MLL_MPCORER_PTSA_RATE 0x44c
|
|
||||||
#define MC_RING2_PTSA_RATE 0x440
|
|
||||||
#define MC_USBD_PTSA_RATE 0x530
|
|
||||||
#define MC_USBX_PTSA_MIN 0x528
|
|
||||||
#define MC_USBD_PTSA_MIN 0x534
|
|
||||||
#define MC_APB_PTSA_MAX 0x4f0
|
|
||||||
#define MC_JPG_PTSA_RATE 0x584
|
|
||||||
#define MC_DIS_PTSA_MIN 0x420
|
|
||||||
#define MC_AVP_PTSA_MAX 0x4fc
|
|
||||||
#define MC_AVP_PTSA_RATE 0x4f4
|
|
||||||
#define MC_RING1_PTSA_MIN 0x480
|
|
||||||
#define MC_DIS_PTSA_MAX 0x424
|
|
||||||
#define MC_SD_PTSA_MAX 0x4d8
|
|
||||||
#define MC_MSE_PTSA_RATE 0x4c4
|
|
||||||
#define MC_VICPC_PTSA_MIN 0x558
|
|
||||||
#define MC_PCX_PTSA_MAX 0x4b4
|
|
||||||
#define MC_ISP_PTSA_RATE 0x4a0
|
|
||||||
#define MC_A9AVPPC_PTSA_MIN 0x48c
|
|
||||||
#define MC_RING2_PTSA_MAX 0x448
|
|
||||||
#define MC_AUD_PTSA_RATE 0x548
|
|
||||||
#define MC_HOST_PTSA_MIN 0x51c
|
|
||||||
#define MC_MLL_MPCORER_PTSA_MAX 0x454
|
|
||||||
#define MC_SD_PTSA_MIN 0x4d4
|
|
||||||
#define MC_RING1_PTSA_RATE 0x47c
|
|
||||||
#define MC_JPG_PTSA_MIN 0x588
|
|
||||||
#define MC_HDAPC_PTSA_MIN 0x62c
|
|
||||||
#define MC_AVP_PTSA_MIN 0x4f8
|
|
||||||
#define MC_JPG_PTSA_MAX 0x58c
|
|
||||||
#define MC_VE_PTSA_MAX 0x43c
|
|
||||||
#define MC_DFD_PTSA_MAX 0x63c
|
|
||||||
#define MC_VICPC_PTSA_RATE 0x554
|
|
||||||
#define MC_GK_PTSA_MAX 0x544
|
|
||||||
#define MC_VICPC_PTSA_MAX 0x55c
|
|
||||||
#define MC_SDM_PTSA_MAX 0x624
|
|
||||||
#define MC_SAX_PTSA_RATE 0x4b8
|
|
||||||
#define MC_PCX_PTSA_MIN 0x4b0
|
|
||||||
#define MC_APB_PTSA_MIN 0x4ec
|
|
||||||
#define MC_GK2_PTSA_MIN 0x614
|
|
||||||
#define MC_PCX_PTSA_RATE 0x4ac
|
|
||||||
#define MC_RING1_PTSA_MAX 0x484
|
|
||||||
#define MC_HDAPC_PTSA_RATE 0x628
|
|
||||||
#define MC_MLL_MPCORER_PTSA_MIN 0x450
|
|
||||||
#define MC_GK2_PTSA_MAX 0x618
|
|
||||||
#define MC_AUD_PTSA_MAX 0x550
|
|
||||||
#define MC_GK2_PTSA_RATE 0x610
|
|
||||||
#define MC_ISP_PTSA_MAX 0x4a8
|
|
||||||
#define MC_DISB_PTSA_RATE 0x428
|
|
||||||
#define MC_VE2_PTSA_MAX 0x49c
|
|
||||||
#define MC_DFD_PTSA_MIN 0x638
|
|
||||||
#define MC_FTOP_PTSA_RATE 0x50c
|
|
||||||
#define MC_A9AVPPC_PTSA_RATE 0x488
|
|
||||||
#define MC_VE2_PTSA_MIN 0x498
|
|
||||||
#define MC_USBX_PTSA_MAX 0x52c
|
|
||||||
#define MC_DIS_PTSA_RATE 0x41c
|
|
||||||
#define MC_USBD_PTSA_MAX 0x538
|
|
||||||
#define MC_A9AVPPC_PTSA_MAX 0x490
|
|
||||||
#define MC_USBX_PTSA_RATE 0x524
|
|
||||||
#define MC_FTOP_PTSA_MAX 0x514
|
|
||||||
#define MC_HDAPC_PTSA_MAX 0x630
|
|
||||||
#define MC_SD_PTSA_RATE 0x4d0
|
|
||||||
#define MC_DFD_PTSA_RATE 0x634
|
|
||||||
#define MC_FTOP_PTSA_MIN 0x510
|
|
||||||
#define MC_SDM_PTSA_RATE 0x61c
|
|
||||||
#define MC_AHB_PTSA_RATE 0x4dc
|
|
||||||
#define MC_SMMU_SMMU_PTSA_MAX 0x460
|
|
||||||
#define MC_RING2_PTSA_MIN 0x444
|
|
||||||
#define MC_SDM_PTSA_MIN 0x620
|
|
||||||
#define MC_APB_PTSA_RATE 0x4e8
|
|
||||||
#define MC_MSE_PTSA_MIN 0x4c8
|
|
||||||
#define MC_HOST_PTSA_RATE 0x518
|
|
||||||
#define MC_VE_PTSA_RATE 0x434
|
|
||||||
#define MC_AHB_PTSA_MAX 0x4e4
|
|
||||||
#define MC_SAX_PTSA_MIN 0x4bc
|
|
||||||
#define MC_SMMU_SMMU_PTSA_MIN 0x45c
|
|
||||||
#define MC_ISP_PTSA_MIN 0x4a4
|
|
||||||
#define MC_HOST_PTSA_MAX 0x520
|
|
||||||
#define MC_SAX_PTSA_MAX 0x4c0
|
|
||||||
#define MC_VE_PTSA_MIN 0x438
|
|
||||||
#define MC_GK_PTSA_MIN 0x540
|
|
||||||
#define MC_MSE_PTSA_MAX 0x4cc
|
|
||||||
#define MC_DISB_PTSA_MAX 0x430
|
|
||||||
#define MC_DISB_PTSA_MIN 0x42c
|
|
||||||
#define MC_SMMU_SMMU_PTSA_RATE 0x458
|
|
||||||
#define MC_VE2_PTSA_RATE 0x494
|
|
||||||
#define MC_GK_PTSA_RATE 0x53c
|
|
||||||
#define MC_PTSA_GRANT_DECREMENT 0x960
|
|
||||||
#define MC_LATENCY_ALLOWANCE_AVPC_0 0x2e4
|
|
||||||
#define MC_LATENCY_ALLOWANCE_AXIAP_0 0x3a0
|
|
||||||
#define MC_LATENCY_ALLOWANCE_XUSB_1 0x380
|
|
||||||
#define MC_LATENCY_ALLOWANCE_ISP2B_0 0x384
|
|
||||||
#define MC_LATENCY_ALLOWANCE_SDMMCAA_0 0x3bc
|
|
||||||
#define MC_LATENCY_ALLOWANCE_SDMMCA_0 0x3b8
|
|
||||||
#define MC_LATENCY_ALLOWANCE_ISP2_0 0x370
|
|
||||||
#define MC_LATENCY_ALLOWANCE_SE_0 0x3e0
|
|
||||||
#define MC_LATENCY_ALLOWANCE_ISP2_1 0x374
|
|
||||||
#define MC_LATENCY_ALLOWANCE_DC_0 0x2e8
|
|
||||||
#define MC_LATENCY_ALLOWANCE_VIC_0 0x394
|
|
||||||
#define MC_LATENCY_ALLOWANCE_DCB_1 0x2f8
|
|
||||||
#define MC_LATENCY_ALLOWANCE_NVDEC_0 0x3d8
|
|
||||||
#define MC_LATENCY_ALLOWANCE_DCB_2 0x2fc
|
|
||||||
#define MC_LATENCY_ALLOWANCE_TSEC_0 0x390
|
|
||||||
#define MC_LATENCY_ALLOWANCE_DC_2 0x2f0
|
|
||||||
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0AB 0x694
|
|
||||||
#define MC_LATENCY_ALLOWANCE_PPCS_1 0x348
|
|
||||||
#define MC_LATENCY_ALLOWANCE_XUSB_0 0x37c
|
|
||||||
#define MC_LATENCY_ALLOWANCE_PPCS_0 0x344
|
|
||||||
#define MC_LATENCY_ALLOWANCE_TSECB_0 0x3f0
|
|
||||||
#define MC_LATENCY_ALLOWANCE_AFI_0 0x2e0
|
|
||||||
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0B 0x698
|
|
||||||
#define MC_LATENCY_ALLOWANCE_DC_1 0x2ec
|
|
||||||
#define MC_LATENCY_ALLOWANCE_APE_0 0x3dc
|
|
||||||
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0C 0x6a0
|
|
||||||
#define MC_LATENCY_ALLOWANCE_A9AVP_0 0x3a4
|
|
||||||
#define MC_LATENCY_ALLOWANCE_GPU2_0 0x3e8
|
|
||||||
#define MC_LATENCY_ALLOWANCE_DCB_0 0x2f4
|
|
||||||
#define MC_LATENCY_ALLOWANCE_HC_1 0x314
|
|
||||||
#define MC_LATENCY_ALLOWANCE_SDMMC_0 0x3c0
|
|
||||||
#define MC_LATENCY_ALLOWANCE_NVJPG_0 0x3e4
|
|
||||||
#define MC_LATENCY_ALLOWANCE_PTC_0 0x34c
|
|
||||||
#define MC_LATENCY_ALLOWANCE_ETR_0 0x3ec
|
|
||||||
#define MC_LATENCY_ALLOWANCE_MPCORE_0 0x320
|
|
||||||
#define MC_LATENCY_ALLOWANCE_VI2_0 0x398
|
|
||||||
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0BB 0x69c
|
|
||||||
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0CB 0x6a4
|
|
||||||
#define MC_LATENCY_ALLOWANCE_SATA_0 0x350
|
|
||||||
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0A 0x690
|
|
||||||
#define MC_LATENCY_ALLOWANCE_HC_0 0x310
|
|
||||||
#define MC_LATENCY_ALLOWANCE_DC_3 0x3c8
|
|
||||||
#define MC_LATENCY_ALLOWANCE_GPU_0 0x3ac
|
|
||||||
#define MC_LATENCY_ALLOWANCE_SDMMCAB_0 0x3c4
|
|
||||||
#define MC_LATENCY_ALLOWANCE_ISP2B_1 0x388
|
|
||||||
#define MC_LATENCY_ALLOWANCE_NVENC_0 0x328
|
|
||||||
#define MC_LATENCY_ALLOWANCE_HDA_0 0x318
|
|
||||||
#define MC_MIN_LENGTH_APE_0 0xb34
|
|
||||||
#define MC_MIN_LENGTH_DCB_2 0x8a8
|
|
||||||
#define MC_MIN_LENGTH_A9AVP_0 0x950
|
|
||||||
#define MC_MIN_LENGTH_TSEC_0 0x93c
|
|
||||||
#define MC_MIN_LENGTH_DC_1 0x898
|
|
||||||
#define MC_MIN_LENGTH_AXIAP_0 0x94c
|
|
||||||
#define MC_MIN_LENGTH_ISP2B_0 0x930
|
|
||||||
#define MC_MIN_LENGTH_VI2_0 0x944
|
|
||||||
#define MC_MIN_LENGTH_DCB_0 0x8a0
|
|
||||||
#define MC_MIN_LENGTH_DCB_1 0x8a4
|
|
||||||
#define MC_MIN_LENGTH_PPCS_1 0x8f4
|
|
||||||
#define MC_MIN_LENGTH_NVJPG_0 0xb3c
|
|
||||||
#define MC_MIN_LENGTH_HDA_0 0x8c4
|
|
||||||
#define MC_MIN_LENGTH_NVENC_0 0x8d4
|
|
||||||
#define MC_MIN_LENGTH_SDMMC_0 0xb18
|
|
||||||
#define MC_MIN_LENGTH_ISP2B_1 0x934
|
|
||||||
#define MC_MIN_LENGTH_HC_1 0x8c0
|
|
||||||
#define MC_MIN_LENGTH_DC_3 0xb20
|
|
||||||
#define MC_MIN_LENGTH_AVPC_0 0x890
|
|
||||||
#define MC_MIN_LENGTH_VIC_0 0x940
|
|
||||||
#define MC_MIN_LENGTH_ISP2_0 0x91c
|
|
||||||
#define MC_MIN_LENGTH_HC_0 0x8bc
|
|
||||||
#define MC_MIN_LENGTH_SE_0 0xb38
|
|
||||||
#define MC_MIN_LENGTH_NVDEC_0 0xb30
|
|
||||||
#define MC_MIN_LENGTH_SATA_0 0x8fc
|
|
||||||
#define MC_MIN_LENGTH_DC_0 0x894
|
|
||||||
#define MC_MIN_LENGTH_XUSB_1 0x92c
|
|
||||||
#define MC_MIN_LENGTH_DC_2 0x89c
|
|
||||||
#define MC_MIN_LENGTH_SDMMCAA_0 0xb14
|
|
||||||
#define MC_MIN_LENGTH_GPU_0 0xb04
|
|
||||||
#define MC_MIN_LENGTH_ETR_0 0xb44
|
|
||||||
#define MC_MIN_LENGTH_AFI_0 0x88c
|
|
||||||
#define MC_MIN_LENGTH_PPCS_0 0x8f0
|
|
||||||
#define MC_MIN_LENGTH_ISP2_1 0x920
|
|
||||||
#define MC_MIN_LENGTH_XUSB_0 0x928
|
|
||||||
#define MC_MIN_LENGTH_MPCORE_0 0x8cc
|
|
||||||
#define MC_MIN_LENGTH_TSECB_0 0xb48
|
|
||||||
#define MC_MIN_LENGTH_SDMMCA_0 0xb10
|
|
||||||
#define MC_MIN_LENGTH_GPU2_0 0xb40
|
|
||||||
#define MC_MIN_LENGTH_SDMMCAB_0 0xb1c
|
|
||||||
#define MC_MIN_LENGTH_PTC_0 0x8f8
|
|
||||||
#define MC_EMEM_ARB_OVERRIDE_1 0x968
|
|
||||||
#define MC_VIDEO_PROTECT_GPU_OVERRIDE_0 0x984
|
|
||||||
#define MC_VIDEO_PROTECT_GPU_OVERRIDE_1 0x988
|
|
||||||
#define MC_EMEM_ARB_STATS_0 0x990
|
|
||||||
#define MC_EMEM_ARB_STATS_1 0x994
|
|
||||||
#define MC_MTS_CARVEOUT_BOM 0x9a0
|
|
||||||
#define MC_MTS_CARVEOUT_SIZE_MB 0x9a4
|
|
||||||
#define MC_MTS_CARVEOUT_ADR_HI 0x9a8
|
|
||||||
#define MC_MTS_CARVEOUT_REG_CTRL 0x9ac
|
|
||||||
#define MC_ERR_MTS_STATUS 0x9b0
|
|
||||||
#define MC_ERR_MTS_ADR 0x9b4
|
|
||||||
#define MC_ERR_GENERALIZED_CARVEOUT_STATUS 0xc00
|
|
||||||
#define MC_ERR_GENERALIZED_CARVEOUT_ADR 0xc04
|
|
||||||
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS2 0xd74
|
|
||||||
#define MC_SECURITY_CARVEOUT4_CFG0 0xcf8
|
|
||||||
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS2 0xd10
|
|
||||||
#define MC_SECURITY_CARVEOUT4_SIZE_128KB 0xd04
|
|
||||||
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS4 0xc28
|
|
||||||
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS1 0xc30
|
|
||||||
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS4 0xc8c
|
|
||||||
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS0 0xd1c
|
|
||||||
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS1 0xd70
|
|
||||||
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS0 0xc2c
|
|
||||||
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS4 0xd7c
|
|
||||||
#define MC_SECURITY_CARVEOUT3_SIZE_128KB 0xcb4
|
|
||||||
#define MC_SECURITY_CARVEOUT2_CFG0 0xc58
|
|
||||||
#define MC_SECURITY_CARVEOUT1_CFG0 0xc08
|
|
||||||
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS2 0xc84
|
|
||||||
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS0 0xc68
|
|
||||||
#define MC_SECURITY_CARVEOUT3_BOM 0xcac
|
|
||||||
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2 0xc70
|
|
||||||
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS3 0xd78
|
|
||||||
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS0 0xc7c
|
|
||||||
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS4 0xd18
|
|
||||||
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS1 0xcbc
|
|
||||||
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS3 0xc38
|
|
||||||
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS2 0xc34
|
|
||||||
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS2 0xcc0
|
|
||||||
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS2 0xd60
|
|
||||||
#define MC_SECURITY_CARVEOUT3_CFG0 0xca8
|
|
||||||
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS0 0xcb8
|
|
||||||
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS3 0xc88
|
|
||||||
#define MC_SECURITY_CARVEOUT2_SIZE_128KB 0xc64
|
|
||||||
#define MC_SECURITY_CARVEOUT5_BOM_HI 0xd50
|
|
||||||
#define MC_SECURITY_CARVEOUT1_SIZE_128KB 0xc14
|
|
||||||
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS3 0xd14
|
|
||||||
#define MC_SECURITY_CARVEOUT1_BOM 0xc0c
|
|
||||||
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS4 0xd2c
|
|
||||||
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS4 0xd68
|
|
||||||
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS4 0xcc8
|
|
||||||
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS0 0xd58
|
|
||||||
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS2 0xd24
|
|
||||||
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS3 0xcc4
|
|
||||||
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS4 0xc78
|
|
||||||
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS1 0xc1c
|
|
||||||
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS0 0xc18
|
|
||||||
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS3 0xd28
|
|
||||||
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS1 0xd5c
|
|
||||||
#define MC_SECURITY_CARVEOUT3_BOM_HI 0xcb0
|
|
||||||
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS3 0xcd8
|
|
||||||
#define MC_SECURITY_CARVEOUT2_BOM_HI 0xc60
|
|
||||||
#define MC_SECURITY_CARVEOUT4_BOM_HI 0xd00
|
|
||||||
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS3 0xd64
|
|
||||||
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS4 0xcdc
|
|
||||||
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS1 0xc80
|
|
||||||
#define MC_SECURITY_CARVEOUT5_SIZE_128KB 0xd54
|
|
||||||
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS1 0xd20
|
|
||||||
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS2 0xcd4
|
|
||||||
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS1 0xd0c
|
|
||||||
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS3 0xc74
|
|
||||||
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS0 0xccc
|
|
||||||
#define MC_SECURITY_CARVEOUT4_BOM 0xcfc
|
|
||||||
#define MC_SECURITY_CARVEOUT5_CFG0 0xd48
|
|
||||||
#define MC_SECURITY_CARVEOUT2_BOM 0xc5c
|
|
||||||
#define MC_SECURITY_CARVEOUT5_BOM 0xd4c
|
|
||||||
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS3 0xc24
|
|
||||||
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS0 0xd6c
|
|
||||||
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS1 0xcd0
|
|
||||||
#define MC_SECURITY_CARVEOUT1_BOM_HI 0xc10
|
|
||||||
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS2 0xc20
|
|
||||||
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS4 0xc3c
|
|
||||||
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS1 0xc6c
|
|
||||||
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS0 0xd08
|
|
||||||
#define MC_ERR_APB_ASID_UPDATE_STATUS 0x9d0
|
|
||||||
#define MC_DA_CONFIG0 0x9dc
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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
|
|
||||||
|
|
||||||
#define APBDEV_PMC_DPD_ENABLE 0x024
|
|
||||||
#define APBDEV_PMC_SCRATCH0 0x050
|
|
||||||
#define APBDEV_PMC_SCRATCH4 0x060
|
|
||||||
#define APBDEV_PMC_SCRATCH39 0x138
|
|
||||||
@@ -37,6 +37,9 @@ namespace ams::kern::board::nintendo::nx::smc {
|
|||||||
FunctionId_Panic = 0xC3000006,
|
FunctionId_Panic = 0xC3000006,
|
||||||
FunctionId_ConfigureCarveout = 0xC3000007,
|
FunctionId_ConfigureCarveout = 0xC3000007,
|
||||||
FunctionId_ReadWriteRegister = 0xC3000008,
|
FunctionId_ReadWriteRegister = 0xC3000008,
|
||||||
|
|
||||||
|
/* NOTE: Atmosphere extension for mesosphere. This ID is subject to change at any time. */
|
||||||
|
FunctionId_SetConfig = 0xC3000409,
|
||||||
};
|
};
|
||||||
|
|
||||||
void CallPrivilegedSecureMonitorFunction(SecureMonitorArguments &args) {
|
void CallPrivilegedSecureMonitorFunction(SecureMonitorArguments &args) {
|
||||||
@@ -140,35 +143,6 @@ namespace ams::kern::board::nintendo::nx::smc {
|
|||||||
args.x[7] = x7;
|
args.x[7] = x7;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CallUserSecureMonitorFunctionForInit(SecureMonitorArguments &args) {
|
|
||||||
/* Load arguments into registers. */
|
|
||||||
register u64 x0 asm("x0") = args.x[0];
|
|
||||||
register u64 x1 asm("x1") = args.x[1];
|
|
||||||
register u64 x2 asm("x2") = args.x[2];
|
|
||||||
register u64 x3 asm("x3") = args.x[3];
|
|
||||||
register u64 x4 asm("x4") = args.x[4];
|
|
||||||
register u64 x5 asm("x5") = args.x[5];
|
|
||||||
register u64 x6 asm("x6") = args.x[6];
|
|
||||||
register u64 x7 asm("x7") = args.x[7];
|
|
||||||
|
|
||||||
/* Actually make the call. */
|
|
||||||
__asm__ __volatile__("smc #0"
|
|
||||||
: "+r"(x0), "+r"(x1), "+r"(x2), "+r"(x3), "+r"(x4), "+r"(x5), "+r"(x6), "+r"(x7)
|
|
||||||
:
|
|
||||||
: "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "cc", "memory"
|
|
||||||
);
|
|
||||||
|
|
||||||
/* Store arguments to output. */
|
|
||||||
args.x[0] = x0;
|
|
||||||
args.x[1] = x1;
|
|
||||||
args.x[2] = x2;
|
|
||||||
args.x[3] = x3;
|
|
||||||
args.x[4] = x4;
|
|
||||||
args.x[5] = x5;
|
|
||||||
args.x[6] = x6;
|
|
||||||
args.x[7] = x7;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Global lock for generate random bytes. */
|
/* Global lock for generate random bytes. */
|
||||||
KSpinLock g_generate_random_lock;
|
KSpinLock g_generate_random_lock;
|
||||||
|
|
||||||
@@ -210,21 +184,30 @@ namespace ams::kern::board::nintendo::nx::smc {
|
|||||||
return static_cast<SmcResult>(args.x[0]) == SmcResult::Success;
|
return static_cast<SmcResult>(args.x[0]) == SmcResult::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SetConfig(ConfigItem config_item, u64 value) {
|
|
||||||
SecureMonitorArguments args = { UserFunctionId_SetConfig, static_cast<u32>(config_item), 0, value };
|
|
||||||
CallUserSecureMonitorFunctionForInit(args);
|
|
||||||
return static_cast<SmcResult>(args.x[0]) == SmcResult::Success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
bool TryGetConfig(u64 *out, size_t num_qwords, ConfigItem config_item) {
|
||||||
|
|
||||||
void GetConfig(u64 *out, size_t num_qwords, ConfigItem config_item) {
|
|
||||||
SecureMonitorArguments args = { FunctionId_GetConfig, static_cast<u32>(config_item) };
|
SecureMonitorArguments args = { FunctionId_GetConfig, static_cast<u32>(config_item) };
|
||||||
CallPrivilegedSecureMonitorFunction(args);
|
CallPrivilegedSecureMonitorFunction(args);
|
||||||
MESOSPHERE_ABORT_UNLESS((static_cast<SmcResult>(args.x[0]) == SmcResult::Success));
|
if (static_cast<SmcResult>(args.x[0]) != SmcResult::Success) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < num_qwords && i < 7; i++) {
|
for (size_t i = 0; i < num_qwords && i < 7; i++) {
|
||||||
out[i] = args.x[1 + i];
|
out[i] = args.x[1 + i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetConfig(u64 *out, size_t num_qwords, ConfigItem config_item) {
|
||||||
|
MESOSPHERE_ABORT_UNLESS(TryGetConfig(out, num_qwords, config_item));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SetConfig(ConfigItem config_item, u64 value) {
|
||||||
|
SecureMonitorArguments args = { FunctionId_SetConfig, static_cast<u32>(config_item), 0, value };
|
||||||
|
CallPrivilegedSecureMonitorFunction(args);
|
||||||
|
return static_cast<SmcResult>(args.x[0]) == SmcResult::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ReadWriteRegister(u32 *out, ams::svc::PhysicalAddress address, u32 mask, u32 value) {
|
bool ReadWriteRegister(u32 *out, ams::svc::PhysicalAddress address, u32 mask, u32 value) {
|
||||||
|
|||||||
@@ -60,6 +60,10 @@ namespace ams::kern::board::nintendo::nx::smc {
|
|||||||
ExosphereNeedsShutdown = 65002,
|
ExosphereNeedsShutdown = 65002,
|
||||||
ExosphereGitCommitHash = 65003,
|
ExosphereGitCommitHash = 65003,
|
||||||
ExosphereHasRcmBugPatch = 65004,
|
ExosphereHasRcmBugPatch = 65004,
|
||||||
|
ExosphereBlankProdInfo = 65005,
|
||||||
|
ExosphereAllowCalWrites = 65006,
|
||||||
|
ExosphereEmummcType = 65007,
|
||||||
|
ExospherePayloadAddress = 65008,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class SmcResult {
|
enum class SmcResult {
|
||||||
@@ -89,12 +93,14 @@ namespace ams::kern::board::nintendo::nx::smc {
|
|||||||
UserRebootType_ToPayload = 2,
|
UserRebootType_ToPayload = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* TODO: Rest of Secure Monitor API. */
|
|
||||||
void GenerateRandomBytes(void *dst, size_t size);
|
void GenerateRandomBytes(void *dst, size_t size);
|
||||||
|
bool TryGetConfig(u64 *out, size_t num_qwords, ConfigItem config_item);
|
||||||
void GetConfig(u64 *out, size_t num_qwords, ConfigItem config_item);
|
void GetConfig(u64 *out, size_t num_qwords, ConfigItem config_item);
|
||||||
bool ReadWriteRegister(u32 *out, ams::svc::PhysicalAddress address, u32 mask, u32 value);
|
bool ReadWriteRegister(u32 *out, ams::svc::PhysicalAddress address, u32 mask, u32 value);
|
||||||
void ConfigureCarveout(size_t which, uintptr_t address, size_t size);
|
void ConfigureCarveout(size_t which, uintptr_t address, size_t size);
|
||||||
|
|
||||||
|
bool SetConfig(ConfigItem config_item, u64 value);
|
||||||
|
|
||||||
void CpuOn(u64 core_id, uintptr_t entrypoint, uintptr_t arg);
|
void CpuOn(u64 core_id, uintptr_t entrypoint, uintptr_t arg);
|
||||||
|
|
||||||
void NORETURN Panic(u32 color);
|
void NORETURN Panic(u32 color);
|
||||||
@@ -108,8 +114,6 @@ namespace ams::kern::board::nintendo::nx::smc {
|
|||||||
void GenerateRandomBytes(void *dst, size_t size);
|
void GenerateRandomBytes(void *dst, size_t size);
|
||||||
bool ReadWriteRegister(u32 *out, u64 address, u32 mask, u32 value);
|
bool ReadWriteRegister(u32 *out, u64 address, u32 mask, u32 value);
|
||||||
|
|
||||||
bool SetConfig(ConfigItem config_item, u64 value);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -17,386 +17,9 @@
|
|||||||
#include "kern_debug_log_impl.hpp"
|
#include "kern_debug_log_impl.hpp"
|
||||||
|
|
||||||
namespace ams::kern {
|
namespace ams::kern {
|
||||||
#pragma GCC push_options
|
|
||||||
#pragma GCC optimize ("-Os")
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
/* Useful definitions for our VSNPrintf implementation. */
|
|
||||||
enum FormatSpecifierFlag : u32 {
|
|
||||||
FormatSpecifierFlag_None = 0,
|
|
||||||
FormatSpecifierFlag_EmptySign = (1 << 0),
|
|
||||||
FormatSpecifierFlag_ForceSign = (1 << 1),
|
|
||||||
FormatSpecifierFlag_Hash = (1 << 2),
|
|
||||||
FormatSpecifierFlag_LeftJustify = (1 << 3),
|
|
||||||
FormatSpecifierFlag_ZeroPad = (1 << 4),
|
|
||||||
FormatSpecifierFlag_Char = (1 << 5),
|
|
||||||
FormatSpecifierFlag_Short = (1 << 6),
|
|
||||||
FormatSpecifierFlag_Long = (1 << 7),
|
|
||||||
FormatSpecifierFlag_LongLong = (1 << 8),
|
|
||||||
FormatSpecifierFlag_Uppercase = (1 << 9),
|
|
||||||
FormatSpecifierFlag_HasPrecision = (1 << 10),
|
|
||||||
};
|
|
||||||
|
|
||||||
using FormatSpecifierFlagStorage = std::underlying_type<FormatSpecifierFlag>::type;
|
|
||||||
|
|
||||||
constexpr ALWAYS_INLINE bool IsDigit(char c) {
|
|
||||||
return '0' <= c && c <= '9';
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr ALWAYS_INLINE u32 ParseU32(const char *&str) {
|
|
||||||
u32 value = 0;
|
|
||||||
do {
|
|
||||||
value = (value * 10) + static_cast<u32>(*(str++) - '0');
|
|
||||||
} while (IsDigit(*str));
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr ALWAYS_INLINE size_t Strnlen(const char *str, size_t max) {
|
|
||||||
const char *cur = str;
|
|
||||||
while (*cur && max--) {
|
|
||||||
cur++;
|
|
||||||
}
|
|
||||||
return static_cast<size_t>(cur - str);
|
|
||||||
}
|
|
||||||
|
|
||||||
ALWAYS_INLINE void VSNPrintfImpl(char * const dst, const size_t dst_size, const char *format, ::std::va_list vl) {
|
|
||||||
size_t dst_index = 0;
|
|
||||||
|
|
||||||
auto WriteCharacter = [dst, dst_size, &dst_index](char c) ALWAYS_INLINE_LAMBDA {
|
|
||||||
if (dst_index < dst_size) {
|
|
||||||
dst[dst_index++] = c;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Loop over every character in the string, looking for format specifiers. */
|
|
||||||
while (*format) {
|
|
||||||
if (const char c = *(format++); c != '%') {
|
|
||||||
WriteCharacter(c);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We have to parse a format specifier. */
|
|
||||||
/* Start by parsing flags. */
|
|
||||||
FormatSpecifierFlagStorage flags = FormatSpecifierFlag_None;
|
|
||||||
auto SetFlag = [&flags](FormatSpecifierFlag f) ALWAYS_INLINE_LAMBDA { flags |= f; };
|
|
||||||
auto ClearFlag = [&flags](FormatSpecifierFlag f) ALWAYS_INLINE_LAMBDA { flags &= ~f; };
|
|
||||||
auto HasFlag = [&flags](FormatSpecifierFlag f) ALWAYS_INLINE_LAMBDA { return (flags & f) != 0; };
|
|
||||||
{
|
|
||||||
bool parsed_flags = false;
|
|
||||||
while (!parsed_flags) {
|
|
||||||
switch (*format) {
|
|
||||||
case ' ': SetFlag(FormatSpecifierFlag_EmptySign); format++; break;
|
|
||||||
case '+': SetFlag(FormatSpecifierFlag_ForceSign); format++; break;
|
|
||||||
case '#': SetFlag(FormatSpecifierFlag_Hash); format++; break;
|
|
||||||
case '-': SetFlag(FormatSpecifierFlag_LeftJustify); format++; break;
|
|
||||||
case '0': SetFlag(FormatSpecifierFlag_ZeroPad); format++; break;
|
|
||||||
default:
|
|
||||||
parsed_flags = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Next, parse width. */
|
|
||||||
u32 width = 0;
|
|
||||||
if (IsDigit(*format)) {
|
|
||||||
/* Integer width. */
|
|
||||||
width = ParseU32(format);
|
|
||||||
} else if (*format == '*') {
|
|
||||||
/* Dynamic width. */
|
|
||||||
const int _width = va_arg(vl, int);
|
|
||||||
if (_width >= 0) {
|
|
||||||
width = static_cast<u32>(_width);
|
|
||||||
} else {
|
|
||||||
SetFlag(FormatSpecifierFlag_LeftJustify);
|
|
||||||
width = static_cast<u32>(-_width);
|
|
||||||
}
|
|
||||||
format++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Next, parse precision if present. */
|
|
||||||
u32 precision = 0;
|
|
||||||
if (*format == '.') {
|
|
||||||
SetFlag(FormatSpecifierFlag_HasPrecision);
|
|
||||||
format++;
|
|
||||||
|
|
||||||
if (IsDigit(*format)) {
|
|
||||||
/* Integer precision. */
|
|
||||||
precision = ParseU32(format);
|
|
||||||
} else if (*format == '*') {
|
|
||||||
/* Dynamic precision. */
|
|
||||||
const int _precision = va_arg(vl, int);
|
|
||||||
if (_precision > 0) {
|
|
||||||
precision = static_cast<u32>(_precision);
|
|
||||||
}
|
|
||||||
format++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Parse length. */
|
|
||||||
constexpr bool SizeIsLong = sizeof(size_t) == sizeof(long);
|
|
||||||
constexpr bool IntMaxIsLong = sizeof(intmax_t) == sizeof(long);
|
|
||||||
constexpr bool PtrDiffIsLong = sizeof(ptrdiff_t) == sizeof(long);
|
|
||||||
switch (*format) {
|
|
||||||
case 'z':
|
|
||||||
SetFlag(SizeIsLong ? FormatSpecifierFlag_Long : FormatSpecifierFlag_LongLong);
|
|
||||||
format++;
|
|
||||||
break;
|
|
||||||
case 'j':
|
|
||||||
SetFlag(IntMaxIsLong ? FormatSpecifierFlag_Long : FormatSpecifierFlag_LongLong);
|
|
||||||
format++;
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
SetFlag(PtrDiffIsLong ? FormatSpecifierFlag_Long : FormatSpecifierFlag_LongLong);
|
|
||||||
format++;
|
|
||||||
break;
|
|
||||||
case 'h':
|
|
||||||
SetFlag(FormatSpecifierFlag_Short);
|
|
||||||
format++;
|
|
||||||
if (*format == 'h') {
|
|
||||||
SetFlag(FormatSpecifierFlag_Char);
|
|
||||||
format++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'l':
|
|
||||||
SetFlag(FormatSpecifierFlag_Long);
|
|
||||||
format++;
|
|
||||||
if (*format == 'l') {
|
|
||||||
SetFlag(FormatSpecifierFlag_LongLong);
|
|
||||||
format++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char specifier = *(format++);
|
|
||||||
switch (specifier) {
|
|
||||||
case 'p':
|
|
||||||
if constexpr (sizeof(uintptr_t) == sizeof(long long)) {
|
|
||||||
SetFlag(FormatSpecifierFlag_LongLong);
|
|
||||||
} else {
|
|
||||||
SetFlag(FormatSpecifierFlag_Long);
|
|
||||||
}
|
|
||||||
SetFlag(FormatSpecifierFlag_Hash);
|
|
||||||
[[fallthrough]];
|
|
||||||
case 'd':
|
|
||||||
case 'i':
|
|
||||||
case 'u':
|
|
||||||
case 'b':
|
|
||||||
case 'o':
|
|
||||||
case 'x':
|
|
||||||
case 'X':
|
|
||||||
{
|
|
||||||
/* Determine the base to print with. */
|
|
||||||
u32 base;
|
|
||||||
switch (specifier) {
|
|
||||||
case 'b':
|
|
||||||
base = 2;
|
|
||||||
break;
|
|
||||||
case 'o':
|
|
||||||
base = 8;
|
|
||||||
break;
|
|
||||||
case 'X':
|
|
||||||
SetFlag(FormatSpecifierFlag_Uppercase);
|
|
||||||
[[fallthrough]];
|
|
||||||
case 'p':
|
|
||||||
case 'x':
|
|
||||||
base = 16;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
base = 10;
|
|
||||||
ClearFlag(FormatSpecifierFlag_Hash);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Precision implies no zero-padding. */
|
|
||||||
if (HasFlag(FormatSpecifierFlag_HasPrecision)) {
|
|
||||||
ClearFlag(FormatSpecifierFlag_ZeroPad);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Unsigned types don't get signs. */
|
|
||||||
const bool is_unsigned = base != 10 || specifier == 'u';
|
|
||||||
if (is_unsigned) {
|
|
||||||
ClearFlag(FormatSpecifierFlag_EmptySign);
|
|
||||||
ClearFlag(FormatSpecifierFlag_ForceSign);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto PrintInteger = [&](bool negative, uintmax_t value) {
|
|
||||||
constexpr size_t BufferSize = 64; /* Binary digits for 64-bit numbers may use 64 digits. */
|
|
||||||
char buf[BufferSize];
|
|
||||||
size_t len = 0;
|
|
||||||
|
|
||||||
/* No hash flag for zero. */
|
|
||||||
if (value == 0) {
|
|
||||||
ClearFlag(FormatSpecifierFlag_Hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!HasFlag(FormatSpecifierFlag_HasPrecision) || value != 0) {
|
|
||||||
do {
|
|
||||||
const char digit = static_cast<char>(value % base);
|
|
||||||
buf[len++] = (digit < 10) ? ('0' + digit) : ((HasFlag(FormatSpecifierFlag_Uppercase) ? 'A' : 'a') + digit - 10);
|
|
||||||
value /= base;
|
|
||||||
} while (value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Determine our prefix length. */
|
|
||||||
size_t prefix_len = 0;
|
|
||||||
const bool has_sign = negative || HasFlag(FormatSpecifierFlag_ForceSign) || HasFlag(FormatSpecifierFlag_EmptySign);
|
|
||||||
if (has_sign) {
|
|
||||||
prefix_len++;
|
|
||||||
}
|
|
||||||
if (HasFlag(FormatSpecifierFlag_Hash)) {
|
|
||||||
prefix_len += (base != 8) ? 2 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Determine zero-padding count. */
|
|
||||||
size_t num_zeroes = (len < precision) ? precision - len : 0;
|
|
||||||
if (!HasFlag(FormatSpecifierFlag_LeftJustify) && HasFlag(FormatSpecifierFlag_ZeroPad)) {
|
|
||||||
num_zeroes = (len + prefix_len < width) ? width - len - prefix_len : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print out left padding. */
|
|
||||||
if (!HasFlag(FormatSpecifierFlag_LeftJustify)) {
|
|
||||||
for (size_t i = len + prefix_len + num_zeroes; i < static_cast<size_t>(width); i++) {
|
|
||||||
WriteCharacter(' ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print out sign. */
|
|
||||||
if (negative) {
|
|
||||||
WriteCharacter('-');
|
|
||||||
} else if (HasFlag(FormatSpecifierFlag_ForceSign)) {
|
|
||||||
WriteCharacter('+');
|
|
||||||
} else if (HasFlag(FormatSpecifierFlag_EmptySign)) {
|
|
||||||
WriteCharacter(' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print out base prefix. */
|
|
||||||
if (HasFlag(FormatSpecifierFlag_Hash)) {
|
|
||||||
WriteCharacter('0');
|
|
||||||
if (base == 2) {
|
|
||||||
WriteCharacter('b');
|
|
||||||
} else if (base == 16) {
|
|
||||||
WriteCharacter('x');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print out zeroes. */
|
|
||||||
for (size_t i = 0; i < num_zeroes; i++) {
|
|
||||||
WriteCharacter('0');
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print out digits. */
|
|
||||||
for (size_t i = 0; i < len; i++) {
|
|
||||||
WriteCharacter(buf[len - 1 - i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print out right padding. */
|
|
||||||
if (HasFlag(FormatSpecifierFlag_LeftJustify)) {
|
|
||||||
for (size_t i = len + prefix_len + num_zeroes; i < static_cast<size_t>(width); i++) {
|
|
||||||
WriteCharacter(' ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Output the integer. */
|
|
||||||
if (is_unsigned) {
|
|
||||||
uintmax_t n = 0;
|
|
||||||
if (HasFlag(FormatSpecifierFlag_LongLong)) {
|
|
||||||
n = static_cast<unsigned long long>(va_arg(vl, unsigned long long));
|
|
||||||
} else if (HasFlag(FormatSpecifierFlag_Long)) {
|
|
||||||
n = static_cast<unsigned long>(va_arg(vl, unsigned long));
|
|
||||||
} else if (HasFlag(FormatSpecifierFlag_Char)) {
|
|
||||||
n = static_cast<unsigned char>(va_arg(vl, unsigned int));
|
|
||||||
} else if (HasFlag(FormatSpecifierFlag_Short)) {
|
|
||||||
n = static_cast<unsigned short>(va_arg(vl, unsigned int));
|
|
||||||
} else {
|
|
||||||
n = static_cast<unsigned int>(va_arg(vl, unsigned int));
|
|
||||||
}
|
|
||||||
if (specifier == 'p' && n == 0) {
|
|
||||||
WriteCharacter('(');
|
|
||||||
WriteCharacter('n');
|
|
||||||
WriteCharacter('i');
|
|
||||||
WriteCharacter('l');
|
|
||||||
WriteCharacter(')');
|
|
||||||
} else {
|
|
||||||
PrintInteger(false, n);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
intmax_t n = 0;
|
|
||||||
if (HasFlag(FormatSpecifierFlag_LongLong)) {
|
|
||||||
n = static_cast<signed long long>(va_arg(vl, signed long long));
|
|
||||||
} else if (HasFlag(FormatSpecifierFlag_Long)) {
|
|
||||||
n = static_cast<signed long>(va_arg(vl, signed long));
|
|
||||||
} else if (HasFlag(FormatSpecifierFlag_Char)) {
|
|
||||||
n = static_cast<signed char>(va_arg(vl, signed int));
|
|
||||||
} else if (HasFlag(FormatSpecifierFlag_Short)) {
|
|
||||||
n = static_cast<signed short>(va_arg(vl, signed int));
|
|
||||||
} else {
|
|
||||||
n = static_cast<signed int>(va_arg(vl, signed int));
|
|
||||||
}
|
|
||||||
const bool negative = n < 0;
|
|
||||||
const uintmax_t u = (negative) ? static_cast<uintmax_t>(-n) : static_cast<uintmax_t>(n);
|
|
||||||
PrintInteger(negative, u);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
{
|
|
||||||
size_t len = 1;
|
|
||||||
if (!HasFlag(FormatSpecifierFlag_LeftJustify)) {
|
|
||||||
while (len++ < width) {
|
|
||||||
WriteCharacter(' ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
WriteCharacter(static_cast<char>(va_arg(vl, int)));
|
|
||||||
if (HasFlag(FormatSpecifierFlag_LeftJustify)) {
|
|
||||||
while (len++ < width) {
|
|
||||||
WriteCharacter(' ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
{
|
|
||||||
const char *str = va_arg(vl, char *);
|
|
||||||
if (str == nullptr) {
|
|
||||||
str = "(null)";
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t len = Strnlen(str, precision > 0 ? precision : std::numeric_limits<size_t>::max());
|
|
||||||
if (HasFlag(FormatSpecifierFlag_HasPrecision)) {
|
|
||||||
len = (len < precision) ? len : precision;
|
|
||||||
}
|
|
||||||
if (!HasFlag(FormatSpecifierFlag_LeftJustify)) {
|
|
||||||
while (len++ < width) {
|
|
||||||
WriteCharacter(' ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (*str && (!HasFlag(FormatSpecifierFlag_HasPrecision) || (precision--) != 0)) {
|
|
||||||
WriteCharacter(*(str++));
|
|
||||||
}
|
|
||||||
if (HasFlag(FormatSpecifierFlag_LeftJustify)) {
|
|
||||||
while (len++ < width) {
|
|
||||||
WriteCharacter(' ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case '%':
|
|
||||||
default:
|
|
||||||
WriteCharacter(specifier);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ensure null termination. */
|
|
||||||
WriteCharacter('\0');
|
|
||||||
dst[dst_size - 1] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
KSpinLock g_debug_log_lock;
|
KSpinLock g_debug_log_lock;
|
||||||
bool g_initialized_impl;
|
bool g_initialized_impl;
|
||||||
|
|
||||||
@@ -452,9 +75,6 @@ namespace ams::kern {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#pragma GCC pop_options
|
|
||||||
|
|
||||||
void KDebugLog::Initialize() {
|
void KDebugLog::Initialize() {
|
||||||
if (KTargetSystem::IsDebugLoggingEnabled()) {
|
if (KTargetSystem::IsDebugLoggingEnabled()) {
|
||||||
KScopedInterruptDisable di;
|
KScopedInterruptDisable di;
|
||||||
@@ -486,7 +106,7 @@ namespace ams::kern {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void KDebugLog::VSNPrintf(char *dst, const size_t dst_size, const char *format, ::std::va_list vl) {
|
void KDebugLog::VSNPrintf(char *dst, const size_t dst_size, const char *format, ::std::va_list vl) {
|
||||||
VSNPrintfImpl(dst, dst_size, format, vl);
|
::ams::util::TVSNPrintf(dst, dst_size, format, vl);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result KDebugLog::PrintUserString(ams::kern::svc::KUserPointer<const char *> user_str, size_t len) {
|
Result KDebugLog::PrintUserString(ams::kern::svc::KUserPointer<const char *> user_str, size_t len) {
|
||||||
|
|||||||
@@ -73,15 +73,16 @@ namespace ams::kern {
|
|||||||
s32 num_waiters = 0;
|
s32 num_waiters = 0;
|
||||||
{
|
{
|
||||||
KScopedSchedulerLock sl;
|
KScopedSchedulerLock sl;
|
||||||
g_cv_arbiter_compare_thread.SetupForAddressArbiterCompare(addr, -1);
|
|
||||||
|
|
||||||
auto it = this->tree.nfind(g_cv_arbiter_compare_thread);
|
|
||||||
|
|
||||||
/* Check the userspace value. */
|
/* Check the userspace value. */
|
||||||
s32 user_value;
|
s32 user_value;
|
||||||
R_UNLESS(UpdateIfEqual(std::addressof(user_value), addr, value, value + 1), svc::ResultInvalidCurrentMemory());
|
R_UNLESS(UpdateIfEqual(std::addressof(user_value), addr, value, value + 1), svc::ResultInvalidCurrentMemory());
|
||||||
R_UNLESS(user_value == value, svc::ResultInvalidState());
|
R_UNLESS(user_value == value, svc::ResultInvalidState());
|
||||||
|
|
||||||
|
g_cv_arbiter_compare_thread.SetupForAddressArbiterCompare(addr, -1);
|
||||||
|
|
||||||
|
auto it = this->tree.nfind(g_cv_arbiter_compare_thread);
|
||||||
|
|
||||||
while ((it != this->tree.end()) && (count <= 0 || num_waiters < count) && (it->GetAddressArbiterKey() == addr)) {
|
while ((it != this->tree.end()) && (count <= 0 || num_waiters < count) && (it->GetAddressArbiterKey() == addr)) {
|
||||||
KThread *target_thread = std::addressof(*it);
|
KThread *target_thread = std::addressof(*it);
|
||||||
target_thread->SetSyncedObject(nullptr, ResultSuccess());
|
target_thread->SetSyncedObject(nullptr, ResultSuccess());
|
||||||
@@ -108,6 +109,33 @@ namespace ams::kern {
|
|||||||
|
|
||||||
/* Determine the updated value. */
|
/* Determine the updated value. */
|
||||||
s32 new_value;
|
s32 new_value;
|
||||||
|
if (GetTargetFirmware() >= TargetFirmware_7_0_0) {
|
||||||
|
if (count <= 0) {
|
||||||
|
if ((it != this->tree.end()) && (it->GetAddressArbiterKey() == addr)) {
|
||||||
|
new_value = value - 2;
|
||||||
|
} else {
|
||||||
|
new_value = value + 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((it != this->tree.end()) && (it->GetAddressArbiterKey() == addr)) {
|
||||||
|
auto tmp_it = it;
|
||||||
|
s32 tmp_num_waiters = 0;
|
||||||
|
while ((++tmp_it != this->tree.end()) && (tmp_it->GetAddressArbiterKey() == addr)) {
|
||||||
|
if ((tmp_num_waiters++) >= count) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmp_num_waiters < count) {
|
||||||
|
new_value = value - 1;
|
||||||
|
} else {
|
||||||
|
new_value = value;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
new_value = value + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if (count <= 0) {
|
if (count <= 0) {
|
||||||
if ((it != this->tree.end()) && (it->GetAddressArbiterKey() == addr)) {
|
if ((it != this->tree.end()) && (it->GetAddressArbiterKey() == addr)) {
|
||||||
new_value = value - 1;
|
new_value = value - 1;
|
||||||
@@ -116,7 +144,7 @@ namespace ams::kern {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto tmp_it = it;
|
auto tmp_it = it;
|
||||||
int tmp_num_waiters = 0;
|
s32 tmp_num_waiters = 0;
|
||||||
while ((tmp_it != this->tree.end()) && (tmp_it->GetAddressArbiterKey() == addr) && (tmp_num_waiters < count + 1)) {
|
while ((tmp_it != this->tree.end()) && (tmp_it->GetAddressArbiterKey() == addr) && (tmp_num_waiters < count + 1)) {
|
||||||
++tmp_num_waiters;
|
++tmp_num_waiters;
|
||||||
++tmp_it;
|
++tmp_it;
|
||||||
@@ -130,6 +158,7 @@ namespace ams::kern {
|
|||||||
new_value = value;
|
new_value = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Check the userspace value. */
|
/* Check the userspace value. */
|
||||||
s32 user_value;
|
s32 user_value;
|
||||||
|
|||||||
@@ -205,13 +205,8 @@ namespace ams::kern {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Close threads in the list. */
|
/* Close threads in the list. */
|
||||||
if (num_waiters > MaxThreads) {
|
for (auto it = thread_list.begin(); it != thread_list.end(); it = thread_list.erase(it)) {
|
||||||
auto it = thread_list.begin();
|
(*it).Close();
|
||||||
while (it != thread_list.end()) {
|
|
||||||
KThread *thread = std::addressof(*it);
|
|
||||||
thread->Close();
|
|
||||||
it = thread_list.erase(it);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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 <mesosphere.hpp>
|
||||||
|
|
||||||
|
namespace ams::kern {
|
||||||
|
|
||||||
|
KScopedDisableDispatch::~KScopedDisableDispatch() {
|
||||||
|
if (GetCurrentThread().GetDisableDispatchCount() <= 1) {
|
||||||
|
Kernel::GetScheduler().RescheduleCurrentCore();
|
||||||
|
} else {
|
||||||
|
GetCurrentThread().EnableDispatch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# pull in common atmosphere configuration
|
# pull in common atmosphere configuration
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../config/common.mk
|
THIS_MAKEFILE := $(abspath $(lastword $(MAKEFILE_LIST)))
|
||||||
|
CURRENT_DIRECTORY := $(abspath $(dir $(THIS_MAKEFILE)))
|
||||||
|
include $(CURRENT_DIRECTORY)/../config/common.mk
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# pull in switch rules
|
# pull in switch rules
|
||||||
@@ -15,7 +17,7 @@ include $(DEVKITPRO)/libnx/switch_rules
|
|||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# options for code generation
|
# options for code generation
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
PRECOMPILED_HEADERS := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/include/stratosphere.hpp
|
PRECOMPILED_HEADERS := $(CURRENT_DIRECTORY)/include/stratosphere.hpp
|
||||||
|
|
||||||
DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_STRATOSPHERE -D_GNU_SOURCE
|
DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_STRATOSPHERE -D_GNU_SOURCE
|
||||||
SETTINGS := $(ATMOSPHERE_SETTINGS) -O2
|
SETTINGS := $(ATMOSPHERE_SETTINGS) -O2
|
||||||
@@ -66,7 +68,7 @@ endif
|
|||||||
|
|
||||||
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
|
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
|
||||||
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||||
export GCH_FILES := $(foreach hdr,$(PRECOMPILED_HEADERS:.hpp=.gch),$(notdir $(hdr)))
|
export GCH_FILES := $(PRECOMPILED_HEADERS:.hpp=.hpp.gch)
|
||||||
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
|
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
|
||||||
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
|
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
|
||||||
|
|
||||||
@@ -103,12 +105,12 @@ dist: dist-src dist-bin
|
|||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
clean:
|
clean:
|
||||||
@echo clean ...
|
@echo clean ...
|
||||||
@rm -fr release lib *.bz2 include/stratosphere.hpp.gch
|
@rm -fr release lib *.bz2 $(GCH_FILES)
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
else
|
else
|
||||||
|
|
||||||
DEPENDS := $(OFILES:.o=.d) $(GCH_FILES:.gch=.d)
|
DEPENDS := $(OFILES:.o=.d) $(foreach hdr,$(GCH_FILES:.hpp.gch=.d),$(notdir $(hdr)))
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# main targets
|
# main targets
|
||||||
|
|||||||
@@ -41,14 +41,19 @@
|
|||||||
/* At this point, just include the rest alphabetically. */
|
/* At this point, just include the rest alphabetically. */
|
||||||
/* TODO: Figure out optimal order. */
|
/* TODO: Figure out optimal order. */
|
||||||
#include <stratosphere/boot2.hpp>
|
#include <stratosphere/boot2.hpp>
|
||||||
|
#include <stratosphere/cal.hpp>
|
||||||
#include <stratosphere/capsrv.hpp>
|
#include <stratosphere/capsrv.hpp>
|
||||||
#include <stratosphere/cfg.hpp>
|
#include <stratosphere/cfg.hpp>
|
||||||
|
#include <stratosphere/clkrst.hpp>
|
||||||
|
#include <stratosphere/ddsf.hpp>
|
||||||
#include <stratosphere/dmnt.hpp>
|
#include <stratosphere/dmnt.hpp>
|
||||||
#include <stratosphere/erpt.hpp>
|
#include <stratosphere/erpt.hpp>
|
||||||
#include <stratosphere/err.hpp>
|
#include <stratosphere/err.hpp>
|
||||||
#include <stratosphere/fatal.hpp>
|
#include <stratosphere/fatal.hpp>
|
||||||
|
#include <stratosphere/gpio.hpp>
|
||||||
#include <stratosphere/hid.hpp>
|
#include <stratosphere/hid.hpp>
|
||||||
#include <stratosphere/hos.hpp>
|
#include <stratosphere/hos.hpp>
|
||||||
|
#include <stratosphere/i2c.hpp>
|
||||||
#include <stratosphere/kvdb.hpp>
|
#include <stratosphere/kvdb.hpp>
|
||||||
#include <stratosphere/ldr.hpp>
|
#include <stratosphere/ldr.hpp>
|
||||||
#include <stratosphere/lr.hpp>
|
#include <stratosphere/lr.hpp>
|
||||||
@@ -57,10 +62,14 @@
|
|||||||
#include <stratosphere/nim.hpp>
|
#include <stratosphere/nim.hpp>
|
||||||
#include <stratosphere/ns.hpp>
|
#include <stratosphere/ns.hpp>
|
||||||
#include <stratosphere/patcher.hpp>
|
#include <stratosphere/patcher.hpp>
|
||||||
|
#include <stratosphere/pcv.hpp>
|
||||||
#include <stratosphere/pgl.hpp>
|
#include <stratosphere/pgl.hpp>
|
||||||
|
#include <stratosphere/pinmux.hpp>
|
||||||
|
#include <stratosphere/powctl.hpp>
|
||||||
#include <stratosphere/psc.hpp>
|
#include <stratosphere/psc.hpp>
|
||||||
#include <stratosphere/pm.hpp>
|
#include <stratosphere/pm.hpp>
|
||||||
#include <stratosphere/reg.hpp>
|
#include <stratosphere/pwm.hpp>
|
||||||
|
#include <stratosphere/regulator.hpp>
|
||||||
#include <stratosphere/ro.hpp>
|
#include <stratosphere/ro.hpp>
|
||||||
#include <stratosphere/settings.hpp>
|
#include <stratosphere/settings.hpp>
|
||||||
#include <stratosphere/sf.hpp>
|
#include <stratosphere/sf.hpp>
|
||||||
@@ -68,6 +77,7 @@
|
|||||||
#include <stratosphere/spl.hpp>
|
#include <stratosphere/spl.hpp>
|
||||||
#include <stratosphere/time.hpp>
|
#include <stratosphere/time.hpp>
|
||||||
#include <stratosphere/updater.hpp>
|
#include <stratosphere/updater.hpp>
|
||||||
|
#include <stratosphere/wec.hpp>
|
||||||
|
|
||||||
/* Include FS last. */
|
/* Include FS last. */
|
||||||
#include <stratosphere/fs.hpp>
|
#include <stratosphere/fs.hpp>
|
||||||
|
|||||||
@@ -39,12 +39,14 @@ namespace ams::impl {
|
|||||||
AMS_DEFINE_SYSTEM_THREAD(21, pm, Main);
|
AMS_DEFINE_SYSTEM_THREAD(21, pm, Main);
|
||||||
AMS_DEFINE_SYSTEM_THREAD(21, pm, ProcessTrack);
|
AMS_DEFINE_SYSTEM_THREAD(21, pm, ProcessTrack);
|
||||||
|
|
||||||
|
|
||||||
/* NCM. */
|
/* NCM. */
|
||||||
AMS_DEFINE_SYSTEM_THREAD(21, ncm, MainWaitThreads);
|
AMS_DEFINE_SYSTEM_THREAD(21, ncm, MainWaitThreads);
|
||||||
AMS_DEFINE_SYSTEM_THREAD(21, ncm, ContentManagerServerIpcSession);
|
AMS_DEFINE_SYSTEM_THREAD(21, ncm, ContentManagerServerIpcSession);
|
||||||
AMS_DEFINE_SYSTEM_THREAD(21, ncm, LocationResolverServerIpcSession);
|
AMS_DEFINE_SYSTEM_THREAD(21, ncm, LocationResolverServerIpcSession);
|
||||||
|
|
||||||
/* FS. */
|
/* FS. */
|
||||||
|
AMS_DEFINE_SYSTEM_THREAD(11, sdmmc, DeviceDetector);
|
||||||
AMS_DEFINE_SYSTEM_THREAD(16, fs, WorkerThreadPool);
|
AMS_DEFINE_SYSTEM_THREAD(16, fs, WorkerThreadPool);
|
||||||
AMS_DEFINE_SYSTEM_THREAD(17, fs, Main);
|
AMS_DEFINE_SYSTEM_THREAD(17, fs, Main);
|
||||||
AMS_DEFINE_SYSTEM_THREAD(17, fs, WorkerRealTimeAccess);
|
AMS_DEFINE_SYSTEM_THREAD(17, fs, WorkerRealTimeAccess);
|
||||||
@@ -87,9 +89,15 @@ namespace ams::impl {
|
|||||||
/* ro. */
|
/* ro. */
|
||||||
AMS_DEFINE_SYSTEM_THREAD(16, ro, Main);
|
AMS_DEFINE_SYSTEM_THREAD(16, ro, Main);
|
||||||
|
|
||||||
|
/* gpio. */
|
||||||
|
AMS_DEFINE_SYSTEM_THREAD(-12, gpio, InterruptHandler);
|
||||||
|
|
||||||
/* bpc. */
|
/* bpc. */
|
||||||
AMS_DEFINE_SYSTEM_THREAD(4, bpc, IpcServer);
|
AMS_DEFINE_SYSTEM_THREAD(4, bpc, IpcServer);
|
||||||
|
|
||||||
|
/* powctl. */
|
||||||
|
AMS_DEFINE_SYSTEM_THREAD(9, powctl, InterruptHandler);
|
||||||
|
|
||||||
/* hid. */
|
/* hid. */
|
||||||
AMS_DEFINE_SYSTEM_THREAD(-10, hid, IpcServer);
|
AMS_DEFINE_SYSTEM_THREAD(-10, hid, IpcServer);
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License
|
* under the terms and conditions of the GNU General Public License,
|
||||||
* version 2, as published by the Free Software Foundation.
|
* version 2, as published by the Free Software Foundation.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
@@ -13,6 +13,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define EVP_COP_RESET_VECTOR 0x200
|
#include <stratosphere/cal/cal_battery_api.hpp>
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
#include <vapours.hpp>
|
||||||
|
|
||||||
|
namespace ams::cal {
|
||||||
|
|
||||||
|
Result GetBatteryVersion(u8 *out);
|
||||||
|
Result GetBatteryVendor(size_t *out_vendor_size, void *dst, size_t dst_size);
|
||||||
|
|
||||||
|
}
|
||||||
21
libraries/libstratosphere/include/stratosphere/clkrst.hpp
Normal file
21
libraries/libstratosphere/include/stratosphere/clkrst.hpp
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
|
||||||
|
#include <stratosphere/clkrst/clkrst_types.hpp>
|
||||||
|
#include <stratosphere/clkrst/clkrst_api.hpp>
|
||||||
|
#include <stratosphere/clkrst/clkrst_session_api.hpp>
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/clkrst/clkrst_types.hpp>
|
||||||
|
|
||||||
|
namespace ams::clkrst {
|
||||||
|
|
||||||
|
void Initialize();
|
||||||
|
void Finalize();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/clkrst/clkrst_types.hpp>
|
||||||
|
|
||||||
|
namespace ams::clkrst {
|
||||||
|
|
||||||
|
struct ClkRstSession {
|
||||||
|
void *_session;
|
||||||
|
};
|
||||||
|
|
||||||
|
Result OpenSession(ClkRstSession *out, DeviceCode device_code);
|
||||||
|
void CloseSession(ClkRstSession *session);
|
||||||
|
|
||||||
|
void SetResetAsserted(ClkRstSession *session);
|
||||||
|
void SetResetDeasserted(ClkRstSession *session);
|
||||||
|
|
||||||
|
void SetClockRate(ClkRstSession *session, u32 hz);
|
||||||
|
|
||||||
|
void SetClockDisabled(ClkRstSession *session);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
#include <vapours.hpp>
|
||||||
|
|
||||||
|
namespace ams::clkrst {
|
||||||
|
|
||||||
|
/* ... */
|
||||||
|
|
||||||
|
}
|
||||||
@@ -16,5 +16,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "dd/dd_io_mappings.hpp"
|
#include <stratosphere/dd/dd_types.hpp>
|
||||||
#include "dd/dd_process_handle.hpp"
|
#include <stratosphere/dd/dd_device_address_space.hpp>
|
||||||
|
#include <stratosphere/dd/dd_io_mappings.hpp>
|
||||||
|
#include <stratosphere/dd/dd_process_handle.hpp>
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
#include <vapours.hpp>
|
||||||
|
|
||||||
|
#include <stratosphere/dd/dd_device_address_space_common.hpp>
|
||||||
|
#include <stratosphere/dd/dd_device_address_space_types.hpp>
|
||||||
|
#include <stratosphere/dd/dd_device_address_space_api.hpp>
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/dd/dd_types.hpp>
|
||||||
|
#include <stratosphere/dd/dd_device_address_space_common.hpp>
|
||||||
|
#include <stratosphere/dd/dd_device_address_space_types.hpp>
|
||||||
|
|
||||||
|
namespace ams::dd {
|
||||||
|
|
||||||
|
Result CreateDeviceAddressSpace(DeviceAddressSpaceType *das, u64 address, u64 size);
|
||||||
|
Result CreateDeviceAddressSpace(DeviceAddressSpaceType *das, u64 size);
|
||||||
|
void DestroyDeviceAddressSpace(DeviceAddressSpaceType *das);
|
||||||
|
|
||||||
|
void AttachDeviceAddressSpaceHandle(DeviceAddressSpaceType *das, Handle handle, bool managed);
|
||||||
|
|
||||||
|
Handle GetDeviceAddressSpaceHandle(DeviceAddressSpaceType *das);
|
||||||
|
|
||||||
|
Result MapDeviceAddressSpaceAligned(DeviceAddressSpaceType *das, ProcessHandle process_handle, u64 process_address, size_t size, DeviceVirtualAddress device_address, MemoryPermission device_perm);
|
||||||
|
Result MapDeviceAddressSpaceNotAligned(DeviceAddressSpaceType *das, ProcessHandle process_handle, u64 process_address, size_t size, DeviceVirtualAddress device_address, MemoryPermission device_perm);
|
||||||
|
void UnmapDeviceAddressSpace(DeviceAddressSpaceType *das, ProcessHandle process_handle, u64 process_address, size_t size, DeviceVirtualAddress device_address);
|
||||||
|
|
||||||
|
void InitializeDeviceAddressSpaceMapInfo(DeviceAddressSpaceMapInfo *info, DeviceAddressSpaceType *das, ProcessHandle process_handle, u64 process_address, size_t size, DeviceVirtualAddress device_address, MemoryPermission device_perm);
|
||||||
|
|
||||||
|
Result MapNextDeviceAddressSpaceRegion(size_t *out_mapped_size, DeviceAddressSpaceMapInfo *info);
|
||||||
|
void UnmapDeviceAddressSpaceRegion(DeviceAddressSpaceMapInfo *info);
|
||||||
|
|
||||||
|
u64 GetMappedProcessAddress(DeviceAddressSpaceMapInfo *info);
|
||||||
|
DeviceVirtualAddress GetMappedDeviceVirtualAddress(DeviceAddressSpaceMapInfo *info);
|
||||||
|
size_t GetMappedSize(DeviceAddressSpaceMapInfo *info);
|
||||||
|
|
||||||
|
Result AttachDeviceAddressSpace(DeviceAddressSpaceType *das, DeviceName device_name);
|
||||||
|
void DetachDeviceAddressSpace(DeviceAddressSpaceType *das, DeviceName device_name);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/dd/dd_types.hpp>
|
||||||
|
|
||||||
|
namespace ams::dd {
|
||||||
|
|
||||||
|
using DeviceName = ::ams::svc::DeviceName;
|
||||||
|
|
||||||
|
constexpr inline u64 DeviceAddressSpaceMemoryRegionAlignment = 4_KB;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/dd/dd_types.hpp>
|
||||||
|
|
||||||
|
namespace ams::dd {
|
||||||
|
|
||||||
|
using DeviceVirtualAddress = u64;
|
||||||
|
|
||||||
|
using DeviceAddressSpaceHandle = ::Handle;
|
||||||
|
|
||||||
|
struct DeviceAddressSpaceType {
|
||||||
|
enum State {
|
||||||
|
State_NotInitialized = 0,
|
||||||
|
State_Initialized = 1,
|
||||||
|
};
|
||||||
|
DeviceAddressSpaceHandle device_handle;
|
||||||
|
u8 state;
|
||||||
|
bool is_handle_managed;
|
||||||
|
};
|
||||||
|
static_assert(std::is_trivial<DeviceAddressSpaceType>::value);
|
||||||
|
|
||||||
|
struct DeviceAddressSpaceMapInfo {
|
||||||
|
size_t last_mapped_size;
|
||||||
|
size_t size;
|
||||||
|
u64 process_address;
|
||||||
|
DeviceVirtualAddress device_start_address;
|
||||||
|
DeviceVirtualAddress device_end_address;
|
||||||
|
ProcessHandle process_handle;
|
||||||
|
MemoryPermission device_permission;
|
||||||
|
DeviceAddressSpaceType *device_address_space;
|
||||||
|
};
|
||||||
|
static_assert(std::is_trivial<DeviceAddressSpaceMapInfo>::value);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -19,16 +19,9 @@
|
|||||||
|
|
||||||
namespace ams::dd {
|
namespace ams::dd {
|
||||||
|
|
||||||
uintptr_t QueryIoMapping(uintptr_t phys_addr, size_t size);
|
|
||||||
|
|
||||||
u32 ReadRegister(uintptr_t phys_addr);
|
|
||||||
void WriteRegister(uintptr_t phys_addr, u32 value);
|
|
||||||
u32 ReadWriteRegister(uintptr_t phys_addr, u32 value, u32 mask);
|
|
||||||
|
|
||||||
/* Convenience Helper. */
|
/* Convenience Helper. */
|
||||||
|
inline uintptr_t GetIoMapping(dd::PhysicalAddress phys_addr, size_t size) {
|
||||||
inline uintptr_t GetIoMapping(uintptr_t phys_addr, size_t size) {
|
const uintptr_t io_mapping = dd::QueryIoMapping(phys_addr, size);
|
||||||
const uintptr_t io_mapping = QueryIoMapping(phys_addr, size);
|
|
||||||
AMS_ABORT_UNLESS(io_mapping);
|
AMS_ABORT_UNLESS(io_mapping);
|
||||||
return io_mapping;
|
return io_mapping;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,12 +13,12 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <vapours.hpp>
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/dd/dd_types.hpp>
|
||||||
|
|
||||||
namespace ams::dd {
|
namespace ams::dd {
|
||||||
|
|
||||||
::Handle GetCurrentProcessHandle();
|
ProcessHandle GetCurrentProcessHandle();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/dd/dd_types.hpp>
|
||||||
|
|
||||||
|
namespace ams::dd {
|
||||||
|
|
||||||
|
using ProcessHandle = ::Handle;
|
||||||
|
|
||||||
|
enum MemoryPermission {
|
||||||
|
MemoryPermission_None = 0,
|
||||||
|
MemoryPermission_ReadOnly = (1u << 0),
|
||||||
|
MemoryPermission_WriteOnly = (1u << 1),
|
||||||
|
|
||||||
|
MemoryPermission_ReadWrite = MemoryPermission_ReadOnly | MemoryPermission_WriteOnly,
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
27
libraries/libstratosphere/include/stratosphere/ddsf.hpp
Normal file
27
libraries/libstratosphere/include/stratosphere/ddsf.hpp
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
|
||||||
|
#include <stratosphere/ddsf/ddsf_types.hpp>
|
||||||
|
#include <stratosphere/ddsf/ddsf_i_castable.hpp>
|
||||||
|
#include <stratosphere/ddsf/ddsf_i_session.hpp>
|
||||||
|
#include <stratosphere/ddsf/ddsf_i_device.hpp>
|
||||||
|
#include <stratosphere/ddsf/ddsf_i_driver.hpp>
|
||||||
|
#include <stratosphere/ddsf/ddsf_device_code_entry.hpp>
|
||||||
|
#include <stratosphere/ddsf/ddsf_device_code_entry_manager.hpp>
|
||||||
|
#include <stratosphere/ddsf/ddsf_i_event_handler.hpp>
|
||||||
|
#include <stratosphere/ddsf/ddsf_event_handler_manager.hpp>
|
||||||
|
#include <stratosphere/ddsf/ddsf_memory_api.hpp>
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
#include <vapours.hpp>
|
||||||
|
|
||||||
|
namespace ams::ddsf {
|
||||||
|
|
||||||
|
class IDevice;
|
||||||
|
|
||||||
|
class DeviceCodeEntry {
|
||||||
|
NON_COPYABLE(DeviceCodeEntry);
|
||||||
|
NON_MOVEABLE(DeviceCodeEntry);
|
||||||
|
private:
|
||||||
|
ams::DeviceCode device_code = ams::InvalidDeviceCode;
|
||||||
|
IDevice *device = nullptr;
|
||||||
|
public:
|
||||||
|
constexpr DeviceCodeEntry(ams::DeviceCode dc, IDevice *dev) : device_code(dc), device(dev) {
|
||||||
|
AMS_ASSERT(dev != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr ams::DeviceCode GetDeviceCode() const {
|
||||||
|
return this->device_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr IDevice &GetDevice() {
|
||||||
|
return *this->device;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr const IDevice &GetDevice() const {
|
||||||
|
return *this->device;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class DeviceCodeEntryHolder {
|
||||||
|
NON_COPYABLE(DeviceCodeEntryHolder);
|
||||||
|
NON_MOVEABLE(DeviceCodeEntryHolder);
|
||||||
|
private:
|
||||||
|
util::IntrusiveListNode list_node;
|
||||||
|
TYPED_STORAGE(DeviceCodeEntry) entry_storage;
|
||||||
|
bool is_constructed;
|
||||||
|
public:
|
||||||
|
using ListTraits = util::IntrusiveListMemberTraitsDeferredAssert<&DeviceCodeEntryHolder::list_node>;
|
||||||
|
using List = typename ListTraits::ListType;
|
||||||
|
friend class util::IntrusiveList<DeviceCodeEntryHolder, util::IntrusiveListMemberTraitsDeferredAssert<&DeviceCodeEntryHolder::list_node>>;
|
||||||
|
public:
|
||||||
|
DeviceCodeEntryHolder() : list_node(), entry_storage(), is_constructed(false) {
|
||||||
|
/* ... */
|
||||||
|
}
|
||||||
|
|
||||||
|
~DeviceCodeEntryHolder() {
|
||||||
|
if (this->IsConstructed()) {
|
||||||
|
this->Destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddTo(List &list) {
|
||||||
|
list.push_back(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoveFrom(List list) {
|
||||||
|
list.erase(list.iterator_to(*this));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsLinkedToList() const {
|
||||||
|
return this->list_node.IsLinked();
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceCodeEntry &Construct(DeviceCode dc, IDevice *dev) {
|
||||||
|
AMS_ASSERT(!this->IsConstructed());
|
||||||
|
DeviceCodeEntry *entry = new (GetPointer(this->entry_storage)) DeviceCodeEntry(dc, dev);
|
||||||
|
this->is_constructed = true;
|
||||||
|
return *entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsConstructed() const {
|
||||||
|
return this->is_constructed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Destroy() {
|
||||||
|
AMS_ASSERT(this->IsConstructed());
|
||||||
|
GetReference(this->entry_storage).~DeviceCodeEntry();
|
||||||
|
this->is_constructed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceCodeEntry &Get() {
|
||||||
|
AMS_ASSERT(this->IsConstructed());
|
||||||
|
return GetReference(this->entry_storage);
|
||||||
|
}
|
||||||
|
|
||||||
|
const DeviceCodeEntry &Get() const {
|
||||||
|
AMS_ASSERT(this->IsConstructed());
|
||||||
|
return GetReference(this->entry_storage);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static_assert(DeviceCodeEntryHolder::ListTraits::IsValid());
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/ddsf/ddsf_types.hpp>
|
||||||
|
#include <stratosphere/ddsf/impl/ddsf_for_each.hpp>
|
||||||
|
#include <stratosphere/ddsf/ddsf_device_code_entry.hpp>
|
||||||
|
|
||||||
|
namespace ams::ddsf {
|
||||||
|
|
||||||
|
class IDevice;
|
||||||
|
|
||||||
|
class DeviceCodeEntryManager {
|
||||||
|
private:
|
||||||
|
ams::MemoryResource *memory_resource;
|
||||||
|
ddsf::DeviceCodeEntryHolder::List entry_list;
|
||||||
|
mutable os::SdkMutex entry_list_lock;
|
||||||
|
private:
|
||||||
|
void DestroyAllEntries() {
|
||||||
|
auto it = this->entry_list.begin();
|
||||||
|
while (it != this->entry_list.end()) {
|
||||||
|
ddsf::DeviceCodeEntryHolder *entry = std::addressof(*it);
|
||||||
|
it = this->entry_list.erase(it);
|
||||||
|
|
||||||
|
AMS_ASSERT(entry->IsConstructed());
|
||||||
|
if (entry->IsConstructed()) {
|
||||||
|
entry->Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
this->memory_resource->Deallocate(entry, sizeof(*entry));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
DeviceCodeEntryManager(ams::MemoryResource *mr) : memory_resource(mr), entry_list(), entry_list_lock() { /* ... */ }
|
||||||
|
|
||||||
|
~DeviceCodeEntryManager() {
|
||||||
|
this->DestroyAllEntries();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reset() {
|
||||||
|
std::scoped_lock lk(this->entry_list_lock);
|
||||||
|
this->DestroyAllEntries();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result Add(DeviceCode device_code, IDevice *device);
|
||||||
|
bool Remove(DeviceCode device_code);
|
||||||
|
|
||||||
|
Result FindDeviceCodeEntry(DeviceCodeEntry **out, DeviceCode device_code);
|
||||||
|
Result FindDeviceCodeEntry(const DeviceCodeEntry **out, DeviceCode device_code) const;
|
||||||
|
|
||||||
|
Result FindDevice(IDevice **out, DeviceCode device_code);
|
||||||
|
Result FindDevice(const IDevice **out, DeviceCode device_code) const;
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
|
int ForEachEntry(F f) {
|
||||||
|
return impl::ForEach(this->entry_list_lock, this->entry_list, [&](DeviceCodeEntryHolder &holder) -> bool {
|
||||||
|
AMS_ASSERT(holder.IsConstructed());
|
||||||
|
return f(holder.Get());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
|
int ForEachEntry(F f) const {
|
||||||
|
return impl::ForEach(this->entry_list_lock, this->entry_list, [&](const DeviceCodeEntryHolder &holder) -> bool {
|
||||||
|
AMS_ASSERT(holder.IsConstructed());
|
||||||
|
return f(holder.Get());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/os.hpp>
|
||||||
|
#include <stratosphere/ddsf/ddsf_i_event_handler.hpp>
|
||||||
|
|
||||||
|
namespace ams::ddsf {
|
||||||
|
|
||||||
|
class EventHandlerManager;
|
||||||
|
|
||||||
|
class EventHandlerManager {
|
||||||
|
NON_COPYABLE(EventHandlerManager);
|
||||||
|
NON_MOVEABLE(EventHandlerManager);
|
||||||
|
private:
|
||||||
|
struct LoopControlCommandParameters;
|
||||||
|
private:
|
||||||
|
bool is_initialized;
|
||||||
|
bool is_looping;
|
||||||
|
os::SdkConditionVariable is_looping_cv;
|
||||||
|
os::WaitableManagerType waitable_manager;
|
||||||
|
os::ThreadType *loop_thread;
|
||||||
|
os::Event loop_control_event;
|
||||||
|
os::WaitableHolderType loop_control_event_holder;
|
||||||
|
LoopControlCommandParameters *loop_control_command_params;
|
||||||
|
os::Event loop_control_command_done_event; /* TODO: os::LightEvent, requires mesosphere for < 4.0.0 compat. */
|
||||||
|
os::SdkMutex loop_control_lock;
|
||||||
|
private:
|
||||||
|
void ProcessControlCommand(LoopControlCommandParameters *params);
|
||||||
|
void ProcessControlCommandImpl(LoopControlCommandParameters *params);
|
||||||
|
public:
|
||||||
|
EventHandlerManager()
|
||||||
|
: is_initialized(false), is_looping(false), is_looping_cv(), waitable_manager(),
|
||||||
|
loop_thread(), loop_control_event(os::EventClearMode_AutoClear), loop_control_event_holder(),
|
||||||
|
loop_control_command_params(), loop_control_command_done_event(os::EventClearMode_AutoClear),
|
||||||
|
loop_control_lock()
|
||||||
|
{
|
||||||
|
this->Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
~EventHandlerManager() {
|
||||||
|
if (this->is_looping) {
|
||||||
|
AMS_ASSERT(!this->IsRunningOnLoopThread());
|
||||||
|
this->RequestStop();
|
||||||
|
}
|
||||||
|
if (this->is_initialized) {
|
||||||
|
this->Finalize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsRunningOnLoopThread() const { return this->loop_thread == os::GetCurrentThread(); }
|
||||||
|
bool IsLooping() const { return this->is_looping; }
|
||||||
|
|
||||||
|
void Initialize();
|
||||||
|
void Finalize();
|
||||||
|
|
||||||
|
void RegisterHandler(IEventHandler *handler);
|
||||||
|
void UnregisterHandler(IEventHandler *handler);
|
||||||
|
|
||||||
|
void WaitLoopEnter();
|
||||||
|
void WaitLoopExit();
|
||||||
|
void RequestStop();
|
||||||
|
|
||||||
|
void LoopAuto();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/ddsf/ddsf_types.hpp>
|
||||||
|
#include <stratosphere/ddsf/impl/ddsf_type_tag.hpp>
|
||||||
|
|
||||||
|
namespace ams::ddsf {
|
||||||
|
|
||||||
|
#if defined(AMS_BUILD_FOR_DEBUGGING) || defined(AMS_BUILD_FOR_AUDITING)
|
||||||
|
|
||||||
|
#define AMS_DDSF_CASTABLE_TRAITS(__CLASS__, __BASE__) \
|
||||||
|
static_assert(std::convertible_to<__CLASS__ *, __BASE__ *>); \
|
||||||
|
public: \
|
||||||
|
static constexpr inline ::ams::ddsf::impl::TypeTag s_ams_ddsf_castable_type_tag{#__CLASS__, __BASE__::s_ams_ddsf_castable_type_tag}; \
|
||||||
|
constexpr virtual const ::ams::ddsf::impl::TypeTag &GetTypeTag() const override { return s_ams_ddsf_castable_type_tag; }
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define AMS_DDSF_CASTABLE_TRAITS(__CLASS__, __BASE__) \
|
||||||
|
static_assert(std::convertible_to<__CLASS__ *, __BASE__ *>); \
|
||||||
|
public: \
|
||||||
|
static constexpr inline ::ams::ddsf::impl::TypeTag s_ams_ddsf_castable_type_tag{__BASE__::s_ams_ddsf_castable_type_tag}; \
|
||||||
|
constexpr virtual const ::ams::ddsf::impl::TypeTag &GetTypeTag() const override { return s_ams_ddsf_castable_type_tag; }
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class ICastable {
|
||||||
|
private:
|
||||||
|
constexpr virtual const impl::TypeTag &GetTypeTag() const = 0;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr ALWAYS_INLINE void AssertCastableTo() const {
|
||||||
|
AMS_ASSERT(this->IsCastableTo<T>());
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
template<typename T>
|
||||||
|
constexpr bool IsCastableTo() const {
|
||||||
|
return this->GetTypeTag().DerivesFrom(T::s_ams_ddsf_castable_type_tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr T &SafeCastTo() {
|
||||||
|
this->AssertCastableTo<T>();
|
||||||
|
return static_cast<T &>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr const T &SafeCastTo() const {
|
||||||
|
this->AssertCastableTo<T>();
|
||||||
|
return static_cast<const T &>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr T *SafeCastToPointer() {
|
||||||
|
this->AssertCastableTo<T>();
|
||||||
|
return static_cast<T *>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr const T *SafeCastToPointer() const {
|
||||||
|
this->AssertCastableTo<T>();
|
||||||
|
return static_cast<const T *>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(AMS_BUILD_FOR_AUDITING) || defined(AMS_BUILD_FOR_DEBUGGING)
|
||||||
|
|
||||||
|
constexpr const char *GetClassName() const {
|
||||||
|
return this->GetTypeTag().GetClassName();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/os/os_sdk_mutex.hpp>
|
||||||
|
#include <stratosphere/ddsf/ddsf_types.hpp>
|
||||||
|
#include <stratosphere/ddsf/impl/ddsf_for_each.hpp>
|
||||||
|
#include <stratosphere/ddsf/ddsf_i_castable.hpp>
|
||||||
|
#include <stratosphere/ddsf/ddsf_i_session.hpp>
|
||||||
|
|
||||||
|
namespace ams::ddsf {
|
||||||
|
|
||||||
|
class IDriver;
|
||||||
|
|
||||||
|
class IDevice : public ICastable {
|
||||||
|
friend Result OpenSession(IDevice *device, ISession *session, AccessMode mode);
|
||||||
|
friend void CloseSession(ISession *session);
|
||||||
|
friend class IDriver;
|
||||||
|
public:
|
||||||
|
AMS_DDSF_CASTABLE_ROOT_TRAITS(ams::ddsf::IDevice);
|
||||||
|
private:
|
||||||
|
util::IntrusiveListNode list_node;
|
||||||
|
IDriver *driver;
|
||||||
|
ISession::List session_list;
|
||||||
|
mutable os::SdkMutex session_list_lock;
|
||||||
|
bool is_exclusive_write;
|
||||||
|
public:
|
||||||
|
using ListTraits = util::IntrusiveListMemberTraitsDeferredAssert<&IDevice::list_node>;
|
||||||
|
using List = typename ListTraits::ListType;
|
||||||
|
friend class util::IntrusiveList<IDevice, util::IntrusiveListMemberTraitsDeferredAssert<&IDevice::list_node>>;
|
||||||
|
private:
|
||||||
|
Result AttachSession(ISession *session) {
|
||||||
|
AMS_ASSERT(session != nullptr);
|
||||||
|
std::scoped_lock lk(this->session_list_lock);
|
||||||
|
|
||||||
|
/* Check if we're allowed to attach the session. */
|
||||||
|
if (this->is_exclusive_write && session->CheckExclusiveWrite()) {
|
||||||
|
for (const auto &attached : this->session_list) {
|
||||||
|
R_UNLESS(!attached.CheckAccess(AccessMode_Write), ddsf::ResultAccessModeDenied());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Attach the session. */
|
||||||
|
this->session_list.push_back(*session);
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DetachSession(ISession *session) {
|
||||||
|
AMS_ASSERT(session != nullptr);
|
||||||
|
std::scoped_lock lk(this->session_list_lock);
|
||||||
|
this->session_list.erase(this->session_list.iterator_to(*session));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AttachDriver(IDriver *drv) {
|
||||||
|
AMS_ASSERT(drv != nullptr);
|
||||||
|
AMS_ASSERT(!this->IsDriverAttached());
|
||||||
|
this->driver = drv;
|
||||||
|
AMS_ASSERT(this->IsDriverAttached());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DetachDriver() {
|
||||||
|
AMS_ASSERT(this->IsDriverAttached());
|
||||||
|
this->driver = nullptr;
|
||||||
|
AMS_ASSERT(!this->IsDriverAttached());
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
IDevice(bool exclusive_write) : list_node(), driver(nullptr), session_list(), session_list_lock(), is_exclusive_write(exclusive_write) {
|
||||||
|
this->session_list.clear();
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
~IDevice() {
|
||||||
|
this->session_list.clear();
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
void AddTo(List &list) {
|
||||||
|
list.push_back(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoveFrom(List list) {
|
||||||
|
list.erase(list.iterator_to(*this));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsLinkedToList() const {
|
||||||
|
return this->list_node.IsLinked();
|
||||||
|
}
|
||||||
|
|
||||||
|
IDriver &GetDriver() {
|
||||||
|
AMS_ASSERT(this->IsDriverAttached());
|
||||||
|
return *this->driver;
|
||||||
|
}
|
||||||
|
|
||||||
|
const IDriver &GetDriver() const {
|
||||||
|
AMS_ASSERT(this->IsDriverAttached());
|
||||||
|
return *this->driver;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsDriverAttached() const {
|
||||||
|
return this->driver != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
|
Result ForEachSession(F f, bool return_on_fail) {
|
||||||
|
return impl::ForEach(this->session_list_lock, this->session_list, f, return_on_fail);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
|
Result ForEachSession(F f, bool return_on_fail) const {
|
||||||
|
return impl::ForEach(this->session_list_lock, this->session_list, f, return_on_fail);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
|
int ForEachSession(F f) {
|
||||||
|
return impl::ForEach(this->session_list_lock, this->session_list, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
|
int ForEachSession(F f) const {
|
||||||
|
return impl::ForEach(this->session_list_lock, this->session_list, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HasAnyOpenSession() const {
|
||||||
|
return !this->session_list.empty();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static_assert(IDevice::ListTraits::IsValid());
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/os/os_sdk_mutex.hpp>
|
||||||
|
#include <stratosphere/ddsf/ddsf_types.hpp>
|
||||||
|
#include <stratosphere/ddsf/impl/ddsf_for_each.hpp>
|
||||||
|
#include <stratosphere/ddsf/ddsf_i_castable.hpp>
|
||||||
|
#include <stratosphere/ddsf/ddsf_i_device.hpp>
|
||||||
|
|
||||||
|
namespace ams::ddsf {
|
||||||
|
|
||||||
|
class IDriver : public ICastable {
|
||||||
|
public:
|
||||||
|
AMS_DDSF_CASTABLE_ROOT_TRAITS(ams::ddsf::IDriver);
|
||||||
|
private:
|
||||||
|
util::IntrusiveListNode list_node;
|
||||||
|
IDevice::List device_list;
|
||||||
|
mutable os::SdkMutex device_list_lock;
|
||||||
|
public:
|
||||||
|
using ListTraits = util::IntrusiveListMemberTraitsDeferredAssert<&IDriver::list_node>;
|
||||||
|
using List = typename ListTraits::ListType;
|
||||||
|
friend class util::IntrusiveList<IDriver, util::IntrusiveListMemberTraitsDeferredAssert<&IDriver::list_node>>;
|
||||||
|
private:
|
||||||
|
public:
|
||||||
|
IDriver() : list_node(), device_list(), device_list_lock() {
|
||||||
|
this->device_list.clear();
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
~IDriver() {
|
||||||
|
this->device_list.clear();
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
void AddTo(List &list) {
|
||||||
|
list.push_back(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoveFrom(List list) {
|
||||||
|
list.erase(list.iterator_to(*this));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsLinkedToList() const {
|
||||||
|
return this->list_node.IsLinked();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HasAnyDevice() const {
|
||||||
|
return !this->device_list.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterDevice(IDevice *dev) {
|
||||||
|
AMS_ASSERT(dev != nullptr);
|
||||||
|
std::scoped_lock lk(this->device_list_lock);
|
||||||
|
dev->AttachDriver(this);
|
||||||
|
this->device_list.push_back(*dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnregisterDevice(IDevice *dev) {
|
||||||
|
AMS_ASSERT(dev != nullptr);
|
||||||
|
std::scoped_lock lk(this->device_list_lock);
|
||||||
|
this->device_list.erase(this->device_list.iterator_to(*dev));
|
||||||
|
dev->DetachDriver();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
|
Result ForEachDevice(F f, bool return_on_fail) {
|
||||||
|
return impl::ForEach(this->device_list_lock, this->device_list, f, return_on_fail);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
|
Result ForEachDevice(F f, bool return_on_fail) const {
|
||||||
|
return impl::ForEach(this->device_list_lock, this->device_list, f, return_on_fail);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
|
int ForEachDevice(F f) {
|
||||||
|
return impl::ForEach(this->device_list_lock, this->device_list, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
|
int ForEachDevice(F f) const {
|
||||||
|
return impl::ForEach(this->device_list_lock, this->device_list, f);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static_assert(IDriver::ListTraits::IsValid());
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/os.hpp>
|
||||||
|
|
||||||
|
namespace ams::ddsf {
|
||||||
|
|
||||||
|
class EventHandlerManager;
|
||||||
|
|
||||||
|
class IEventHandler {
|
||||||
|
NON_COPYABLE(IEventHandler);
|
||||||
|
NON_MOVEABLE(IEventHandler);
|
||||||
|
friend class EventHandlerManager;
|
||||||
|
private:
|
||||||
|
os::WaitableHolderType holder;
|
||||||
|
uintptr_t user_data;
|
||||||
|
bool is_initialized;
|
||||||
|
bool is_registered;
|
||||||
|
private:
|
||||||
|
void Link(os::WaitableManagerType *manager) {
|
||||||
|
AMS_ASSERT(this->IsInitialized());
|
||||||
|
AMS_ASSERT(!this->IsRegistered());
|
||||||
|
AMS_ASSERT(manager != nullptr);
|
||||||
|
os::LinkWaitableHolder(manager, std::addressof(this->holder));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Unlink() {
|
||||||
|
AMS_ASSERT(this->IsInitialized());
|
||||||
|
AMS_ASSERT(this->IsRegistered());
|
||||||
|
os::UnlinkWaitableHolder(std::addressof(this->holder));
|
||||||
|
}
|
||||||
|
|
||||||
|
static IEventHandler &ToEventHandler(os::WaitableHolderType *holder) {
|
||||||
|
AMS_ASSERT(holder != nullptr);
|
||||||
|
auto &event_handler = *reinterpret_cast<IEventHandler *>(os::GetWaitableHolderUserData(holder));
|
||||||
|
AMS_ASSERT(event_handler.IsInitialized());
|
||||||
|
return event_handler;
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
IEventHandler() : holder(), user_data(0), is_initialized(false), is_registered(false) { /* ... */ }
|
||||||
|
|
||||||
|
~IEventHandler() {
|
||||||
|
if (this->IsRegistered()) {
|
||||||
|
this->Unlink();
|
||||||
|
}
|
||||||
|
if (this->IsInitialized()) {
|
||||||
|
this->Finalize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsInitialized() const { return this->is_initialized; }
|
||||||
|
bool IsRegistered() const { return this->is_registered; }
|
||||||
|
|
||||||
|
uintptr_t GetUserData() const { return this->user_data; }
|
||||||
|
void SetUserData(uintptr_t d) { this->user_data = d; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void Initialize(T *object) {
|
||||||
|
AMS_ASSERT(object != nullptr);
|
||||||
|
AMS_ASSERT(!this->IsInitialized());
|
||||||
|
os::InitializeWaitableHolder(std::addressof(this->holder), object);
|
||||||
|
os::SetWaitableHolderUserData(std::addressof(this->holder), reinterpret_cast<uintptr_t>(this));
|
||||||
|
this->is_initialized = true;
|
||||||
|
this->is_registered = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Finalize() {
|
||||||
|
AMS_ASSERT(this->IsInitialized());
|
||||||
|
AMS_ASSERT(!this->IsRegistered());
|
||||||
|
os::FinalizeWaitableHolder(std::addressof(this->holder));
|
||||||
|
this->is_initialized = false;
|
||||||
|
this->is_registered = false;
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
virtual void HandleEvent() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/ddsf/ddsf_types.hpp>
|
||||||
|
#include <stratosphere/ddsf/impl/ddsf_for_each.hpp>
|
||||||
|
#include <stratosphere/ddsf/ddsf_i_castable.hpp>
|
||||||
|
|
||||||
|
namespace ams::ddsf {
|
||||||
|
|
||||||
|
class ISession;
|
||||||
|
class IDevice;
|
||||||
|
|
||||||
|
Result OpenSession(IDevice *device, ISession *session, AccessMode access_mode);
|
||||||
|
void CloseSession(ISession *session);
|
||||||
|
|
||||||
|
class ISession : public ICastable {
|
||||||
|
friend Result OpenSession(IDevice *device, ISession *session, AccessMode mode);
|
||||||
|
friend void CloseSession(ISession *session);
|
||||||
|
public:
|
||||||
|
AMS_DDSF_CASTABLE_ROOT_TRAITS(ams::ddsf::IDevice);
|
||||||
|
private:
|
||||||
|
util::IntrusiveListNode list_node;
|
||||||
|
IDevice *device;
|
||||||
|
AccessMode access_mode;
|
||||||
|
public:
|
||||||
|
using ListTraits = util::IntrusiveListMemberTraitsDeferredAssert<&ISession::list_node>;
|
||||||
|
using List = typename ListTraits::ListType;
|
||||||
|
friend class util::IntrusiveList<ISession, util::IntrusiveListMemberTraitsDeferredAssert<&ISession::list_node>>;
|
||||||
|
private:
|
||||||
|
void AttachDevice(IDevice *dev, AccessMode mode) {
|
||||||
|
AMS_ASSERT(dev != nullptr);
|
||||||
|
AMS_ASSERT(!this->IsOpen());
|
||||||
|
this->device = dev;
|
||||||
|
this->access_mode = mode;
|
||||||
|
AMS_ASSERT(this->IsOpen());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DetachDevice() {
|
||||||
|
AMS_ASSERT(this->IsOpen());
|
||||||
|
this->device = nullptr;
|
||||||
|
this->access_mode = AccessMode_None;
|
||||||
|
AMS_ASSERT(!this->IsOpen());
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
ISession() : list_node(), device(nullptr), access_mode() { /* ... */ }
|
||||||
|
protected:
|
||||||
|
~ISession() { this->DetachDevice(); AMS_ASSERT(!this->IsOpen()); }
|
||||||
|
public:
|
||||||
|
void AddTo(List &list) {
|
||||||
|
list.push_back(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoveFrom(List list) {
|
||||||
|
list.erase(list.iterator_to(*this));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsLinkedToList() const {
|
||||||
|
return this->list_node.IsLinked();
|
||||||
|
}
|
||||||
|
|
||||||
|
IDevice &GetDevice() {
|
||||||
|
AMS_ASSERT(this->IsOpen());
|
||||||
|
return *this->device;
|
||||||
|
}
|
||||||
|
|
||||||
|
const IDevice &GetDevice() const {
|
||||||
|
AMS_ASSERT(this->IsOpen());
|
||||||
|
return *this->device;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsOpen() const {
|
||||||
|
return this->device != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CheckAccess(AccessMode mode) const {
|
||||||
|
AMS_ASSERT(this->IsOpen());
|
||||||
|
return ((~this->access_mode) & mode) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CheckExclusiveWrite() const {
|
||||||
|
return this->CheckAccess(AccessMode_Write) && !this->CheckAccess(AccessMode_Shared);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static_assert(ISession::ListTraits::IsValid());
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/ddsf/ddsf_device_code_entry.hpp>
|
||||||
|
|
||||||
|
namespace ams::ddsf {
|
||||||
|
|
||||||
|
void SetMemoryResource(ams::MemoryResource *mr);
|
||||||
|
ams::MemoryResource *GetMemoryResource();
|
||||||
|
|
||||||
|
static constexpr size_t DeviceCodeEntryHolderSize = sizeof(DeviceCodeEntryHolder);
|
||||||
|
|
||||||
|
void SetDeviceCodeEntryHolderMemoryResource(ams::MemoryResource *mr);
|
||||||
|
ams::MemoryResource *GetDeviceCodeEntryHolderMemoryResource();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
#include <vapours.hpp>
|
||||||
|
|
||||||
|
namespace ams::ddsf {
|
||||||
|
|
||||||
|
enum AccessMode {
|
||||||
|
AccessMode_None = (0u << 0),
|
||||||
|
AccessMode_Read = (1u << 0),
|
||||||
|
AccessMode_Write = (1u << 1),
|
||||||
|
AccessMode_Shared = (1u << 2),
|
||||||
|
|
||||||
|
AccessMode_ReadWrite = AccessMode_Read | AccessMode_Write,
|
||||||
|
AccessMode_WriteShared = AccessMode_Write | AccessMode_Shared,
|
||||||
|
AccessMode_ReadWriteShared = AccessMode_Read | AccessMode_WriteShared,
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
#include <vapours.hpp>
|
||||||
|
|
||||||
|
namespace ams::ddsf::impl {
|
||||||
|
|
||||||
|
template<typename Lock, typename List, typename F>
|
||||||
|
inline Result ForEach(Lock &lock, List &list, F f, bool return_on_fail) {
|
||||||
|
std::scoped_lock lk(lock);
|
||||||
|
|
||||||
|
Result result = ResultSuccess();
|
||||||
|
for (auto && it : list) {
|
||||||
|
if (const auto cur_result = f(std::addressof(it)); R_FAILED(cur_result)) {
|
||||||
|
if (return_on_fail) {
|
||||||
|
return cur_result;
|
||||||
|
} else if (R_SUCCEEDED(result)) {
|
||||||
|
result = cur_result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename List, typename F, typename Lock>
|
||||||
|
inline int ForEach(Lock &lock, List &list, F f) {
|
||||||
|
std::scoped_lock lk(lock);
|
||||||
|
|
||||||
|
int success_count = 0;
|
||||||
|
for (auto && it : list) {
|
||||||
|
if (!f(it)) {
|
||||||
|
return success_count;
|
||||||
|
}
|
||||||
|
++success_count;
|
||||||
|
}
|
||||||
|
return success_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/ddsf/ddsf_types.hpp>
|
||||||
|
|
||||||
|
namespace ams::ddsf::impl {
|
||||||
|
|
||||||
|
#if defined(AMS_BUILD_FOR_DEBUGGING) || defined(AMS_BUILD_FOR_AUDITING)
|
||||||
|
|
||||||
|
#define AMS_DDSF_CASTABLE_ROOT_TRAITS(__CLASS__) \
|
||||||
|
public: \
|
||||||
|
static constexpr inline ::ams::ddsf::impl::TypeTag s_ams_ddsf_castable_type_tag{#__CLASS__}; \
|
||||||
|
constexpr virtual const ::ams::ddsf::impl::TypeTag &GetTypeTag() const override { return s_ams_ddsf_castable_type_tag; }
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define AMS_DDSF_CASTABLE_ROOT_TRAITS(__CLASS__) \
|
||||||
|
public: \
|
||||||
|
static constexpr inline ::ams::ddsf::impl::TypeTag s_ams_ddsf_castable_type_tag{}; \
|
||||||
|
constexpr virtual const ::ams::ddsf::impl::TypeTag &GetTypeTag() const override { return s_ams_ddsf_castable_type_tag; }
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class TypeTag {
|
||||||
|
private:
|
||||||
|
const char * const class_name;
|
||||||
|
const TypeTag * const base;
|
||||||
|
public:
|
||||||
|
#if !(defined(AMS_BUILD_FOR_DEBUGGING) || defined(AMS_BUILD_FOR_AUDITING))
|
||||||
|
constexpr TypeTag() : class_name(nullptr), base(nullptr) { /* ... */}
|
||||||
|
constexpr TypeTag(const TypeTag &b) : class_name(nullptr), base(std::addressof(b)) { AMS_ASSERT(this != this->base); }
|
||||||
|
|
||||||
|
constexpr TypeTag(const char *c) : class_name(nullptr), base(nullptr) { AMS_UNUSED(c); }
|
||||||
|
constexpr TypeTag(const char *c, const TypeTag &b) : class_name(nullptr), base(std::addressof(b)) { AMS_UNUSED(c); AMS_ASSERT(this != this->base); }
|
||||||
|
#else
|
||||||
|
constexpr TypeTag(const char *c) : class_name(c), base(nullptr) { /* ... */ }
|
||||||
|
constexpr TypeTag(const char *c, const TypeTag &b) : class_name(c), base(std::addressof(b)) { AMS_ASSERT(this != this->base); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
constexpr const char * GetClassName() const { return this->class_name; }
|
||||||
|
|
||||||
|
constexpr bool Is(const TypeTag &rhs) const { return this == std::addressof(rhs); }
|
||||||
|
|
||||||
|
constexpr bool DerivesFrom(const TypeTag &rhs) const {
|
||||||
|
const TypeTag * cur = this;
|
||||||
|
while (cur != nullptr) {
|
||||||
|
if (cur == std::addressof(rhs)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
cur = cur->base;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
26
libraries/libstratosphere/include/stratosphere/gpio.hpp
Normal file
26
libraries/libstratosphere/include/stratosphere/gpio.hpp
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
#include <stratosphere/gpio/gpio_types.hpp>
|
||||||
|
#include <stratosphere/gpio/sf/gpio_sf_i_pad_session.hpp>
|
||||||
|
#include <stratosphere/gpio/sf/gpio_sf_i_manager.hpp>
|
||||||
|
#include <stratosphere/gpio/gpio_api.hpp>
|
||||||
|
#include <stratosphere/gpio/gpio_pad_api.hpp>
|
||||||
|
#include <stratosphere/gpio/driver/gpio_select_driver_api.hpp>
|
||||||
|
#include <stratosphere/gpio/driver/gpio_pad_accessor.hpp>
|
||||||
|
#include <stratosphere/gpio/driver/impl/gpio_pad_session_impl.hpp>
|
||||||
|
#include <stratosphere/gpio/server/gpio_server_api.hpp>
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/gpio/gpio_types.hpp>
|
||||||
|
#include <stratosphere/gpio/driver/gpio_i_gpio_driver.hpp>
|
||||||
|
|
||||||
|
namespace ams::gpio::driver::board::nintendo_nx {
|
||||||
|
|
||||||
|
void Initialize(bool enable_interrupt_handlers);
|
||||||
|
|
||||||
|
void SetInitialGpioConfig();
|
||||||
|
void SetInitialWakePinConfig();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/gpio/gpio_types.hpp>
|
||||||
|
#include <stratosphere/gpio/driver/gpio_i_gpio_driver.hpp>
|
||||||
|
|
||||||
|
namespace ams::gpio::driver {
|
||||||
|
|
||||||
|
void Initialize();
|
||||||
|
void Finalize();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/gpio/gpio_types.hpp>
|
||||||
|
#include <stratosphere/gpio/driver/gpio_i_gpio_driver.hpp>
|
||||||
|
|
||||||
|
namespace ams::gpio::driver {
|
||||||
|
|
||||||
|
void RegisterDriver(IGpioDriver *driver);
|
||||||
|
void UnregisterDriver(IGpioDriver *driver);
|
||||||
|
|
||||||
|
Result RegisterDeviceCode(DeviceCode device_code, Pad *pad);
|
||||||
|
bool UnregisterDeviceCode(DeviceCode device_code);
|
||||||
|
|
||||||
|
void RegisterInterruptHandler(ddsf::IEventHandler *handler);
|
||||||
|
void UnregisterInterruptHandler(ddsf::IEventHandler *handler);
|
||||||
|
|
||||||
|
void SetInitialGpioConfig();
|
||||||
|
void SetInitialWakePinConfig();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/gpio/gpio_types.hpp>
|
||||||
|
#include <stratosphere/ddsf.hpp>
|
||||||
|
|
||||||
|
namespace ams::gpio::driver {
|
||||||
|
|
||||||
|
class Pad;
|
||||||
|
|
||||||
|
class IGpioDriver : public ::ams::ddsf::IDriver {
|
||||||
|
NON_COPYABLE(IGpioDriver);
|
||||||
|
NON_MOVEABLE(IGpioDriver);
|
||||||
|
AMS_DDSF_CASTABLE_TRAITS(ams::gpio::driver::IGpioDriver, ::ams::ddsf::IDriver);
|
||||||
|
public:
|
||||||
|
IGpioDriver() : IDriver() { /* ... */ }
|
||||||
|
virtual ~IGpioDriver() { /* ... */ }
|
||||||
|
|
||||||
|
virtual void InitializeDriver() = 0;
|
||||||
|
virtual void FinalizeDriver() = 0;
|
||||||
|
|
||||||
|
virtual Result InitializePad(Pad *pad) = 0;
|
||||||
|
virtual void FinalizePad(Pad *pad) = 0;
|
||||||
|
|
||||||
|
virtual Result GetDirection(Direction *out, Pad *pad) const = 0;
|
||||||
|
virtual Result SetDirection(Pad *pad, Direction direction) = 0;
|
||||||
|
|
||||||
|
virtual Result GetValue(GpioValue *out, Pad *pad) const = 0;
|
||||||
|
virtual Result SetValue(Pad *pad, GpioValue value) = 0;
|
||||||
|
|
||||||
|
virtual Result GetInterruptMode(InterruptMode *out, Pad *pad) const = 0;
|
||||||
|
virtual Result SetInterruptMode(Pad *pad, InterruptMode mode) = 0;
|
||||||
|
|
||||||
|
virtual Result SetInterruptEnabled(Pad *pad, bool en) = 0;
|
||||||
|
|
||||||
|
virtual Result GetInterruptStatus(InterruptStatus *out, Pad *pad) = 0;
|
||||||
|
virtual Result ClearInterruptStatus(Pad *pad) = 0;
|
||||||
|
|
||||||
|
virtual os::SdkMutex &GetInterruptControlMutex(const Pad &pad) const = 0;
|
||||||
|
|
||||||
|
virtual Result GetDebounceEnabled(bool *out, Pad *pad) const = 0;
|
||||||
|
virtual Result SetDebounceEnabled(Pad *pad, bool en) = 0;
|
||||||
|
|
||||||
|
virtual Result GetDebounceTime(s32 *out_ms, Pad *pad) const = 0;
|
||||||
|
virtual Result SetDebounceTime(Pad *pad, s32 ms) = 0;
|
||||||
|
|
||||||
|
virtual Result GetUnknown22(u32 *out) = 0;
|
||||||
|
virtual void Unknown23();
|
||||||
|
|
||||||
|
virtual Result SetValueForSleepState(Pad *pad, GpioValue value) = 0;
|
||||||
|
virtual Result IsWakeEventActive(bool *out, Pad *pad) const = 0;
|
||||||
|
virtual Result SetWakeEventActiveFlagSetForDebug(Pad *pad, bool en) = 0;
|
||||||
|
virtual Result SetWakePinDebugMode(WakePinDebugMode mode) = 0;
|
||||||
|
|
||||||
|
virtual Result Suspend() = 0;
|
||||||
|
virtual Result SuspendLow() = 0;
|
||||||
|
virtual Result Resume() = 0;
|
||||||
|
virtual Result ResumeLow() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/gpio/gpio_types.hpp>
|
||||||
|
#include <stratosphere/ddsf.hpp>
|
||||||
|
|
||||||
|
namespace ams::gpio::driver {
|
||||||
|
|
||||||
|
class Pad : public ::ams::ddsf::IDevice {
|
||||||
|
NON_COPYABLE(Pad);
|
||||||
|
NON_MOVEABLE(Pad);
|
||||||
|
AMS_DDSF_CASTABLE_TRAITS(ams::gpio::driver::Pad, ::ams::ddsf::IDevice);
|
||||||
|
private:
|
||||||
|
int pad_number;
|
||||||
|
bool is_interrupt_enabled;
|
||||||
|
public:
|
||||||
|
explicit Pad(int pad) : IDevice(true), pad_number(pad), is_interrupt_enabled(false) { /* ... */ }
|
||||||
|
|
||||||
|
Pad() : Pad(0) { /* ... */ }
|
||||||
|
|
||||||
|
virtual ~Pad() { /* ... */ }
|
||||||
|
|
||||||
|
int GetPadNumber() const {
|
||||||
|
return this->pad_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetPadNumber(int p) {
|
||||||
|
this->pad_number = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsInterruptEnabled() const {
|
||||||
|
return this->is_interrupt_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetInterruptEnabled(bool en) {
|
||||||
|
this->is_interrupt_enabled = en;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsInterruptRequiredForDriver() const {
|
||||||
|
return this->IsInterruptEnabled() && this->IsAnySessionBoundToInterrupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsAnySessionBoundToInterrupt() const;
|
||||||
|
void SignalInterruptBoundEvent();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/gpio/gpio_types.hpp>
|
||||||
|
|
||||||
|
namespace ams::gpio::driver {
|
||||||
|
|
||||||
|
namespace impl {
|
||||||
|
|
||||||
|
constexpr inline size_t GpioPadSessionSize = 0x60;
|
||||||
|
constexpr inline size_t GpioPadSessionAlign = 8;
|
||||||
|
struct alignas(GpioPadSessionAlign) GpioPadSessionImplPadded;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
struct GpioPadSession {
|
||||||
|
util::TypedStorage<impl::GpioPadSessionImplPadded, impl::GpioPadSessionSize, impl::GpioPadSessionAlign> _impl;
|
||||||
|
};
|
||||||
|
|
||||||
|
Result OpenSession(GpioPadSession *out, DeviceCode device_code, ddsf::AccessMode access_mode);
|
||||||
|
void CloseSession(GpioPadSession *session);
|
||||||
|
|
||||||
|
Result SetDirection(GpioPadSession *session, gpio::Direction direction);
|
||||||
|
Result GetDirection(gpio::Direction *out, GpioPadSession *session);
|
||||||
|
|
||||||
|
Result SetValue(GpioPadSession *session, gpio::GpioValue value);
|
||||||
|
Result GetValue(gpio::GpioValue *out, GpioPadSession *session);
|
||||||
|
|
||||||
|
/* TODO */
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/gpio/gpio_types.hpp>
|
||||||
|
#include <stratosphere/gpio/driver/gpio_i_gpio_driver.hpp>
|
||||||
|
#include <stratosphere/gpio/driver/gpio_driver_service_api.hpp>
|
||||||
|
#include <stratosphere/gpio/driver/gpio_driver_client_api.hpp>
|
||||||
|
|
||||||
|
#if defined(ATMOSPHERE_BOARD_NINTENDO_NX)
|
||||||
|
|
||||||
|
#include <stratosphere/gpio/driver/board/nintendo_nx/gpio_driver_api.hpp>
|
||||||
|
|
||||||
|
namespace ams::gpio::driver::board {
|
||||||
|
|
||||||
|
using namespace ams::gpio::driver::board::nintendo_nx;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#error "Unknown board for ams::gpio::driver::"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/os.hpp>
|
||||||
|
|
||||||
|
namespace ams::gpio::driver::impl {
|
||||||
|
|
||||||
|
class EventHolder {
|
||||||
|
NON_COPYABLE(EventHolder);
|
||||||
|
NON_MOVEABLE(EventHolder);
|
||||||
|
private:
|
||||||
|
os::SystemEventType *event;
|
||||||
|
public:
|
||||||
|
constexpr EventHolder() : event(nullptr) { /* ... */ }
|
||||||
|
|
||||||
|
void AttachEvent(os::SystemEventType *event) {
|
||||||
|
this->event = event;
|
||||||
|
}
|
||||||
|
|
||||||
|
os::SystemEventType *DetachEvent() {
|
||||||
|
auto ev = this->event;
|
||||||
|
this->event = nullptr;
|
||||||
|
return ev;
|
||||||
|
}
|
||||||
|
|
||||||
|
os::SystemEventType *GetSystemEvent() {
|
||||||
|
return this->event;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsBound() const {
|
||||||
|
return this->event != nullptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/gpio/gpio_types.hpp>
|
||||||
|
#include <stratosphere/gpio/driver/gpio_pad_accessor.hpp>
|
||||||
|
#include <stratosphere/gpio/driver/impl/gpio_event_holder.hpp>
|
||||||
|
#include <stratosphere/ddsf.hpp>
|
||||||
|
|
||||||
|
namespace ams::gpio::driver {
|
||||||
|
|
||||||
|
class Pad;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace ams::gpio::driver::impl {
|
||||||
|
|
||||||
|
class PadSessionImpl : public ::ams::ddsf::ISession {
|
||||||
|
NON_COPYABLE(PadSessionImpl);
|
||||||
|
NON_MOVEABLE(PadSessionImpl);
|
||||||
|
AMS_DDSF_CASTABLE_TRAITS(ams::gpio::driver::impl::PadSessionImpl, ::ams::ddsf::ISession);
|
||||||
|
private:
|
||||||
|
EventHolder event_holder;
|
||||||
|
private:
|
||||||
|
Result UpdateDriverInterruptEnabled();
|
||||||
|
public:
|
||||||
|
PadSessionImpl() : event_holder() { /* ... */ }
|
||||||
|
|
||||||
|
~PadSessionImpl() {
|
||||||
|
this->Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsInterruptBound() const {
|
||||||
|
return this->event_holder.IsBound();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result Open(Pad *pad, ddsf::AccessMode access_mode);
|
||||||
|
void Close();
|
||||||
|
|
||||||
|
Result BindInterrupt(os::SystemEventType *event);
|
||||||
|
void UnbindInterrupt();
|
||||||
|
|
||||||
|
Result GetInterruptEnabled(bool *out) const;
|
||||||
|
Result SetInterruptEnabled(bool en);
|
||||||
|
void SignalInterruptBoundEvent();
|
||||||
|
};
|
||||||
|
static_assert( sizeof(PadSessionImpl) <= GpioPadSessionSize);
|
||||||
|
static_assert(alignof(PadSessionImpl) <= GpioPadSessionAlign);
|
||||||
|
|
||||||
|
struct alignas(GpioPadSessionAlign) GpioPadSessionImplPadded {
|
||||||
|
PadSessionImpl _impl;
|
||||||
|
u8 _padding[GpioPadSessionSize - sizeof(PadSessionImpl)];
|
||||||
|
};
|
||||||
|
static_assert( sizeof(GpioPadSessionImplPadded) == GpioPadSessionSize);
|
||||||
|
static_assert(alignof(GpioPadSessionImplPadded) == GpioPadSessionAlign);
|
||||||
|
|
||||||
|
ALWAYS_INLINE PadSessionImpl &GetPadSessionImpl(GpioPadSession &session) {
|
||||||
|
return GetReference(session._impl)._impl;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALWAYS_INLINE const PadSessionImpl &GetPadSessionImpl(const GpioPadSession &session) {
|
||||||
|
return GetReference(session._impl)._impl;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALWAYS_INLINE PadSessionImpl &GetOpenPadSessionImpl(GpioPadSession &session) {
|
||||||
|
auto &ref = GetReference(session._impl)._impl;
|
||||||
|
AMS_ASSERT(ref.IsOpen());
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALWAYS_INLINE const PadSessionImpl &GetOpenPadSessionImpl(const GpioPadSession &session) {
|
||||||
|
const auto &ref = GetReference(session._impl)._impl;
|
||||||
|
AMS_ASSERT(ref.IsOpen());
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -13,16 +13,16 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <switch.h>
|
#include <vapours.hpp>
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere/gpio/gpio_types.hpp>
|
||||||
|
#include <stratosphere/gpio/sf/gpio_sf_i_manager.hpp>
|
||||||
|
|
||||||
namespace ams::gpio {
|
namespace ams::gpio {
|
||||||
|
|
||||||
/* GPIO Utilities. */
|
void Initialize();
|
||||||
u32 Configure(u32 gpio_pad_name);
|
void Finalize();
|
||||||
u32 SetDirection(u32 gpio_pad_name, GpioDirection dir);
|
|
||||||
u32 SetValue(u32 gpio_pad_name, GpioValue val);
|
void InitializeWith(std::shared_ptr<gpio::sf::IManager> &&sp);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/ddsf/ddsf_types.hpp>
|
||||||
|
#include <stratosphere/gpio/gpio_types.hpp>
|
||||||
|
#include <stratosphere/gpio/gpio_select_pad_name.hpp>
|
||||||
|
#include <stratosphere/gpio/driver/gpio_pad.hpp>
|
||||||
|
|
||||||
|
namespace ams::gpio {
|
||||||
|
|
||||||
|
struct GpioPadSession {
|
||||||
|
void *_session;
|
||||||
|
os::SystemEventType *_event;
|
||||||
|
};
|
||||||
|
|
||||||
|
Result OpenSession(GpioPadSession *out_session, ams::DeviceCode device_code);
|
||||||
|
void CloseSession(GpioPadSession *session);
|
||||||
|
|
||||||
|
Direction GetDirection(GpioPadSession *session);
|
||||||
|
void SetDirection(GpioPadSession *session, Direction direction);
|
||||||
|
|
||||||
|
GpioValue GetValue(GpioPadSession *session);
|
||||||
|
void SetValue(GpioPadSession *session, GpioValue value);
|
||||||
|
|
||||||
|
InterruptMode GetInterruptMode(GpioPadSession *session);
|
||||||
|
void SetInterruptMode(GpioPadSession *session, InterruptMode mode);
|
||||||
|
|
||||||
|
bool GetInterruptEnable(GpioPadSession *session);
|
||||||
|
void SetInterruptEnable(GpioPadSession *session, bool en);
|
||||||
|
|
||||||
|
InterruptStatus GetInterruptStatus(GpioPadSession *session);
|
||||||
|
void ClearInterruptStatus(GpioPadSession *session);
|
||||||
|
|
||||||
|
int GetDebounceTime(GpioPadSession *session);
|
||||||
|
void SetDebounceTime(GpioPadSession *session, int ms);
|
||||||
|
|
||||||
|
bool GetDebounceEnabled(GpioPadSession *session);
|
||||||
|
void SetDebounceEnabled(GpioPadSession *session, bool en);
|
||||||
|
|
||||||
|
Result BindInterrupt(os::SystemEventType *event, GpioPadSession *session);
|
||||||
|
void UnbindInterrupt(GpioPadSession *session);
|
||||||
|
|
||||||
|
Result IsWakeEventActive(bool *out_is_active, ams::DeviceCode device_code);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,416 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/gpio/gpio_types.hpp>
|
||||||
|
|
||||||
|
namespace ams::gpio {
|
||||||
|
|
||||||
|
enum GpioPadName : u32 {
|
||||||
|
GpioPadName_CodecLdoEnTemp = 1,
|
||||||
|
GpioPadName_PowSdEn = 2,
|
||||||
|
GpioPadName_BtRst = 3,
|
||||||
|
GpioPadName_RamCode3 = 4,
|
||||||
|
GpioPadName_GameCardReset = 5,
|
||||||
|
GpioPadName_CodecAlert = 6,
|
||||||
|
GpioPadName_PowGc = 7,
|
||||||
|
GpioPadName_DebugControllerDet = 8,
|
||||||
|
GpioPadName_BattChgStatus = 9,
|
||||||
|
GpioPadName_BattChgEnableN = 10,
|
||||||
|
GpioPadName_FanTach = 11,
|
||||||
|
GpioPadName_ExtconDetS = 12,
|
||||||
|
GpioPadName_Vdd50AEn = 13,
|
||||||
|
GpioPadName_SdevCoaxSel1 = 14,
|
||||||
|
GpioPadName_GameCardCd = 15,
|
||||||
|
GpioPadName_ProdType0 = 16,
|
||||||
|
GpioPadName_ProdType1 = 17,
|
||||||
|
GpioPadName_ProdType2 = 18,
|
||||||
|
GpioPadName_ProdType3 = 19,
|
||||||
|
GpioPadName_TempAlert = 20,
|
||||||
|
GpioPadName_CodecHpDetIrq = 21,
|
||||||
|
GpioPadName_MotionInt = 22,
|
||||||
|
GpioPadName_TpIrq = 23,
|
||||||
|
GpioPadName_ButtonSleep2 = 24,
|
||||||
|
GpioPadName_ButtonVolUp = 25,
|
||||||
|
GpioPadName_ButtonVolDn = 26,
|
||||||
|
GpioPadName_BattMgicIrq = 27,
|
||||||
|
GpioPadName_RecoveryKey = 28,
|
||||||
|
GpioPadName_PowLcdBlEn = 29,
|
||||||
|
GpioPadName_LcdReset = 30,
|
||||||
|
GpioPadName_PdVconnEn = 31,
|
||||||
|
GpioPadName_PdRstN = 32,
|
||||||
|
GpioPadName_Bq24190Irq = 33,
|
||||||
|
GpioPadName_SdevCoaxSel0 = 34,
|
||||||
|
GpioPadName_SdWp = 35,
|
||||||
|
GpioPadName_TpReset = 36,
|
||||||
|
GpioPadName_BtGpio2 = 37,
|
||||||
|
GpioPadName_BtGpio3 = 38,
|
||||||
|
GpioPadName_BtGpio4 = 39,
|
||||||
|
GpioPadName_CradleIrq = 40,
|
||||||
|
GpioPadName_PowVcpuInt = 41,
|
||||||
|
GpioPadName_Max77621GpuInt = 42,
|
||||||
|
GpioPadName_ExtconChgU = 43,
|
||||||
|
GpioPadName_ExtconChgS = 44,
|
||||||
|
GpioPadName_WifiRfDisable = 45,
|
||||||
|
GpioPadName_WifiReset = 46,
|
||||||
|
GpioPadName_ApWakeBt = 47,
|
||||||
|
GpioPadName_BtWakeAp = 48,
|
||||||
|
GpioPadName_BtGpio5 = 49,
|
||||||
|
GpioPadName_PowLcdVddPEn = 50,
|
||||||
|
GpioPadName_PowLcdVddNEn = 51,
|
||||||
|
GpioPadName_ExtconDetU = 52,
|
||||||
|
GpioPadName_RamCode2 = 53,
|
||||||
|
GpioPadName_Vdd50BEn = 54,
|
||||||
|
GpioPadName_WifiWakeHost = 55,
|
||||||
|
GpioPadName_SdCd = 56,
|
||||||
|
GpioPadName_OtgFet1ForSdev = 57,
|
||||||
|
GpioPadName_OtgFet2ForSdev = 58,
|
||||||
|
GpioPadName_ExtConWakeU = 59,
|
||||||
|
GpioPadName_ExtConWakeS = 60,
|
||||||
|
GpioPadName_PmuIrq = 61,
|
||||||
|
GpioPadName_ExtUart2Cts = 62,
|
||||||
|
GpioPadName_ExtUart3Cts = 63,
|
||||||
|
GpioPadName_5VStepDownEn = 64,
|
||||||
|
GpioPadName_UsbSwitchB2Oc = 65,
|
||||||
|
GpioPadName_5VStepDownPg = 66,
|
||||||
|
GpioPadName_UsbSwitchAEn = 67,
|
||||||
|
GpioPadName_UsbSwitchAFlag = 68,
|
||||||
|
GpioPadName_UsbSwitchB3Oc = 69,
|
||||||
|
GpioPadName_UsbSwitchB3En = 70,
|
||||||
|
GpioPadName_UsbSwitchB2En = 71,
|
||||||
|
GpioPadName_Hdmi5VEn = 72,
|
||||||
|
GpioPadName_UsbSwitchB1En = 73,
|
||||||
|
GpioPadName_HdmiPdTrEn = 74,
|
||||||
|
GpioPadName_FanEn = 75,
|
||||||
|
GpioPadName_UsbSwitchB1Oc = 76,
|
||||||
|
GpioPadName_PwmFan = 77,
|
||||||
|
GpioPadName_HdmiHpd = 78,
|
||||||
|
GpioPadName_Max77812Irq = 79,
|
||||||
|
GpioPadName_Debug0 = 80,
|
||||||
|
GpioPadName_Debug1 = 81,
|
||||||
|
GpioPadName_Debug2 = 82,
|
||||||
|
GpioPadName_Debug3 = 83,
|
||||||
|
GpioPadName_NfcIrq = 84,
|
||||||
|
GpioPadName_NfcRst = 85,
|
||||||
|
GpioPadName_McuIrq = 86,
|
||||||
|
GpioPadName_McuBoot = 87,
|
||||||
|
GpioPadName_McuRst = 88,
|
||||||
|
GpioPadName_Vdd5V3En = 89,
|
||||||
|
GpioPadName_McuPor = 90,
|
||||||
|
GpioPadName_LcdGpio1 = 91,
|
||||||
|
GpioPadName_NfcEn = 92,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* TODO: Better place for this? */
|
||||||
|
constexpr inline const DeviceCode DeviceCode_CodecLdoEnTemp = 0x33000002;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_PowSdEn = 0x3C000001;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_BtRst = 0x37000002;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_RamCode3 = 0xC9000402;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_GameCardReset = 0x3C000402;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_CodecAlert = 0x33000003;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_PowGc = 0x3C000401;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_DebugControllerDet = 0x350000CA;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_BattChgStatus = 0x39000407;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_BattChgEnableN = 0x39000003;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_FanTach = 0x3D000002;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_ExtconDetS = 0x3500040B;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_Vdd50AEn = 0x39000401;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_SdevCoaxSel1 = 0xCA000402;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_GameCardCd = 0x3C000403;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_ProdType0 = 0xC900040B;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_ProdType1 = 0xC900040C;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_ProdType2 = 0xC900040D;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_ProdType3 = 0xC900040E;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_TempAlert = 0x3E000002;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_CodecHpDetIrq = 0x33000004;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_MotionInt = 0x35000041;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_TpIrq = 0x35000036;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_ButtonSleep2 = 0x35000001;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_ButtonVolUp = 0x35000002;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_ButtonVolDn = 0x35000003;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_BattMgicIrq = 0x39000034;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_RecoveryKey = 0x35000004;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_PowLcdBlEn = 0x3400003E;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_LcdReset = 0x34000033;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_PdVconnEn = 0x040000CC;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_PdRstN = 0x040000CA;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_Bq24190Irq = 0x39000002;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_SdevCoaxSel0 = 0xCA000401;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_SdWp = 0x3C000003;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_TpReset = 0x35000035;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_BtGpio2 = 0x37000401;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_BtGpio3 = 0x37000402;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_BtGpio4 = 0x37000403;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_CradleIrq = 0x040000CB;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_PowVcpuInt = 0x3E000003;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_Max77621GpuInt = 0x3E000004;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_ExtconChgU = 0x35000402;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_ExtconChgS = 0x3500040C;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_WifiRfDisable = 0x38000003;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_WifiReset = 0x38000002;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_ApWakeBt = 0x37000003;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_BtWakeAp = 0x37000004;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_BtGpio5 = 0x37000404;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_PowLcdVddPEn = 0x34000034;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_PowLcdVddNEn = 0x34000035;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_ExtconDetU = 0x35000401;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_RamCode2 = 0xC9000401;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_Vdd50BEn = 0x39000402;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_WifiWakeHost = 0x38000004;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_SdCd = 0x3C000002;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_OtgFet1ForSdev = 0x39000404;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_OtgFet2ForSdev = 0x39000405;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_ExtConWakeU = 0x35000403;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_ExtConWakeS = 0x3500040D;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_PmuIrq = 0x39000406;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_ExtUart2Cts = 0x35000404;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_ExtUart3Cts = 0x3500040E;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_5VStepDownEn = 0x39000408;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_UsbSwitchB2Oc = 0x04000401;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_5VStepDownPg = 0x39000409;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_UsbSwitchAEn = 0x04000402;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_UsbSwitchAFlag = 0x04000403;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_UsbSwitchB3Oc = 0x04000404;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_UsbSwitchB3En = 0x04000405;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_UsbSwitchB2En = 0x04000406;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_Hdmi5VEn = 0x34000004;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_UsbSwitchB1En = 0x04000407;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_HdmiPdTrEn = 0x34000005;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_FanEn = 0x3D000003;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_UsbSwitchB1Oc = 0x04000408;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_PwmFan = 0x3D000001;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_HdmiHpd = 0x34000006;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_Max77812Irq = 0x3E000003;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_Debug0 = 0xCA000001;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_Debug1 = 0xCA000002;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_Debug2 = 0xCA000003;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_Debug3 = 0xCA000004;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_NfcIrq = 0x36000004;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_NfcRst = 0x36000003;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_McuIrq = 0x35000415;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_McuBoot = 0x35000416;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_McuRst = 0x35000417;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_Vdd5V3En = 0x39000403;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_McuPor = 0x35000418;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_LcdGpio1 = 0x35000005;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_NfcEn = 0x36000002;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_ExtUart2Rts = 0x35000406;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_ExtUart3Rts = 0x35000410;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_GpioPortC7 = 0x3500041B;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_GpioPortD0 = 0x3500041C;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_GpioPortC5 = 0x3500041D;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_GpioPortC6 = 0x3500041E;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_GpioPortY7 = 0x35000065;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_GpioPortF1 = 0x04000409;
|
||||||
|
constexpr inline const DeviceCode DeviceCode_GpioPortH0 = 0x34000401;
|
||||||
|
|
||||||
|
constexpr inline GpioPadName ConvertToGpioPadName(DeviceCode dc) {
|
||||||
|
switch (dc.GetInternalValue()) {
|
||||||
|
case DeviceCode_CodecLdoEnTemp .GetInternalValue(): return GpioPadName_CodecLdoEnTemp;
|
||||||
|
case DeviceCode_PowSdEn .GetInternalValue(): return GpioPadName_PowSdEn;
|
||||||
|
case DeviceCode_BtRst .GetInternalValue(): return GpioPadName_BtRst;
|
||||||
|
case DeviceCode_RamCode3 .GetInternalValue(): return GpioPadName_RamCode3;
|
||||||
|
case DeviceCode_GameCardReset .GetInternalValue(): return GpioPadName_GameCardReset;
|
||||||
|
case DeviceCode_CodecAlert .GetInternalValue(): return GpioPadName_CodecAlert;
|
||||||
|
case DeviceCode_PowGc .GetInternalValue(): return GpioPadName_PowGc;
|
||||||
|
case DeviceCode_DebugControllerDet.GetInternalValue(): return GpioPadName_DebugControllerDet;
|
||||||
|
case DeviceCode_BattChgStatus .GetInternalValue(): return GpioPadName_BattChgStatus;
|
||||||
|
case DeviceCode_BattChgEnableN .GetInternalValue(): return GpioPadName_BattChgEnableN;
|
||||||
|
case DeviceCode_FanTach .GetInternalValue(): return GpioPadName_FanTach;
|
||||||
|
case DeviceCode_ExtconDetS .GetInternalValue(): return GpioPadName_ExtconDetS;
|
||||||
|
case DeviceCode_Vdd50AEn .GetInternalValue(): return GpioPadName_Vdd50AEn;
|
||||||
|
case DeviceCode_SdevCoaxSel1 .GetInternalValue(): return GpioPadName_SdevCoaxSel1;
|
||||||
|
case DeviceCode_GameCardCd .GetInternalValue(): return GpioPadName_GameCardCd;
|
||||||
|
case DeviceCode_ProdType0 .GetInternalValue(): return GpioPadName_ProdType0;
|
||||||
|
case DeviceCode_ProdType1 .GetInternalValue(): return GpioPadName_ProdType1;
|
||||||
|
case DeviceCode_ProdType2 .GetInternalValue(): return GpioPadName_ProdType2;
|
||||||
|
case DeviceCode_ProdType3 .GetInternalValue(): return GpioPadName_ProdType3;
|
||||||
|
case DeviceCode_TempAlert .GetInternalValue(): return GpioPadName_TempAlert;
|
||||||
|
case DeviceCode_CodecHpDetIrq .GetInternalValue(): return GpioPadName_CodecHpDetIrq;
|
||||||
|
case DeviceCode_MotionInt .GetInternalValue(): return GpioPadName_MotionInt;
|
||||||
|
case DeviceCode_TpIrq .GetInternalValue(): return GpioPadName_TpIrq;
|
||||||
|
case DeviceCode_ButtonSleep2 .GetInternalValue(): return GpioPadName_ButtonSleep2;
|
||||||
|
case DeviceCode_ButtonVolUp .GetInternalValue(): return GpioPadName_ButtonVolUp;
|
||||||
|
case DeviceCode_ButtonVolDn .GetInternalValue(): return GpioPadName_ButtonVolDn;
|
||||||
|
case DeviceCode_BattMgicIrq .GetInternalValue(): return GpioPadName_BattMgicIrq;
|
||||||
|
case DeviceCode_RecoveryKey .GetInternalValue(): return GpioPadName_RecoveryKey;
|
||||||
|
case DeviceCode_PowLcdBlEn .GetInternalValue(): return GpioPadName_PowLcdBlEn;
|
||||||
|
case DeviceCode_LcdReset .GetInternalValue(): return GpioPadName_LcdReset;
|
||||||
|
case DeviceCode_PdVconnEn .GetInternalValue(): return GpioPadName_PdVconnEn;
|
||||||
|
case DeviceCode_PdRstN .GetInternalValue(): return GpioPadName_PdRstN;
|
||||||
|
case DeviceCode_Bq24190Irq .GetInternalValue(): return GpioPadName_Bq24190Irq;
|
||||||
|
case DeviceCode_SdevCoaxSel0 .GetInternalValue(): return GpioPadName_SdevCoaxSel0;
|
||||||
|
case DeviceCode_SdWp .GetInternalValue(): return GpioPadName_SdWp;
|
||||||
|
case DeviceCode_TpReset .GetInternalValue(): return GpioPadName_TpReset;
|
||||||
|
case DeviceCode_BtGpio2 .GetInternalValue(): return GpioPadName_BtGpio2;
|
||||||
|
case DeviceCode_BtGpio3 .GetInternalValue(): return GpioPadName_BtGpio3;
|
||||||
|
case DeviceCode_BtGpio4 .GetInternalValue(): return GpioPadName_BtGpio4;
|
||||||
|
case DeviceCode_CradleIrq .GetInternalValue(): return GpioPadName_CradleIrq;
|
||||||
|
/* case DeviceCode_PowVcpuInt .GetInternalValue(): return GpioPadName_PowVcpuInt; */
|
||||||
|
case DeviceCode_Max77621GpuInt .GetInternalValue(): return GpioPadName_Max77621GpuInt;
|
||||||
|
case DeviceCode_ExtconChgU .GetInternalValue(): return GpioPadName_ExtconChgU;
|
||||||
|
case DeviceCode_ExtconChgS .GetInternalValue(): return GpioPadName_ExtconChgS;
|
||||||
|
case DeviceCode_WifiRfDisable .GetInternalValue(): return GpioPadName_WifiRfDisable;
|
||||||
|
case DeviceCode_WifiReset .GetInternalValue(): return GpioPadName_WifiReset;
|
||||||
|
case DeviceCode_ApWakeBt .GetInternalValue(): return GpioPadName_ApWakeBt;
|
||||||
|
case DeviceCode_BtWakeAp .GetInternalValue(): return GpioPadName_BtWakeAp;
|
||||||
|
case DeviceCode_BtGpio5 .GetInternalValue(): return GpioPadName_BtGpio5;
|
||||||
|
case DeviceCode_PowLcdVddPEn .GetInternalValue(): return GpioPadName_PowLcdVddPEn;
|
||||||
|
case DeviceCode_PowLcdVddNEn .GetInternalValue(): return GpioPadName_PowLcdVddNEn;
|
||||||
|
case DeviceCode_ExtconDetU .GetInternalValue(): return GpioPadName_ExtconDetU;
|
||||||
|
case DeviceCode_RamCode2 .GetInternalValue(): return GpioPadName_RamCode2;
|
||||||
|
case DeviceCode_Vdd50BEn .GetInternalValue(): return GpioPadName_Vdd50BEn;
|
||||||
|
case DeviceCode_WifiWakeHost .GetInternalValue(): return GpioPadName_WifiWakeHost;
|
||||||
|
case DeviceCode_SdCd .GetInternalValue(): return GpioPadName_SdCd;
|
||||||
|
case DeviceCode_OtgFet1ForSdev .GetInternalValue(): return GpioPadName_OtgFet1ForSdev;
|
||||||
|
case DeviceCode_OtgFet2ForSdev .GetInternalValue(): return GpioPadName_OtgFet2ForSdev;
|
||||||
|
case DeviceCode_ExtConWakeU .GetInternalValue(): return GpioPadName_ExtConWakeU;
|
||||||
|
case DeviceCode_ExtConWakeS .GetInternalValue(): return GpioPadName_ExtConWakeS;
|
||||||
|
case DeviceCode_PmuIrq .GetInternalValue(): return GpioPadName_PmuIrq;
|
||||||
|
case DeviceCode_ExtUart2Cts .GetInternalValue(): return GpioPadName_ExtUart2Cts;
|
||||||
|
case DeviceCode_ExtUart3Cts .GetInternalValue(): return GpioPadName_ExtUart3Cts;
|
||||||
|
case DeviceCode_5VStepDownEn .GetInternalValue(): return GpioPadName_5VStepDownEn;
|
||||||
|
case DeviceCode_UsbSwitchB2Oc .GetInternalValue(): return GpioPadName_UsbSwitchB2Oc;
|
||||||
|
case DeviceCode_5VStepDownPg .GetInternalValue(): return GpioPadName_5VStepDownPg;
|
||||||
|
case DeviceCode_UsbSwitchAEn .GetInternalValue(): return GpioPadName_UsbSwitchAEn;
|
||||||
|
case DeviceCode_UsbSwitchAFlag .GetInternalValue(): return GpioPadName_UsbSwitchAFlag;
|
||||||
|
case DeviceCode_UsbSwitchB3Oc .GetInternalValue(): return GpioPadName_UsbSwitchB3Oc;
|
||||||
|
case DeviceCode_UsbSwitchB3En .GetInternalValue(): return GpioPadName_UsbSwitchB3En;
|
||||||
|
case DeviceCode_UsbSwitchB2En .GetInternalValue(): return GpioPadName_UsbSwitchB2En;
|
||||||
|
case DeviceCode_Hdmi5VEn .GetInternalValue(): return GpioPadName_Hdmi5VEn;
|
||||||
|
case DeviceCode_UsbSwitchB1En .GetInternalValue(): return GpioPadName_UsbSwitchB1En;
|
||||||
|
case DeviceCode_HdmiPdTrEn .GetInternalValue(): return GpioPadName_HdmiPdTrEn;
|
||||||
|
case DeviceCode_FanEn .GetInternalValue(): return GpioPadName_FanEn;
|
||||||
|
case DeviceCode_UsbSwitchB1Oc .GetInternalValue(): return GpioPadName_UsbSwitchB1Oc;
|
||||||
|
case DeviceCode_PwmFan .GetInternalValue(): return GpioPadName_PwmFan;
|
||||||
|
case DeviceCode_HdmiHpd .GetInternalValue(): return GpioPadName_HdmiHpd;
|
||||||
|
case DeviceCode_Max77812Irq .GetInternalValue(): return GpioPadName_Max77812Irq;
|
||||||
|
case DeviceCode_Debug0 .GetInternalValue(): return GpioPadName_Debug0;
|
||||||
|
case DeviceCode_Debug1 .GetInternalValue(): return GpioPadName_Debug1;
|
||||||
|
case DeviceCode_Debug2 .GetInternalValue(): return GpioPadName_Debug2;
|
||||||
|
case DeviceCode_Debug3 .GetInternalValue(): return GpioPadName_Debug3;
|
||||||
|
case DeviceCode_NfcIrq .GetInternalValue(): return GpioPadName_NfcIrq;
|
||||||
|
case DeviceCode_NfcRst .GetInternalValue(): return GpioPadName_NfcRst;
|
||||||
|
case DeviceCode_McuIrq .GetInternalValue(): return GpioPadName_McuIrq;
|
||||||
|
case DeviceCode_McuBoot .GetInternalValue(): return GpioPadName_McuBoot;
|
||||||
|
case DeviceCode_McuRst .GetInternalValue(): return GpioPadName_McuRst;
|
||||||
|
case DeviceCode_Vdd5V3En .GetInternalValue(): return GpioPadName_Vdd5V3En;
|
||||||
|
case DeviceCode_McuPor .GetInternalValue(): return GpioPadName_McuPor;
|
||||||
|
case DeviceCode_LcdGpio1 .GetInternalValue(): return GpioPadName_LcdGpio1;
|
||||||
|
case DeviceCode_NfcEn .GetInternalValue(): return GpioPadName_NfcEn;
|
||||||
|
AMS_UNREACHABLE_DEFAULT_CASE();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr inline DeviceCode ConvertToDeviceCode(GpioPadName gpn) {
|
||||||
|
switch (gpn) {
|
||||||
|
case GpioPadName_CodecLdoEnTemp: return DeviceCode_CodecLdoEnTemp;
|
||||||
|
case GpioPadName_PowSdEn: return DeviceCode_PowSdEn;
|
||||||
|
case GpioPadName_BtRst: return DeviceCode_BtRst;
|
||||||
|
case GpioPadName_RamCode3: return DeviceCode_RamCode3;
|
||||||
|
case GpioPadName_GameCardReset: return DeviceCode_GameCardReset;
|
||||||
|
case GpioPadName_CodecAlert: return DeviceCode_CodecAlert;
|
||||||
|
case GpioPadName_PowGc: return DeviceCode_PowGc;
|
||||||
|
case GpioPadName_DebugControllerDet: return DeviceCode_DebugControllerDet;
|
||||||
|
case GpioPadName_BattChgStatus: return DeviceCode_BattChgStatus;
|
||||||
|
case GpioPadName_BattChgEnableN: return DeviceCode_BattChgEnableN;
|
||||||
|
case GpioPadName_FanTach: return DeviceCode_FanTach;
|
||||||
|
case GpioPadName_ExtconDetS: return DeviceCode_ExtconDetS;
|
||||||
|
case GpioPadName_Vdd50AEn: return DeviceCode_Vdd50AEn;
|
||||||
|
case GpioPadName_SdevCoaxSel1: return DeviceCode_SdevCoaxSel1;
|
||||||
|
case GpioPadName_GameCardCd: return DeviceCode_GameCardCd;
|
||||||
|
case GpioPadName_ProdType0: return DeviceCode_ProdType0;
|
||||||
|
case GpioPadName_ProdType1: return DeviceCode_ProdType1;
|
||||||
|
case GpioPadName_ProdType2: return DeviceCode_ProdType2;
|
||||||
|
case GpioPadName_ProdType3: return DeviceCode_ProdType3;
|
||||||
|
case GpioPadName_TempAlert: return DeviceCode_TempAlert;
|
||||||
|
case GpioPadName_CodecHpDetIrq: return DeviceCode_CodecHpDetIrq;
|
||||||
|
case GpioPadName_MotionInt: return DeviceCode_MotionInt;
|
||||||
|
case GpioPadName_TpIrq: return DeviceCode_TpIrq;
|
||||||
|
case GpioPadName_ButtonSleep2: return DeviceCode_ButtonSleep2;
|
||||||
|
case GpioPadName_ButtonVolUp: return DeviceCode_ButtonVolUp;
|
||||||
|
case GpioPadName_ButtonVolDn: return DeviceCode_ButtonVolDn;
|
||||||
|
case GpioPadName_BattMgicIrq: return DeviceCode_BattMgicIrq;
|
||||||
|
case GpioPadName_RecoveryKey: return DeviceCode_RecoveryKey;
|
||||||
|
case GpioPadName_PowLcdBlEn: return DeviceCode_PowLcdBlEn;
|
||||||
|
case GpioPadName_LcdReset: return DeviceCode_LcdReset;
|
||||||
|
case GpioPadName_PdVconnEn: return DeviceCode_PdVconnEn;
|
||||||
|
case GpioPadName_PdRstN: return DeviceCode_PdRstN;
|
||||||
|
case GpioPadName_Bq24190Irq: return DeviceCode_Bq24190Irq;
|
||||||
|
case GpioPadName_SdevCoaxSel0: return DeviceCode_SdevCoaxSel0;
|
||||||
|
case GpioPadName_SdWp: return DeviceCode_SdWp;
|
||||||
|
case GpioPadName_TpReset: return DeviceCode_TpReset;
|
||||||
|
case GpioPadName_BtGpio2: return DeviceCode_BtGpio2;
|
||||||
|
case GpioPadName_BtGpio3: return DeviceCode_BtGpio3;
|
||||||
|
case GpioPadName_BtGpio4: return DeviceCode_BtGpio4;
|
||||||
|
case GpioPadName_CradleIrq: return DeviceCode_CradleIrq;
|
||||||
|
case GpioPadName_PowVcpuInt: return DeviceCode_PowVcpuInt;
|
||||||
|
case GpioPadName_Max77621GpuInt: return DeviceCode_Max77621GpuInt;
|
||||||
|
case GpioPadName_ExtconChgU: return DeviceCode_ExtconChgU;
|
||||||
|
case GpioPadName_ExtconChgS: return DeviceCode_ExtconChgS;
|
||||||
|
case GpioPadName_WifiRfDisable: return DeviceCode_WifiRfDisable;
|
||||||
|
case GpioPadName_WifiReset: return DeviceCode_WifiReset;
|
||||||
|
case GpioPadName_ApWakeBt: return DeviceCode_ApWakeBt;
|
||||||
|
case GpioPadName_BtWakeAp: return DeviceCode_BtWakeAp;
|
||||||
|
case GpioPadName_BtGpio5: return DeviceCode_BtGpio5;
|
||||||
|
case GpioPadName_PowLcdVddPEn: return DeviceCode_PowLcdVddPEn;
|
||||||
|
case GpioPadName_PowLcdVddNEn: return DeviceCode_PowLcdVddNEn;
|
||||||
|
case GpioPadName_ExtconDetU: return DeviceCode_ExtconDetU;
|
||||||
|
case GpioPadName_RamCode2: return DeviceCode_RamCode2;
|
||||||
|
case GpioPadName_Vdd50BEn: return DeviceCode_Vdd50BEn;
|
||||||
|
case GpioPadName_WifiWakeHost: return DeviceCode_WifiWakeHost;
|
||||||
|
case GpioPadName_SdCd: return DeviceCode_SdCd;
|
||||||
|
case GpioPadName_OtgFet1ForSdev: return DeviceCode_OtgFet1ForSdev;
|
||||||
|
case GpioPadName_OtgFet2ForSdev: return DeviceCode_OtgFet2ForSdev;
|
||||||
|
case GpioPadName_ExtConWakeU: return DeviceCode_ExtConWakeU;
|
||||||
|
case GpioPadName_ExtConWakeS: return DeviceCode_ExtConWakeS;
|
||||||
|
case GpioPadName_PmuIrq: return DeviceCode_PmuIrq;
|
||||||
|
case GpioPadName_ExtUart2Cts: return DeviceCode_ExtUart2Cts;
|
||||||
|
case GpioPadName_ExtUart3Cts: return DeviceCode_ExtUart3Cts;
|
||||||
|
case GpioPadName_5VStepDownEn: return DeviceCode_5VStepDownEn;
|
||||||
|
case GpioPadName_UsbSwitchB2Oc: return DeviceCode_UsbSwitchB2Oc;
|
||||||
|
case GpioPadName_5VStepDownPg: return DeviceCode_5VStepDownPg;
|
||||||
|
case GpioPadName_UsbSwitchAEn: return DeviceCode_UsbSwitchAEn;
|
||||||
|
case GpioPadName_UsbSwitchAFlag: return DeviceCode_UsbSwitchAFlag;
|
||||||
|
case GpioPadName_UsbSwitchB3Oc: return DeviceCode_UsbSwitchB3Oc;
|
||||||
|
case GpioPadName_UsbSwitchB3En: return DeviceCode_UsbSwitchB3En;
|
||||||
|
case GpioPadName_UsbSwitchB2En: return DeviceCode_UsbSwitchB2En;
|
||||||
|
case GpioPadName_Hdmi5VEn: return DeviceCode_Hdmi5VEn;
|
||||||
|
case GpioPadName_UsbSwitchB1En: return DeviceCode_UsbSwitchB1En;
|
||||||
|
case GpioPadName_HdmiPdTrEn: return DeviceCode_HdmiPdTrEn;
|
||||||
|
case GpioPadName_FanEn: return DeviceCode_FanEn;
|
||||||
|
case GpioPadName_UsbSwitchB1Oc: return DeviceCode_UsbSwitchB1Oc;
|
||||||
|
case GpioPadName_PwmFan: return DeviceCode_PwmFan;
|
||||||
|
case GpioPadName_HdmiHpd: return DeviceCode_HdmiHpd;
|
||||||
|
case GpioPadName_Max77812Irq: return DeviceCode_Max77812Irq;
|
||||||
|
case GpioPadName_Debug0: return DeviceCode_Debug0;
|
||||||
|
case GpioPadName_Debug1: return DeviceCode_Debug1;
|
||||||
|
case GpioPadName_Debug2: return DeviceCode_Debug2;
|
||||||
|
case GpioPadName_Debug3: return DeviceCode_Debug3;
|
||||||
|
case GpioPadName_NfcIrq: return DeviceCode_NfcIrq;
|
||||||
|
case GpioPadName_NfcRst: return DeviceCode_NfcRst;
|
||||||
|
case GpioPadName_McuIrq: return DeviceCode_McuIrq;
|
||||||
|
case GpioPadName_McuBoot: return DeviceCode_McuBoot;
|
||||||
|
case GpioPadName_McuRst: return DeviceCode_McuRst;
|
||||||
|
case GpioPadName_Vdd5V3En: return DeviceCode_Vdd5V3En;
|
||||||
|
case GpioPadName_McuPor: return DeviceCode_McuPor;
|
||||||
|
case GpioPadName_LcdGpio1: return DeviceCode_LcdGpio1;
|
||||||
|
case GpioPadName_NfcEn: return DeviceCode_NfcEn;
|
||||||
|
AMS_UNREACHABLE_DEFAULT_CASE();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user