mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-09-25 12:53:19 +02:00
sync to latest
This commit is contained in:
parent
2a17fe793b
commit
a575254741
13
.gitattributes
vendored
13
.gitattributes
vendored
@ -1 +1,14 @@
|
||||
config_templates/hbl_html/accessible-urls/accessible-urls.txt text eol=lf
|
||||
|
||||
# Mark C++ "include" files as C++
|
||||
*.inc linguist-language=C++
|
||||
|
||||
# Mark RapidJSON include as vendored
|
||||
libraries/include/stratosphere/rapidjson/** linguist-vendored
|
||||
|
||||
# Mark emummc as vendored
|
||||
emummc/** linguist-vendored
|
||||
|
||||
# Mark fatfs as vendored
|
||||
exosphere/mariko_fatal/source/fatfs/** linguist-vendored
|
||||
fusee/program/source/fatfs/** linguist-vendored
|
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -49,6 +49,8 @@ X.X.X</br>
|
||||
- [ Ex: Kosmos' distribution of Atmosphère ]
|
||||
- Do you have additional kips or sysmodules you're loading:
|
||||
- Homebrew software installed: [ * ]
|
||||
- EmuMMC or SysNAND:
|
||||
- [ If using an EmuMMC, include whether it's partition-based or file-based. ]
|
||||
|
||||
### Additional context?
|
||||
|
||||
|
15
.gitignore
vendored
15
.gitignore
vendored
@ -79,9 +79,8 @@ dkms.conf
|
||||
*.nam
|
||||
*.til
|
||||
|
||||
# KEYS file for sept-secondary.
|
||||
# Compiled python files.
|
||||
*.pyc
|
||||
sept/sept-secondary/KEYS.py
|
||||
|
||||
.**/
|
||||
|
||||
@ -91,3 +90,15 @@ sept/sept-secondary/KEYS.py
|
||||
|
||||
**/out
|
||||
**/build
|
||||
**/build_nintendo_nx_arm64
|
||||
**/build_nintendo_nx_arm64_armv8a
|
||||
**/build_nintendo_nx_arm
|
||||
**/build_nintendo_nx_arm_armv8a
|
||||
**/build_nintendo_nx_arm_armv7a
|
||||
**/build_nintendo_nx_arm_armv4t
|
||||
**/build_nintendo_nx_x64
|
||||
**/build_nintendo_nx_x86
|
||||
|
||||
package3
|
||||
|
||||
stratosphere/test/
|
||||
|
130
Makefile
130
Makefile
@ -1,3 +1,9 @@
|
||||
ifeq ($(strip $(DEVKITPRO)),)
|
||||
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>devkitPro)
|
||||
endif
|
||||
|
||||
include $(DEVKITPRO)/devkitA64/base_tools
|
||||
|
||||
TOPTARGETS := all clean dist-no-debug dist
|
||||
AMSBRANCH := $(shell git symbolic-ref --short HEAD)
|
||||
AMSHASH := $(shell git rev-parse --short HEAD)
|
||||
@ -7,9 +13,29 @@ ifneq (, $(strip $(shell git status --porcelain 2>/dev/null)))
|
||||
AMSREV := $(AMSREV)-dirty
|
||||
endif
|
||||
|
||||
COMPONENTS := fusee stratosphere mesosphere exosphere thermosphere troposphere libraries
|
||||
COMPONENTS := fusee stratosphere mesosphere exosphere emummc thermosphere troposphere libraries
|
||||
|
||||
all: $(COMPONENTS)
|
||||
$(eval MAJORVER = $(shell grep 'define ATMOSPHERE_RELEASE_VERSION_MAJOR\b' libraries/libvapours/include/vapours/ams/ams_api_version.h \
|
||||
| tr -s [:blank:] \
|
||||
| cut -d' ' -f3))
|
||||
$(eval MINORVER = $(shell grep 'define ATMOSPHERE_RELEASE_VERSION_MINOR\b' libraries/libvapours/include/vapours/ams/ams_api_version.h \
|
||||
| tr -s [:blank:] \
|
||||
| cut -d' ' -f3))
|
||||
$(eval MICROVER = $(shell grep 'define ATMOSPHERE_RELEASE_VERSION_MICRO\b' libraries/libvapours/include/vapours/ams/ams_api_version.h \
|
||||
| tr -s [:blank:] \
|
||||
| cut -d' ' -f3))
|
||||
$(eval S_MAJORVER = $(shell grep 'define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR\b' libraries/libvapours/include/vapours/ams/ams_api_version.h \
|
||||
| tr -s [:blank:] \
|
||||
| cut -d' ' -f3))
|
||||
$(eval S_MINORVER = $(shell grep 'define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR\b' libraries/libvapours/include/vapours/ams/ams_api_version.h \
|
||||
| tr -s [:blank:] \
|
||||
| cut -d' ' -f3))
|
||||
$(eval S_MICROVER = $(shell grep 'define ATMOSPHERE_SUPPORTED_HOS_VERSION_MICRO\b' libraries/libvapours/include/vapours/ams/ams_api_version.h \
|
||||
| tr -s [:blank:] \
|
||||
| cut -d' ' -f3))
|
||||
@python fusee/build_package3.py $(CURDIR) release $(AMSHASH) $(MAJORVER) $(MINORVER) $(MICROVER) 0 $(S_MAJORVER) $(S_MINORVER) $(S_MICROVER) 0
|
||||
@echo "Built package3!"
|
||||
|
||||
thermosphere:
|
||||
$(MAKE) -C thermosphere all
|
||||
@ -26,10 +52,10 @@ mesosphere: exosphere libraries
|
||||
troposphere: stratosphere
|
||||
$(MAKE) -C troposphere all
|
||||
|
||||
sept: exosphere
|
||||
$(MAKE) -C sept all
|
||||
emummc:
|
||||
$(MAKE) -C emummc all
|
||||
|
||||
fusee: exosphere mesosphere stratosphere sept
|
||||
fusee: exosphere mesosphere stratosphere
|
||||
$(MAKE) -C $@ all
|
||||
|
||||
libraries:
|
||||
@ -37,6 +63,12 @@ libraries:
|
||||
|
||||
clean:
|
||||
$(MAKE) -C fusee clean
|
||||
$(MAKE) -C emummc clean
|
||||
$(MAKE) -C libraries clean
|
||||
$(MAKE) -C exosphere clean
|
||||
$(MAKE) -C thermosphere clean
|
||||
$(MAKE) -C mesosphere clean
|
||||
$(MAKE) -C stratosphere clean
|
||||
rm -rf out
|
||||
|
||||
dist-no-debug: all
|
||||
@ -54,56 +86,57 @@ dist-no-debug: all
|
||||
rm -rf out
|
||||
mkdir atmosphere-$(AMSVER)
|
||||
mkdir atmosphere-$(AMSVER)/atmosphere
|
||||
mkdir atmosphere-$(AMSVER)/sept
|
||||
mkdir atmosphere-$(AMSVER)/switch
|
||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000008
|
||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/010000000000000D
|
||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/010000000000002B
|
||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000032
|
||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000034
|
||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000036
|
||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000037
|
||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/010000000000003C
|
||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000042
|
||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/fatal_errors
|
||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/config_templates
|
||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/config
|
||||
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-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/atmosphere/fusee-secondary.bin
|
||||
cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/sept/payload.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_00.enc atmosphere-$(AMSVER)/sept/sept-secondary_00.enc
|
||||
cp sept/sept-secondary/sept-secondary_01.enc atmosphere-$(AMSVER)/sept/sept-secondary_01.enc
|
||||
cp sept/sept-secondary/sept-secondary_dev_00.enc atmosphere-$(AMSVER)/sept/sept-secondary_dev_00.enc
|
||||
cp sept/sept-secondary/sept-secondary_dev_01.enc atmosphere-$(AMSVER)/sept/sept-secondary_dev_01.enc
|
||||
cp config_templates/BCT.ini atmosphere-$(AMSVER)/atmosphere/config/BCT.ini
|
||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/flags
|
||||
cp fusee/fusee.bin atmosphere-$(AMSVER)/atmosphere/reboot_payload.bin
|
||||
cp fusee/package3 atmosphere-$(AMSVER)/atmosphere/package3
|
||||
cp config_templates/stratosphere.ini atmosphere-$(AMSVER)/atmosphere/config_templates/stratosphere.ini
|
||||
cp config_templates/override_config.ini atmosphere-$(AMSVER)/atmosphere/config_templates/override_config.ini
|
||||
cp config_templates/system_settings.ini atmosphere-$(AMSVER)/atmosphere/config_templates/system_settings.ini
|
||||
cp config_templates/exosphere.ini atmosphere-$(AMSVER)/atmosphere/config_templates/exosphere.ini
|
||||
mkdir -p config_templates/kip_patches
|
||||
cp -r config_templates/kip_patches atmosphere-$(AMSVER)/atmosphere/kip_patches
|
||||
cp -r config_templates/hbl_html atmosphere-$(AMSVER)/atmosphere/hbl_html
|
||||
cp stratosphere/boot2/boot2.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000008/exefs.nsp
|
||||
cp stratosphere/dmnt/dmnt.nsp atmosphere-$(AMSVER)/atmosphere/contents/010000000000000D/exefs.nsp
|
||||
cp stratosphere/erpt/erpt.nsp atmosphere-$(AMSVER)/atmosphere/contents/010000000000002B/exefs.nsp
|
||||
cp stratosphere/eclct.stub/eclct.stub.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000032/exefs.nsp
|
||||
cp stratosphere/fatal/fatal.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000034/exefs.nsp
|
||||
cp stratosphere/creport/creport.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000036/exefs.nsp
|
||||
cp stratosphere/ro/ro.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000037/exefs.nsp
|
||||
cp stratosphere/jpegdec/jpegdec.nsp atmosphere-$(AMSVER)/atmosphere/contents/010000000000003C/exefs.nsp
|
||||
cp stratosphere/pgl/pgl.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000042/exefs.nsp
|
||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000032/flags
|
||||
touch atmosphere-$(AMSVER)/atmosphere/contents/0100000000000032/flags/boot2.flag
|
||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000037/flags
|
||||
touch atmosphere-$(AMSVER)/atmosphere/contents/0100000000000037/flags/boot2.flag
|
||||
mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000008
|
||||
mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/010000000000000D
|
||||
mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000017
|
||||
mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/010000000000002B
|
||||
mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000032
|
||||
mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000034
|
||||
mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000036
|
||||
mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000037
|
||||
mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/010000000000003C
|
||||
mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000042
|
||||
mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000420
|
||||
mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/010000000000B240
|
||||
mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/010000000000D609
|
||||
mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/010000000000D623
|
||||
cp stratosphere/boot2/boot2.nsp atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000008/exefs.nsp
|
||||
cp stratosphere/dmnt/dmnt.nsp atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/010000000000000D/exefs.nsp
|
||||
cp stratosphere/cs/cs.nsp atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000017/exefs.nsp
|
||||
cp stratosphere/erpt/erpt.nsp atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/010000000000002B/exefs.nsp
|
||||
cp stratosphere/eclct.stub/eclct.stub.nsp atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000032/exefs.nsp
|
||||
cp stratosphere/fatal/fatal.nsp atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000034/exefs.nsp
|
||||
cp stratosphere/creport/creport.nsp atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000036/exefs.nsp
|
||||
cp stratosphere/ro/ro.nsp atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000037/exefs.nsp
|
||||
cp stratosphere/jpegdec/jpegdec.nsp atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/010000000000003C/exefs.nsp
|
||||
cp stratosphere/pgl/pgl.nsp atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000042/exefs.nsp
|
||||
cp stratosphere/LogManager/LogManager.nsp atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000420/exefs.nsp
|
||||
cp stratosphere/htc/htc.nsp atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/010000000000B240/exefs.nsp
|
||||
cp stratosphere/dmnt.gen2/dmnt.gen2.nsp atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/010000000000D609/exefs.nsp
|
||||
cp stratosphere/TioServer/TioServer.nsp atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/010000000000D623/exefs.nsp
|
||||
@build_romfs atmosphere-$(AMSVER)/stratosphere_romfs atmosphere-$(AMSVER)/atmosphere/stratosphere.romfs
|
||||
rm -r atmosphere-$(AMSVER)/stratosphere_romfs
|
||||
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
|
||||
cd atmosphere-$(AMSVER); zip -r ../atmosphere-$(AMSVER).zip ./*; cd ../;
|
||||
rm -r atmosphere-$(AMSVER)
|
||||
rm -rf atmosphere-$(AMSVER)
|
||||
mkdir out
|
||||
mv atmosphere-$(AMSVER).zip out/atmosphere-$(AMSVER).zip
|
||||
cp fusee/fusee-primary/fusee-primary.bin out/fusee-primary.bin
|
||||
cp fusee/fusee.bin out/fusee.bin
|
||||
|
||||
dist: dist-no-debug
|
||||
$(eval MAJORVER = $(shell grep 'define ATMOSPHERE_RELEASE_VERSION_MAJOR\b' libraries/libvapours/include/vapours/ams/ams_api_version.h \
|
||||
@ -118,33 +151,32 @@ dist: dist-no-debug
|
||||
$(eval AMSVER = $(MAJORVER).$(MINORVER).$(MICROVER)-$(AMSREV))
|
||||
rm -rf atmosphere-$(AMSVER)-debug
|
||||
mkdir atmosphere-$(AMSVER)-debug
|
||||
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-secondary/fusee-secondary.elf atmosphere-$(AMSVER)-debug/fusee-secondary.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/key_derivation/key_derivation.elf atmosphere-$(AMSVER)-debug/sept-secondary-key-derivation.elf
|
||||
cp fusee/loader_stub/loader_stub.elf atmosphere-$(AMSVER)-debug/fusee-loader-stub.elf
|
||||
cp fusee/program/program.elf atmosphere-$(AMSVER)-debug/fusee-program.elf
|
||||
cp exosphere/loader_stub/loader_stub.elf atmosphere-$(AMSVER)-debug/exosphere-loader-stub.elf
|
||||
cp exosphere/program/program.elf atmosphere-$(AMSVER)-debug/exosphere-program.elf
|
||||
cp exosphere/warmboot/warmboot.elf atmosphere-$(AMSVER)-debug/exosphere-warmboot.elf
|
||||
cp exosphere/mariko_fatal/mariko_fatal.elf atmosphere-$(AMSVER)-debug/exosphere-mariko-fatal.elf
|
||||
cp exosphere/program/sc7fw/sc7fw.elf atmosphere-$(AMSVER)-debug/exosphere-sc7fw.elf
|
||||
cp exosphere/program/rebootstub/rebootstub.elf atmosphere-$(AMSVER)-debug/exosphere-rebootstub.elf
|
||||
cp mesosphere/kernel_ldr/kernel_ldr.elf atmosphere-$(AMSVER)-debug/kernel_ldr.elf
|
||||
cp mesosphere/kernel/kernel.elf atmosphere-$(AMSVER)-debug/kernel.elf
|
||||
cp stratosphere/ams_mitm/ams_mitm.elf atmosphere-$(AMSVER)-debug/ams_mitm.elf
|
||||
cp stratosphere/boot/boot.elf atmosphere-$(AMSVER)-debug/boot.elf
|
||||
cp stratosphere/boot2/boot2.elf atmosphere-$(AMSVER)-debug/boot2.elf
|
||||
cp stratosphere/creport/creport.elf atmosphere-$(AMSVER)-debug/creport.elf
|
||||
cp stratosphere/dmnt/dmnt.elf atmosphere-$(AMSVER)-debug/dmnt.elf
|
||||
cp stratosphere/eclct.stub/eclct.stub.elf atmosphere-$(AMSVER)-debug/eclct.stub.elf
|
||||
cp stratosphere/erpt/erpt.elf atmosphere-$(AMSVER)-debug/erpt.elf
|
||||
cp stratosphere/fatal/fatal.elf atmosphere-$(AMSVER)-debug/fatal.elf
|
||||
cp stratosphere/jpegdec/jpegdec.elf atmosphere-$(AMSVER)-debug/jpegdec.elf
|
||||
cp stratosphere/loader/loader.elf atmosphere-$(AMSVER)-debug/loader.elf
|
||||
cp stratosphere/ncm/ncm.elf atmosphere-$(AMSVER)-debug/ncm.elf
|
||||
cp stratosphere/pgl/pgl.elf atmosphere-$(AMSVER)-debug/pgl.elf
|
||||
cp stratosphere/pm/pm.elf atmosphere-$(AMSVER)-debug/pm.elf
|
||||
cp stratosphere/ro/ro.elf atmosphere-$(AMSVER)-debug/ro.elf
|
||||
cp stratosphere/sm/sm.elf atmosphere-$(AMSVER)-debug/sm.elf
|
||||
cp stratosphere/spl/spl.elf atmosphere-$(AMSVER)-debug/spl.elf
|
||||
cp stratosphere/erpt/erpt.elf atmosphere-$(AMSVER)-debug/erpt.elf
|
||||
cp stratosphere/jpegdec/jpegdec.elf atmosphere-$(AMSVER)-debug/jpegdec.elf
|
||||
cp stratosphere/pgl/pgl.elf atmosphere-$(AMSVER)-debug/pgl.elf
|
||||
cp troposphere/daybreak/daybreak.elf atmosphere-$(AMSVER)-debug/daybreak.elf
|
||||
cd atmosphere-$(AMSVER)-debug; zip -r ../atmosphere-$(AMSVER)-debug.zip ./*; cd ../;
|
||||
rm -r atmosphere-$(AMSVER)-debug
|
||||
|
@ -1,5 +1,3 @@
|
||||
This fork add ForceCloseCheatProcess to dmnt:cht service to enable reloading of cheatcode and detaching dmnt from game process without relaunching the game.
|
||||
|
||||
|
||||

|
||||
=====
|
||||
|
@ -35,6 +35,17 @@
|
||||
# mmc space, encrypted to prevent detection. This backup can be used
|
||||
# to prevent unrecoverable edits in emergencies.
|
||||
|
||||
# Key: log_port, default: 0.
|
||||
# Desc: Controls what uart port exosphere will set up for logging.
|
||||
# NOTE: 0 = UART-A, 1 = UART-B, 2 = UART-C, 3 = UART-D
|
||||
|
||||
# Key: log_baud_rate, default: 115200
|
||||
# Desc: Controls the baud rate exosphere will set up for logging.
|
||||
# NOTE: 0 is treated as equivalent to 115200.
|
||||
|
||||
# Key: log_inverted, default: 0.
|
||||
# Desc: Controls whether the logging uart port is inverted.
|
||||
|
||||
[exosphere]
|
||||
debugmode=1
|
||||
debugmode_user=0
|
||||
@ -43,3 +54,6 @@ enable_user_pmu_access=0
|
||||
blank_prodinfo_sysmmc=0
|
||||
blank_prodinfo_emummc=0
|
||||
allow_writing_to_cal_sysmmc=0
|
||||
log_port=0
|
||||
log_baud_rate=115200
|
||||
log_inverted=0
|
||||
|
@ -1,9 +1,10 @@
|
||||
[hbl_config]
|
||||
; Program Specific Config
|
||||
; Up to 8 program-specific configurations can be set.
|
||||
; These use `program_id_#` and `override_key_#`
|
||||
; These use `program_id_#`, `override_address_space_#`, and `override_key_#`
|
||||
; where # is in range [0,7].
|
||||
; program_id_0=010000000000100D
|
||||
; override_address_space=39_bit
|
||||
; override_key_0=!R
|
||||
|
||||
; Any Application Config
|
||||
@ -12,6 +13,7 @@
|
||||
; by a program specific config.
|
||||
; override_any_app=true
|
||||
; override_any_app_key=R
|
||||
; override_any_app_address_space=39_bit
|
||||
; path=atmosphere/hbl.nsp
|
||||
|
||||
[default_config]
|
||||
|
4
config_templates/stratosphere.ini
Normal file
4
config_templates/stratosphere.ini
Normal file
@ -0,0 +1,4 @@
|
||||
[stratosphere]
|
||||
; To force-enable nogc, add nogc = 1
|
||||
; To force-disable nogc, add nogc = 0
|
||||
|
@ -1,11 +1,25 @@
|
||||
; Disable uploading error reports to Nintendo
|
||||
[eupld]
|
||||
; Disable uploading error reports to Nintendo
|
||||
; upload_enabled = u8!0x0
|
||||
[usb]
|
||||
; Enable USB 3.0 superspeed for homebrew
|
||||
; 0 = USB 3.0 support is system default (usually disabled), 1 = USB 3.0 support is enabled.
|
||||
; usb30_force_enabled = u8!0x0
|
||||
[ro]
|
||||
; Control whether RO should ease its validation of NROs.
|
||||
; (note: this is normally not necessary, and ips patches can be used.)
|
||||
[ro]
|
||||
; ease_nro_restriction = u8!0x1
|
||||
[lm]
|
||||
; Control whether lm should log to the SD card.
|
||||
; Note that this setting does nothing when log manager is not enabled.
|
||||
; enable_sd_card_logging = u8!0x1
|
||||
; Control the output directory for SD card logs.
|
||||
; Note that this setting does nothing when log manager is not enabled/sd card logging is not enabled.
|
||||
; sd_card_log_output_directory = str!atmosphere/binlogs
|
||||
; Atmosphere custom settings
|
||||
[erpt]
|
||||
; Control whether erpt reports should always be preserved, instead of automatically cleaning periodically.
|
||||
; disable_automatic_report_cleanup = u8!0x0
|
||||
[atmosphere]
|
||||
; Reboot from fatal automatically after some number of milliseconds.
|
||||
; If field is not present or 0, fatal will wait indefinitely for user input.
|
||||
@ -32,12 +46,27 @@
|
||||
; NOTE: EXPERIMENTAL
|
||||
; If you do not know what you are doing, do not touch this yet.
|
||||
; fsmitm_redirect_saves_to_sd = u8!0x0
|
||||
; Controls whether to enable the deprecated hid mitm
|
||||
; to fix compatibility with old homebrew.
|
||||
; 0 = Do not enable, 1 = Enable.
|
||||
; Please note this setting may be removed in a
|
||||
; future release of Atmosphere.
|
||||
; enable_deprecated_hid_mitm = u8!0x0
|
||||
; Controls whether am sees system settings "DebugModeFlag" as
|
||||
; enabled or disabled.
|
||||
; 0 = Disabled (not debug mode), 1 = Enabled (debug mode)
|
||||
; enable_am_debug_mode = u8!0x0
|
||||
; Controls whether dns.mitm is enabled
|
||||
; 0 = Disabled, 1 = Enabled
|
||||
; enable_dns_mitm = u8!0x1
|
||||
; Controls whether dns.mitm uses the default redirections in addition to
|
||||
; whatever is specified in the user's hosts file.
|
||||
; 0 = Disabled (use hosts file contents), 1 = Enabled (use defaults and hosts file contents)
|
||||
; add_defaults_to_dns_hosts = u8!0x1
|
||||
; Controls whether dns.mitm logs to the sd card for debugging
|
||||
; 0 = Disabled, 1 = Enabled
|
||||
; enable_dns_mitm_debug_log = u8!0x0
|
||||
; Controls whether htc is enabled
|
||||
; 0 = Disabled, 1 = Enabled
|
||||
; enable_htc = u8!0x0
|
||||
; Controls whether atmosphere's log manager is enabled
|
||||
; Note that this setting is ignored (and treated as 1) when htc is enabled.
|
||||
; 0 = Disabled, 1 = Enabled
|
||||
; enable_log_manager = u8!0x0
|
||||
[hbloader]
|
||||
; Controls the size of the homebrew heap when running as applet.
|
||||
; If set to zero, all available applet memory is used as heap.
|
||||
|
@ -4,24 +4,23 @@ Building Atmosphère is a very straightforward process that relies almost exclus
|
||||
## Dependencies
|
||||
+ [devkitA64](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)
|
||||
+ [LZ4](https://pypi.org/project/lz4)
|
||||
+ [PyCryptodome](https://pypi.org/project/pycryptodome) (optional)
|
||||
+ [hactool](https://github.com/SciresM/hactool)
|
||||
|
||||
## Instructions
|
||||
1. Follow the guide located [here](https://devkitpro.org/wiki/Getting_Started) to install and configure all the tools necessary for the build process.
|
||||
1. Follow the guide located [here](https://devkitpro.org/wiki/Getting_Started) to install and configure all the tools necessary for the build process.
|
||||
|
||||
2. Install the following packages via (dkp-)pacman:
|
||||
+ `switch-dev`
|
||||
+ `switch-glm`
|
||||
+ `switch-libjpeg-turbo`
|
||||
+ `devkitARM`
|
||||
+ `devkitarm-rules`
|
||||
+ `hactool`
|
||||
|
||||
3. (Optional) In order to build [sept](components/sept.md) the pycryptodome PyPi package is required, which can be installed by running `pip install pycryptodome` under the installed Python environment of your choice or by installing the complete zip package to support the `make dist` recipe. This is an optional step included for advanced users who have the ability to provide the necessary encryption/signing keys themselves.
|
||||
3. Install the following library via python's package manager `pip`, required by [exosphere](components/exosphere.md):
|
||||
+ `lz4`
|
||||
|
||||
4. It is, instead, possible to build [sept](components/sept.md) by providing previously encrypted/signed binaries distributed by official Atmosphère release packages. In order to do so, export the following variables in your current environment:
|
||||
+ `SEPT_00_ENC_PATH` (must point to the `sept-secondary_00.enc` file)
|
||||
+ `SEPT_01_ENC_PATH` (must point to the `sept-secondary_01.enc` file)
|
||||
+ `SEPT_DEV_00_ENC_PATH` (must point to the `sept-secondary_dev_00.enc` file)
|
||||
+ `SEPT_DEV_01_ENC_PATH` (must point to the `sept-secondary_dev_01.enc` file)
|
||||
|
||||
5. Finally, clone the Atmosphère repository and run `make` under its root directory.
|
||||
4. Finally, clone the Atmosphère repository and run `make` under its root directory.
|
||||
|
@ -1,4 +1,459 @@
|
||||
# Changelog
|
||||
## 1.2.6
|
||||
+ Support was added for 13.2.1.
|
||||
+ A number of minor issues were fixed and improvements were made, including:
|
||||
+ A minor performance improvement was implemented in service table dispatch by sorting and binary-searching the service command table instead of using linear search.
|
||||
+ Static initialization logic in Atmosphere was made much more regular.
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
## 1.2.5
|
||||
+ Support was added for 13.2.0.
|
||||
+ A number of minor issues were fixed and improvements were made, including:
|
||||
+ A bug was fixed that caused `mesosphère` to underreport the total memory size by 8MB for certain games which use newer system-resource-size memory management.
|
||||
+ This caused FIFA 19 to crash, and possibly other issues.
|
||||
+ Memory management changes were made to `sm` that save 0x5000 of memory.
|
||||
+ A microoptimization was made to the way `mesosphère` manages updating the debug register for hardware single-step support.
|
||||
+ Support was fixed for enabling `usb!usb30_force_enabled` on 13.0.0+.
|
||||
+ The work-in-progress unit testing framework was updated to use doctest instead of catch2.
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
## 1.2.4
|
||||
+ Changes were made to the way fs.mitm builds images when providing a layeredfs romfs.
|
||||
+ Cache management (to avoid unnecessary rebuild) was revised, to add a grace period of ~500ms-1s between process closing romfs image and ams.mitm needing to rebuild if romfs is re-opened.
|
||||
+ This makes our cache much more effective, previously we were re-building romfs several times.
|
||||
+ RomFS image ownership was overhauled, with a new reference-counting implementation added (used to implement the above grace period).
|
||||
+ Certain games (e.g. Puyo Puyo Tetris 2, probably others) were sensitive to this timing, and could use access patterns which would trigger creation of romfs image while previous romfs image was in the middle of destructor.
|
||||
+ This could cause a fatal error, because the destructor for the old image could run simultaneously with building the new image.
|
||||
+ This also provides a speedup versus the 1.2.3 code, with Animal Crossing now taking ~8 fewer seconds to get past the Nintendo Switch logo.
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
## 1.2.3
|
||||
+ Because ams.TMA is taking longer to develop than expected, experimental support for Atmosphère's gdbstub as a standalone is now available.
|
||||
+ To enable it, set `atmosphere!enable_standalone_gdbstub` = u8!0x1 in system_settings.ini.
|
||||
+ The standalone also requires `atmosphere!enable_htc` = u8!0x0, but this should be the case for everyone since ams.TMA isn't actually usable yet.
|
||||
+ Once enabled, open the devkitPro provided-gdb (`aarch64-none-elf-gdb` for 64-bit or `arm-none-eabi-gdb` for 32-bit).
|
||||
+ The standalone stub exposes itself on port 22225 -- so the command to connect is `target extended-remote <ip address>:22225`.
|
||||
+ Type `info os processes` to get a list of process IDs that can be attached to.
|
||||
+ The stub should work on both system programs, games, and homebrew -- but please note that debugging certain processes (like sockets) can cause hang due to the stub using them itself.
|
||||
+ Software break-points, hardware break-points, hardware watch-points, and hardware single-step are all supported/implemented.
|
||||
+ The following monitor commands are currently supported:
|
||||
+ `monitor get info`: Get process info, address space layout, and information on modules.
|
||||
+ `monitor get mappings`: Get all memory mappings.
|
||||
+ `monitor get mapping <addr>`: Get the memory mapping for a specific address.
|
||||
+ `monitor wait application`: Causes the stub to wait for an application to be launched. The next application will be started suspended.
|
||||
+ User is expected to send `attach <pid>` after launching, which will cause attach-on-first-instruction. Failure to attach may cause system instability, this probably needs work.
|
||||
+ **Please Note**: The GDBstub is new and may have bugs/need work. If you find issues, please report them to SciresM#0524 -- all help finding/fixing bugs is appreciated, here.
|
||||
+ Generally speaking, if you would like to report information about fixes needed/discuss development of the gdbstub, join ReSwitched's #dev-support channel.
|
||||
+ Changes were made to the way fs.mitm builds images when providing a layeredfs romfs.
|
||||
+ Animal Crossing's 2.0.0 update contains >99000 files, and has tables so big that we ran out of memory even after the optimizations made in 0.10.5.
|
||||
+ Previously, we used fixed-sized 0x40000 work buffers for file/directory tables and simultaneously built hash/content tables in one loop over files/directories.
|
||||
+ We now iterate over the file/directory tables multiple times, first once to determine the hash table indices, then repeatedly to build hash tables, then once to build content tables.
|
||||
+ We also now allow smaller-than-0x40000 work buffers, trying half-as-big buffers until allocation succeeds (or work buffer would be <0x4000, which is a safeguard against truly horrible performance).
|
||||
+ There is a slight speed penalty to these changes, but it's on the order of seconds for the worst case (Animal Crossing) and trivial for most games with reasonable tables.
|
||||
+ If you encounter a game that exhausts ams.mitm's memory (crashing it) when loading layeredfs mods, please contact `SciresM#0524`.
|
||||
+ It's really hard to imagine any game being worse than Animal Crossing, but if it happens again I will drop everything to fix it as usual.
|
||||
+ `creport` now attempts to parse symbol tables if present.
|
||||
+ If a game executable has a symbol for a given address, the function-relative-offset will now be printed after the module-relative-offset.
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
## 1.2.2
|
||||
+ A number of fixes were made to Atmosphère's implementation of the new "sprofile" service added in 13.0.0.
|
||||
+ Nintendo is finally transmitting data over the internet to certain consoles, which has allowed for validating our service implementation.
|
||||
+ Unfortunately, there were several problems, and if your console began trying to use the new services atmosphere would show a fatal error with code 0xCAF6 (sprofile::ResultInvalidState()).
|
||||
+ With actual test data in hand, a test program was written and it was verified that our implementation can successfully import/access profile data now.
|
||||
+ Hopefully there are no more issues, and I sincerely apologize for anyone who got an 0xCAF6 fatal due to this.
|
||||
+ A number of minor improvements were made to `mesosphère`, including:
|
||||
+ KThread::GetContextForSchedulerLoop was implemented in assembly (using static assertions to verify offset-of-context-in-struct is correct).
|
||||
+ This saves an unnecessary function call in the middle of the scheduler hot loop, replacing it with an addition instruction, which should improve microperformance.
|
||||
+ Mesosphere's hardware maintenance instructions were audited via a script and now directly match Nintendo's kernels.
|
||||
+ Notably, this inserts a missing instruction synchronization barrier when validating that slab heaps may be constructed.
|
||||
+ This missing ISB could cause an abort on certain (see: particularly sensitive) hardware on boot if the relevant codepath was speculatively executed (it normally only executes on game launch...)
|
||||
+ The SVC handlers for performing light IPC (normally unused) from 32-bit process were fixed in Mesosphere.
|
||||
+ A bug was fixed that would cause the register x27 to be overwritten with the contents of x26 when returning from a user exception handler.
|
||||
+ A bug was fixed that would cause the kernel to use the userland stack pointer instead of the kernel stack pointer while generating an error report for a kernel abort.
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
## 1.2.1
|
||||
+ Support was implemented for 13.1.0.
|
||||
+ `mesosphère` was updated to reflect the kernel behavioral changes made in 13.1.0.
|
||||
+ KScheduler now issues a data memory barrier when unlocking the scheduler lock and when early-returning due to top-thread-is-current during scheduling.
|
||||
+ `erpt` was updated to reflect the latest official behaviors.
|
||||
+ The new service added in 13.0.0 ("sprofile") was revised, and the data formats it expects was changed.
|
||||
+ This still appears to be (possibly(?)) untestable due to data not being transmitted yet, but I have greater confidence things will go smoothly than I did when 1.1.0 released.
|
||||
+ A number of improvements were made to `mesosphère`, including:
|
||||
+ A build target was created to build targeting the qemu `virt` board.
|
||||
+ This facilitates writing unit tests for the kernel (and other atmosphere components) and running them under PC.
|
||||
+ **Please Note**: Official system software will not work at all under this, and the Atmosphère project has zero interest in attempting to run official software of any kind. This is unit testing machinery, and explicitly not more than that.
|
||||
+ This should hopefully allow us to have greater confidence that all of atmosphere's components work the way they're theoretically supposed to in the future.
|
||||
+ **Please Note**: If you are a developer who is familiar with the Horizon operating system (or capable of becoming familiar), I would greatly appreciate help writing tests and improving the testing framework.
|
||||
+ Please contact `SciresM#0524` if you are capable and interested.
|
||||
+ Really, if you are actually a developer who would like to help me get this off the ground, I would deeply appreciate it.
|
||||
+ That said, if you are not a developer but want to be one, this probably isn't the best opportunity; I expect it to be highly technical.
|
||||
+ Consider the ReSwitched discord's #hack-n-all channel for your educational purposes.
|
||||
+ We are (at least for now) using [catch2](https://github.com/catchorg/Catch2) for unit tests.
|
||||
+ Almost all virtual calls in the kernel are now resolved statically.
|
||||
+ This eliminates substantial virtual call overhead, and should lead to improved kernel microperformance in pretty much every function.
|
||||
+ The remaining red black tree find operations which weren't using the optimized "find key" variant are now using the optimized version.
|
||||
+ Custom assembly was written to improve tick-to-timespan conversion.
|
||||
+ This works around gcc emitting suboptimal assembly at -Os (it emits good assembly at -O3, clang is fine at both -O3 and -Os).
|
||||
+ KThread and KSession structures were updated to optimize member layout, saving 0x10 bytes per KThread/KSession object.
|
||||
+ Rather than unnecessarily zero-ing all data in kernel objects only to overwrite members later, we now only initialize the members we need to in kernel object constructors.
|
||||
+ This is what Nintendo was doing already.
|
||||
+ A set of custom optimized atomic primitives were implemented and are used in place of std::atomic<>
|
||||
+ This works around a gcc bug which downgrades specified memory order to seq_cst, and introduces clrex in places where it is appropriate.
|
||||
+ This should strictly improve microperformance of many system calls.
|
||||
+ An compile-time toggleable extension was added to support 40-bit physical addresses in MapRange capabilities (using currently reserved bits).
|
||||
+ A number of minor bugs were fixed, including:
|
||||
+ Initial cache management now better reflects official behavior.
|
||||
+ This fixes an issue that caused certain hardware with cache sensitivity to produce cryptic kernel panics during boot.
|
||||
+ Incorrect logic when checking thread priority capabilities was fixed to reflect official behavior.
|
||||
+ The scheduler was updated to reflect latest official behavior, and a number of minor bugs involving clz/ctz were fixed.
|
||||
+ Accesses to the processes local region were fixed to properly use kernel linear region, not userland pointers.
|
||||
+ The cache SVCs exposed for 32-bit processes now better reflect official core mask request semantics.
|
||||
+ A bug was fixed that could cause a kernel panic if SvcArbitrateLock was called on a thread with exactly one reference in the middle of handling a user-mode exception.
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
## 1.2.0
|
||||
+ `boot` was updated to reflect the latest official behavior for display/battery management.
|
||||
+ This should fix any issues that might result from running older releases on the OLED model, if you're somehow in a position to do so.
|
||||
+ The "target firmware" system was changed to allow the bootloader to specify an approximation, rather than the true target firmware.
|
||||
+ Previously we expected compliant bootloaders to inspect SYSTEM:/ to determine the specific target firmware.
|
||||
+ Now, we only require an approximate version, with major version == true major version and approximate version <= true version.
|
||||
+ This greatly simplifies bootloader requirements, and correspondingly all code for accessing SYSTEM has been removed from fusee.
|
||||
+ This should result in a substantial speedup when booting emummc with fusee, as SYSTEM accesses were the most expensive thing done previously.
|
||||
+ This should resolve any inconsistency in firmware detection when booting via fusee vs hekate.
|
||||
+ This should also improve our compatibility with micro firmware releases, making it more likely that atmosphere "just works" if nothing important has changed.
|
||||
+ Dynamic resource limit determination logic was implemented in `pm` to match latest official behavior.
|
||||
+ This greatly simplifies/makes consistent the resource limits on older firmwares, as well.
|
||||
+ An enormous amount of refactoring was performed under the hood, including:
|
||||
+ **Please Note**: If you are a developer who uses Atmosphere-libs, a number of changes here are breaking.
|
||||
+ Feel free to contact SciresM#0524 for help updating your program.
|
||||
+ The OS namespace had many primitives implemented/made more accurate.
|
||||
+ Since mesosphere is now always-on, os::LightEvent (which required newer SVCs) is now globally usable (and used by stratosphere where relevant).
|
||||
+ Assertions are now true no-ops when building for release.
|
||||
+ Stratosphere is now built with -Wextra/-Werror.
|
||||
+ Most "common" logic in system module main.cpp files was moved into libstratosphere.
|
||||
+ **Please Note**: main.cpp files for prior atmosphere-libs will no longer work, for a really large number of reasons.
|
||||
+ A number of longstanding code style issues were corrected.
|
||||
+ Mesosphere now uses util::BitFlagSet for SVC permissions.
|
||||
+ Mesosphere now puts its relocation table inside .bss, which allows that memory to be reclaimed after relocations are performed.
|
||||
+ These changes save ~16KB of memory in the kernel, all said and done.
|
||||
+ A number of locations in stratosphere where memory could be saved were spotted and taken advantage of, leading to ~150-200KB of saved memory.
|
||||
+ The `spl` and `loader` system module was refactored to better reflect official logic.
|
||||
+ `sf` ipc server code was updated to only emit mitm/defer logic when that logic is actually required somewhere in process.
|
||||
+ `tipc` ipc server code was updated to reflect changes to official logic made in 13.0.0.
|
||||
+ Many, many other minor changes, please talk to SciresM#0524 or read the relevant commits if you want to know more.
|
||||
+ A number of minor issues were fixed, including:
|
||||
+ Mesosphere's handling of SVC permissions on thread pin/unpin was updated to reflect official kernel behavior.
|
||||
+ util::CountTrailingZeroes() was fixed to calculate the correct value when used at compile-time.
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
## 1.1.1
|
||||
+ A bug was fixed which caused some memory to leak when launching a game with mods enabled, eventually causing a crash after enough game launches without rebooting.
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
## 1.1.0
|
||||
+ Support was implemented for 13.0.0.
|
||||
+ `mesosphère` was updated to reflect the latest official kernel behavior.
|
||||
+ `ncm` was updated to reflect the latest official behaviors.
|
||||
+ `erpt` was updated to reflect the latest official behaviors.
|
||||
+ Two new services ("sprofile") were added to `erpt`, and have been fully reimplemented.
|
||||
+ **Please Note**: These services provide a way for settings to be pushed to consoles over the internet without system update.
|
||||
+ Because there appear to be no settings pushed out yet, this implementation fundamentally cannot be fully tested right now, but hopefully there are no issues once settings begin being distributed.
|
||||
+ The `LogManager` system module was reimplemented.
|
||||
+ This system module provides services that some games use for logging.
|
||||
+ Atmosphere's reimplementation supports logging to the SD card (if `lm!enable_sd_card_logging` is true) and to ams.TMA.
|
||||
+ To control the directory where logs are saved, modify the `lm!sd_card_log_output_directory` setting.
|
||||
+ Atmosphere's reimplementation is disabled by default (in order to save memory), but can be enabled by setting `lm!enable_log_manager` to true.
|
||||
+ This will allow reading over logs from games which use the services (or potentially logging from homebrew in the future), which can be useful to developers.
|
||||
+ Please note that when TMA is fully implemented in the future, enabling TMA will forcibly enable `LogManager`.
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
## 1.0.0
|
||||
+ `fusee` was completely re-written in C++ to use the same atmosphere-libs APIs as the rest of atmosphere's code.
|
||||
+ The rewrite was performed with a big emphasis on ensuring a good boot speed, and generally boot should be much faster than it was previously.
|
||||
+ Depending on SD card/environment, boot speed may now be slightly faster than, roughly the same as, or slightly slower than when booting with hekate.
|
||||
+ The obvious low-hanging fruit for performance improvements has been picked, so hopefully the improved performance is to everybody's liking.
|
||||
+ SD card compatibility was improved: fusee should now have SD card compatibility identical to the official OS driver.
|
||||
+ **Please Note**: various components were renamed (fusee-primary.bin -> fusee.bin, fusee-secondary.bin -> package3).
|
||||
+ If you use another bootloader (like hekate), you may need to update your configuration to use the new layout.
|
||||
+ **Please Note**: BCT.ini no longer exists, nogc configuration has been moved to `/atmosphere/stratosphere.ini`.
|
||||
+ If you rely on custom nogc configuration, please be sure to update accordingly.
|
||||
+ Custom splash screen BMP parsing is no longer supported (as it slows down boot for 99% of users).
|
||||
+ To compensate for this, a script to insert a custom splash screen into a `package3` binary has been added to the `utilities` folder of the atmosphere repository.
|
||||
+ The release build should be equivalent to running the following command from the root of the atmosphere repository: `python utilities/insert_splash_screen.py img/splash.png fusee/package3`
|
||||
+ A number of pending changes were made, following the end of the relevant testing periods:
|
||||
+ `mesosphere` is no longer opt-out, and stratosphere code will begin depending on its being present/in use.
|
||||
+ `NCM` is no longer opt-out.
|
||||
+ The cleanup to ease the transition from < 0.19.0 to 0.19.0 has been removed.
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
## 0.20.1
|
||||
+ An issue was fixed that caused severely degraded performance after wake-from-sleep on Mariko hardware.
|
||||
+ This was due to Mariko MTC resulting in a frequency of 1599.999MHz instead of 1600MHz.
|
||||
+ Due to this off-by-one, Nintendo's EMC management code failed to initialize/take over, and after wake from sleep RAM would be in a strange state.
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
## 0.20.0
|
||||
+ DRAM training (MTC) was implemented for Mariko hardware, increasing RAM speed from 204MHz to 1600MHz.
|
||||
+ This significantly optimizes Mariko boot speed, cutting boot time roughly in half.
|
||||
+ Typical boot time reductions (measured as "select fusee" to "home menu visible"):
|
||||
+ Normal (Iowa): ~35 seconds -> ~18 seconds.
|
||||
+ Lite (Hoag): ~65 seconds -> ~30 seconds.
|
||||
+ NOTE: Work is being started on a re-written `fusee` component, with an eye specifically towards ensuring a good boot speed.
|
||||
+ With any luck, boot will be much much faster on all units (Mariko and Erista) in an upcoming release.
|
||||
+ Sept was replaced, and deleted from the repository.
|
||||
+ Erista units now use a custom TSEC firmware to manage key derivation.
|
||||
+ For more details, contact SciresM#0524 on discord.
|
||||
+ This has a number of benefits, including:
|
||||
+ This greatly simplifies key derivation logic by making it consistent on all firmwares.
|
||||
+ Fusee no longer accesses/uses keyblobs at all, so units which have accidentally destroyed/lost keyblobs can boot without them.
|
||||
+ This greatly increases stability (sept was the biggest source of boot failures).
|
||||
+ This improves boot speed (sept rebooted multiple times, performed hardware init multiple times, and was generally very slow).
|
||||
+ Atmosphère build process is now much saner.
|
||||
+ A number of improvements were made to the dmnt cheat engine.
|
||||
+ Cheats which take in a memory region operand may now use types "2" or "3" to perform accesses relative to the alias/aslr regions, respectively.
|
||||
+ Support was added for an "else" opcode in the cheat engine, to make writing certain conditional logic more natural.
|
||||
+ Support was added for a cheat orchestrator homebrew (like edizon) to detach from a cheat process/set the master cheat programmatically.
|
||||
+ Daybreak now provides a warning when attempting to install a firmware newer than the highest version atmosphère knows it supports.
|
||||
+ To facilitate this, exosphere now exposes the supported HOS version via an extension ConfigItem.
|
||||
+ A number of minor issues were fixed, including:
|
||||
+ Several mesosphere debug SVC implementations were updated to reflect the semantics of the latest kernel.
|
||||
+ Support was fixed for deriving BIS encryption keys on certain prototype hardware.
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
## 0.19.5
|
||||
+ Support was added for 12.1.0.
|
||||
+ LayeredFS support was added for OpenDataStorageWithProgramIndex commands.
|
||||
+ Certain games using newer (7.0.0+ APIs) which include multiple programs under a single title previously could not be modified.
|
||||
+ These are now supported as normal, and LayeredFS should have 100% compatibility again.
|
||||
+ A number of minor issues were fixed, including:
|
||||
+ The Reboot to Payload NRO was updated to allow the OS to save state prior to rebooting (thanks @AuroraWright)!
|
||||
+ An issue was fixed that could cause dns.mitm to fail when games requested resolution of an empty string.
|
||||
+ An issue was fixed that caused a memory leak in the erpt system module.
|
||||
+ This would eventually cause a system crash after ~540 reports were generated without rebooting.
|
||||
+ A number of minor improvements were made to improve mesosphere's accuracy.
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
## 0.19.4
|
||||
+ Support was added for 12.0.3.
|
||||
+ A number of minor issues were fixed, including:
|
||||
+ An issue was fixed that could cause heap memory corruption when allocation was highly contended.
|
||||
+ An issue was fixed that could cause sleep to fail under certain conditions.
|
||||
+ An issue was fixed that could cause a scheduler slow path to be taken more often than necessary.
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
## 0.19.3
|
||||
+ Support was added for 12.0.2.
|
||||
+ A number of minor issues were fixed, including:
|
||||
+ An issue was fixed in dns.mitm that caused a crash when games attempted to resolve the IP address of nullptr.
|
||||
+ An issue was fixed in erpt that would cause an abort when booting without having ever booted stock previously.
|
||||
+ An issue was fixed in (file-based) emummc that caused an error on system format/downloading certain games.
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
## 0.19.2
|
||||
+ Atmosphère's components were further updated to reflect latest official behaviors as of 12.0.0.
|
||||
+ Notably, `erpt` was updated to implement the new forced shutdown detection feature.
|
||||
+ When a forced-shutdown occurs, an erpt_report will be generated and saved to the SD card on the next boot.
|
||||
+ Atmosphere-libs was updated to use GCC 11 (latest devkitA64/devkitARM releases).
|
||||
+ Initial inspections show mild-to-moderate optimizer improvements in several important places (kernel is 0x3000 smaller).
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
+ A number of minor issues were fixed, including:
|
||||
+ A bug was fixed that caused a black screen when attempting to boot firmware versions 2.0.0-4.1.0.
|
||||
+ A bug was fixed that caused sm to abort when at the session limit, rather than returning error codes.
|
||||
+ A bug was fixed that allowed for resource exhaustion on 12.0.0, under certain circumstances.
|
||||
+ Several issues were fixed, and usability and stability were improved.
|
||||
## 0.19.1
|
||||
+ An issue was fixed that caused a fatal error when using official `migration` services to transfer data between consoles.
|
||||
+ An issue was fixed in `ncm` that caused an error when the OS tried to enumerate installed SD card content.
|
||||
+ Several issues were fixed, and usability and stability were improved.
|
||||
## 0.19.0
|
||||
+ Support was added for 12.0.0.
|
||||
+ `mesosphère` was updated to reflect the latest official kernel behavior.
|
||||
+ `sm`, `boot2`, `pgl` were updated to reflect the latest official behaviors.
|
||||
+ **Please Note**: 12.0.0 added a new protocol for IPC ("tipc"), which has been freshly reimplemented in its entirety.
|
||||
+ It is possible there may be as of yet unfound issues; if there are, please send the appropriate crash reports to SciresM (SciresM#0524 on discord).
|
||||
+ Homebrew which uses atmosphere extensions (including the mitm API) will need to be re-compiled in order to function on 0.19.0.
|
||||
+ I apologize for this, but it's unavoidable for technical reasons. If you're affected by this and mad about it, please contact SciresM to complain.
|
||||
+ `erpt` was partially updated to reflect the latest official behaviors.
|
||||
+ New features were added to erpt to track the activity of running applets, and to detect when a forced shutdown occurs.
|
||||
+ These behaviors have been temporarily stubbed, as they are not necessary for 12.0.0 to run (and their outputs won't be saved anywhere).
|
||||
+ A future atmosphère update will implement these behaviors, in the interest of reflecting official logic as faithfully as we can.
|
||||
+ Atmosphère no longer uses the /contents/ folder for its own programs.
|
||||
+ Atmosphère's system modules are now bundled together in the single file "stratosphere.romfs".
|
||||
+ For those working on developing for atmosphère, executables inside the /contents/ directory will be preferred to those in "stratosphere.romfs".
|
||||
+ **Please Note**: In order to facilitate this change (and the desired behavior), the first time you boot after extracting a release zip, atmosphère system modules inside /contents/ will be deleted.
|
||||
+ This will have no impact on user programs (it only removes programs with specific program ids).
|
||||
+ Improvements were made to mesosphere, including:
|
||||
+ An extension InfoType was added for getting the current process handle, without having to spawn a thread and do IPC with oneself.
|
||||
+ An issue was fixed in SvcSetDebugThreadContext.
|
||||
+ An issue was fixed when doing IPC with user buffers.
|
||||
+ Support was fixed for toggling the custom setting `usb!usb30_force_enabled` on 9.0.0+.
|
||||
+ This was broken by Nintendo's introducing a dependency that made USB a requirement to launch before custom settings are parsed.
|
||||
+ Since the fix, you can now toggle the setting (as you could prior to atmosphère 0.9.4), and it will work as expected.
|
||||
+ **Please Note**: Enabling USB 3.0 often severely impacts wireless communications.
|
||||
+ Because of this, the setting will default to off. If you experience issues with it enabled, consider disabling it.
|
||||
+ A warning was added to daybreak when resetting the console to factory settings.
|
||||
+ Substantial work was completed towards atmosphere's upcoming implementation of the host target connection protocol.
|
||||
+ Once completed, users will be able to interact with a Switch running atmosphère via a PC application ("Starlink") currently under development.
|
||||
+ Planned eventual features for connected consoles include a gdbstub, interacting with memory (for cheat development), streaming gameplay audio and video, and accessing the Switch's SD card filesystem.
|
||||
+ Switch homebrew will also have access to a (configurable and sandboxed) filesystem on the host PC, while connected.
|
||||
+ Towards this end, the following was accomplished:
|
||||
+ The "htc" system module was reimplemented completely.
|
||||
+ The system module which provides remote access to the SD card was reimplemented completely.
|
||||
+ This is currently the active focus of atmosphère's development.
|
||||
+ **Please Note**: Support is not yet completed, and users are disadvised from interacting with the related settings for the time being, unless they particularly know what they're doing.
|
||||
+ A number of minor issues were fixed, including:
|
||||
+ A bug was fixed in `dmnt` that could cause a fatal when launching certain games with cheats active.
|
||||
+ An issue was fixed that could cause an abort in `sm` when using a large number of custom system modules.
|
||||
+ An issue was fixed that prevented launching gamecards on 1.0.0.
|
||||
+ Minor issues were fixed in the cheat virtual machine's behavior.
|
||||
+ Several issues were fixed, and usability and stability were improved.
|
||||
## 0.18.1
|
||||
+ A number of minor issues were fixed, including:
|
||||
+ The new `dns.mitm` module added in 0.18.0 no longer fatal errors when receiving port=nullptr.
|
||||
+ This fixes youtube ad-blocking, and possibly other usecases.
|
||||
+ A bug was fixed that caused ams.mitm to incorrectly cache data storages.
|
||||
+ This potentially broke DLC when using romfs mods, and could have caused other issues (e.g. with custom themes, and maybe other cases).
|
||||
+ A bug was fixed in power state control module registration.
|
||||
+ This might fix a weird edge case with system module dependencies on sleep/wake, but probably nobody should notice any differences.
|
||||
+ A bug was fixed where mesosphere sometimes treated virtual core IDs as though they were physical core IDs.
|
||||
+ This had zero impact, because for Switch virtual core == physical core, but it could have affected future platforms if it had remained unresolved.
|
||||
+ Several issues were fixed, and usability and stability were improved.
|
||||
## 0.18.0
|
||||
+ A new mitm module was added (`dns.mitm`).
|
||||
+ This provides a highly configurable mechanism for redirecting DNS resolution requests.
|
||||
+ By default atmosphère redirects resolution requests for official telemetry servers to a loopback address.
|
||||
+ Documentation on how to configure `dns.mitm` to meet your more specific needs may be found [here](https://github.com/Atmosphere-NX/Atmosphere/blob/master/docs/features/dns_mitm.md).
|
||||
+ The service framework API (`sf`) was refactored to be more accurate to official logic and greatly reduce memory requirements.
|
||||
+ The comparison of atmosphère module memory usage versus Nintendo's found [here](https://github.com/Atmosphere-NX/Atmosphere/wiki/Memory-Comparisons) was updated to reflect this.
|
||||
+ **Please Note**: If you are a developer using the libstratosphere service APIs, some updating may be required. Contact SciresM#0524 on discord for assistance if required.
|
||||
+ A number of deprecations were removed, following a general codebase cleanup:
|
||||
+ The `sm` extension to not unregister services on connection close was superseded by official opt-in logic in 11.0.0, and has been removed in favor of official logic.
|
||||
+ This should have zero impact on users.
|
||||
+ The temporary `hid-mitm` added in 0.9.0 has finally been removed, following over a year of deprecation.
|
||||
+ There shouldn't be any homebrew in use still affected by this, but the situation will be monitored.
|
||||
+ If this is somehow still a real issue, an unaffiliated hid mitm sysmodule providing the same functionality can be created and released, separate from atmosphère itself.
|
||||
+ Several issues were fixed, and usability and stability were improved.
|
||||
## 0.17.1
|
||||
+ A number of atmosphère's modules were using more memory than their Nintendo equivalent's in 0.17.0; a number of code generatio tweaks have been applied to fix this across the board.
|
||||
+ A detailed comparison of atmosphère module memory usage versus Nintendo's was made and can be found [here](https://github.com/Atmosphere-NX/Atmosphere/wiki/Memory-Comparisons).
|
||||
+ Several minor bugs were fixed, including:
|
||||
+ A bug was fixed in mesosphère that caused games which attempt to map more memory than the Switch has to fail.
|
||||
+ This affected "Piczle Lines DX 500 More Puzzles!", and possibly other games.
|
||||
+ Enabling configuration to "blank" PRODINFO no longer causes a hang on Mariko devices (or any devices with newer format).
|
||||
+ Several issues were fixed, and usability and stability were improved.
|
||||
## 0.17.0
|
||||
+ fusee was heavily rewritten in order to add support for Mariko hardware.
|
||||
+ **Please Note**: Mariko hardware currently has no (and may not ever have any) software exploits; fusee works when loaded from bootloader context with the right keys in the security engine. No means of getting the system into this state is provided.
|
||||
+ An issue was fixed in the way shutdown was performed on Erista hardware.
|
||||
+ This fixes an issue that caused OFW to black screen on boot after power off from atmosphere without first doing a reboot.
|
||||
+ This also substantially improves power drain when the system is shut off; consoles powered off from Atmosphere should now drain battery at the same reduced rate as original firmware.
|
||||
+ A number of minor changes were made, including:
|
||||
+ A number of inconsistencies in the build system were fixed.
|
||||
+ For those building atmosphère at home, the `boot` sysmodule will no longer rebuild every time make is invoked.
|
||||
+ This substantially improves build times during development iteration.
|
||||
+ `sm` was updated to more accurately reflect how official code manages request deferral.
|
||||
+ `mesosphère` was updated to more accurately reflect official kernel management of the trace buffer.
|
||||
+ `mesosphère` was updated to improve kernel loader's logic by taking advantage of the assumption that we only boot our kernel, not Nintendo's.
|
||||
+ As it has been a few months with zero reported issues, `mesosphère` is now opt-out.
|
||||
+ Users who wish to begin using or continue using mesosphere should use the standard/cool kids zip ("atmosphere-").
|
||||
+ Users who wish to opt-out of mesosphere should download and extract the opt-out zip ("atmosphere-WITHOUT_MESOSPHERE-").
|
||||
+ Several issues were fixed, and usability and stability were improved.
|
||||
## 0.16.2
|
||||
+ Atmosphère release zips no longer bundle BCT.ini, instead relying on defaults in code.
|
||||
+ This means atmosphere updates should no longer overwrite any user configuration at all.
|
||||
+ If you wish to modify BCT.ini config, copy the template from /config_templates/ as with other configuration.
|
||||
+ `pgl` and `creport` were further updated to reflect differences in official behavior in 11.0.0.
|
||||
+ An issue was fixed that caused creport to be launched multiple times on process crash.
|
||||
+ This fixes the "duplicate reports" issue that sometimes plagued people.
|
||||
+ A new system setting (`atmosphere!enable_am_debug_mode`) configuring am to use debug mode.
|
||||
+ If you are not a developer or don't see a clear use for this, leave it configured to the default (off).
|
||||
+ Reboot to payload NRO was updated to fix support with certain payloads.
|
||||
+ Support was fixed for atmosphere's extension to support homebrew use of new (8.0.0+) kernel mappings.
|
||||
+ In particular, when running tracing debug builds of `mesosphère`, hbloader now has access to the kernel trace buffer.
|
||||
+ Several issues were fixed, and usability and stability were improved.
|
||||
## 0.16.1
|
||||
+ Support was added for 11.0.1.
|
||||
+ `mesosphère` was updated to reflect the latest official kernel behavior.
|
||||
+ A new svc::InfoType added in 11.0.0 was implemented (it wasn't discovered before 0.16.0 released).
|
||||
+ The new Control Flow Integrity (CFI) logic added in 11.0.0 kernel was implemented.
|
||||
+ `fs` logic was refactored and cleaned up to reflect some newer sysmodule behavioral and structural changes.
|
||||
+ `exosphère` was updated to allow dynamic control of what uart port is used for logging.
|
||||
+ This can be controlled by editing the `log_port`, `log_baud_rate`, and `log_inverted` fields in `exosphere.ini`.
|
||||
+ `mesosphère` was updated to improve debugging capabilities.
|
||||
+ This is still a work in progress, but developers may be interested.
|
||||
+ A bug was fixed that caused `fatal` to fatal error if the fatal process was already being debugged.
|
||||
+ Several issues were fixed, and usability and stability were improved.
|
||||
## 0.16.0
|
||||
+ Support was added for 11.0.0.
|
||||
+ `exosphère` was updated to reflect the latest official secure monitor behavior.
|
||||
+ `mesosphère` was updated to reflect the latest official kernel behavior.
|
||||
+ `loader`, `sm`, `boot`, `pgl` were updated to reflect the latest official behaviors.
|
||||
+ **Please Note**: 11.0.0 implements an opt-in version of the atmosphère `sm` extension that allows for closing session without unregistering services.
|
||||
+ Correspondingly, the extension will be deprecated in favor of the new official opt-in command. In 0.17.0, it will be removed entirely.
|
||||
+ If your custom system module relies on this extension (however unlikely that seems to me), please update it accordingly.
|
||||
+ `erpt` was partially updated to provide compatibility with 11.0.0.
|
||||
+ The latest firmware attaches additional fields and context information to logs.
|
||||
+ A future atmosphère update will implement this logic, so that users who are interested can also get the new information when examining their logs.
|
||||
+ **Please Note**: 11.0.0 introduced breaking changes to the `usb` system module's `usb:ds` API.
|
||||
+ Homebrew which uses the `usb:ds` service should rebuild with the latest libnx version to support running on 11.0.0.
|
||||
+ The `boot` system module was rewritten to reflect the huge driver changes introduced in 8.0.0.
|
||||
+ This includes a number of improvements to both logo display and battery management logic.
|
||||
+ Support was added for configuring the address space width for `hbl`.
|
||||
+ The `hbl_config!override_address_space_(#)` and `hbl_config!override_any_app_address_space` can now be set to `39_bit`, `36_bit`, or `32_bit` to control the address space for hbl on a per-override basis.
|
||||
+ If a configuration has not been set, hbl will now default to 39-bit address space.
|
||||
+ Previously, a legacy 36-bit address space was always used to maintain compatibility with 1.0.0.
|
||||
+ A new loader extension was added to support 39-bit whenever possible (including mesosphere-on-1.0.0), with fallback to 36-bit when unavailable.
|
||||
+ Support was added to a number of components for running on Mariko hardware.
|
||||
+ The `boot` system module can now safely be run on mariko hardware, performing correct hardware initialization.
|
||||
+ Daybreak (and generally, system update logic) were updated to be usable on Mariko.
|
||||
+ Boot0 protection/management logic was updated to perform correct actions on Mariko.
|
||||
+ Reboot to payload does not and cannot work on Mariko. Correspondingly, A "fatal error" handler was written, to display and save fatal errors from within TrustZone.
|
||||
+ **Please Note:** Atmosphere is still not properly usable on Mariko hardware.
|
||||
+ In particular, wake-from-sleep will not properly function (the magic numbers aren't set correctly), among a few other minor issues.
|
||||
+ `exosphère` received support for building under debug configuration.
|
||||
+ A small (otherwise unused) portion of IRAM is now reserved for debug-only exosphere code (this region is unused/untouched under release config).
|
||||
+ This enables logging (including printf) to uart from the secure monitor, for those interested.
|
||||
+ A number of bugs were fixed, including:
|
||||
+ Minor issues in a number of filesystem related code were fixed.
|
||||
+ An issue was fixed that could cause NCM to abort on consoles which came with 3.0.x and were never updated.
|
||||
+ Several issues were fixed, and usability and stability were improved.
|
||||
## 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
|
||||
+ Support was added for 10.2.0.
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
## 0.14.2
|
||||
+ A bug was fixed that could cause a deadlock when installing mitm services.
|
||||
+ Fixing this required a breaking change to the client behavior when installing a mitm service, and so custom sysmodules which use mitm will need to be re-compiled to function properly.
|
||||
+ A bug was fixed that caused atmosphere sysmodules to respond incorrectly when receiving invalid messages.
|
||||
+ A bug was fixed that caused fatal auto-reboot timing to work improperly.
|
||||
+ Support was added to fusee for loading binaries for `mesosphere`, atmosphère's reimplementation of the Nintendo Switch kernel.
|
||||
+ 0.14.2 does not include mesosphere, but those who are especially interested can build and test mesosphere themselves.
|
||||
+ In the future, to enable a sufficient testing period Atmosphère releases will distribute two zips for some time.
|
||||
+ One zip will use mesosphere, and the other will not.
|
||||
+ This will allow users who are interested to opt-in to mesosphere usage before it has been tested to be stable.
|
||||
+ When mesosphere is stable and well-tested, it will be enabled by default and Atmosphère's version will transition to 1.0.0.
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
## 0.14.1
|
||||
+ An issue was fixed in 0.14.0 that would cause a black screen on boot when the INI1's size was not aligned to 8 bytes.
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
|
103
docs/components/detail/exosphere_memory_layout.txt
Normal file
103
docs/components/detail/exosphere_memory_layout.txt
Normal file
@ -0,0 +1,103 @@
|
||||
exosphere, storage requirements:
|
||||
|
||||
Nonvolatile memory:
|
||||
0xE000
|
||||
|
||||
Volatile memory: 0x2000
|
||||
|
||||
Physical Address Space:
|
||||
-0x7C010000-0x7C012000 - boot code/volatile memory
|
||||
-0x7C012000-0x7C01E000 - program region
|
||||
-0x7C01E000-0x7C01F000 - global data/context
|
||||
-0x7C01F000-0x7C020000 - L2/L3 page table
|
||||
|
||||
-0x7C020000-0x7C040000 - Mariko-only program region
|
||||
-0x7C040000-0x7C048000 - Mariko-only program stack
|
||||
-0x7C048000-0x7C050000 - Reserved Mariko TZRAM (SE context carveouts, etc)
|
||||
|
||||
Virtual Address Space:
|
||||
|
||||
L1: 0x40 bytes.
|
||||
|
||||
L1 Entries:
|
||||
-0 (0x000000000-0x040000000): Empty
|
||||
-1 (0x040000000-0x080000000): Identity Mapping/Empty
|
||||
-2 (0x080000000-0x0C0000000): DRAM Mapping/Empty
|
||||
-3 (0x0C0000000-0x100000000): DRAM Mapping/Empty
|
||||
-4 (0x100000000-0x140000000): Empty
|
||||
-5 (0x140000000-0x180000000): Empty
|
||||
-6 (0x180000000-0x1C0000000): Empty
|
||||
-7 (0x1C0000000-0x200000000): Virtual Region
|
||||
|
||||
L2 Page and L3 page are both0x7C01F000
|
||||
|
||||
L2 Entries:
|
||||
-0x040000000 (Identity IRAM Table)
|
||||
- Entry Used: 0x000
|
||||
-0x07C000000 (Identity TZRAM Table)
|
||||
- Entry Used: 0x1E0
|
||||
-0x1F0000000 (Virtual Region Table)
|
||||
- Entry Used: 0x180
|
||||
|
||||
L3 Entries:
|
||||
- Identity TZRAM mapping (0x7C010000-0x7C020000)
|
||||
- Entry Used: 0x010-0x01F
|
||||
- Identity IRAM mapping (0x40020000-0x40040000)
|
||||
- Entry Used: 0x020-0x03F
|
||||
- Virtual Device region (0x1F0040000-0x1F0080000)
|
||||
- Entry Used: 0x040-0x07F
|
||||
- Read Only TZRAM Alias (0x1F00A0000-0x1F00B0000)
|
||||
- Entry Used: 0x0A0-0x0AF
|
||||
- Program region (0x1F00C0000-0x1F00CC000)
|
||||
- Entry Used: 0x0C0-0x0CB
|
||||
- Mariko Program region (0x1F00D0000-0x1F00F0000)
|
||||
- Entry Used: 0x0D0-0x0EF
|
||||
- Mariko Program stack (0x1F00F4000-0x1F00FC000)
|
||||
- Entry Used: 0x0F4-0x0FB
|
||||
- Secure DRAM Storage (0x1F0100000-0x1F0110000)
|
||||
- Entry Used: 0x100-0x10F
|
||||
- Debug DRAM Storage (0x1F0110000-0x1F0114000)
|
||||
- Entry Used: 0x110-0x113
|
||||
- SC7 IRAM Work Space (0x1F0120000-0x1F0130000)
|
||||
- Entry Used: 0x120-0x12F
|
||||
- SC7 IRAM Firmware (0x1F0140000-0x1F0141000)
|
||||
- Entry Used: 0x140-0x140
|
||||
- Debug Code (0x1F0150000-0x1F0154000)
|
||||
- Entry Used: 0x150-0x153
|
||||
- Reserved For Debug (0x1F0160000-0x1F0170000)
|
||||
- Entry Used: 0x160-0x16F
|
||||
- Boot Code (0x1F01C0000-0x1F01C2000)
|
||||
- Entry Used: 0x1C0-0x1C1
|
||||
- AMS IRAM Page (0x1F01F2000-0x1F01F2000)
|
||||
- Entry Used: 0x1F2-0x1F2
|
||||
- AMS User Page (0x1F01F4000-0x1F01F4000)
|
||||
- Entry Used: 0x1F4-0x1F4
|
||||
- SMC User Page (0x1F01F6000-0x1F01F6000)
|
||||
- Entry Used: 0x1F6-0x1F6
|
||||
- Volatile (Data) (0x1F01F8000-0x1F01F9000)
|
||||
- Entry Used: 0x1F8-0x1F8
|
||||
- Volatile (Stacks) (0x1F01FA000-0x1F01FB000)
|
||||
- Entry Used: 0x1FA-0x1FA
|
||||
- Global Data (0x1F01FC000-0x1F01FD000)
|
||||
|
||||
|
||||
NV Global Data needs:
|
||||
Exosphere + Emummc Config (<=0x200)
|
||||
Boot Config[0x400]
|
||||
RSA Context(0x100)
|
||||
Old Device Keys[0x20][0x10];
|
||||
Old Master Keys[0x20][0x10];
|
||||
Imported Rsa Keys[4][0x200];
|
||||
CPU Ctx[4][0x100];
|
||||
|
||||
Total: 0x1700
|
||||
|
||||
Global Data Page (accessible via X18):
|
||||
0x000-0x200: Exosphere Config
|
||||
0x200-0x400: Emummc Config
|
||||
0x400-0x800: Sealed AES Keys
|
||||
0x800-0xC00: Boot Config
|
||||
0xC00-0xFFF: CPU contexts. Can be replaced, but this fits exactly so minimizes program space waste.
|
||||
|
||||
Volatile Global Data needs:
|
||||
Random Cache 0x400 bytes
|
@ -1,22 +1,8 @@
|
||||
# fusée
|
||||
fusée is a custom bootloader used to start the Atmosphère environment.
|
||||
It is divided into three sub-components: fusée-primary, fusée-mtc and fusée-secondary.
|
||||
|
||||
fusée is also capable of chainloading other payloads (e.g.: Android).
|
||||
|
||||
fusée's behavior can be configured via the [BCT.ini](../features/configurations.md) file located on the SD card.
|
||||
|
||||
## fusée-primary
|
||||
fusée-primary is the first piece of Atmosphère's code that runs on the hardware.
|
||||
## fusée
|
||||
fusée is the first piece of Atmosphère's code that runs on the hardware.
|
||||
It is distributed as a standalone payload designed to be launched via RCM by abusing the CVE-2018-6242 vulnerability.
|
||||
|
||||
This payload is responsible for all the low-level hardware initialization required by the Nintendo Switch, plus the extra task of initializing the SD card and reading the next fusée sub-components from it.
|
||||
|
||||
## fusée-mtc
|
||||
fusée-mtc is an optional, but heavily recommended sub-component that performs DRAM memory training.
|
||||
This ensures a proper environment for running the final fusée sub-component.
|
||||
|
||||
## fusée-secondary
|
||||
fusée-secondary is the last fusée sub-component that runs on the system.
|
||||
It is responsible for configuring and bootstrapping the Atmosphère environment by mimicking the Horizon OS's design.
|
||||
This includes setting up the cryptosystem, mounting or emulating the eMMC, injecting or patching system modules and launching the exosphère component.
|
||||
This payload is responsible for all the low-level hardware initialization required by the Nintendo Switch, setting up the cryptosystem, mounting/emulating the eMMC, injecting/patching system modules, and launching the exosphère component.
|
||||
|
@ -33,3 +33,8 @@ in settings as `#.#.#|AMS #.#.#|?` with `? = S` when running under system eMMC o
|
||||
### System Settings
|
||||
set_mitm intercepts the `GetSettingsItemValueSize` and `GetSettingsItemValue` commands for all requesters.
|
||||
It does so in order to enable user configuration of system settings, which are parsed from `/atmosphere/system_settings.ini` on boot. See [here](../../features/configurations.md) for more information on the system settings format.
|
||||
|
||||
## dns_mitm
|
||||
dns_mitm enables intercepting requests to dns resolution services, to enable redirecting requests for specified hostnames.
|
||||
|
||||
For documentation, see [here](../../features/dns_mitm.md).
|
||||
|
@ -19,6 +19,8 @@ This behavior ensures that cheat codes are only loaded when the user would want
|
||||
|
||||
In cases where `dmnt` has not activated the cheat manager, but the user wants to make it do so anyway, the cheat manager's service API provides a `ForceOpenCheatProcess` command that homebrew can use. This command will cause the cheat manager to try to force itself to attach to the process.
|
||||
|
||||
In cases where `dmnt` has activated the cheat manager, but the user wants to use an alternate debugger, the cheat manager's service API provides a `ForceCloseCheatProcess` command that homebrew can use. This command will cause the cheat manager to detach itself from the process.
|
||||
|
||||
By default, all cheat codes listed in the loaded .txt file will be toggled on. This is configurable by the user by editing the `atmosphere!dmnt_cheats_enabled_by_default` [system setting](configurations.md).
|
||||
|
||||
Users may use homebrew programs to toggle cheats on and off at runtime via the cheat manager's service API.
|
||||
@ -40,30 +42,30 @@ The following provides documentation of the instruction format for the virtual m
|
||||
|
||||
Typically, instruction type is encoded in the upper nybble of the first instruction u32.
|
||||
|
||||
### Code Type 0: Store Static Value to Memory
|
||||
Code type 0 allows writing a static value to a memory address.
|
||||
### Code Type 0x0: Store Static Value to Memory
|
||||
Code type 0x0 allows writing a static value to a memory address.
|
||||
|
||||
#### Encoding
|
||||
`0TMR00AA AAAAAAAA VVVVVVVV (VVVVVVVV)`
|
||||
|
||||
+ T: Width of memory write (1, 2, 4, or 8 bytes).
|
||||
+ M: Memory region to write to (0 = Main NSO, 1 = Heap).
|
||||
+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr).
|
||||
+ R: Register to use as an offset from memory region base.
|
||||
+ A: Immediate offset to use from memory region base.
|
||||
+ V: Value to write.
|
||||
|
||||
---
|
||||
|
||||
### Code Type 1: Begin Conditional Block
|
||||
Code type 1 performs a comparison of the contents of memory to a static value.
|
||||
### Code Type 0x1: Begin Conditional Block
|
||||
Code type 0x1 performs a comparison of the contents of memory to a static value.
|
||||
|
||||
If the condition is not met, all instructions until the appropriate conditional block terminator are skipped.
|
||||
If the condition is not met, all instructions until the appropriate End or Else conditional block terminator are skipped.
|
||||
|
||||
#### Encoding
|
||||
`1TMC00AA AAAAAAAA VVVVVVVV (VVVVVVVV)`
|
||||
|
||||
+ T: Width of memory write (1, 2, 4, or 8 bytes).
|
||||
+ M: Memory region to write to (0 = Main NSO, 1 = Heap).
|
||||
+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr).
|
||||
+ C: Condition to use, see below.
|
||||
+ A: Immediate offset to use from memory region base.
|
||||
+ V: Value to compare to.
|
||||
@ -78,16 +80,20 @@ If the condition is not met, all instructions until the appropriate conditional
|
||||
|
||||
---
|
||||
|
||||
### Code Type 2: End Conditional Block
|
||||
Code type 2 marks the end of a conditional block (started by Code Type 1 or Code Type 8).
|
||||
### Code Type 0x2: End Conditional Block
|
||||
Code type 0x2 marks the end of a conditional block (started by Code Type 0x1 or Code Type 0x8).
|
||||
|
||||
When an Else is executed, all instructions until the appropriate End conditional block terminator are skipped.
|
||||
|
||||
#### Encoding
|
||||
`20000000`
|
||||
`2X000000`
|
||||
|
||||
+ X: End type (0 = End, 1 = Else).
|
||||
|
||||
---
|
||||
|
||||
### Code Type 3: Start/End Loop
|
||||
Code type 3 allows for iterating in a loop a fixed number of times.
|
||||
### Code Type 0x3: Start/End Loop
|
||||
Code type 0x3 allows for iterating in a loop a fixed number of times.
|
||||
|
||||
#### Start Loop Encoding
|
||||
`300R0000 VVVVVVVV`
|
||||
@ -102,8 +108,8 @@ Code type 3 allows for iterating in a loop a fixed number of times.
|
||||
|
||||
---
|
||||
|
||||
### Code Type 4: Load Register with Static Value
|
||||
Code type 4 allows setting a register to a constant value.
|
||||
### Code Type 0x4: Load Register with Static Value
|
||||
Code type 0x4 allows setting a register to a constant value.
|
||||
|
||||
#### Encoding
|
||||
`400R0000 VVVVVVVV VVVVVVVV`
|
||||
@ -113,29 +119,28 @@ Code type 4 allows setting a register to a constant value.
|
||||
|
||||
---
|
||||
|
||||
### Code Type 5: Load Register with Memory Value
|
||||
Code type 5 allows loading a value from memory into a register, either using a fixed address or by dereferencing the destination register.
|
||||
### Code Type 0x5: Load Register with Memory Value
|
||||
Code type 0x5 allows loading a value from memory into a register, either using a fixed address or by dereferencing the destination register.
|
||||
|
||||
#### Load From Fixed Address Encoding
|
||||
`5TMR00AA AAAAAAAA`
|
||||
|
||||
+ T: Width of memory read (1, 2, 4, or 8 bytes).
|
||||
+ M: Memory region to write to (0 = Main NSO, 1 = Heap).
|
||||
+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr).
|
||||
+ R: Register to load value into.
|
||||
+ A: Immediate offset to use from memory region base.
|
||||
|
||||
#### Load from Register Address Encoding
|
||||
`5TMR10AA AAAAAAAA`
|
||||
`5T0R10AA AAAAAAAA`
|
||||
|
||||
+ T: Width of memory read (1, 2, 4, or 8 bytes).
|
||||
+ M: Memory region to write to (0 = Main NSO, 1 = Heap).
|
||||
+ R: Register to load value into.
|
||||
+ R: Register to load value into. (This register is also used as the base memory address).
|
||||
+ A: Immediate offset to use from register R.
|
||||
|
||||
---
|
||||
|
||||
### Code Type 6: Store Static Value to Register Memory Address
|
||||
Code type 6 allows writing a fixed value to a memory address specified by a register.
|
||||
### Code Type 0x6: Store Static Value to Register Memory Address
|
||||
Code type 0x6 allows writing a fixed value to a memory address specified by a register.
|
||||
|
||||
#### Encoding
|
||||
`6T0RIor0 VVVVVVVV VVVVVVVV`
|
||||
@ -149,10 +154,10 @@ Code type 6 allows writing a fixed value to a memory address specified by a regi
|
||||
|
||||
---
|
||||
|
||||
### Code Type 7: Legacy Arithmetic
|
||||
Code type 7 allows performing arithmetic on registers.
|
||||
### Code Type 0x7: Legacy Arithmetic
|
||||
Code type 0x7 allows performing arithmetic on registers.
|
||||
|
||||
However, it has been deprecated by Code type 9, and is only kept for backwards compatibility.
|
||||
However, it has been deprecated by Code type 0x9, and is only kept for backwards compatibility.
|
||||
|
||||
#### Encoding
|
||||
`7T0RC000 VVVVVVVV`
|
||||
@ -171,8 +176,8 @@ However, it has been deprecated by Code type 9, and is only kept for backwards c
|
||||
|
||||
---
|
||||
|
||||
### Code Type 8: Begin Keypress Conditional Block
|
||||
Code type 8 enters or skips a conditional block based on whether a key combination is pressed.
|
||||
### Code Type 0x8: Begin Keypress Conditional Block
|
||||
Code type 0x8 enters or skips a conditional block based on whether a key combination is pressed.
|
||||
|
||||
#### Encoding
|
||||
`8kkkkkkk`
|
||||
@ -213,8 +218,8 @@ Note: This is the direct output of `hidKeysDown()`.
|
||||
|
||||
---
|
||||
|
||||
### Code Type 9: Perform Arithmetic
|
||||
Code type 9 allows performing arithmetic on registers.
|
||||
### Code Type 0x9: Perform Arithmetic
|
||||
Code type 0x9 allows performing arithmetic on registers.
|
||||
|
||||
#### Register Arithmetic Encoding
|
||||
`9TCRS0s0`
|
||||
@ -248,8 +253,8 @@ Code type 9 allows performing arithmetic on registers.
|
||||
|
||||
---
|
||||
|
||||
### Code Type 10: Store Register to Memory Address
|
||||
Code type 10 allows writing a register to memory.
|
||||
### Code Type 0xA: Store Register to Memory Address
|
||||
Code type 0xA allows writing a register to memory.
|
||||
|
||||
#### Encoding
|
||||
`ATSRIOxa (aaaaaaaa)`
|
||||
@ -272,13 +277,13 @@ Code type 10 allows writing a register to memory.
|
||||
|
||||
---
|
||||
|
||||
### Code Type 11: Reserved
|
||||
Code Type 11 is currently reserved for future use.
|
||||
### Code Type 0xB: Reserved
|
||||
Code Type 0xB is currently reserved for future use.
|
||||
|
||||
---
|
||||
|
||||
### Code Type 12-15: Extended-Width Instruction
|
||||
Code Types 12-15 signal to the VM to treat the upper two nybbles of the first dword as instruction type, instead of just the upper nybble.
|
||||
### Code Type 0xC-0xF: Extended-Width Instruction
|
||||
Code Types 0xC-0xF signal to the VM to treat the upper two nybbles of the first dword as instruction type, instead of just the upper nybble.
|
||||
|
||||
This reserves an additional 64 opcodes for future use.
|
||||
|
||||
|
@ -1,21 +1,10 @@
|
||||
# Configurations
|
||||
Atmosphère provides a variety of customizable configurations to better adjust to users' needs.
|
||||
|
||||
## BCT.ini
|
||||
This is the configuration file used by fusée.
|
||||
## stratosphere.ini
|
||||
This is the configuration file used by fusée for configuring user-space system modules.
|
||||
This file is located under the `/atmosphere/config/` folder on your SD card and a default template can be found inside the `/atmosphere/config_templates/` folder.
|
||||
|
||||
### Adding a Custom Boot Splashscreen
|
||||
Atmosphère provides its own default splashscreen which is displayed at boot time. However, this can be replaced at will.
|
||||
|
||||
The boot splashscreen must be a BMP file, it must be 720x1280 (1280x720 rotated 90 degrees left/counterclockwise/anti-clockwise) resolution, and be in 32-bit ARGB format. You can use image editing software such as GIMP or Photoshop to export the image in this format.
|
||||
|
||||
Add the following lines to BCT.ini and change the value of `custom_splash` to the actual path and filename of your boot splashscreen:
|
||||
```
|
||||
[stage2]
|
||||
custom_splash = /path/to/your/bootlogo.bmp
|
||||
```
|
||||
|
||||
### Configuring "nogc" Protection
|
||||
"nogc" is a feature provided by fusée-secondary which disables the Nintendo Switch's Game Card reader. Its purpose is to prevent the reader from being updated when the console has been updated, without burning fuses, from a lower firmware version. More specifically, from firmware versions 4.0.0 or 9.0.0 which introduced updates to the Game Card reader's firmware. By default, Atmosphère will protect the Game Card reader automatically, but you are free to change it.
|
||||
|
||||
@ -29,32 +18,15 @@ nogc = X
|
||||
0 = force-disable nogc, so Atmosphère will always enable the Game Card reader.
|
||||
```
|
||||
|
||||
### NCM opt-in
|
||||
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:
|
||||
```
|
||||
[stratosphere]
|
||||
enable_ncm = 1
|
||||
```
|
||||
## Adding a Custom Boot Splashscreen
|
||||
Atmosphère provides its own default splashscreen which is displayed at boot time. However, this can be replaced at will.
|
||||
|
||||
### Logging
|
||||
This is an advanced feature aimed at developers trying to debug boot time issues. It enables logging of the fusée stages to be displayed on screen.
|
||||
Boot splash screens must be 1280x720 resolution.
|
||||
|
||||
Add the following lines to BCT.ini and change the value of `X` according to the following list:
|
||||
```
|
||||
[config]
|
||||
log_level = X
|
||||
```
|
||||
```
|
||||
0 = NONE
|
||||
1 = ERROR
|
||||
2 = WARNING
|
||||
3 = MANDATORY
|
||||
4 = INFO
|
||||
5 = DEBUG
|
||||
```
|
||||
A script can be found inside the source tree (`/utilities/insert_splash_screen.py`) for inserting a custom splash screen into a release binary.
|
||||
|
||||
A special level is also provided to prevent prefix creation. To use it, do a bitwise OR with this mask:
|
||||
`0x100 = NO_PREFIX`
|
||||
To do so, execute the following command on the script:
|
||||
`python insert_splash_screen.py <path to your splash screen image> <path to /atmosphere/package3 on your SD card>`
|
||||
|
||||
## emummc.ini
|
||||
This is the configuration file used for the [emummc](../components/emummc.md) component.
|
||||
|
53
docs/features/dns_mitm.md
Normal file
53
docs/features/dns_mitm.md
Normal file
@ -0,0 +1,53 @@
|
||||
# DNS.mitm
|
||||
As of 0.18.0, atmosphère provides a mechanism for redirecting DNS resolution requests.
|
||||
|
||||
By default, atmosphère redirects resolution requests for official telemetry servers, redirecting them to a loopback address.
|
||||
|
||||
## Hosts files
|
||||
|
||||
DNS.mitm can be configured through the usage of a slightly-extended `hosts` file format, which is parsed only once on system startup.
|
||||
|
||||
In particular, hosts files parsed by DNS.mitm have the following extensions to the usual format:
|
||||
+ `*` is treated as a wildcard character, matching any collection of 0 or more characters wherever it occurs in a hostname.
|
||||
+ `%` is treated as a stand-in for the value of `nsd!environment_identifier`. This is always `lp1`, on production devices.
|
||||
|
||||
If multiple entries in a host file match a domain, the last-defined match is used.
|
||||
|
||||
Please note that homebrew may trigger a hosts file re-parse by sending the extension IPC command 65000 ("AtmosphereReloadHostsFile") to a connected `sfdnsres` session.
|
||||
|
||||
### Hosts file selection
|
||||
|
||||
Atmosphère will try to read hosts from the following file paths, in order, stopping once it successfully performs a file read:
|
||||
|
||||
+ (emummc only) `/atmosphere/hosts/emummc_%04lx.txt`, formatted with the emummc's id number (see `emummc.ini`).
|
||||
+ (emummc only) `/atmosphere/hosts/emummc.txt`.
|
||||
+ (sysmmc only) `/atmosphere/hosts/sysmmc.txt`.
|
||||
+ `/atmosphere/hosts/default.txt`
|
||||
|
||||
If `/atmosphere/hosts/default.txt` does not exist, atmosphère will create it to contain the defaults.
|
||||
|
||||
### Atmosphère defaults
|
||||
|
||||
By default, atmosphère's default redirections are parsed **in addition to** the contents of the loaded hosts file.
|
||||
|
||||
This is equivalent to thinking of the loaded hosts file as having the atmosphère defaults prepended to it.
|
||||
|
||||
This setting is considered desirable, because it minimizes the telemetry risks if a user forgets to update a custom hosts file on a system update which changes the telemetry servers.
|
||||
|
||||
This behavior can be opted-out from by setting `atmosphere!add_defaults_to_dns_hosts = u8!0x0` in `system_settings.ini`.
|
||||
|
||||
The current default redirections are:
|
||||
|
||||
```
|
||||
# Nintendo telemetry servers
|
||||
127.0.0.1 receive-%.dg.srv.nintendo.net receive-%.er.srv.nintendo.net
|
||||
```
|
||||
|
||||
## Debugging
|
||||
|
||||
On startup (or on hosts file re-parse), DNS.mitm will log both what hosts file it selected and the contents of all redirections it parses to `/atmosphere/logs/dns_mitm_startup.log`.
|
||||
|
||||
In addition, if the user sets `atmosphere!enable_dns_mitm_debug_log = u8!0x1` in `system_settings.ini`, DNS.mitm will log all requests to GetHostByName/GetAddrInfo to `/atmosphere/logs/dns_mitm_debug.log`. All redirections will be noted when they occur.
|
||||
|
||||
## Opting-out of DNS.mitm entirely
|
||||
If you wish to disable DNS.mitm entirely, `system_settings.ini` can be edited to set `atmosphere!enable_dns_mitm = u8!0x0`.
|
@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018-2020 Atmosphère-NX
|
||||
Copyright (c) Atmosphère-NX
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -12,7 +12,6 @@ Atmosphère provides six core components, mimicking to some degree the various l
|
||||
|
||||
Additionally, Atmosphère also provides the following secondary components:
|
||||
+ [emummc](components/emummc.md)
|
||||
+ [sept](components/sept.md)
|
||||
+ [libraries](components/libraries.md)
|
||||
|
||||
## Features
|
||||
|
@ -1,42 +1,32 @@
|
||||
# Planned Features
|
||||
atmosphère has a number of features that are either works-in-progress or planned. Please note that while time-estimates are given, they are loose, and things may be completed sooner or later than advertised.
|
||||
|
||||
The following descriptions were last updated on July 7th, 2020.
|
||||
|
||||
## ams-on-mariko
|
||||
* **Description**: Atmosphere cannot run as-is on Mariko hardware. A large number of changes are needed in many components. Although secure monitor support is complete in exosphere, additional work is needed on the bootloader and stratosphere sides as well. Mariko support will also require further design thought; atmosphere's debugging design heavily relies on reboot-to-payload and (more generally) the ability to perform warmboot bootrom hax at will. This is not possible on Mariko, and will require a new design/software support for whatever solution is chosen.
|
||||
* **Development Status**: Planned.
|
||||
* **Estimated Time**: Summer 2020
|
||||
|
||||
## settings reimplementation
|
||||
* **Description**: A planned reimplementation of the settings system module, and with it a removal of the settings mitm. This will greatly simplify atmosphère's boot process, and will allow much more flexible control over the various system settings.
|
||||
* **Development Status**: Undergoing research/initial development by Adubbz.
|
||||
* **Estimated Time**: Mid 2020
|
||||
|
||||
## mesosphere
|
||||
* **Description**: mesosphère is a reimplementation of the Horizon operating system's Kernel. It aims to provide an open-source reference for Nintendo's code.
|
||||
* **Development Status**: Under active development by SciresM.
|
||||
* **Estimated Time**: Mid-to-Late 2020
|
||||
The following descriptions were last updated on January 14th, 2021
|
||||
|
||||
## tma reimplementation
|
||||
* **Description** tma ("target manager agent") is a system module that manages communication between the Switch and a client PC. Atmosphere's implementation will allow homebrew on the switch to communicate with a connected PC to do various operations such as exchanging data or interacting with files. It will also serve as the communicator for Atmosphère's planned debugger. This will also include PC-side software for interacting with the Switch.
|
||||
* **Development Status**: Planned. Switch-side code is fully implemented but needs heavy refactoring/rebasing, as the code was originally authored in 2018.
|
||||
* **Estimated Time**: Late 2020-2021.
|
||||
* **Estimated Time**: 2021-2022.
|
||||
|
||||
## dmnt.gen2 reimplementation
|
||||
* **Description**: A reimplementation of the Switch's debug monitor, dmnt will provide an interface for debugging applications or system modules running on the Switch. This will include a gdbstub for debugging actively-running system components or applications.
|
||||
* **Development Status**: Planned
|
||||
* **Estimated Time**: 2021
|
||||
* **Estimated Time**: 2021-2022
|
||||
|
||||
## fs reimplementation
|
||||
* **Description**: Following mesosphère's completion, atmosphère will have reimplemented all components of the BootImagePackage firmware except for the filesystem services system module. Reimplementing fs will allow for fixing Nintendo bugs (such as corruption when using exFAT filesystems and encoding inconsistencies with UTF-8 and Shift-JIS).
|
||||
* **Development Status**: Planned.
|
||||
* **Estimated Time**: 2021-2022.
|
||||
|
||||
## settings reimplementation
|
||||
* **Description**: A planned reimplementation of the settings system module, and with it a removal of the settings mitm. This will greatly simplify atmosphère's boot process, and will allow much more flexible control over the various system settings.
|
||||
* **Development Status**: Pending development by Adubbz.
|
||||
* **Estimated Time**: Unclear, pending developer availability.
|
||||
|
||||
## thermosphère
|
||||
* **Description**: A general-purpose hypervisor, thermosphère will enable the virtualization of the Switch's operating system; this is planned to enable debugging of the Switch's kernel.
|
||||
* **Development Status**: Under semi-active development by TuxSH.
|
||||
* **Estimated Time**: 2020-2021.
|
||||
* **Development Status**: Pending development by TuxSH.
|
||||
* **Estimated Time**: Unclear, pending developer availability.
|
||||
|
||||
## other planned features
|
||||
* **Description**: General system stability improvements to enhance the user's experience.
|
||||
@ -59,4 +49,12 @@ Please note that this is not an exhaustive list of features present in atmosphè
|
||||
|
||||
## exosphere re-write
|
||||
* **Description**: exosphère, atmosphère's reimplementation of Horizon's Secure Monitor, was the first component authored for the project in early 2018. It is written in C, and in a style very different from the rest of atmosphère's code. In addition, exosphère was written to conform to constraints that no longer apply in an environment where it is not launched from the web browser, and where using a custom firmware image to orchestrate wake-from-sleep is possible. exosphère currently uses all but 1 KB of the space available to it, putting it at risk of breaking as future firmware updates are supported. A re-write will solve these issues.
|
||||
* **Completion Time**: June 2020
|
||||
* **Completion Time**: June 2020
|
||||
|
||||
## mesosphere
|
||||
* **Description**: mesosphère is a reimplementation of the Horizon operating system's Kernel. It aims to provide an open-source reference for Nintendo's code.
|
||||
* **Estimated Time**: September 2020
|
||||
|
||||
## ams-on-mariko
|
||||
* **Description**: Atmosphere cannot run as-is on Mariko hardware. A large number of changes are needed in many components. Although secure monitor support is complete in exosphere, additional work is needed on the bootloader and stratosphere sides as well. Mariko support will also require further design thought; atmosphere's debugging design heavily relies on reboot-to-payload and (more generally) the ability to perform warmboot bootrom hax at will. This is not possible on Mariko, and will require a new design/software support for whatever solution is chosen.
|
||||
* **Completion Time**: January 2021
|
8
emummc/.gitrepo
vendored
8
emummc/.gitrepo
vendored
@ -5,8 +5,8 @@
|
||||
;
|
||||
[subrepo]
|
||||
remote = https://github.com/m4xw/emuMMC
|
||||
branch = exo2
|
||||
commit = 06ab9b895c4264ecc14d3bf9be1260e2096f6037
|
||||
parent = dccd41f6d25498c191a157123a27724203d3bc37
|
||||
method = rebase
|
||||
branch = develop
|
||||
commit = a9d56959460fc794ce2cb6405402c25a3e89c47f
|
||||
parent = ff719641396c635b735873fb2b020c910f768a04
|
||||
method = merge
|
||||
cmdver = 0.4.1
|
||||
|
7
emummc/Makefile
vendored
7
emummc/Makefile
vendored
@ -32,7 +32,7 @@ CFLAGS += $(INCLUDE) -D__SWITCH__
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17
|
||||
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
LDFLAGS = -specs=$(EMUMMCDIR)/emummc.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||
|
||||
@ -98,7 +98,10 @@ else
|
||||
|
||||
DEPENDS := $(OFILES:.o=.d)
|
||||
|
||||
all : $(OUTPUT).kip
|
||||
all : $(OUTPUT)_unpacked.kip
|
||||
|
||||
$(OUTPUT)_unpacked.kip : $(OUTPUT).kip
|
||||
@hactool -t kip --uncompressed=$(OUTPUT)_unpacked.kip $(OUTPUT).kip
|
||||
|
||||
$(OUTPUT).kip : $(OUTPUT).elf
|
||||
|
||||
|
2
emummc/README.md
vendored
2
emummc/README.md
vendored
@ -2,7 +2,7 @@
|
||||
*A SDMMC driver replacement for Nintendo's Filesystem Services, by **m4xw***
|
||||
|
||||
### Supported Horizon Versions
|
||||
**1.0.0 - 10.0.0**
|
||||
**1.0.0 - 13.1.0**
|
||||
|
||||
## Features
|
||||
* Arbitrary SDMMC backend selection
|
||||
|
201
emummc/emummc.ld
vendored
Normal file
201
emummc/emummc.ld
vendored
Normal file
@ -0,0 +1,201 @@
|
||||
OUTPUT_ARCH(aarch64)
|
||||
ENTRY(_start)
|
||||
|
||||
PHDRS
|
||||
{
|
||||
code PT_LOAD FLAGS(5) /* Read | Execute */;
|
||||
rodata PT_LOAD FLAGS(4) /* Read */;
|
||||
data PT_LOAD FLAGS(6) /* Read | Write */;
|
||||
dyn PT_DYNAMIC;
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* =========== CODE section =========== */
|
||||
PROVIDE(__start__ = 0x0);
|
||||
. = __start__;
|
||||
__code_start = . ;
|
||||
|
||||
.crt0 :
|
||||
{
|
||||
KEEP (*(.crt0))
|
||||
. = ALIGN(8);
|
||||
} :code
|
||||
|
||||
.init :
|
||||
{
|
||||
KEEP( *(.init) )
|
||||
. = ALIGN(8);
|
||||
} :code
|
||||
|
||||
.plt :
|
||||
{
|
||||
*(.plt)
|
||||
*(.iplt)
|
||||
. = ALIGN(8);
|
||||
} :code
|
||||
|
||||
.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);
|
||||
} :code
|
||||
|
||||
.fini :
|
||||
{
|
||||
KEEP( *(.fini) )
|
||||
. = ALIGN(8);
|
||||
} :code
|
||||
|
||||
/* =========== RODATA section =========== */
|
||||
. = ALIGN(0x1000);
|
||||
__rodata_start = . ;
|
||||
|
||||
.nx-module-name : { KEEP (*(.nx-module-name)) } :rodata
|
||||
|
||||
.rodata :
|
||||
{
|
||||
*(.rodata .rodata.* .gnu.linkonce.r.*)
|
||||
. = ALIGN(8);
|
||||
} :rodata
|
||||
|
||||
.eh_frame_hdr : { __eh_frame_hdr_start = .; *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) __eh_frame_hdr_end = .; } :rodata
|
||||
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) } :rodata
|
||||
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } :rodata
|
||||
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } : rodata
|
||||
|
||||
.dynamic : { *(.dynamic) } :rodata :dyn
|
||||
.dynsym : { *(.dynsym) } :rodata
|
||||
.dynstr : { *(.dynstr) } :rodata
|
||||
.rela.dyn : { *(.rela.*) } :rodata
|
||||
.interp : { *(.interp) } :rodata
|
||||
.hash : { *(.hash) } :rodata
|
||||
.gnu.hash : { *(.gnu.hash) } :rodata
|
||||
.gnu.version : { *(.gnu.version) } :rodata
|
||||
.gnu.version_d : { *(.gnu.version_d) } :rodata
|
||||
.gnu.version_r : { *(.gnu.version_r) } :rodata
|
||||
.note.gnu.build-id : { *(.note.gnu.build-id) } :rodata
|
||||
|
||||
/* =========== DATA section =========== */
|
||||
. = ALIGN(0x1000);
|
||||
__data_start = . ;
|
||||
|
||||
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) } :data
|
||||
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } :data
|
||||
.gnu_extab : ONLY_IF_RW { *(.gnu_extab*) } : data
|
||||
.exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) } :data
|
||||
|
||||
.tdata ALIGN(8) :
|
||||
{
|
||||
__tdata_lma = .;
|
||||
*(.tdata .tdata.* .gnu.linkonce.td.*)
|
||||
. = ALIGN(8);
|
||||
__tdata_lma_end = .;
|
||||
} :data
|
||||
|
||||
.tbss ALIGN(8) :
|
||||
{
|
||||
*(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon)
|
||||
. = ALIGN(8);
|
||||
} :data
|
||||
|
||||
.preinit_array ALIGN(8) :
|
||||
{
|
||||
PROVIDE (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE (__preinit_array_end = .);
|
||||
} :data
|
||||
|
||||
.init_array ALIGN(8) :
|
||||
{
|
||||
PROVIDE (__init_array_start = .);
|
||||
KEEP( *(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)) )
|
||||
KEEP( *(.init_array .ctors) )
|
||||
PROVIDE (__init_array_end = .);
|
||||
} :data
|
||||
|
||||
.fini_array ALIGN(8) :
|
||||
{
|
||||
PROVIDE (__fini_array_start = .);
|
||||
KEEP( *(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)) )
|
||||
KEEP( *(.fini_array .dtors) )
|
||||
PROVIDE (__fini_array_end = .);
|
||||
} :data
|
||||
|
||||
__got_start__ = .;
|
||||
|
||||
.got : { *(.got) *(.igot) } :data
|
||||
.got.plt : { *(.got.plt) *(.igot.plt) } :data
|
||||
|
||||
__got_end__ = .;
|
||||
|
||||
.data ALIGN(8) :
|
||||
{
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
SORT(CONSTRUCTORS)
|
||||
} :data
|
||||
|
||||
__bss_start__ = .;
|
||||
.bss ALIGN(8) :
|
||||
{
|
||||
*(.dynbss)
|
||||
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
. = ALIGN(8);
|
||||
|
||||
/* Reserve space for the TLS segment of the main thread */
|
||||
__tls_start = .;
|
||||
. += + SIZEOF(.tdata) + SIZEOF(.tbss);
|
||||
__tls_end = .;
|
||||
} : data
|
||||
__bss_end__ = .;
|
||||
|
||||
__end__ = ABSOLUTE(.) ;
|
||||
|
||||
. = ALIGN(0x1000);
|
||||
__argdata__ = ABSOLUTE(.) ;
|
||||
|
||||
/* ==================
|
||||
==== Metadata ====
|
||||
================== */
|
||||
|
||||
/* Discard sections that difficult post-processing */
|
||||
/DISCARD/ : { *(.group .comment .note) }
|
||||
|
||||
/* 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) }
|
||||
}
|
8
emummc/emummc.specs
vendored
Normal file
8
emummc/emummc.specs
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
%rename link old_link
|
||||
|
||||
*link:
|
||||
%(old_link) -T %:getenv(TOPDIR /emummc.ld) -pie --no-dynamic-linker --spare-dynamic-tags=0 --gc-sections -z text -z nodynamic-undefined-weak --build-id=sha1 --nx-module-name
|
||||
|
||||
*startfile:
|
||||
crti%O%s crtbegin%O%s
|
||||
|
11
emummc/source/FS/FS.h
vendored
11
emummc/source/FS/FS.h
vendored
@ -37,4 +37,15 @@
|
||||
#define BOOT_PARTITION_SIZE 0x2000
|
||||
#define FS_READ_WRITE_ERROR 1048
|
||||
|
||||
#define NAND_PATROL_SECTOR 0xC20
|
||||
#define NAND_PATROL_OFFSET 0x184000
|
||||
|
||||
typedef struct _fs_nand_patrol_t
|
||||
{
|
||||
uint8_t hmac[0x20];
|
||||
unsigned int offset;
|
||||
unsigned int count;
|
||||
uint8_t rsvd[0x1D8];
|
||||
} fs_nand_patrol_t;
|
||||
|
||||
#endif /* __FS_H__ */
|
||||
|
49
emummc/source/FS/FS_offsets.c
vendored
49
emummc/source/FS/FS_offsets.c
vendored
@ -47,6 +47,18 @@
|
||||
#include "offsets/910_exfat.h"
|
||||
#include "offsets/1000.h"
|
||||
#include "offsets/1000_exfat.h"
|
||||
#include "offsets/1020.h"
|
||||
#include "offsets/1020_exfat.h"
|
||||
#include "offsets/1100.h"
|
||||
#include "offsets/1100_exfat.h"
|
||||
#include "offsets/1200.h"
|
||||
#include "offsets/1200_exfat.h"
|
||||
#include "offsets/1203.h"
|
||||
#include "offsets/1203_exfat.h"
|
||||
#include "offsets/1300.h"
|
||||
#include "offsets/1300_exfat.h"
|
||||
#include "offsets/1310.h"
|
||||
#include "offsets/1310_exfat.h"
|
||||
#include "../utils/fatal.h"
|
||||
|
||||
#define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers
|
||||
@ -67,6 +79,7 @@ static const fs_offsets_t GET_OFFSET_STRUCT_NAME(vers) = { \
|
||||
.nand_mutex = FS_OFFSET##vers##_NAND_MUTEX, \
|
||||
.active_partition = FS_OFFSET##vers##_ACTIVE_PARTITION, \
|
||||
.sdmmc_das_handle = FS_OFFSET##vers##_SDMMC_DAS_HANDLE, \
|
||||
.sdmmc_accessor_controller_open = FS_OFFSET##vers##_SDMMC_WRAPPER_CONTROLLER_OPEN, \
|
||||
.sdmmc_accessor_controller_close = FS_OFFSET##vers##_SDMMC_WRAPPER_CONTROLLER_CLOSE, \
|
||||
.sd_das_init = FS_OFFSET##vers##_SD_DAS_INIT, \
|
||||
.nintendo_paths = FS_OFFSET##vers##_NINTENDO_PATHS, \
|
||||
@ -104,6 +117,18 @@ DEFINE_OFFSET_STRUCT(_910);
|
||||
DEFINE_OFFSET_STRUCT(_910_EXFAT);
|
||||
DEFINE_OFFSET_STRUCT(_1000);
|
||||
DEFINE_OFFSET_STRUCT(_1000_EXFAT);
|
||||
DEFINE_OFFSET_STRUCT(_1020);
|
||||
DEFINE_OFFSET_STRUCT(_1020_EXFAT);
|
||||
DEFINE_OFFSET_STRUCT(_1100);
|
||||
DEFINE_OFFSET_STRUCT(_1100_EXFAT);
|
||||
DEFINE_OFFSET_STRUCT(_1200);
|
||||
DEFINE_OFFSET_STRUCT(_1200_EXFAT);
|
||||
DEFINE_OFFSET_STRUCT(_1203);
|
||||
DEFINE_OFFSET_STRUCT(_1203_EXFAT);
|
||||
DEFINE_OFFSET_STRUCT(_1300);
|
||||
DEFINE_OFFSET_STRUCT(_1300_EXFAT);
|
||||
DEFINE_OFFSET_STRUCT(_1310);
|
||||
DEFINE_OFFSET_STRUCT(_1310_EXFAT);
|
||||
|
||||
const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
|
||||
switch (version) {
|
||||
@ -169,6 +194,30 @@ const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
|
||||
return &(GET_OFFSET_STRUCT_NAME(_1000));
|
||||
case FS_VER_10_0_0_EXFAT:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_1000_EXFAT));
|
||||
case FS_VER_10_2_0:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_1020));
|
||||
case FS_VER_10_2_0_EXFAT:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_1020_EXFAT));
|
||||
case FS_VER_11_0_0:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_1100));
|
||||
case FS_VER_11_0_0_EXFAT:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_1100_EXFAT));
|
||||
case FS_VER_12_0_0:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_1200));
|
||||
case FS_VER_12_0_0_EXFAT:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_1200_EXFAT));
|
||||
case FS_VER_12_0_3:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_1203));
|
||||
case FS_VER_12_0_3_EXFAT:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_1203_EXFAT));
|
||||
case FS_VER_13_0_0:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_1300));
|
||||
case FS_VER_13_0_0_EXFAT:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_1300_EXFAT));
|
||||
case FS_VER_13_1_0:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_1310));
|
||||
case FS_VER_13_1_0_EXFAT:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_1310_EXFAT));
|
||||
default:
|
||||
fatal_abort(Fatal_UnknownVersion);
|
||||
}
|
||||
|
1
emummc/source/FS/FS_offsets.h
vendored
1
emummc/source/FS/FS_offsets.h
vendored
@ -41,6 +41,7 @@ typedef struct {
|
||||
// Misc funcs
|
||||
uintptr_t lock_mutex;
|
||||
uintptr_t unlock_mutex;
|
||||
uintptr_t sdmmc_accessor_controller_open;
|
||||
uintptr_t sdmmc_accessor_controller_close;
|
||||
// Misc data
|
||||
uintptr_t sd_mutex;
|
||||
|
2
emummc/source/FS/FS_structs.h
vendored
2
emummc/source/FS/FS_structs.h
vendored
@ -35,7 +35,7 @@ typedef struct sdmmc_accessor_vt
|
||||
void *dtor;
|
||||
void *map_device_addr_space;
|
||||
void *unmap_device_addr_space;
|
||||
void *controller_open;
|
||||
uint64_t (*sdmmc_accessor_controller_open)(void *);
|
||||
uint64_t (*sdmmc_accessor_controller_close)(void *);
|
||||
uint64_t (*read_write)(void *, uint64_t, uint64_t, void *, uint64_t, uint64_t);
|
||||
// More not included because we don't use it.
|
||||
|
18
emummc/source/FS/FS_versions.h
vendored
18
emummc/source/FS/FS_versions.h
vendored
@ -68,6 +68,24 @@ enum FS_VER
|
||||
FS_VER_10_0_0,
|
||||
FS_VER_10_0_0_EXFAT,
|
||||
|
||||
FS_VER_10_2_0,
|
||||
FS_VER_10_2_0_EXFAT,
|
||||
|
||||
FS_VER_11_0_0,
|
||||
FS_VER_11_0_0_EXFAT,
|
||||
|
||||
FS_VER_12_0_0,
|
||||
FS_VER_12_0_0_EXFAT,
|
||||
|
||||
FS_VER_12_0_3,
|
||||
FS_VER_12_0_3_EXFAT,
|
||||
|
||||
FS_VER_13_0_0,
|
||||
FS_VER_13_0_0_EXFAT,
|
||||
|
||||
FS_VER_13_1_0,
|
||||
FS_VER_13_1_0_EXFAT,
|
||||
|
||||
FS_VER_MAX,
|
||||
};
|
||||
|
||||
|
1
emummc/source/FS/offsets/100.h
vendored
1
emummc/source/FS/offsets/100.h
vendored
@ -34,6 +34,7 @@
|
||||
#define FS_OFFSET_100_LOCK_MUTEX 0x2884
|
||||
#define FS_OFFSET_100_UNLOCK_MUTEX 0x28F0
|
||||
|
||||
#define FS_OFFSET_100_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||
#define FS_OFFSET_100_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x6A8AC
|
||||
|
||||
// Misc Data
|
||||
|
1
emummc/source/FS/offsets/1000.h
vendored
1
emummc/source/FS/offsets/1000.h
vendored
@ -34,6 +34,7 @@
|
||||
#define FS_OFFSET_1000_LOCK_MUTEX 0x28910
|
||||
#define FS_OFFSET_1000_UNLOCK_MUTEX 0x28960
|
||||
|
||||
#define FS_OFFSET_1000_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||
#define FS_OFFSET_1000_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1422E0
|
||||
|
||||
// Misc Data
|
||||
|
1
emummc/source/FS/offsets/1000_exfat.h
vendored
1
emummc/source/FS/offsets/1000_exfat.h
vendored
@ -34,6 +34,7 @@
|
||||
#define FS_OFFSET_1000_EXFAT_LOCK_MUTEX 0x28910
|
||||
#define FS_OFFSET_1000_EXFAT_UNLOCK_MUTEX 0x28960
|
||||
|
||||
#define FS_OFFSET_1000_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||
#define FS_OFFSET_1000_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1422E0
|
||||
|
||||
// Misc Data
|
||||
|
59
emummc/source/FS/offsets/1020.h
vendored
Normal file
59
emummc/source/FS/offsets/1020.h
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_1020_H__
|
||||
#define __FS_1020_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_1020_SDMMC_ACCESSOR_GC 0x14E0F0
|
||||
#define FS_OFFSET_1020_SDMMC_ACCESSOR_SD 0x14C200
|
||||
#define FS_OFFSET_1020_SDMMC_ACCESSOR_NAND 0x147080
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_1020_SDMMC_WRAPPER_READ 0x1427E0
|
||||
#define FS_OFFSET_1020_SDMMC_WRAPPER_WRITE 0x1428C0
|
||||
#define FS_OFFSET_1020_RTLD 0x634
|
||||
#define FS_OFFSET_1020_RTLD_DESTINATION 0x9C
|
||||
|
||||
#define FS_OFFSET_1020_CLKRST_SET_MIN_V_CLK_RATE 0x141A00
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_1020_LOCK_MUTEX 0x28910
|
||||
#define FS_OFFSET_1020_UNLOCK_MUTEX 0x28960
|
||||
|
||||
#define FS_OFFSET_1020_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||
#define FS_OFFSET_1020_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x142740
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_1020_SD_MUTEX 0xE273E8
|
||||
#define FS_OFFSET_1020_NAND_MUTEX 0xE22DA0
|
||||
#define FS_OFFSET_1020_ACTIVE_PARTITION 0xE22DE0
|
||||
#define FS_OFFSET_1020_SDMMC_DAS_HANDLE 0xE0AB90
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_1020_SD_DAS_INIT 0x15214C
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_1020_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0006BBA4, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00078520, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007ED0C, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x0009115C, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_1020_H__
|
59
emummc/source/FS/offsets/1020_exfat.h
vendored
Normal file
59
emummc/source/FS/offsets/1020_exfat.h
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_1020_EXFAT_H__
|
||||
#define __FS_1020_EXFAT_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_1020_EXFAT_SDMMC_ACCESSOR_GC 0x14E0F0
|
||||
#define FS_OFFSET_1020_EXFAT_SDMMC_ACCESSOR_SD 0x14C200
|
||||
#define FS_OFFSET_1020_EXFAT_SDMMC_ACCESSOR_NAND 0x147080
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_1020_EXFAT_SDMMC_WRAPPER_READ 0x1427E0
|
||||
#define FS_OFFSET_1020_EXFAT_SDMMC_WRAPPER_WRITE 0x1428C0
|
||||
#define FS_OFFSET_1020_EXFAT_RTLD 0x634
|
||||
#define FS_OFFSET_1020_EXFAT_RTLD_DESTINATION 0x9C
|
||||
|
||||
#define FS_OFFSET_1020_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x141A00
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_1020_EXFAT_LOCK_MUTEX 0x28910
|
||||
#define FS_OFFSET_1020_EXFAT_UNLOCK_MUTEX 0x28960
|
||||
|
||||
#define FS_OFFSET_1020_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||
#define FS_OFFSET_1020_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x142740
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_1020_EXFAT_SD_MUTEX 0xE353E8
|
||||
#define FS_OFFSET_1020_EXFAT_NAND_MUTEX 0xE30DA0
|
||||
#define FS_OFFSET_1020_EXFAT_ACTIVE_PARTITION 0xE30DE0
|
||||
#define FS_OFFSET_1020_EXFAT_SDMMC_DAS_HANDLE 0xE18B90
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_1020_EXFAT_SD_DAS_INIT 0x15214C
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_1020_EXFAT_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0006BBA4, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00078520, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007ED0C, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x0009115C, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_1020_EXFAT_H__
|
59
emummc/source/FS/offsets/1100.h
vendored
Normal file
59
emummc/source/FS/offsets/1100.h
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_1100_H__
|
||||
#define __FS_1100_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_1100_SDMMC_ACCESSOR_GC 0x156D90
|
||||
#define FS_OFFSET_1100_SDMMC_ACCESSOR_SD 0x154F40
|
||||
#define FS_OFFSET_1100_SDMMC_ACCESSOR_NAND 0x1500F0
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_1100_SDMMC_WRAPPER_READ 0x14B990
|
||||
#define FS_OFFSET_1100_SDMMC_WRAPPER_WRITE 0x14BA70
|
||||
#define FS_OFFSET_1100_RTLD 0x688
|
||||
#define FS_OFFSET_1100_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x3C)))
|
||||
|
||||
#define FS_OFFSET_1100_CLKRST_SET_MIN_V_CLK_RATE 0x14AC40
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_1100_LOCK_MUTEX 0x28FF0
|
||||
#define FS_OFFSET_1100_UNLOCK_MUTEX 0x29040
|
||||
|
||||
#define FS_OFFSET_1100_SDMMC_WRAPPER_CONTROLLER_OPEN 0x14B840
|
||||
#define FS_OFFSET_1100_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x14B8F0
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_1100_SD_MUTEX 0xE323E8
|
||||
#define FS_OFFSET_1100_NAND_MUTEX 0xE2D338
|
||||
#define FS_OFFSET_1100_ACTIVE_PARTITION 0xE2D378
|
||||
#define FS_OFFSET_1100_SDMMC_DAS_HANDLE 0xE15D40
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_1100_SD_DAS_INIT 0x273B4
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_1100_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0006D944, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007A3C0, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00080708, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x00092198, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_1100_H__
|
59
emummc/source/FS/offsets/1100_exfat.h
vendored
Normal file
59
emummc/source/FS/offsets/1100_exfat.h
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_1100_EXFAT_H__
|
||||
#define __FS_1100_EXFAT_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_1100_EXFAT_SDMMC_ACCESSOR_GC 0x156D90
|
||||
#define FS_OFFSET_1100_EXFAT_SDMMC_ACCESSOR_SD 0x154F40
|
||||
#define FS_OFFSET_1100_EXFAT_SDMMC_ACCESSOR_NAND 0x1500F0
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_1100_EXFAT_SDMMC_WRAPPER_READ 0x14B990
|
||||
#define FS_OFFSET_1100_EXFAT_SDMMC_WRAPPER_WRITE 0x14BA70
|
||||
#define FS_OFFSET_1100_EXFAT_RTLD 0x688
|
||||
#define FS_OFFSET_1100_EXFAT_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x3C)))
|
||||
|
||||
#define FS_OFFSET_1100_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x14AC40
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_1100_EXFAT_LOCK_MUTEX 0x28FF0
|
||||
#define FS_OFFSET_1100_EXFAT_UNLOCK_MUTEX 0x29040
|
||||
|
||||
#define FS_OFFSET_1100_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x14B840
|
||||
#define FS_OFFSET_1100_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x14B8F0
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_1100_EXFAT_SD_MUTEX 0xE403E8
|
||||
#define FS_OFFSET_1100_EXFAT_NAND_MUTEX 0xE3B338
|
||||
#define FS_OFFSET_1100_EXFAT_ACTIVE_PARTITION 0xE3B378
|
||||
#define FS_OFFSET_1100_EXFAT_SDMMC_DAS_HANDLE 0xE23D40
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_1100_EXFAT_SD_DAS_INIT 0x273B4
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_1100_EXFAT_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0006D944, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007A3C0, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00080708, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x00092198, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_1100_EXFAT_H__
|
59
emummc/source/FS/offsets/1200.h
vendored
Normal file
59
emummc/source/FS/offsets/1200.h
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_1200_H__
|
||||
#define __FS_1200_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_1200_SDMMC_ACCESSOR_GC 0x154FD0
|
||||
#define FS_OFFSET_1200_SDMMC_ACCESSOR_SD 0x156DE0
|
||||
#define FS_OFFSET_1200_SDMMC_ACCESSOR_NAND 0x155500
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_1200_SDMMC_WRAPPER_READ 0x150970
|
||||
#define FS_OFFSET_1200_SDMMC_WRAPPER_WRITE 0x150A30
|
||||
#define FS_OFFSET_1200_RTLD 0x688
|
||||
#define FS_OFFSET_1200_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x3C)))
|
||||
|
||||
#define FS_OFFSET_1200_CLKRST_SET_MIN_V_CLK_RATE 0x14FCC0
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_1200_LOCK_MUTEX 0x29350
|
||||
#define FS_OFFSET_1200_UNLOCK_MUTEX 0x293A0
|
||||
|
||||
#define FS_OFFSET_1200_SDMMC_WRAPPER_CONTROLLER_OPEN 0x150850
|
||||
#define FS_OFFSET_1200_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1508E0
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_1200_SD_MUTEX 0xE3D3E8
|
||||
#define FS_OFFSET_1200_NAND_MUTEX 0xE38768
|
||||
#define FS_OFFSET_1200_ACTIVE_PARTITION 0xE387A8
|
||||
#define FS_OFFSET_1200_SDMMC_DAS_HANDLE 0xE20DB0
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_1200_SD_DAS_INIT 0x27244
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_1200_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0006E810, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007AEC0, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x00081254, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x00092850, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_1200_H__
|
59
emummc/source/FS/offsets/1200_exfat.h
vendored
Normal file
59
emummc/source/FS/offsets/1200_exfat.h
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_1200_EXFAT_H__
|
||||
#define __FS_1200_EXFAT_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_1200_EXFAT_SDMMC_ACCESSOR_GC 0x154FD0
|
||||
#define FS_OFFSET_1200_EXFAT_SDMMC_ACCESSOR_SD 0x156DE0
|
||||
#define FS_OFFSET_1200_EXFAT_SDMMC_ACCESSOR_NAND 0x155500
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_1200_EXFAT_SDMMC_WRAPPER_READ 0x150970
|
||||
#define FS_OFFSET_1200_EXFAT_SDMMC_WRAPPER_WRITE 0x150A30
|
||||
#define FS_OFFSET_1200_EXFAT_RTLD 0x688
|
||||
#define FS_OFFSET_1200_EXFAT_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x3C)))
|
||||
|
||||
#define FS_OFFSET_1200_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x14FCC0
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_1200_EXFAT_LOCK_MUTEX 0x29350
|
||||
#define FS_OFFSET_1200_EXFAT_UNLOCK_MUTEX 0x293A0
|
||||
|
||||
#define FS_OFFSET_1200_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x150850
|
||||
#define FS_OFFSET_1200_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1508E0
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_1200_EXFAT_SD_MUTEX 0xE4B3E8
|
||||
#define FS_OFFSET_1200_EXFAT_NAND_MUTEX 0xE46768
|
||||
#define FS_OFFSET_1200_EXFAT_ACTIVE_PARTITION 0xE467A8
|
||||
#define FS_OFFSET_1200_EXFAT_SDMMC_DAS_HANDLE 0xE2EDB0
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_1200_EXFAT_SD_DAS_INIT 0x27244
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_1200_EXFAT_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0006E810, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007AEC0, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x00081254, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x00092850, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_1200_EXFAT_H__
|
60
emummc/source/FS/offsets/1203.h
vendored
Normal file
60
emummc/source/FS/offsets/1203.h
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
* Copyright (c) 2021 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_1203_H__
|
||||
#define __FS_1203_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_1203_SDMMC_ACCESSOR_GC 0x1550E0
|
||||
#define FS_OFFSET_1203_SDMMC_ACCESSOR_SD 0x156EF0
|
||||
#define FS_OFFSET_1203_SDMMC_ACCESSOR_NAND 0x155610
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_1203_SDMMC_WRAPPER_READ 0x150A80
|
||||
#define FS_OFFSET_1203_SDMMC_WRAPPER_WRITE 0x150B40
|
||||
#define FS_OFFSET_1203_RTLD 0x688
|
||||
#define FS_OFFSET_1203_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x3C)))
|
||||
|
||||
#define FS_OFFSET_1203_CLKRST_SET_MIN_V_CLK_RATE 0x14FDD0
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_1203_LOCK_MUTEX 0x29350
|
||||
#define FS_OFFSET_1203_UNLOCK_MUTEX 0x293A0
|
||||
|
||||
#define FS_OFFSET_1203_SDMMC_WRAPPER_CONTROLLER_OPEN 0x150960
|
||||
#define FS_OFFSET_1203_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1509F0
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_1203_SD_MUTEX 0xE3D3E8
|
||||
#define FS_OFFSET_1203_NAND_MUTEX 0xE38768
|
||||
#define FS_OFFSET_1203_ACTIVE_PARTITION 0xE387A8
|
||||
#define FS_OFFSET_1203_SDMMC_DAS_HANDLE 0xE20DB0
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_1203_SD_DAS_INIT 0x27244
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_1203_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0006E920, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007AFD0, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x00081364, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x00092960, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_1203_H__
|
60
emummc/source/FS/offsets/1203_exfat.h
vendored
Normal file
60
emummc/source/FS/offsets/1203_exfat.h
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
* Copyright (c) 2021 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_1203_EXFAT_H__
|
||||
#define __FS_1203_EXFAT_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_1203_EXFAT_SDMMC_ACCESSOR_GC 0x1550E0
|
||||
#define FS_OFFSET_1203_EXFAT_SDMMC_ACCESSOR_SD 0x156EF0
|
||||
#define FS_OFFSET_1203_EXFAT_SDMMC_ACCESSOR_NAND 0x155610
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_1203_EXFAT_SDMMC_WRAPPER_READ 0x150A80
|
||||
#define FS_OFFSET_1203_EXFAT_SDMMC_WRAPPER_WRITE 0x150B40
|
||||
#define FS_OFFSET_1203_EXFAT_RTLD 0x688
|
||||
#define FS_OFFSET_1203_EXFAT_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x3C)))
|
||||
|
||||
#define FS_OFFSET_1203_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x14FDD0
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_1203_EXFAT_LOCK_MUTEX 0x29350
|
||||
#define FS_OFFSET_1203_EXFAT_UNLOCK_MUTEX 0x293A0
|
||||
|
||||
#define FS_OFFSET_1203_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x150960
|
||||
#define FS_OFFSET_1203_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1509F0
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_1203_EXFAT_SD_MUTEX 0xE4B3E8
|
||||
#define FS_OFFSET_1203_EXFAT_NAND_MUTEX 0xE46768
|
||||
#define FS_OFFSET_1203_EXFAT_ACTIVE_PARTITION 0xE467A8
|
||||
#define FS_OFFSET_1203_EXFAT_SDMMC_DAS_HANDLE 0xE2EDB0
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_1203_EXFAT_SD_DAS_INIT 0x27244
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_1203_EXFAT_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0006E920, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007AFD0, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x00081364, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x00092960, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_1203_EXFAT_H__
|
59
emummc/source/FS/offsets/1300.h
vendored
Normal file
59
emummc/source/FS/offsets/1300.h
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_1300_H__
|
||||
#define __FS_1300_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_1300_SDMMC_ACCESSOR_GC 0x158C80
|
||||
#define FS_OFFSET_1300_SDMMC_ACCESSOR_SD 0x15AA90
|
||||
#define FS_OFFSET_1300_SDMMC_ACCESSOR_NAND 0x1591B0
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_1300_SDMMC_WRAPPER_READ 0x154620
|
||||
#define FS_OFFSET_1300_SDMMC_WRAPPER_WRITE 0x1546E0
|
||||
#define FS_OFFSET_1300_RTLD 0x688
|
||||
#define FS_OFFSET_1300_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x3C)))
|
||||
|
||||
#define FS_OFFSET_1300_CLKRST_SET_MIN_V_CLK_RATE 0x153820
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_1300_LOCK_MUTEX 0x29690
|
||||
#define FS_OFFSET_1300_UNLOCK_MUTEX 0x296E0
|
||||
|
||||
#define FS_OFFSET_1300_SDMMC_WRAPPER_CONTROLLER_OPEN 0x154500
|
||||
#define FS_OFFSET_1300_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x154590
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_1300_SD_MUTEX 0xE133E8
|
||||
#define FS_OFFSET_1300_NAND_MUTEX 0xE0E768
|
||||
#define FS_OFFSET_1300_ACTIVE_PARTITION 0xE0E7A8
|
||||
#define FS_OFFSET_1300_SDMMC_DAS_HANDLE 0xDF6E18
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_1300_SD_DAS_INIT 0x27744
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_1300_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0006EBE0, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007BEEC, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x00082294, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x0009422C, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_1300_H__
|
59
emummc/source/FS/offsets/1300_exfat.h
vendored
Normal file
59
emummc/source/FS/offsets/1300_exfat.h
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_1300_EXFAT_H__
|
||||
#define __FS_1300_EXFAT_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_1300_EXFAT_SDMMC_ACCESSOR_GC 0x158C80
|
||||
#define FS_OFFSET_1300_EXFAT_SDMMC_ACCESSOR_SD 0x15AA90
|
||||
#define FS_OFFSET_1300_EXFAT_SDMMC_ACCESSOR_NAND 0x1591B0
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_1300_EXFAT_SDMMC_WRAPPER_READ 0x154620
|
||||
#define FS_OFFSET_1300_EXFAT_SDMMC_WRAPPER_WRITE 0x1546E0
|
||||
#define FS_OFFSET_1300_EXFAT_RTLD 0x688
|
||||
#define FS_OFFSET_1300_EXFAT_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x3C)))
|
||||
|
||||
#define FS_OFFSET_1300_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x153820
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_1300_EXFAT_LOCK_MUTEX 0x29690
|
||||
#define FS_OFFSET_1300_EXFAT_UNLOCK_MUTEX 0x296E0
|
||||
|
||||
#define FS_OFFSET_1300_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x154500
|
||||
#define FS_OFFSET_1300_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x154590
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_1300_EXFAT_SD_MUTEX 0xE203E8
|
||||
#define FS_OFFSET_1300_EXFAT_NAND_MUTEX 0xE1B768
|
||||
#define FS_OFFSET_1300_EXFAT_ACTIVE_PARTITION 0xE1B7A8
|
||||
#define FS_OFFSET_1300_EXFAT_SDMMC_DAS_HANDLE 0xE03E18
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_1300_EXFAT_SD_DAS_INIT 0x27744
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_1300_EXFAT_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0006EBE0, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007BEEC, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x00082294, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x0009422C, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_1300_EXFAT_H__
|
59
emummc/source/FS/offsets/1310.h
vendored
Normal file
59
emummc/source/FS/offsets/1310.h
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_1310_H__
|
||||
#define __FS_1310_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_1310_SDMMC_ACCESSOR_GC 0x158C20
|
||||
#define FS_OFFSET_1310_SDMMC_ACCESSOR_SD 0x15AA30
|
||||
#define FS_OFFSET_1310_SDMMC_ACCESSOR_NAND 0x159150
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_1310_SDMMC_WRAPPER_READ 0x1545C0
|
||||
#define FS_OFFSET_1310_SDMMC_WRAPPER_WRITE 0x154680
|
||||
#define FS_OFFSET_1310_RTLD 0x688
|
||||
#define FS_OFFSET_1310_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x3C)))
|
||||
|
||||
#define FS_OFFSET_1310_CLKRST_SET_MIN_V_CLK_RATE 0x1537C0
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_1310_LOCK_MUTEX 0x29690
|
||||
#define FS_OFFSET_1310_UNLOCK_MUTEX 0x296E0
|
||||
|
||||
#define FS_OFFSET_1310_SDMMC_WRAPPER_CONTROLLER_OPEN 0x1544A0
|
||||
#define FS_OFFSET_1310_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x154530
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_1310_SD_MUTEX 0xE133E8
|
||||
#define FS_OFFSET_1310_NAND_MUTEX 0xE0E768
|
||||
#define FS_OFFSET_1310_ACTIVE_PARTITION 0xE0E7A8
|
||||
#define FS_OFFSET_1310_SDMMC_DAS_HANDLE 0xDF6E18
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_1310_SD_DAS_INIT 0x27744
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_1310_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0006EBE0, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007BEEC, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x00082294, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x0009422C, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_1310_H__
|
59
emummc/source/FS/offsets/1310_exfat.h
vendored
Normal file
59
emummc/source/FS/offsets/1310_exfat.h
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_1310_EXFAT_H__
|
||||
#define __FS_1310_EXFAT_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_1310_EXFAT_SDMMC_ACCESSOR_GC 0x158C20
|
||||
#define FS_OFFSET_1310_EXFAT_SDMMC_ACCESSOR_SD 0x15AA30
|
||||
#define FS_OFFSET_1310_EXFAT_SDMMC_ACCESSOR_NAND 0x159150
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_1310_EXFAT_SDMMC_WRAPPER_READ 0x1545C0
|
||||
#define FS_OFFSET_1310_EXFAT_SDMMC_WRAPPER_WRITE 0x154680
|
||||
#define FS_OFFSET_1310_EXFAT_RTLD 0x688
|
||||
#define FS_OFFSET_1310_EXFAT_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x3C)))
|
||||
|
||||
#define FS_OFFSET_1310_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x1537C0
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_1310_EXFAT_LOCK_MUTEX 0x29690
|
||||
#define FS_OFFSET_1310_EXFAT_UNLOCK_MUTEX 0x296E0
|
||||
|
||||
#define FS_OFFSET_1310_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x1544A0
|
||||
#define FS_OFFSET_1310_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x154530
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_1310_EXFAT_SD_MUTEX 0xE203E8
|
||||
#define FS_OFFSET_1310_EXFAT_NAND_MUTEX 0xE1B768
|
||||
#define FS_OFFSET_1310_EXFAT_ACTIVE_PARTITION 0xE1B7A8
|
||||
#define FS_OFFSET_1310_EXFAT_SDMMC_DAS_HANDLE 0xE03E18
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_1310_EXFAT_SD_DAS_INIT 0x27744
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_1310_EXFAT_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0006EBE0, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007BEEC, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x00082294, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x0009422C, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_1310_EXFAT_H__
|
1
emummc/source/FS/offsets/200.h
vendored
1
emummc/source/FS/offsets/200.h
vendored
@ -34,6 +34,7 @@
|
||||
#define FS_OFFSET_200_LOCK_MUTEX 0x3264
|
||||
#define FS_OFFSET_200_UNLOCK_MUTEX 0x32D0
|
||||
|
||||
#define FS_OFFSET_200_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||
#define FS_OFFSET_200_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x733F4
|
||||
|
||||
// Misc Data
|
||||
|
1
emummc/source/FS/offsets/200_exfat.h
vendored
1
emummc/source/FS/offsets/200_exfat.h
vendored
@ -34,6 +34,7 @@
|
||||
#define FS_OFFSET_200_EXFAT_LOCK_MUTEX 0x3264
|
||||
#define FS_OFFSET_200_EXFAT_UNLOCK_MUTEX 0x32D0
|
||||
|
||||
#define FS_OFFSET_200_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||
#define FS_OFFSET_200_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x733F4
|
||||
|
||||
// Misc Data
|
||||
|
1
emummc/source/FS/offsets/210.h
vendored
1
emummc/source/FS/offsets/210.h
vendored
@ -34,6 +34,7 @@
|
||||
#define FS_OFFSET_210_LOCK_MUTEX 0x3264
|
||||
#define FS_OFFSET_210_UNLOCK_MUTEX 0x32D0
|
||||
|
||||
#define FS_OFFSET_210_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||
#define FS_OFFSET_210_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x737D4
|
||||
|
||||
// Misc Data
|
||||
|
1
emummc/source/FS/offsets/210_exfat.h
vendored
1
emummc/source/FS/offsets/210_exfat.h
vendored
@ -34,6 +34,7 @@
|
||||
#define FS_OFFSET_210_EXFAT_LOCK_MUTEX 0x3264
|
||||
#define FS_OFFSET_210_EXFAT_UNLOCK_MUTEX 0x32D0
|
||||
|
||||
#define FS_OFFSET_210_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||
#define FS_OFFSET_210_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x737D4
|
||||
|
||||
// Misc Data
|
||||
|
1
emummc/source/FS/offsets/300.h
vendored
1
emummc/source/FS/offsets/300.h
vendored
@ -34,6 +34,7 @@
|
||||
#define FS_OFFSET_300_LOCK_MUTEX 0x35CC
|
||||
#define FS_OFFSET_300_UNLOCK_MUTEX 0x3638
|
||||
|
||||
#define FS_OFFSET_300_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||
#define FS_OFFSET_300_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x8A270
|
||||
|
||||
// Misc Data
|
||||
|
1
emummc/source/FS/offsets/300_exfat.h
vendored
1
emummc/source/FS/offsets/300_exfat.h
vendored
@ -34,6 +34,7 @@
|
||||
#define FS_OFFSET_300_EXFAT_LOCK_MUTEX 0x35CC
|
||||
#define FS_OFFSET_300_EXFAT_UNLOCK_MUTEX 0x3638
|
||||
|
||||
#define FS_OFFSET_300_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||
#define FS_OFFSET_300_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x8A270
|
||||
|
||||
// Misc Data
|
||||
|
1
emummc/source/FS/offsets/301.h
vendored
1
emummc/source/FS/offsets/301.h
vendored
@ -34,6 +34,7 @@
|
||||
#define FS_OFFSET_301_LOCK_MUTEX 0x3638
|
||||
#define FS_OFFSET_301_UNLOCK_MUTEX 0x36A4
|
||||
|
||||
#define FS_OFFSET_301_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||
#define FS_OFFSET_301_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x8A32C
|
||||
|
||||
// Misc Data
|
||||
|
1
emummc/source/FS/offsets/301_exfat.h
vendored
1
emummc/source/FS/offsets/301_exfat.h
vendored
@ -34,6 +34,7 @@
|
||||
#define FS_OFFSET_301_EXFAT_LOCK_MUTEX 0x3638
|
||||
#define FS_OFFSET_301_EXFAT_UNLOCK_MUTEX 0x36A4
|
||||
|
||||
#define FS_OFFSET_301_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||
#define FS_OFFSET_301_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x8A32C
|
||||
|
||||
// Misc Data
|
||||
|
1
emummc/source/FS/offsets/400.h
vendored
1
emummc/source/FS/offsets/400.h
vendored
@ -34,6 +34,7 @@
|
||||
#define FS_OFFSET_400_LOCK_MUTEX 0x39A0
|
||||
#define FS_OFFSET_400_UNLOCK_MUTEX 0x3A0C
|
||||
|
||||
#define FS_OFFSET_400_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||
#define FS_OFFSET_400_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x9DB48
|
||||
|
||||
// Misc Data
|
||||
|
1
emummc/source/FS/offsets/400_exfat.h
vendored
1
emummc/source/FS/offsets/400_exfat.h
vendored
@ -34,6 +34,7 @@
|
||||
#define FS_OFFSET_400_EXFAT_LOCK_MUTEX 0x39A0
|
||||
#define FS_OFFSET_400_EXFAT_UNLOCK_MUTEX 0x3A0C
|
||||
|
||||
#define FS_OFFSET_400_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||
#define FS_OFFSET_400_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x9DB48
|
||||
|
||||
// Misc Data
|
||||
|
3
emummc/source/FS/offsets/410.h
vendored
3
emummc/source/FS/offsets/410.h
vendored
@ -34,7 +34,8 @@
|
||||
#define FS_OFFSET_410_LOCK_MUTEX 0x39A0
|
||||
#define FS_OFFSET_410_UNLOCK_MUTEX 0x3A0C
|
||||
|
||||
#define FS_OFFSET_410_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x9DBAC
|
||||
#define FS_OFFSET_410_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||
#define FS_OFFSET_410_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x9DBAC
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_410_SD_MUTEX 0xE80268
|
||||
|
1
emummc/source/FS/offsets/410_exfat.h
vendored
1
emummc/source/FS/offsets/410_exfat.h
vendored
@ -34,6 +34,7 @@
|
||||
#define FS_OFFSET_410_EXFAT_LOCK_MUTEX 0x39A0
|
||||
#define FS_OFFSET_410_EXFAT_UNLOCK_MUTEX 0x3A0C
|
||||
|
||||
#define FS_OFFSET_410_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||
#define FS_OFFSET_410_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x9DBAC
|
||||
|
||||
// Misc Data
|
||||
|
1
emummc/source/FS/offsets/500.h
vendored
1
emummc/source/FS/offsets/500.h
vendored
@ -34,6 +34,7 @@
|
||||
#define FS_OFFSET_500_LOCK_MUTEX 0x4080
|
||||
#define FS_OFFSET_500_UNLOCK_MUTEX 0x40D0
|
||||
|
||||
#define FS_OFFSET_500_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||
#define FS_OFFSET_500_SDMMC_WRAPPER_CONTROLLER_CLOSE 0xC9380
|
||||
|
||||
// Misc Data
|
||||
|
1
emummc/source/FS/offsets/500_exfat.h
vendored
1
emummc/source/FS/offsets/500_exfat.h
vendored
@ -34,6 +34,7 @@
|
||||
#define FS_OFFSET_500_EXFAT_LOCK_MUTEX 0x4080
|
||||
#define FS_OFFSET_500_EXFAT_UNLOCK_MUTEX 0x40D0
|
||||
|
||||
#define FS_OFFSET_500_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||
#define FS_OFFSET_500_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0xC9380
|
||||
|
||||
// Misc Data
|
||||
|
1
emummc/source/FS/offsets/510.h
vendored
1
emummc/source/FS/offsets/510.h
vendored
@ -34,6 +34,7 @@
|
||||
#define FS_OFFSET_510_LOCK_MUTEX 0x4080
|
||||
#define FS_OFFSET_510_UNLOCK_MUTEX 0x40D0
|
||||
|
||||
#define FS_OFFSET_510_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||
#define FS_OFFSET_510_SDMMC_WRAPPER_CONTROLLER_CLOSE 0xC9750
|
||||
|
||||
// Misc Data
|
||||
|
1
emummc/source/FS/offsets/510_exfat.h
vendored
1
emummc/source/FS/offsets/510_exfat.h
vendored
@ -34,6 +34,7 @@
|
||||
#define FS_OFFSET_510_EXFAT_LOCK_MUTEX 0x4080
|
||||
#define FS_OFFSET_510_EXFAT_UNLOCK_MUTEX 0x40D0
|
||||
|
||||
#define FS_OFFSET_510_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||
#define FS_OFFSET_510_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0xC9750
|
||||
|
||||
// Misc Data
|
||||
|
1
emummc/source/FS/offsets/600.h
vendored
1
emummc/source/FS/offsets/600.h
vendored
@ -34,6 +34,7 @@
|
||||
#define FS_OFFSET_600_LOCK_MUTEX 0x1412C0
|
||||
#define FS_OFFSET_600_UNLOCK_MUTEX 0x141310
|
||||
|
||||
#define FS_OFFSET_600_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||
#define FS_OFFSET_600_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x148500
|
||||
|
||||
// Misc Data
|
||||
|
1
emummc/source/FS/offsets/600_exfat.h
vendored
1
emummc/source/FS/offsets/600_exfat.h
vendored
@ -34,6 +34,7 @@
|
||||
#define FS_OFFSET_600_EXFAT_LOCK_MUTEX 0x14C9C0
|
||||
#define FS_OFFSET_600_EXFAT_UNLOCK_MUTEX 0x14CA10
|
||||
|
||||
#define FS_OFFSET_600_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||
#define FS_OFFSET_600_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x153C00
|
||||
|
||||
// Misc Data
|
||||
|
1
emummc/source/FS/offsets/700.h
vendored
1
emummc/source/FS/offsets/700.h
vendored
@ -34,6 +34,7 @@
|
||||
#define FS_OFFSET_700_LOCK_MUTEX 0x148A90
|
||||
#define FS_OFFSET_700_UNLOCK_MUTEX 0x148AE0
|
||||
|
||||
#define FS_OFFSET_700_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||
#define FS_OFFSET_700_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x14FD50
|
||||
|
||||
// Misc Data
|
||||
|
1
emummc/source/FS/offsets/700_exfat.h
vendored
1
emummc/source/FS/offsets/700_exfat.h
vendored
@ -34,6 +34,7 @@
|
||||
#define FS_OFFSET_700_EXFAT_LOCK_MUTEX 0x154040
|
||||
#define FS_OFFSET_700_EXFAT_UNLOCK_MUTEX 0x154090
|
||||
|
||||
#define FS_OFFSET_700_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||
#define FS_OFFSET_700_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x15B300
|
||||
|
||||
// Misc Data
|
||||
|
1
emummc/source/FS/offsets/800.h
vendored
1
emummc/source/FS/offsets/800.h
vendored
@ -34,6 +34,7 @@
|
||||
#define FS_OFFSET_800_LOCK_MUTEX 0x14B6D0
|
||||
#define FS_OFFSET_800_UNLOCK_MUTEX 0x14B720
|
||||
|
||||
#define FS_OFFSET_800_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||
#define FS_OFFSET_800_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1529E0
|
||||
|
||||
// Misc Data
|
||||
|
1
emummc/source/FS/offsets/800_exfat.h
vendored
1
emummc/source/FS/offsets/800_exfat.h
vendored
@ -34,6 +34,7 @@
|
||||
#define FS_OFFSET_800_EXFAT_LOCK_MUTEX 0x156C80
|
||||
#define FS_OFFSET_800_EXFAT_UNLOCK_MUTEX 0x156CD0
|
||||
|
||||
#define FS_OFFSET_800_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||
#define FS_OFFSET_800_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x15DF90
|
||||
|
||||
// Misc Data
|
||||
|
1
emummc/source/FS/offsets/810.h
vendored
1
emummc/source/FS/offsets/810.h
vendored
@ -34,6 +34,7 @@
|
||||
#define FS_OFFSET_810_LOCK_MUTEX 0x14B6D0
|
||||
#define FS_OFFSET_810_UNLOCK_MUTEX 0x14B720
|
||||
|
||||
#define FS_OFFSET_810_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||
#define FS_OFFSET_810_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1529E0
|
||||
|
||||
// Misc Data
|
||||
|
1
emummc/source/FS/offsets/810_exfat.h
vendored
1
emummc/source/FS/offsets/810_exfat.h
vendored
@ -34,6 +34,7 @@
|
||||
#define FS_OFFSET_810_EXFAT_LOCK_MUTEX 0x156C80
|
||||
#define FS_OFFSET_810_EXFAT_UNLOCK_MUTEX 0x156CD0
|
||||
|
||||
#define FS_OFFSET_810_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||
#define FS_OFFSET_810_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x15DF90
|
||||
|
||||
// Misc Data
|
||||
|
1
emummc/source/FS/offsets/900.h
vendored
1
emummc/source/FS/offsets/900.h
vendored
@ -34,6 +34,7 @@
|
||||
#define FS_OFFSET_900_LOCK_MUTEX 0x25280
|
||||
#define FS_OFFSET_900_UNLOCK_MUTEX 0x252D0
|
||||
|
||||
#define FS_OFFSET_900_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||
#define FS_OFFSET_900_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x137740
|
||||
|
||||
// Misc Data
|
||||
|
1
emummc/source/FS/offsets/900_exfat.h
vendored
1
emummc/source/FS/offsets/900_exfat.h
vendored
@ -34,6 +34,7 @@
|
||||
#define FS_OFFSET_900_EXFAT_LOCK_MUTEX 0x25280
|
||||
#define FS_OFFSET_900_EXFAT_UNLOCK_MUTEX 0x252D0
|
||||
|
||||
#define FS_OFFSET_900_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||
#define FS_OFFSET_900_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x137740
|
||||
|
||||
// Misc Data
|
||||
|
1
emummc/source/FS/offsets/910.h
vendored
1
emummc/source/FS/offsets/910.h
vendored
@ -34,6 +34,7 @@
|
||||
#define FS_OFFSET_910_LOCK_MUTEX 0x25280
|
||||
#define FS_OFFSET_910_UNLOCK_MUTEX 0x252D0
|
||||
|
||||
#define FS_OFFSET_910_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||
#define FS_OFFSET_910_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x137750
|
||||
|
||||
// Misc Data
|
||||
|
1
emummc/source/FS/offsets/910_exfat.h
vendored
1
emummc/source/FS/offsets/910_exfat.h
vendored
@ -34,6 +34,7 @@
|
||||
#define FS_OFFSET_910_EXFAT_LOCK_MUTEX 0x25280
|
||||
#define FS_OFFSET_910_EXFAT_UNLOCK_MUTEX 0x252D0
|
||||
|
||||
#define FS_OFFSET_910_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||
#define FS_OFFSET_910_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x137750
|
||||
|
||||
// Misc Data
|
||||
|
4
emummc/source/emmc/mmc.h
vendored
4
emummc/source/emmc/mmc.h
vendored
@ -136,8 +136,8 @@ c : clear by read
|
||||
#define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */
|
||||
#define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */
|
||||
#define R1_ERASE_RESET (1 << 13) /* sr, c */
|
||||
#define R1_STATUS(x) (x & 0xFFFFE000)
|
||||
#define R1_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */
|
||||
#define R1_STATUS(x) ((x) & 0xFFFFE000)
|
||||
#define R1_CURRENT_STATE(x) (((x) & 0x00001E00) >> 9) /* sx, b (4 bits) */
|
||||
#define R1_READY_FOR_DATA (1 << 8) /* sx, a */
|
||||
#define R1_SWITCH_ERROR (1 << 7) /* sx, c */
|
||||
#define R1_EXCEPTION_EVENT (1 << 6) /* sr, a */
|
||||
|
6
emummc/source/emmc/sd.h
vendored
6
emummc/source/emmc/sd.h
vendored
@ -1,6 +1,4 @@
|
||||
/*
|
||||
* include/linux/mmc/sd.h
|
||||
*
|
||||
* Copyright (c) 2005-2007 Pierre Ossman, All Rights Reserved.
|
||||
* Copyright (c) 2018 CTCaer
|
||||
*
|
||||
@ -10,8 +8,8 @@
|
||||
* your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef LINUX_MMC_SD_H
|
||||
#define LINUX_MMC_SD_H
|
||||
#ifndef MMC_SD_H
|
||||
#define MMC_SD_H
|
||||
|
||||
/* SD commands type argument response */
|
||||
/* class 0 */
|
||||
|
128
emummc/source/emmc/sdmmc.c
vendored
128
emummc/source/emmc/sdmmc.c
vendored
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@ -156,7 +156,7 @@ int sdmmc_calculate_fitting_dma_index(sdmmc_accessor_t *_this, unsigned int num_
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sdmmc_memcpy_buf = true;
|
||||
return dma_buf_idx;
|
||||
}
|
||||
@ -164,15 +164,18 @@ int sdmmc_calculate_fitting_dma_index(sdmmc_accessor_t *_this, unsigned int num_
|
||||
static int _sdmmc_storage_check_result(u32 res)
|
||||
{
|
||||
//Error mask:
|
||||
//R1_OUT_OF_RANGE, R1_ADDRESS_ERROR, R1_BLOCK_LEN_ERROR,
|
||||
//R1_ERASE_SEQ_ERROR, R1_ERASE_PARAM, R1_WP_VIOLATION,
|
||||
//R1_LOCK_UNLOCK_FAILED, R1_COM_CRC_ERROR, R1_ILLEGAL_COMMAND,
|
||||
//R1_CARD_ECC_FAILED, R1_CC_ERROR, R1_ERROR, R1_CID_CSD_OVERWRITE,
|
||||
//R1_WP_ERASE_SKIP, R1_ERASE_RESET, R1_SWITCH_ERROR
|
||||
if (!(res & 0xFDF9A080))
|
||||
return 1;
|
||||
//TODO: R1_SWITCH_ERROR we can skip for certain card types.
|
||||
return 0;
|
||||
//TODO: R1_SWITCH_ERROR can be skipped for certain card types.
|
||||
if (res &
|
||||
(R1_OUT_OF_RANGE | R1_ADDRESS_ERROR | R1_BLOCK_LEN_ERROR |
|
||||
R1_ERASE_SEQ_ERROR | R1_ERASE_PARAM | R1_WP_VIOLATION |
|
||||
R1_LOCK_UNLOCK_FAILED | R1_COM_CRC_ERROR | R1_ILLEGAL_COMMAND |
|
||||
R1_CARD_ECC_FAILED | R1_CC_ERROR | R1_ERROR |
|
||||
R1_CID_CSD_OVERWRITE | R1_WP_ERASE_SKIP | R1_ERASE_RESET |
|
||||
R1_SWITCH_ERROR))
|
||||
return 0;
|
||||
|
||||
// No errors.
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _sdmmc_storage_execute_cmd_type1_ex(sdmmc_storage_t *storage, u32 *resp, u32 cmd, u32 arg, u32 check_busy, u32 expected_state, u32 mask)
|
||||
@ -285,14 +288,23 @@ int sdmmc_storage_end(sdmmc_storage_t *storage)
|
||||
|
||||
sdmmc_end(storage->sdmmc);
|
||||
|
||||
storage->initialized = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _sdmmc_storage_readwrite(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf, u32 is_write)
|
||||
{
|
||||
u8 *bbuf = (u8 *)buf;
|
||||
bool first_reinit = false;
|
||||
while (num_sectors)
|
||||
u32 sct_off = sector;
|
||||
u32 sct_total = num_sectors;
|
||||
bool first_reinit = true;
|
||||
|
||||
// Exit if not initialized.
|
||||
if (!storage->initialized)
|
||||
return 0;
|
||||
|
||||
while (sct_total)
|
||||
{
|
||||
u32 blkcnt = 0;
|
||||
// Retry 5 times if failed.
|
||||
@ -300,7 +312,7 @@ static int _sdmmc_storage_readwrite(sdmmc_storage_t *storage, u32 sector, u32 nu
|
||||
do
|
||||
{
|
||||
reinit_try:
|
||||
if (_sdmmc_storage_readwrite_ex(storage, &blkcnt, sector, MIN(num_sectors, 0xFFFF), bbuf, is_write))
|
||||
if (_sdmmc_storage_readwrite_ex(storage, &blkcnt, sct_off, MIN(sct_total, 0xFFFF), bbuf, is_write))
|
||||
goto out;
|
||||
else
|
||||
retries--;
|
||||
@ -313,24 +325,33 @@ reinit_try:
|
||||
{
|
||||
int res;
|
||||
|
||||
if (!first_reinit)
|
||||
if (first_reinit)
|
||||
res = nx_sd_initialize(true);
|
||||
else
|
||||
res = nx_sd_init_retry(true);
|
||||
|
||||
// Reset values for a retry.
|
||||
blkcnt = 0;
|
||||
retries = 3;
|
||||
first_reinit = true;
|
||||
first_reinit = false;
|
||||
|
||||
// If succesful reinit, restart xfer.
|
||||
if (res)
|
||||
{
|
||||
bbuf = (u8 *)buf;
|
||||
sct_off = sector;
|
||||
sct_total = num_sectors;
|
||||
|
||||
goto reinit_try;
|
||||
}
|
||||
}
|
||||
|
||||
// Failed.
|
||||
return 0;
|
||||
|
||||
out:
|
||||
DPRINTF("readwrite: %08X\n", blkcnt);
|
||||
sector += blkcnt;
|
||||
num_sectors -= blkcnt;
|
||||
sct_off += blkcnt;
|
||||
sct_total -= blkcnt;
|
||||
bbuf += 512 * blkcnt;
|
||||
}
|
||||
|
||||
@ -459,9 +480,11 @@ static int _mmc_storage_get_op_cond_inner(sdmmc_storage_t *storage, u32 *pout, u
|
||||
case SDMMC_POWER_1_8:
|
||||
arg = SD_OCR_CCS | SD_OCR_VDD_18;
|
||||
break;
|
||||
|
||||
case SDMMC_POWER_3_3:
|
||||
arg = SD_OCR_CCS | SD_OCR_VDD_27_34;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -518,6 +541,7 @@ static void _mmc_storage_parse_cid(sdmmc_storage_t *storage)
|
||||
storage->cid.fwrev = unstuff_bits(raw_cid, 40, 4);
|
||||
storage->cid.serial = unstuff_bits(raw_cid, 16, 24);
|
||||
break;
|
||||
|
||||
case 2: /* MMC v2.0 - v2.2 */
|
||||
case 3: /* MMC v3.1 - v3.3 */
|
||||
case 4: /* MMC v4 */
|
||||
@ -527,6 +551,7 @@ static void _mmc_storage_parse_cid(sdmmc_storage_t *storage)
|
||||
storage->cid.prv = unstuff_bits(raw_cid, 48, 8);
|
||||
storage->cid.serial = unstuff_bits(raw_cid, 16, 32);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -571,6 +596,10 @@ static void _mmc_storage_parse_ext_csd(sdmmc_storage_t *storage, u8 *buf)
|
||||
storage->ext_csd.bkops_en = buf[EXT_CSD_BKOPS_EN];
|
||||
storage->ext_csd.bkops_status = buf[EXT_CSD_BKOPS_STATUS];
|
||||
|
||||
storage->ext_csd.pre_eol_info = buf[EXT_CSD_PRE_EOL_INFO];
|
||||
storage->ext_csd.dev_life_est_a = buf[EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A];
|
||||
storage->ext_csd.dev_life_est_b = buf[EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B];
|
||||
|
||||
storage->sec_cnt = *(u32 *)&buf[EXT_CSD_SEC_CNT];
|
||||
}
|
||||
|
||||
@ -613,6 +642,7 @@ static int _mmc_storage_switch_buswidth(sdmmc_storage_t *storage, u32 bus_width)
|
||||
case SDMMC_BUS_WIDTH_4:
|
||||
arg = SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_4);
|
||||
break;
|
||||
|
||||
case SDMMC_BUS_WIDTH_8:
|
||||
arg = SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_8);
|
||||
break;
|
||||
@ -671,7 +701,7 @@ static int _mmc_storage_enable_HS400(sdmmc_storage_t *storage)
|
||||
if (!_mmc_storage_enable_HS200(storage))
|
||||
return 0;
|
||||
|
||||
sdmmc_set_tap_value(storage->sdmmc);
|
||||
sdmmc_save_tap_value(storage->sdmmc);
|
||||
|
||||
if (!_mmc_storage_enable_HS(storage, 0))
|
||||
return 0;
|
||||
@ -727,7 +757,7 @@ int sdmmc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_wid
|
||||
storage->sdmmc = sdmmc;
|
||||
storage->rca = 2; //TODO: this could be a config item.
|
||||
|
||||
if (!sdmmc_init(sdmmc, SDMMC_4, SDMMC_POWER_1_8, SDMMC_BUS_WIDTH_1, SDHCI_TIMING_MMC_ID, SDMMC_AUTO_CAL_DISABLE))
|
||||
if (!sdmmc_init(sdmmc, SDMMC_4, SDMMC_POWER_1_8, SDMMC_BUS_WIDTH_1, SDHCI_TIMING_MMC_ID, SDMMC_POWER_SAVE_DISABLE))
|
||||
return 0;
|
||||
DPRINTF("[MMC] after init\n");
|
||||
|
||||
@ -798,7 +828,9 @@ DPRINTF("[MMC] BKOPS enabled\n");
|
||||
return 0;
|
||||
DPRINTF("[MMC] succesfully switched to HS mode\n");
|
||||
|
||||
sdmmc_card_clock_ctrl(storage->sdmmc, SDMMC_AUTO_CAL_ENABLE);
|
||||
sdmmc_card_clock_powersave(storage->sdmmc, SDMMC_POWER_SAVE_ENABLE);
|
||||
|
||||
storage->initialized = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -812,6 +844,7 @@ int sdmmc_storage_set_mmc_partition(sdmmc_storage_t *storage, u32 partition)
|
||||
return 0;
|
||||
|
||||
storage->partition = partition;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -850,7 +883,7 @@ static int _sd_storage_send_if_cond(sdmmc_storage_t *storage)
|
||||
return (resp & 0xFF) == 0xAA ? 0 : 2;
|
||||
}
|
||||
|
||||
static int _sd_storage_get_op_cond_once(sdmmc_storage_t *storage, u32 *cond, int is_version_1, int supports_low_voltage)
|
||||
static int _sd_storage_get_op_cond_once(sdmmc_storage_t *storage, u32 *cond, int is_version_1, int bus_low_voltage_support)
|
||||
{
|
||||
sdmmc_cmd_t cmdbuf;
|
||||
// Support for Current > 150mA
|
||||
@ -858,7 +891,7 @@ static int _sd_storage_get_op_cond_once(sdmmc_storage_t *storage, u32 *cond, int
|
||||
// Support for handling block-addressed SDHC cards
|
||||
arg |= (~is_version_1 & 1) ? SD_OCR_CCS : 0;
|
||||
// Support for 1.8V
|
||||
arg |= (supports_low_voltage & ~is_version_1 & 1) ? SD_OCR_S18R : 0;
|
||||
arg |= (bus_low_voltage_support & ~is_version_1 & 1) ? SD_OCR_S18R : 0;
|
||||
// This is needed for most cards. Do not set bit7 even if 1.8V is supported.
|
||||
arg |= SD_OCR_VDD_32_33;
|
||||
sdmmc_init_cmd(&cmdbuf, SD_APP_OP_COND, arg, SDMMC_RSP_TYPE_3, 0);
|
||||
@ -868,22 +901,24 @@ static int _sd_storage_get_op_cond_once(sdmmc_storage_t *storage, u32 *cond, int
|
||||
return sdmmc_get_rsp(storage->sdmmc, cond, 4, SDMMC_RSP_TYPE_3);
|
||||
}
|
||||
|
||||
static int _sd_storage_get_op_cond(sdmmc_storage_t *storage, int is_version_1, int supports_low_voltage)
|
||||
static int _sd_storage_get_op_cond(sdmmc_storage_t *storage, int is_version_1, int bus_low_voltage_support)
|
||||
{
|
||||
u64 timeout = get_tmr_ms() + 1500;
|
||||
|
||||
while (1)
|
||||
{
|
||||
u32 cond = 0;
|
||||
if (!_sd_storage_get_op_cond_once(storage, &cond, is_version_1, supports_low_voltage))
|
||||
if (!_sd_storage_get_op_cond_once(storage, &cond, is_version_1, bus_low_voltage_support))
|
||||
break;
|
||||
if (cond & MMC_CARD_BUSY)
|
||||
{
|
||||
DPRINTF("[SD] cond: %08X, lv: %d\n", cond, bus_low_voltage_support);
|
||||
|
||||
if (cond & SD_OCR_CCS)
|
||||
storage->has_sector_access = 1;
|
||||
|
||||
// Check if card supports 1.8V signaling.
|
||||
if (cond & SD_ROCR_S18A && supports_low_voltage)
|
||||
if (cond & SD_ROCR_S18A && bus_low_voltage_support)
|
||||
{
|
||||
//The low voltage regulator configuration is valid for SDMMC1 only.
|
||||
if (storage->sdmmc->id == SDMMC_1 &&
|
||||
@ -896,6 +931,10 @@ static int _sd_storage_get_op_cond(sdmmc_storage_t *storage, int is_version_1, i
|
||||
DPRINTF("-> switched to low voltage\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINTF("[SD] no low voltage support\n");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -1050,12 +1089,15 @@ void _sd_storage_set_current_limit(sdmmc_storage_t *storage, u16 current_limit,
|
||||
case SD_SET_CURRENT_LIMIT_800:
|
||||
DPRINTF("[SD] power limit raised to 800mA\n");
|
||||
break;
|
||||
|
||||
case SD_SET_CURRENT_LIMIT_600:
|
||||
DPRINTF("[SD] power limit raised to 600mA\n");
|
||||
break;
|
||||
|
||||
case SD_SET_CURRENT_LIMIT_400:
|
||||
DPRINTF("[SD] power limit raised to 400mA\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
case SD_SET_CURRENT_LIMIT_200:
|
||||
DPRINTF("[SD] power limit defaulted to 200mA\n");
|
||||
@ -1068,7 +1110,7 @@ int _sd_storage_enable_highspeed(sdmmc_storage_t *storage, u32 hs_type, u8 *buf)
|
||||
{
|
||||
if (!_sd_storage_switch(storage, buf, SD_SWITCH_CHECK, 0, hs_type))
|
||||
return 0;
|
||||
DPRINTF("[SD] supports switch to (U)HS mode\n");
|
||||
DPRINTF("[SD] supports (U)HS mode: %d\n", buf[16] & 0xF);
|
||||
|
||||
u32 type_out = buf[16] & 0xF;
|
||||
if (type_out != hs_type)
|
||||
@ -1104,6 +1146,7 @@ int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type, u8 *buf)
|
||||
|
||||
u8 access_mode = buf[13];
|
||||
u16 current_limit = buf[7] | buf[6] << 8;
|
||||
DPRINTF("[SD] access: %02X, current: %02X\n", access_mode, current_limit);
|
||||
|
||||
// Try to raise the current limit to let the card perform better.
|
||||
_sd_storage_set_current_limit(storage, current_limit, buf);
|
||||
@ -1142,7 +1185,7 @@ DPRINTF("[SD] bus speed set to SDR50\n");
|
||||
if (access_mode & SD_MODE_UHS_SDR25)
|
||||
{
|
||||
type = SDHCI_TIMING_UHS_SDR25;
|
||||
hs_type = UHS_SDR50_BUS_SPEED;
|
||||
hs_type = UHS_SDR25_BUS_SPEED;
|
||||
DPRINTF("[SD] bus speed set to SDR25\n");
|
||||
storage->csd.busspeed = 25;
|
||||
break;
|
||||
@ -1155,6 +1198,7 @@ DPRINTF("[SD] bus speed set to SDR25\n");
|
||||
DPRINTF("[SD] bus speed set to SDR12\n");
|
||||
storage->csd.busspeed = 12;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
@ -1165,10 +1209,10 @@ DPRINTF("[SD] bus speed set to SDR12\n");
|
||||
DPRINTF("[SD] card accepted UHS\n");
|
||||
if (!sdmmc_setup_clock(storage->sdmmc, type))
|
||||
return 0;
|
||||
DPRINTF("[SD] setup clock\n");
|
||||
DPRINTF("[SD] after setup clock\n");
|
||||
if (!sdmmc_tuning_execute(storage->sdmmc, type, MMC_SEND_TUNING_BLOCK))
|
||||
return 0;
|
||||
DPRINTF("[SD] config tuning\n");
|
||||
DPRINTF("[SD] after tuning\n");
|
||||
return _sdmmc_storage_check_status(storage);
|
||||
}
|
||||
|
||||
@ -1227,6 +1271,7 @@ static void _sd_storage_parse_csd(sdmmc_storage_t *storage)
|
||||
case 0:
|
||||
storage->csd.capacity = (1 + unstuff_bits(raw_csd, 62, 12)) << (unstuff_bits(raw_csd, 47, 3) + 2);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
storage->csd.c_size = (1 + unstuff_bits(raw_csd, 48, 22));
|
||||
storage->csd.capacity = storage->csd.c_size << 10;
|
||||
@ -1235,7 +1280,7 @@ static void _sd_storage_parse_csd(sdmmc_storage_t *storage)
|
||||
}
|
||||
}
|
||||
|
||||
static bool _sdmmc_storage_supports_low_voltage(u32 bus_width, u32 type)
|
||||
static bool _sdmmc_storage_get_low_voltage_support(u32 bus_width, u32 type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
@ -1261,7 +1306,7 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_widt
|
||||
memset(storage, 0, sizeof(sdmmc_storage_t));
|
||||
storage->sdmmc = sdmmc;
|
||||
|
||||
if (!sdmmc_init(sdmmc, SDMMC_1, SDMMC_POWER_3_3, SDMMC_BUS_WIDTH_1, SDHCI_TIMING_SD_ID, SDMMC_AUTO_CAL_DISABLE))
|
||||
if (!sdmmc_init(sdmmc, SDMMC_1, SDMMC_POWER_3_3, SDMMC_BUS_WIDTH_1, SDHCI_TIMING_SD_ID, SDMMC_POWER_SAVE_DISABLE))
|
||||
return 0;
|
||||
DPRINTF("[SD] after init\n");
|
||||
|
||||
@ -1276,9 +1321,9 @@ DPRINTF("[SD] went to idle state\n");
|
||||
return 0;
|
||||
DPRINTF("[SD] after send if cond\n");
|
||||
|
||||
bool supports_low_voltage = _sdmmc_storage_supports_low_voltage(bus_width, type);
|
||||
bool bus_low_voltage_support = _sdmmc_storage_get_low_voltage_support(bus_width, type);
|
||||
|
||||
if (!_sd_storage_get_op_cond(storage, is_version_1, supports_low_voltage))
|
||||
if (!_sd_storage_get_op_cond(storage, is_version_1, bus_low_voltage_support))
|
||||
return 0;
|
||||
DPRINTF("[SD] got op cond\n");
|
||||
|
||||
@ -1356,7 +1401,7 @@ DPRINTF("[SD] SD does not support wide bus width\n");
|
||||
return 0;
|
||||
DPRINTF("[SD] enabled UHS\n");
|
||||
|
||||
sdmmc_card_clock_ctrl(sdmmc, SDMMC_AUTO_CAL_ENABLE);
|
||||
sdmmc_card_clock_powersave(sdmmc, SDMMC_POWER_SAVE_ENABLE);
|
||||
}
|
||||
else if (type != SDHCI_TIMING_SD_DS12 && (storage->scr.sda_vsn & 0xF) != 0)
|
||||
{
|
||||
@ -1369,12 +1414,15 @@ DPRINTF("[SD] enabled HS\n");
|
||||
case SDMMC_BUS_WIDTH_4:
|
||||
storage->csd.busspeed = 25;
|
||||
break;
|
||||
|
||||
case SDMMC_BUS_WIDTH_1:
|
||||
storage->csd.busspeed = 6;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
storage->initialized = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1414,17 +1462,19 @@ int sdmmc_storage_init_gc(sdmmc_storage_t *storage, sdmmc_t *sdmmc)
|
||||
memset(storage, 0, sizeof(sdmmc_storage_t));
|
||||
storage->sdmmc = sdmmc;
|
||||
|
||||
if (!sdmmc_init(sdmmc, SDMMC_2, SDMMC_POWER_1_8, SDMMC_BUS_WIDTH_8, SDHCI_TIMING_MMC_DDR52, SDMMC_AUTO_CAL_DISABLE))
|
||||
if (!sdmmc_init(sdmmc, SDMMC_2, SDMMC_POWER_1_8, SDMMC_BUS_WIDTH_8, SDHCI_TIMING_MMC_HS102, SDMMC_POWER_SAVE_DISABLE))
|
||||
return 0;
|
||||
DPRINTF("[gc] after init\n");
|
||||
|
||||
usleep(1000 + (10000 + sdmmc->divisor - 1) / sdmmc->divisor);
|
||||
|
||||
if (!sdmmc_tuning_execute(storage->sdmmc, SDHCI_TIMING_MMC_DDR52, MMC_SEND_TUNING_BLOCK_HS200))
|
||||
if (!sdmmc_tuning_execute(storage->sdmmc, SDHCI_TIMING_MMC_HS102, MMC_SEND_TUNING_BLOCK_HS200))
|
||||
return 0;
|
||||
DPRINTF("[gc] after tuning\n");
|
||||
|
||||
sdmmc_card_clock_ctrl(sdmmc, SDMMC_AUTO_CAL_ENABLE);
|
||||
sdmmc_card_clock_powersave(sdmmc, SDMMC_POWER_SAVE_ENABLE);
|
||||
|
||||
storage->initialized = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
11
emummc/source/emmc/sdmmc.h
vendored
11
emummc/source/emmc/sdmmc.h
vendored
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 CTCaer
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@ -54,16 +54,19 @@ typedef struct _mmc_csd
|
||||
|
||||
typedef struct _mmc_ext_csd
|
||||
{
|
||||
u8 rev;
|
||||
u32 sectors;
|
||||
int bkops; /* background support bit */
|
||||
int bkops_en; /* manual bkops enable bit */
|
||||
u8 rev;
|
||||
u8 ext_struct; /* 194 */
|
||||
u8 card_type; /* 196 */
|
||||
u8 bkops_status; /* 246 */
|
||||
u16 dev_version;
|
||||
u8 pre_eol_info;
|
||||
u8 dev_life_est_a;
|
||||
u8 dev_life_est_b;
|
||||
u8 boot_mult;
|
||||
u8 rpmb_mult;
|
||||
u16 dev_version;
|
||||
} mmc_ext_csd_t;
|
||||
|
||||
typedef struct _sd_scr
|
||||
@ -81,6 +84,7 @@ typedef struct _sd_ssr
|
||||
u8 uhs_grade;
|
||||
u8 video_class;
|
||||
u8 app_class;
|
||||
u32 protected_size;
|
||||
} sd_ssr_t;
|
||||
|
||||
/*! SDMMC storage context. */
|
||||
@ -99,6 +103,7 @@ typedef struct _sdmmc_storage_t
|
||||
mmc_csd_t csd;
|
||||
mmc_ext_csd_t ext_csd;
|
||||
sd_scr_t scr;
|
||||
int initialized;
|
||||
} sdmmc_storage_t;
|
||||
|
||||
extern sdmmc_accessor_t *_current_accessor;
|
||||
|
428
emummc/source/emmc/sdmmc_driver.c
vendored
428
emummc/source/emmc/sdmmc_driver.c
vendored
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@ -58,12 +58,15 @@ static int _sdmmc_set_io_power(sdmmc_t *sdmmc, u32 power)
|
||||
case SDMMC_POWER_OFF:
|
||||
sdmmc->regs->pwrcon &= ~SDHCI_POWER_ON;
|
||||
break;
|
||||
|
||||
case SDMMC_POWER_1_8:
|
||||
sdmmc->regs->pwrcon = SDHCI_POWER_180;
|
||||
break;
|
||||
|
||||
case SDMMC_POWER_3_3:
|
||||
sdmmc->regs->pwrcon = SDHCI_POWER_330;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -96,7 +99,7 @@ void sdmmc_set_bus_width(sdmmc_t *sdmmc, u32 bus_width)
|
||||
sdmmc->regs->hostctl = host_control | SDHCI_CTRL_8BITBUS;
|
||||
}
|
||||
|
||||
void sdmmc_set_tap_value(sdmmc_t *sdmmc)
|
||||
void sdmmc_save_tap_value(sdmmc_t *sdmmc)
|
||||
{
|
||||
sdmmc->venclkctl_tap = sdmmc->regs->venclkctl >> 16;
|
||||
sdmmc->venclkctl_set = 1;
|
||||
@ -105,7 +108,7 @@ void sdmmc_set_tap_value(sdmmc_t *sdmmc)
|
||||
static int _sdmmc_config_tap_val(sdmmc_t *sdmmc, u32 type)
|
||||
{
|
||||
const u32 dqs_trim_val = 0x28;
|
||||
const u32 tap_values[] = { 4, 0, 3, 0 };
|
||||
const u32 tap_values_t210[] = { 4, 0, 3, 0 };
|
||||
|
||||
u32 tap_val = 0;
|
||||
|
||||
@ -122,36 +125,49 @@ static int _sdmmc_config_tap_val(sdmmc_t *sdmmc, u32 type)
|
||||
tap_val = sdmmc->venclkctl_tap;
|
||||
}
|
||||
else
|
||||
{
|
||||
tap_val = tap_values[sdmmc->id];
|
||||
}
|
||||
tap_val = sdmmc->t210b01 ? 11 : tap_values_t210[sdmmc->id];
|
||||
|
||||
sdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & 0xFF00FFFF) | (tap_val << 16);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _sdmmc_get_clkcon(sdmmc_t *sdmmc)
|
||||
static int _sdmmc_commit_changes(sdmmc_t *sdmmc)
|
||||
{
|
||||
return sdmmc->regs->clkcon;
|
||||
}
|
||||
|
||||
static void _sdmmc_pad_config_fallback(sdmmc_t *sdmmc, u32 power)
|
||||
{
|
||||
_sdmmc_get_clkcon(sdmmc);
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
switch (sdmmc->id)
|
||||
{
|
||||
case SDMMC_1: // 33 Ohm 2X Driver.
|
||||
if (power == SDMMC_POWER_OFF)
|
||||
break;
|
||||
u32 sdmmc1_pad_cfg = APB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL) & 0xF8080FFF;
|
||||
if (power == SDMMC_POWER_1_8)
|
||||
APB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL) = sdmmc1_pad_cfg | (0xB0F << 12); // Up: 11, Dn: 15. For 33 ohm.
|
||||
if (sdmmc->t210b01)
|
||||
sdmmc1_pad_cfg |= (0x808 << 12); // Up: 8, Dn: 8. For 33 ohm.
|
||||
else if (power == SDMMC_POWER_1_8)
|
||||
sdmmc1_pad_cfg |= (0xB0F << 12); // Up: 11, Dn: 15. For 33 ohm.
|
||||
else if (power == SDMMC_POWER_3_3)
|
||||
APB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL) = sdmmc1_pad_cfg | (0xC0C << 12); // Up: 12, Dn: 12. For 33 ohm.
|
||||
sdmmc1_pad_cfg |= (0xC0C << 12); // Up: 12, Dn: 12. For 33 ohm.
|
||||
APB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL) = sdmmc1_pad_cfg;
|
||||
(void)APB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL); // Commit write.
|
||||
break;
|
||||
|
||||
case SDMMC_2:
|
||||
case SDMMC_4: // 50 Ohm 2X Driver. PU:16, PD:16.
|
||||
APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) = (APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) & 0xFFFFC003) | 0x1040;
|
||||
if (sdmmc->t210b01)
|
||||
APB_MISC(APB_MISC_GP_EMMC2_PAD_CFGPADCTRL) = (APB_MISC(APB_MISC_GP_EMMC2_PAD_CFGPADCTRL) & 0xF8080FFF) | 0xA0A000;
|
||||
else
|
||||
APB_MISC(APB_MISC_GP_EMMC2_PAD_CFGPADCTRL) = (APB_MISC(APB_MISC_GP_EMMC2_PAD_CFGPADCTRL) & 0xFFFFC003) | 0x1040; // PU:16, PD:16.
|
||||
(void)APB_MISC(APB_MISC_GP_EMMC2_PAD_CFGPADCTRL);
|
||||
break;
|
||||
|
||||
case SDMMC_4: // 50 Ohm 2X Driver. PU:16, PD:16, B01: PU:10, PD:10.
|
||||
APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) =
|
||||
(APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) & 0xFFFFC003) | (sdmmc->t210b01 ? 0xA28 : 0x1040);
|
||||
(void)APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL); // Commit write.
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -169,13 +185,13 @@ static void _sdmmc_autocal_execute(sdmmc_t *sdmmc, u32 power)
|
||||
if (!(sdmmc->regs->sdmemcmppadctl & TEGRA_MMC_SDMEMCOMPPADCTRL_PAD_E_INPUT_PWRD))
|
||||
{
|
||||
sdmmc->regs->sdmemcmppadctl |= TEGRA_MMC_SDMEMCOMPPADCTRL_PAD_E_INPUT_PWRD;
|
||||
_sdmmc_get_clkcon(sdmmc);
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
usleep(1);
|
||||
}
|
||||
|
||||
// Enable auto calibration and start auto configuration.
|
||||
sdmmc->regs->autocalcfg |= TEGRA_MMC_AUTOCALCFG_AUTO_CAL_ENABLE | TEGRA_MMC_AUTOCALCFG_AUTO_CAL_START;
|
||||
_sdmmc_get_clkcon(sdmmc);
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
usleep(2);
|
||||
|
||||
u64 timeout = get_tmr_ms() + 10;
|
||||
@ -187,24 +203,18 @@ static void _sdmmc_autocal_execute(sdmmc_t *sdmmc, u32 power)
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
// Check if PU results are inside limits.
|
||||
// SDMMC1: CZ pads - 7-bit PU. SDMMC2/4: LV_CZ pads - 5-bit PU.
|
||||
u8 autocal_pu_status = sdmmc->regs->autocalsts & 0x7F;
|
||||
switch (sdmmc->id)
|
||||
{
|
||||
case SDMMC_1:
|
||||
if (!autocal_pu_status || autocal_pu_status == 0x7F)
|
||||
timeout = 0;
|
||||
break;
|
||||
case SDMMC_2:
|
||||
case SDMMC_4:
|
||||
autocal_pu_status &= 0x1F;
|
||||
if (!autocal_pu_status || autocal_pu_status == 0x1F)
|
||||
timeout = 0;
|
||||
break;
|
||||
}
|
||||
*/
|
||||
|
||||
#if 0
|
||||
// Check if Comp pad is open or short to ground.
|
||||
// SDMMC1: CZ pads - T210/T210B01: 7-bit/5-bit. SDMMC2/4: LV_CZ pads - 5-bit.
|
||||
u8 code_mask = (sdmmc->t210b01 || sdmmc->id != SDMMC_1) ? 0x1F : 0x7F;
|
||||
u8 autocal_pu_status = sdmmc->regs->autocalsts & code_mask;
|
||||
if (!autocal_pu_status)
|
||||
EPRINTF("SDMMC: Comp Pad short to gnd!");
|
||||
else if (autocal_pu_status == code_mask)
|
||||
EPRINTF("SDMMC: Comp Pad open!");
|
||||
#endif
|
||||
|
||||
// In case auto calibration fails, we load suggested standard values.
|
||||
if (!timeout)
|
||||
{
|
||||
@ -230,7 +240,7 @@ static int _sdmmc_dll_cal_execute(sdmmc_t *sdmmc)
|
||||
}
|
||||
|
||||
sdmmc->regs->vendllcalcfg |= TEGRA_MMC_DLLCAL_CFG_EN_CALIBRATE;
|
||||
_sdmmc_get_clkcon(sdmmc);
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
|
||||
u64 timeout = get_tmr_ms() + 5;
|
||||
while (sdmmc->regs->vendllcalcfg & TEGRA_MMC_DLLCAL_CFG_EN_CALIBRATE)
|
||||
@ -261,12 +271,21 @@ out:;
|
||||
static void _sdmmc_reset(sdmmc_t *sdmmc)
|
||||
{
|
||||
sdmmc->regs->swrst |= SDHCI_RESET_CMD | SDHCI_RESET_DATA;
|
||||
_sdmmc_get_clkcon(sdmmc);
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
u64 timeout = get_tmr_ms() + 2000;
|
||||
while ((sdmmc->regs->swrst & (SDHCI_RESET_CMD | SDHCI_RESET_DATA)) && get_tmr_ms() < timeout)
|
||||
;
|
||||
}
|
||||
|
||||
static void _sdmmc_reset_all(sdmmc_t *sdmmc)
|
||||
{
|
||||
sdmmc->regs->swrst |= SDHCI_RESET_ALL;
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
u32 timeout = get_tmr_ms() + 2000;//100ms
|
||||
while ((sdmmc->regs->swrst & SDHCI_RESET_ALL) && get_tmr_ms() < timeout)
|
||||
;
|
||||
}
|
||||
|
||||
int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type)
|
||||
{
|
||||
// Disable the SD clock if it was enabled, and reenable it later.
|
||||
@ -290,36 +309,41 @@ int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type)
|
||||
sdmmc->regs->hostctl &= ~SDHCI_CTRL_HISPD;
|
||||
sdmmc->regs->hostctl2 &= ~SDHCI_CTRL_VDD_180;
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_MMC_HS52:
|
||||
case SDHCI_TIMING_SD_HS25:
|
||||
sdmmc->regs->hostctl |= SDHCI_CTRL_HISPD;
|
||||
sdmmc->regs->hostctl2 &= ~SDHCI_CTRL_VDD_180;
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_MMC_HS200:
|
||||
case SDHCI_TIMING_UHS_SDR50: // T210 Errata for SDR50, the host must be set to SDR104.
|
||||
case SDHCI_TIMING_UHS_SDR104:
|
||||
case SDHCI_TIMING_UHS_SDR82:
|
||||
case SDHCI_TIMING_UHS_DDR50:
|
||||
case SDHCI_TIMING_MMC_DDR52:
|
||||
case SDHCI_TIMING_MMC_HS102:
|
||||
sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & SDHCI_CTRL_UHS_MASK) | UHS_SDR104_BUS_SPEED;
|
||||
sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_MMC_HS400:
|
||||
// Non standard.
|
||||
sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & SDHCI_CTRL_UHS_MASK) | HS400_BUS_SPEED;
|
||||
sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_UHS_SDR25:
|
||||
sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & SDHCI_CTRL_UHS_MASK) | UHS_SDR25_BUS_SPEED;
|
||||
sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_UHS_SDR12:
|
||||
sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & SDHCI_CTRL_UHS_MASK) | UHS_SDR12_BUS_SPEED;
|
||||
sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;
|
||||
break;
|
||||
}
|
||||
|
||||
_sdmmc_get_clkcon(sdmmc);
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
|
||||
u32 clock;
|
||||
u16 divisor;
|
||||
@ -349,10 +373,10 @@ int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type)
|
||||
static void _sdmmc_card_clock_enable(sdmmc_t *sdmmc)
|
||||
{
|
||||
// Recalibrate conditionally.
|
||||
if ((sdmmc->id == SDMMC_1) && !sdmmc->auto_cal_enabled)
|
||||
if (sdmmc->manual_cal && !sdmmc->powersave_enabled)
|
||||
_sdmmc_autocal_execute(sdmmc, sdmmc_get_io_power(sdmmc));
|
||||
|
||||
if (!sdmmc->auto_cal_enabled)
|
||||
if (!sdmmc->powersave_enabled)
|
||||
{
|
||||
if (!(sdmmc->regs->clkcon & SDHCI_CLOCK_CARD_EN))
|
||||
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
|
||||
@ -366,18 +390,17 @@ static void _sdmmc_sd_clock_disable(sdmmc_t *sdmmc)
|
||||
sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN;
|
||||
}
|
||||
|
||||
void sdmmc_card_clock_ctrl(sdmmc_t *sdmmc, int auto_cal_enable)
|
||||
void sdmmc_card_clock_powersave(sdmmc_t *sdmmc, int powersave_enable)
|
||||
{
|
||||
// Recalibrate periodically for SDMMC1.
|
||||
if ((sdmmc->id == SDMMC_1) && !auto_cal_enable && sdmmc->card_clock_enabled)
|
||||
if (sdmmc->manual_cal && !powersave_enable && sdmmc->card_clock_enabled)
|
||||
_sdmmc_autocal_execute(sdmmc, sdmmc_get_io_power(sdmmc));
|
||||
|
||||
sdmmc->auto_cal_enabled = auto_cal_enable;
|
||||
if (auto_cal_enable)
|
||||
sdmmc->powersave_enabled = powersave_enable;
|
||||
if (powersave_enable)
|
||||
{
|
||||
if (!(sdmmc->regs->clkcon & SDHCI_CLOCK_CARD_EN))
|
||||
return;
|
||||
sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN;
|
||||
if (sdmmc->regs->clkcon & SDHCI_CLOCK_CARD_EN)
|
||||
sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -398,6 +421,7 @@ static int _sdmmc_cache_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 size, u32 type)
|
||||
return 0;
|
||||
rsp[0] = sdmmc->regs->rspreg0;
|
||||
break;
|
||||
|
||||
case SDMMC_RSP_TYPE_2:
|
||||
if (size < 0x10)
|
||||
return 0;
|
||||
@ -426,9 +450,9 @@ static int _sdmmc_cache_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 size, u32 type)
|
||||
rsp[i - 1] |= (tempreg >> 24) & 0xFF;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
@ -449,6 +473,7 @@ int sdmmc_get_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 size, u32 type)
|
||||
return 0;
|
||||
rsp[0] = sdmmc->rsp[0];
|
||||
break;
|
||||
|
||||
case SDMMC_RSP_TYPE_2:
|
||||
if (size < 0x10)
|
||||
return 0;
|
||||
@ -457,9 +482,9 @@ int sdmmc_get_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 size, u32 type)
|
||||
rsp[2] = sdmmc->rsp[2];
|
||||
rsp[3] = sdmmc->rsp[3];
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
@ -467,7 +492,7 @@ int sdmmc_get_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 size, u32 type)
|
||||
|
||||
static int _sdmmc_wait_cmd_data_inhibit(sdmmc_t *sdmmc, bool wait_dat)
|
||||
{
|
||||
_sdmmc_get_clkcon(sdmmc);
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
|
||||
u64 timeout = get_tmr_ms() + 2000;
|
||||
while(sdmmc->regs->prnsts & SDHCI_CMD_INHIBIT)
|
||||
@ -493,7 +518,7 @@ static int _sdmmc_wait_cmd_data_inhibit(sdmmc_t *sdmmc, bool wait_dat)
|
||||
|
||||
static int _sdmmc_wait_card_busy(sdmmc_t *sdmmc)
|
||||
{
|
||||
_sdmmc_get_clkcon(sdmmc);
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
|
||||
u64 timeout = get_tmr_ms() + 2000;
|
||||
while (!(sdmmc->regs->prnsts & SDHCI_DATA_0_LVL_MASK))
|
||||
@ -512,16 +537,19 @@ static int _sdmmc_setup_read_small_block(sdmmc_t *sdmmc)
|
||||
{
|
||||
case SDMMC_BUS_WIDTH_1:
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case SDMMC_BUS_WIDTH_4:
|
||||
sdmmc->regs->blksize = 64;
|
||||
break;
|
||||
|
||||
case SDMMC_BUS_WIDTH_8:
|
||||
sdmmc->regs->blksize = 128;
|
||||
break;
|
||||
}
|
||||
|
||||
sdmmc->regs->blkcnt = 1;
|
||||
sdmmc->regs->trnmod = SDHCI_TRNS_READ;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -533,6 +561,7 @@ static int _sdmmc_send_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, bool is_data_presen
|
||||
{
|
||||
case SDMMC_RSP_TYPE_0:
|
||||
break;
|
||||
|
||||
case SDMMC_RSP_TYPE_1:
|
||||
case SDMMC_RSP_TYPE_4:
|
||||
case SDMMC_RSP_TYPE_5:
|
||||
@ -541,15 +570,17 @@ static int _sdmmc_send_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, bool is_data_presen
|
||||
else
|
||||
cmdflags = SDHCI_CMD_RESP_LEN48 | SDHCI_CMD_INDEX | SDHCI_CMD_CRC;
|
||||
break;
|
||||
|
||||
case SDMMC_RSP_TYPE_2:
|
||||
cmdflags = SDHCI_CMD_RESP_LEN136 | SDHCI_CMD_CRC;
|
||||
break;
|
||||
|
||||
case SDMMC_RSP_TYPE_3:
|
||||
cmdflags = SDHCI_CMD_RESP_LEN48;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_data_present)
|
||||
@ -572,7 +603,7 @@ static void _sdmmc_send_tuning_cmd(sdmmc_t *sdmmc, u32 cmd)
|
||||
|
||||
static int _sdmmc_tuning_execute_once(sdmmc_t *sdmmc, u32 cmd)
|
||||
{
|
||||
if (sdmmc->auto_cal_enabled)
|
||||
if (sdmmc->powersave_enabled)
|
||||
return 0;
|
||||
if (!_sdmmc_wait_cmd_data_inhibit(sdmmc, true))
|
||||
return 0;
|
||||
@ -584,13 +615,13 @@ static int _sdmmc_tuning_execute_once(sdmmc_t *sdmmc, u32 cmd)
|
||||
sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN;
|
||||
|
||||
_sdmmc_send_tuning_cmd(sdmmc, cmd);
|
||||
_sdmmc_get_clkcon(sdmmc);
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
usleep(1);
|
||||
|
||||
_sdmmc_reset(sdmmc);
|
||||
|
||||
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
|
||||
_sdmmc_get_clkcon(sdmmc);
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
|
||||
u64 timeout = get_tmr_us() + 5000;
|
||||
while (get_tmr_us() < timeout)
|
||||
@ -599,7 +630,7 @@ static int _sdmmc_tuning_execute_once(sdmmc_t *sdmmc, u32 cmd)
|
||||
{
|
||||
sdmmc->regs->norintsts = SDHCI_INT_DATA_AVAIL;
|
||||
sdmmc->regs->norintstsen &= ~SDHCI_INT_DATA_AVAIL;
|
||||
_sdmmc_get_clkcon(sdmmc);
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
usleep((1000 * 8 + sdmmc->divisor - 1) / sdmmc->divisor);
|
||||
return 1;
|
||||
}
|
||||
@ -608,7 +639,7 @@ static int _sdmmc_tuning_execute_once(sdmmc_t *sdmmc, u32 cmd)
|
||||
_sdmmc_reset(sdmmc);
|
||||
|
||||
sdmmc->regs->norintstsen &= ~SDHCI_INT_DATA_AVAIL;
|
||||
_sdmmc_get_clkcon(sdmmc);
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
usleep((1000 * 8 + sdmmc->divisor - 1) / sdmmc->divisor);
|
||||
|
||||
return 0;
|
||||
@ -627,15 +658,18 @@ int sdmmc_tuning_execute(sdmmc_t *sdmmc, u32 type, u32 cmd)
|
||||
max = 128;
|
||||
flag = (2 << 13); // 128 iterations.
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_UHS_SDR50:
|
||||
case SDHCI_TIMING_UHS_DDR50:
|
||||
case SDHCI_TIMING_MMC_DDR52:
|
||||
case SDHCI_TIMING_MMC_HS102:
|
||||
max = 256;
|
||||
flag = (4 << 13); // 256 iterations.
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_UHS_SDR12:
|
||||
case SDHCI_TIMING_UHS_SDR25:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -664,7 +698,7 @@ static int _sdmmc_enable_internal_clock(sdmmc_t *sdmmc)
|
||||
{
|
||||
//Enable internal clock and wait till it is stable.
|
||||
sdmmc->regs->clkcon |= SDHCI_CLOCK_INT_EN;
|
||||
_sdmmc_get_clkcon(sdmmc);
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
u64 timeout = get_tmr_ms() + 2000;
|
||||
while (!(sdmmc->regs->clkcon & SDHCI_CLOCK_INT_STABLE))
|
||||
{
|
||||
@ -700,17 +734,28 @@ static int _sdmmc_autocal_config_offset(sdmmc_t *sdmmc, u32 power)
|
||||
off_pd = 5;
|
||||
off_pu = 5;
|
||||
break;
|
||||
|
||||
case SDMMC_1:
|
||||
case SDMMC_3:
|
||||
if (power == SDMMC_POWER_1_8)
|
||||
{
|
||||
off_pd = 123;
|
||||
off_pu = 123;
|
||||
if (!sdmmc->t210b01)
|
||||
{
|
||||
off_pd = 123;
|
||||
off_pu = 123;
|
||||
}
|
||||
else
|
||||
{
|
||||
off_pd = 6;
|
||||
off_pu = 6;
|
||||
}
|
||||
}
|
||||
else if (power == SDMMC_POWER_3_3)
|
||||
{
|
||||
off_pd = 125;
|
||||
off_pu = 0;
|
||||
if (!sdmmc->t210b01)
|
||||
{
|
||||
off_pd = 125;
|
||||
off_pu = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
@ -740,7 +785,7 @@ static int _sdmmc_check_mask_interrupt(sdmmc_t *sdmmc, u16 *pout, u16 mask)
|
||||
u16 norintsts = sdmmc->regs->norintsts;
|
||||
u16 errintsts = sdmmc->regs->errintsts;
|
||||
|
||||
DPRINTF("norintsts %08X; errintsts %08X\n", norintsts, errintsts);
|
||||
DPRINTF("norintsts %08X, errintsts %08X\n", norintsts, errintsts);
|
||||
|
||||
if (pout)
|
||||
*pout = norintsts;
|
||||
@ -762,7 +807,7 @@ DPRINTF("norintsts %08X; errintsts %08X\n", norintsts, errintsts);
|
||||
|
||||
static int _sdmmc_wait_response(sdmmc_t *sdmmc)
|
||||
{
|
||||
_sdmmc_get_clkcon(sdmmc);
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
|
||||
u64 timeout = get_tmr_ms() + 2000;
|
||||
while (true)
|
||||
@ -813,7 +858,7 @@ int sdmmc_stop_transmission(sdmmc_t *sdmmc, u32 *rsp)
|
||||
return 0;
|
||||
|
||||
// Recalibrate periodically for SDMMC1.
|
||||
if ((sdmmc->id == SDMMC_1) && sdmmc->auto_cal_enabled)
|
||||
if (sdmmc->manual_cal && sdmmc->powersave_enabled)
|
||||
_sdmmc_autocal_execute(sdmmc, sdmmc_get_io_power(sdmmc));
|
||||
|
||||
bool should_disable_sd_clock = false;
|
||||
@ -821,7 +866,7 @@ int sdmmc_stop_transmission(sdmmc_t *sdmmc, u32 *rsp)
|
||||
{
|
||||
should_disable_sd_clock = true;
|
||||
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
|
||||
_sdmmc_get_clkcon(sdmmc);
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
usleep((8000 + sdmmc->divisor - 1) / sdmmc->divisor);
|
||||
}
|
||||
|
||||
@ -842,7 +887,7 @@ static int _sdmmc_config_dma(sdmmc_t *sdmmc, u32 *blkcnt_out, sdmmc_req_t *req)
|
||||
u32 blkcnt = req->num_sectors;
|
||||
if (blkcnt >= 0xFFFF)
|
||||
blkcnt = 0xFFFF;
|
||||
|
||||
|
||||
u64 admaaddr = (u64)sdmmc_calculate_dma_addr(_current_accessor, req->buf, blkcnt);
|
||||
if (!admaaddr)
|
||||
{
|
||||
@ -861,7 +906,7 @@ static int _sdmmc_config_dma(sdmmc_t *sdmmc, u32 *blkcnt_out, sdmmc_req_t *req)
|
||||
|
||||
sdmmc->dma_addr_next = (admaaddr + 0x80000) & 0xFFFFFFFFFFF80000;
|
||||
|
||||
sdmmc->regs->blksize = req->blksize | 0x7000;
|
||||
sdmmc->regs->blksize = req->blksize | 0x7000; // DMA 512KB (Detects A18 carry out).
|
||||
sdmmc->regs->blkcnt = blkcnt;
|
||||
|
||||
if (blkcnt_out)
|
||||
@ -953,8 +998,6 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
|
||||
|
||||
is_data_present = true;
|
||||
}
|
||||
else
|
||||
is_data_present = false;
|
||||
|
||||
_sdmmc_enable_interrupts(sdmmc);
|
||||
|
||||
@ -962,7 +1005,7 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
|
||||
return 0;
|
||||
|
||||
int result = _sdmmc_wait_response(sdmmc);
|
||||
DPRINTF("rsp(%d): %08X, %08X, %08X, %08X\n", result,
|
||||
DPRINTF("rsp(%d): %08X, %08X, %08X, %08X\n", result,
|
||||
sdmmc->regs->rspreg0, sdmmc->regs->rspreg1, sdmmc->regs->rspreg2, sdmmc->regs->rspreg3);
|
||||
if (result)
|
||||
{
|
||||
@ -970,12 +1013,6 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
|
||||
{
|
||||
sdmmc->expected_rsp_type = cmd->rsp_type;
|
||||
result = _sdmmc_cache_rsp(sdmmc, sdmmc->rsp, 0x10, cmd->rsp_type);
|
||||
|
||||
/*if(sdmmc->rsp[0] & 0xFDF9A080)
|
||||
{
|
||||
res = 0;
|
||||
sdmmc->rsp[0] = 0; // Reset error
|
||||
}*/
|
||||
}
|
||||
|
||||
if (req && result)
|
||||
@ -1029,7 +1066,56 @@ bool sdmmc_get_sd_inserted()
|
||||
return (!gpio_read(GPIO_PORT_Z, GPIO_PIN_1));
|
||||
}
|
||||
|
||||
static int _sdmmc_config_sdmmc1()
|
||||
static void _sdmmc_config_sdmmc1_schmitt()
|
||||
{
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC1_CLK) |= PINMUX_SCHMT;
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC1_CMD) |= PINMUX_SCHMT;
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT3) |= PINMUX_SCHMT;
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT2) |= PINMUX_SCHMT;
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT1) |= PINMUX_SCHMT;
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT0) |= PINMUX_SCHMT;
|
||||
}
|
||||
|
||||
static void _sdmmc_config_sdmmc2_schmitt()
|
||||
{
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC2_CLK) |= PINMUX_SCHMT;
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC2_CMD) |= PINMUX_SCHMT;
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC2_DAT7) |= PINMUX_SCHMT;
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC2_DAT6) |= PINMUX_SCHMT;
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC2_DAT5) |= PINMUX_SCHMT;
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC2_DAT4) |= PINMUX_SCHMT;
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC2_DAT3) |= PINMUX_SCHMT;
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC2_DAT2) |= PINMUX_SCHMT;
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC2_DAT1) |= PINMUX_SCHMT;
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC2_DAT0) |= PINMUX_SCHMT;
|
||||
}
|
||||
|
||||
static void _sdmmc_config_sdmmc1_pads(bool discharge)
|
||||
{
|
||||
u32 sdmmc1_pin_mask = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5;
|
||||
|
||||
// Set values for Reset state.
|
||||
u32 function = GPIO_MODE_SPIO;
|
||||
u32 level = GPIO_LOW;
|
||||
u32 output = GPIO_OUTPUT_DISABLE;
|
||||
|
||||
// Set values for dicharging.
|
||||
if (discharge)
|
||||
{
|
||||
function = GPIO_MODE_GPIO;
|
||||
level = GPIO_HIGH;
|
||||
output = GPIO_OUTPUT_ENABLE;
|
||||
}
|
||||
|
||||
// Set all pads function.
|
||||
gpio_config(GPIO_PORT_M, sdmmc1_pin_mask, function);
|
||||
// Set all pads output level.
|
||||
gpio_write(GPIO_PORT_M, sdmmc1_pin_mask, level);
|
||||
// Set all pads output.
|
||||
gpio_output_enable(GPIO_PORT_M, sdmmc1_pin_mask, output);
|
||||
}
|
||||
|
||||
static int _sdmmc_config_sdmmc1(bool t210b01)
|
||||
{
|
||||
// Configure SD card detect.
|
||||
PINMUX_AUX(PINMUX_AUX_GPIO_PZ1) = PINMUX_INPUT_ENABLE | PINMUX_PULL_UP | 2; // GPIO control, pull up.
|
||||
@ -1044,76 +1130,102 @@ static int _sdmmc_config_sdmmc1()
|
||||
|
||||
/*
|
||||
* Pinmux config:
|
||||
* DRV_TYPE = DRIVE_2X
|
||||
* DRV_TYPE = DRIVE_2X (for 33 Ohm driver)
|
||||
* E_SCHMT = ENABLE (for 1.8V), DISABLE (for 3.3V)
|
||||
* E_INPUT = ENABLE
|
||||
* TRISTATE = PASSTHROUGH
|
||||
* APB_MISC_GP_SDMMCx_CLK_LPBK_CONTROL = SDMMCx_CLK_PAD_E_LPBK for CLK
|
||||
*/
|
||||
|
||||
// Configure SDMMC1 pinmux.
|
||||
APB_MISC(APB_MISC_GP_SDMMC1_CLK_LPBK_CONTROL) = 1; // Enable deep loopback for SDMMC1 CLK pad.
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC1_CLK) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED;
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC1_CMD) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_PULL_UP;
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT3) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_PULL_UP;
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT2) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_PULL_UP;
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT1) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_PULL_UP;
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT0) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_PULL_UP;
|
||||
// Enable deep loopback for SDMMC1 CLK pad.
|
||||
APB_MISC(APB_MISC_GP_SDMMC1_CLK_LPBK_CONTROL) = 1;
|
||||
|
||||
// Configure SDMMC1 CLK pinmux, based on state and SoC type.
|
||||
if (PINMUX_AUX(PINMUX_AUX_SDMMC1_CLK) != (PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PULL_DOWN)) // Check if CLK pad is already configured.
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC1_CLK) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | (t210b01 ? PINMUX_PULL_NONE : PINMUX_PULL_DOWN);
|
||||
|
||||
// Configure the reset of SDMMC1 pins pinmux.
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC1_CMD) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PULL_UP;
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT3) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PULL_UP;
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT2) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PULL_UP;
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT1) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PULL_UP;
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT0) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PULL_UP;
|
||||
|
||||
// Force schmitt trigger for T210B01.
|
||||
if (t210b01)
|
||||
_sdmmc_config_sdmmc1_schmitt();
|
||||
|
||||
// Make sure the SDMMC1 controller is powered.
|
||||
smcReadWriteRegister(PMC_BASE + APBDEV_PMC_NO_IOPOWER, PMC_NO_IOPOWER_SDMMC1_IO_EN, PMC_NO_IOPOWER_SDMMC1_IO_EN);
|
||||
usleep(1000);
|
||||
smcReadWriteRegister(PMC_BASE + APBDEV_PMC_NO_IOPOWER, ~PMC_NO_IOPOWER_SDMMC1_IO_EN, PMC_NO_IOPOWER_SDMMC1_IO_EN);
|
||||
smcReadWriteRegister(PMC_BASE + APBDEV_PMC_NO_IOPOWER, 0, 0); // Commit write.
|
||||
|
||||
// Inform IO pads that voltage is gonna be 3.3V.
|
||||
smcReadWriteRegister(PMC_BASE + APBDEV_PMC_PWR_DET_VAL, PMC_PWR_DET_SDMMC1_IO_EN, PMC_PWR_DET_SDMMC1_IO_EN);
|
||||
smcReadWriteRegister(PMC_BASE + APBDEV_PMC_PWR_DET_VAL, 0, 0); // Commit write.
|
||||
|
||||
// Set enable SD card power.
|
||||
//PINMUX_AUX(PINMUX_AUX_DMIC3_CLK) = PINMUX_PULL_DOWN | 2; // Pull down.
|
||||
PINMUX_AUX(PINMUX_AUX_DMIC3_CLK) = PINMUX_INPUT_ENABLE | PINMUX_PULL_DOWN | 1; // GPIO control, pull down.
|
||||
//PINMUX_AUX(PINMUX_AUX_DMIC3_CLK) = PINMUX_PULL_DOWN | 2; // Proper pinmuxing. Breaks on HOS, takes over 1 minute to recover.
|
||||
PINMUX_AUX(PINMUX_AUX_DMIC3_CLK) = PINMUX_INPUT_ENABLE | PINMUX_PULL_DOWN | 1; // Wrong but working pinmuxing. Instant take over by FS.
|
||||
gpio_config(GPIO_PORT_E, GPIO_PIN_4, GPIO_MODE_GPIO);
|
||||
gpio_write(GPIO_PORT_E, GPIO_PIN_4, GPIO_HIGH);
|
||||
gpio_output_enable(GPIO_PORT_E, GPIO_PIN_4, GPIO_OUTPUT_ENABLE);
|
||||
usleep(1000);
|
||||
usleep(10000);
|
||||
|
||||
// Enable SD card power.
|
||||
// Enable SD card IO power.
|
||||
max77620_regulator_set_voltage(REGULATOR_LDO2, 3300000);
|
||||
max77620_regulator_enable(REGULATOR_LDO2, 1);
|
||||
usleep(1000);
|
||||
|
||||
// Set pad slew codes to get good quality clock.
|
||||
APB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL) = (APB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL) & 0xFFFFFFF) | 0x50000000;
|
||||
usleep(1000);
|
||||
if (!t210b01)
|
||||
{
|
||||
APB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL) = (APB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL) & 0xFFFFFFF) | 0x50000000;
|
||||
(void)APB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL); // Commit write.
|
||||
usleep(1000);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void _sdmmc_config_emmc(u32 id)
|
||||
static void _sdmmc_config_emmc(u32 id, bool t210b01)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case SDMMC_2:
|
||||
// Unset park for pads.
|
||||
APB_MISC(APB_MISC_GP_EMMC2_PAD_CFGPADCTRL) &= 0xF8003FFF;
|
||||
if (!t210b01)
|
||||
{
|
||||
// Unset park for pads.
|
||||
APB_MISC(APB_MISC_GP_EMMC2_PAD_CFGPADCTRL) &= 0xF8003FFF;
|
||||
(void)APB_MISC(APB_MISC_GP_EMMC2_PAD_CFGPADCTRL); // Commit write.
|
||||
}
|
||||
else // Enable schmitt trigger for T210B01.
|
||||
_sdmmc_config_sdmmc2_schmitt();
|
||||
break;
|
||||
|
||||
case SDMMC_4:
|
||||
// Unset park for pads.
|
||||
APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) &= 0xF8003FFF;
|
||||
// Set default pad cfg.
|
||||
APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) = (APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) & 0xFFFFC003) | 0x1040;
|
||||
|
||||
// Enabled schmitt trigger.
|
||||
APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) |= 1; // Enable Schmitt trigger.
|
||||
if (t210b01)
|
||||
APB_MISC(APB_MISC_GP_EMMC4_PAD_PUPD_CFGPADCTRL) &= 0xFFBFFFF9; // Unset CMD/CLK/DQS powedown.
|
||||
// Enable schmitt trigger.
|
||||
APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) |= 1;
|
||||
(void)APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL); // Commit write.
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int auto_cal_enable)
|
||||
int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int powersave_enable)
|
||||
{
|
||||
const u32 trim_values[] = { 2, 8, 3, 8 };
|
||||
u32 clock;
|
||||
u16 divisor;
|
||||
u8 vref_sel = 7;
|
||||
|
||||
if (id > SDMMC_4)
|
||||
const u32 trim_values_t210[] = { 2, 8, 3, 8 };
|
||||
const u32 trim_values_t210b01[] = { 14, 13, 15, 13 };
|
||||
const u32 *trim_values = sdmmc->t210b01 ? trim_values_t210b01 : trim_values_t210;
|
||||
|
||||
if (id > SDMMC_4 || id == SDMMC_3)
|
||||
return 0;
|
||||
|
||||
memset(sdmmc, 0, sizeof(sdmmc_t));
|
||||
@ -1121,45 +1233,57 @@ int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int a
|
||||
sdmmc->regs = (t210_sdmmc_t *)QueryIoMapping(_sdmmc_bases[id], 0x200);
|
||||
sdmmc->id = id;
|
||||
sdmmc->clock_stopped = 1;
|
||||
sdmmc->t210b01 = splGetSocType() == SplSocType_Mariko;
|
||||
|
||||
// Do specific SDMMC HW configuration.
|
||||
switch (id)
|
||||
{
|
||||
case SDMMC_1:
|
||||
if (!_sdmmc_config_sdmmc1())
|
||||
if (!_sdmmc_config_sdmmc1(sdmmc->t210b01))
|
||||
return 0;
|
||||
if (sdmmc->t210b01)
|
||||
vref_sel = 0;
|
||||
else
|
||||
sdmmc->manual_cal = 1;
|
||||
break;
|
||||
|
||||
case SDMMC_2:
|
||||
case SDMMC_4:
|
||||
_sdmmc_config_emmc(id);
|
||||
_sdmmc_config_emmc(id, sdmmc->t210b01);
|
||||
break;
|
||||
}
|
||||
|
||||
// Disable clock if enabled.
|
||||
if (clock_sdmmc_is_not_reset_and_enabled(id))
|
||||
{
|
||||
_sdmmc_sd_clock_disable(sdmmc);
|
||||
_sdmmc_get_clkcon(sdmmc);
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
}
|
||||
|
||||
u32 clock;
|
||||
u16 divisor;
|
||||
// Configure and enable selected clock.
|
||||
clock_sdmmc_get_card_clock_div(&clock, &divisor, type);
|
||||
clock_sdmmc_enable(id, clock);
|
||||
|
||||
// Make sure all sdmmc registers are reset.
|
||||
_sdmmc_reset_all(sdmmc);
|
||||
|
||||
sdmmc->clock_stopped = 0;
|
||||
|
||||
//TODO: make this skip-able.
|
||||
// Set default pad IO trimming configuration.
|
||||
sdmmc->regs->iospare |= 0x80000; // Enable muxing.
|
||||
sdmmc->regs->veniotrimctl &= 0xFFFFFFFB; // Set Band Gap VREG to supply DLL.
|
||||
sdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & 0xE0FFFFFB) | (trim_values[sdmmc->id] << 24);
|
||||
sdmmc->regs->sdmemcmppadctl =
|
||||
(sdmmc->regs->sdmemcmppadctl & TEGRA_MMC_SDMEMCOMPPADCTRL_COMP_VREF_SEL_MASK) | 7;
|
||||
(sdmmc->regs->sdmemcmppadctl & TEGRA_MMC_SDMEMCOMPPADCTRL_COMP_VREF_SEL_MASK) | vref_sel;
|
||||
|
||||
// Configure auto calibration values.
|
||||
if (!_sdmmc_autocal_config_offset(sdmmc, power))
|
||||
return 0;
|
||||
|
||||
// Calibrate pads.
|
||||
_sdmmc_autocal_execute(sdmmc, power);
|
||||
|
||||
// Enable internal clock and power.
|
||||
if (_sdmmc_enable_internal_clock(sdmmc))
|
||||
{
|
||||
sdmmc_set_bus_width(sdmmc, bus_width);
|
||||
@ -1167,18 +1291,50 @@ int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int a
|
||||
|
||||
if (sdmmc_setup_clock(sdmmc, type))
|
||||
{
|
||||
sdmmc_card_clock_ctrl(sdmmc, auto_cal_enable);
|
||||
sdmmc_card_clock_powersave(sdmmc, powersave_enable);
|
||||
_sdmmc_card_clock_enable(sdmmc);
|
||||
_sdmmc_get_clkcon(sdmmc);
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sdmmc1_disable_power()
|
||||
{
|
||||
// Clear pull down from CLK pad.
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC1_CLK) &= ~PINMUX_PULL_MASK;
|
||||
|
||||
// Set pads to discharge state.
|
||||
_sdmmc_config_sdmmc1_pads(true);
|
||||
|
||||
// Disable SD card IO power regulator.
|
||||
max77620_regulator_enable(REGULATOR_LDO2, 0);
|
||||
usleep(4000);
|
||||
|
||||
// Disable SD card IO power pin.
|
||||
gpio_write(GPIO_PORT_E, GPIO_PIN_4, GPIO_LOW);
|
||||
|
||||
// T210/T210B01 WAR: Set start timer for IO and Controller power discharge.
|
||||
msleep(239);
|
||||
|
||||
// Disable SDMMC1 controller power.
|
||||
smcReadWriteRegister(PMC_BASE + APBDEV_PMC_NO_IOPOWER, PMC_NO_IOPOWER_SDMMC1_IO_EN, PMC_NO_IOPOWER_SDMMC1_IO_EN);
|
||||
smcReadWriteRegister(PMC_BASE + APBDEV_PMC_NO_IOPOWER, 0, 0); // Commit write.
|
||||
|
||||
// Inform IO pads that next voltage might be 3.3V.
|
||||
smcReadWriteRegister(PMC_BASE + APBDEV_PMC_PWR_DET_VAL, PMC_PWR_DET_SDMMC1_IO_EN, PMC_PWR_DET_SDMMC1_IO_EN);
|
||||
smcReadWriteRegister(PMC_BASE + APBDEV_PMC_PWR_DET_VAL, 0, 0); // Commit write.
|
||||
|
||||
// Set pads to reset state.
|
||||
_sdmmc_config_sdmmc1_pads(false);
|
||||
|
||||
// Set pull down to CLK pad.
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC1_CLK) |= PINMUX_PULL_DOWN;
|
||||
}
|
||||
|
||||
void sdmmc_end(sdmmc_t *sdmmc)
|
||||
{
|
||||
if (!sdmmc->clock_stopped)
|
||||
@ -1189,17 +1345,9 @@ void sdmmc_end(sdmmc_t *sdmmc)
|
||||
|
||||
// Disable SD card power.
|
||||
if (sdmmc->id == SDMMC_1)
|
||||
{
|
||||
gpio_output_enable(GPIO_PORT_E, GPIO_PIN_4, GPIO_OUTPUT_DISABLE);
|
||||
max77620_regulator_enable(REGULATOR_LDO2, 0);
|
||||
sdmmc1_disable_power();
|
||||
|
||||
// Inform IO pads that next voltage might be 3.3V.
|
||||
smcReadWriteRegister(PMC_BASE + APBDEV_PMC_PWR_DET_VAL, PMC_PWR_DET_SDMMC1_IO_EN, PMC_PWR_DET_SDMMC1_IO_EN);
|
||||
|
||||
msleep(100); // To power cycle min 1ms without power is needed.
|
||||
}
|
||||
|
||||
_sdmmc_get_clkcon(sdmmc);
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
clock_sdmmc_disable(sdmmc->id);
|
||||
sdmmc->clock_stopped = 1;
|
||||
}
|
||||
@ -1219,7 +1367,7 @@ int sdmmc_execute_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_t *req, u32 *b
|
||||
return 0;
|
||||
|
||||
// Recalibrate periodically for SDMMC1.
|
||||
if (sdmmc->id == SDMMC_1 && sdmmc->auto_cal_enabled)
|
||||
if (sdmmc->manual_cal && sdmmc->powersave_enabled)
|
||||
_sdmmc_autocal_execute(sdmmc, sdmmc_get_io_power(sdmmc));
|
||||
|
||||
int should_disable_sd_clock = 0;
|
||||
@ -1227,7 +1375,7 @@ int sdmmc_execute_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_t *req, u32 *b
|
||||
{
|
||||
should_disable_sd_clock = 1;
|
||||
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
|
||||
_sdmmc_get_clkcon(sdmmc);
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
usleep((8000 + sdmmc->divisor - 1) / sdmmc->divisor);
|
||||
}
|
||||
|
||||
@ -1248,36 +1396,32 @@ int sdmmc_enable_low_voltage(sdmmc_t *sdmmc)
|
||||
if (!sdmmc_setup_clock(sdmmc, SDHCI_TIMING_UHS_SDR12))
|
||||
return 0;
|
||||
|
||||
_sdmmc_get_clkcon(sdmmc);
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
|
||||
// Switch to 1.8V and wait for regulator to stabilize. Assume max possible wait needed.
|
||||
max77620_regulator_set_voltage(REGULATOR_LDO2, 1800000);
|
||||
usleep(300);
|
||||
usleep(150);
|
||||
|
||||
// Inform IO pads that we switched to 1.8V.
|
||||
smcReadWriteRegister(PMC_BASE + APBDEV_PMC_PWR_DET_VAL, ~PMC_PWR_DET_SDMMC1_IO_EN, PMC_PWR_DET_SDMMC1_IO_EN);
|
||||
smcReadWriteRegister(PMC_BASE + APBDEV_PMC_PWR_DET_VAL, 0, 0); // Commit write.
|
||||
|
||||
// Enable schmitt trigger for better duty cycle and low jitter clock.
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC1_CLK) |= PINMUX_SCHMT;
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC1_CMD) |= PINMUX_SCHMT;
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT3) |= PINMUX_SCHMT;
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT2) |= PINMUX_SCHMT;
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT1) |= PINMUX_SCHMT;
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT0) |= PINMUX_SCHMT;
|
||||
_sdmmc_config_sdmmc1_schmitt();
|
||||
|
||||
_sdmmc_autocal_config_offset(sdmmc, SDMMC_POWER_1_8);
|
||||
_sdmmc_autocal_execute(sdmmc, SDMMC_POWER_1_8);
|
||||
_sdmmc_set_io_power(sdmmc, SDMMC_POWER_1_8);
|
||||
_sdmmc_get_clkcon(sdmmc);
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
msleep(5); // Wait minimum 5ms before turning on the card clock.
|
||||
|
||||
// Turn on SDCLK.
|
||||
if (sdmmc->regs->hostctl2 & SDHCI_CTRL_VDD_180)
|
||||
{
|
||||
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
|
||||
_sdmmc_get_clkcon(sdmmc);
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
usleep(1000);
|
||||
if ((sdmmc->regs->prnsts & 0xF00000) == 0xF00000)
|
||||
if ((sdmmc->regs->prnsts & SDHCI_DATA_LVL_MASK) == SDHCI_DATA_LVL_MASK)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
18
emummc/source/emmc/sdmmc_driver.h
vendored
18
emummc/source/emmc/sdmmc_driver.h
vendored
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@ -195,13 +195,13 @@
|
||||
#define SDHCI_TIMING_UHS_SDR104 11
|
||||
#define SDHCI_TIMING_UHS_SDR82 12 // SDR104 with a 163.2MHz -> 81.6MHz clock.
|
||||
#define SDHCI_TIMING_UHS_DDR50 13
|
||||
#define SDHCI_TIMING_MMC_DDR52 14
|
||||
#define SDHCI_TIMING_MMC_HS102 14
|
||||
|
||||
#define SDHCI_CAN_64BIT 0x10000000
|
||||
|
||||
/*! SDMMC Low power features. */
|
||||
#define SDMMC_AUTO_CAL_DISABLE 0
|
||||
#define SDMMC_AUTO_CAL_ENABLE 1
|
||||
#define SDMMC_POWER_SAVE_DISABLE 0
|
||||
#define SDMMC_POWER_SAVE_ENABLE 1
|
||||
|
||||
/*! Helper for SWITCH command argument. */
|
||||
#define SDMMC_SWITCH(mode, index, value) (((mode) << 24) | ((index) << 16) | ((value) << 8))
|
||||
@ -213,7 +213,8 @@ typedef struct _sdmmc_t
|
||||
u32 id;
|
||||
u32 divisor;
|
||||
u32 clock_stopped;
|
||||
int auto_cal_enabled;
|
||||
int powersave_enabled;
|
||||
int manual_cal;
|
||||
int card_clock_enabled;
|
||||
int venclkctl_set;
|
||||
u32 venclkctl_tap;
|
||||
@ -222,6 +223,7 @@ typedef struct _sdmmc_t
|
||||
u64 dma_addr_next;
|
||||
u32 rsp[4];
|
||||
u32 rsp3;
|
||||
int t210b01;
|
||||
} sdmmc_t;
|
||||
|
||||
/*! SDMMC command. */
|
||||
@ -247,15 +249,15 @@ typedef struct _sdmmc_req_t
|
||||
int sdmmc_get_io_power(sdmmc_t *sdmmc);
|
||||
u32 sdmmc_get_bus_width(sdmmc_t *sdmmc);
|
||||
void sdmmc_set_bus_width(sdmmc_t *sdmmc, u32 bus_width);
|
||||
void sdmmc_set_tap_value(sdmmc_t *sdmmc);
|
||||
void sdmmc_save_tap_value(sdmmc_t *sdmmc);
|
||||
int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type);
|
||||
void sdmmc_card_clock_ctrl(sdmmc_t *sdmmc, int auto_cal_enable);
|
||||
void sdmmc_card_clock_powersave(sdmmc_t *sdmmc, int powersave_enable);
|
||||
int sdmmc_get_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 size, u32 type);
|
||||
int sdmmc_tuning_execute(sdmmc_t *sdmmc, u32 type, u32 cmd);
|
||||
int sdmmc_stop_transmission(sdmmc_t *sdmmc, u32 *rsp);
|
||||
int sdmmc_get_sd_power_enabled();
|
||||
bool sdmmc_get_sd_inserted();
|
||||
int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int auto_cal_enable);
|
||||
int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int powersave_enable);
|
||||
void sdmmc_end(sdmmc_t *sdmmc);
|
||||
void sdmmc_init_cmd(sdmmc_cmd_t *cmdbuf, u16 cmd, u32 arg, u32 rsp_type, u32 check_busy);
|
||||
int sdmmc_execute_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_t *req, u32 *blkcnt_out);
|
||||
|
1
emummc/source/emmc/sdmmc_t210.h
vendored
1
emummc/source/emmc/sdmmc_t210.h
vendored
@ -103,6 +103,7 @@ typedef struct _t210_sdmmc_t
|
||||
vu32 iospare;
|
||||
vu32 mcciffifoctl;
|
||||
vu32 timeoutwcoal;
|
||||
vu32 unk1;
|
||||
} t210_sdmmc_t;
|
||||
|
||||
#endif
|
||||
|
173
emummc/source/emuMMC/emummc.c
vendored
173
emummc/source/emuMMC/emummc.c
vendored
@ -89,7 +89,7 @@ static void _sdmmc_ensure_initialized(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void _file_based_update_filename(char *outFilename, u32 sd_path_len, u32 part_idx)
|
||||
static void _file_based_update_filename(char *outFilename, unsigned int sd_path_len, unsigned int part_idx)
|
||||
{
|
||||
snprintf(outFilename + sd_path_len, 3, "%02d", part_idx);
|
||||
}
|
||||
@ -103,9 +103,7 @@ static void _file_based_emmc_finalize(void)
|
||||
f_close(&f_emu.fp_boot1);
|
||||
|
||||
for (int i = 0; i < f_emu.parts; i++)
|
||||
{
|
||||
f_close(&f_emu.fp_gpp[i]);
|
||||
}
|
||||
|
||||
// Force unmount FAT volume.
|
||||
f_mount(NULL, "", 1);
|
||||
@ -114,12 +112,59 @@ static void _file_based_emmc_finalize(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void _nand_patrol_ensure_integrity(void)
|
||||
{
|
||||
fs_nand_patrol_t nand_patrol;
|
||||
static bool nand_patrol_checked = false;
|
||||
|
||||
if (!nand_patrol_checked)
|
||||
{
|
||||
if (emuMMC_ctx.EMMC_Type == emuMMC_SD_Raw)
|
||||
{
|
||||
unsigned int nand_patrol_sector = emuMMC_ctx.EMMC_StoragePartitionOffset + NAND_PATROL_SECTOR;
|
||||
if (!sdmmc_storage_read(&sd_storage, nand_patrol_sector, 1, &nand_patrol))
|
||||
goto out;
|
||||
|
||||
// Clear nand patrol if last offset exceeds storage.
|
||||
if (nand_patrol.offset > sd_storage.sec_cnt)
|
||||
{
|
||||
memset(&nand_patrol, 0, sizeof(fs_nand_patrol_t));
|
||||
sdmmc_storage_write(&sd_storage, nand_patrol_sector, 1, &nand_patrol);
|
||||
}
|
||||
}
|
||||
else if (emuMMC_ctx.EMMC_Type == emuMMC_SD_File && fat_mounted)
|
||||
{
|
||||
FIL *fp = &f_emu.fp_boot0;
|
||||
if (f_lseek(fp, NAND_PATROL_OFFSET) != FR_OK)
|
||||
goto out;
|
||||
|
||||
if (f_read_fast(fp, &nand_patrol, sizeof(fs_nand_patrol_t)) != FR_OK)
|
||||
goto out;
|
||||
|
||||
// Clear nand patrol if last offset exceeds total file based size.
|
||||
if (nand_patrol.offset > f_emu.total_sect)
|
||||
{
|
||||
memset(&nand_patrol, 0, sizeof(fs_nand_patrol_t));
|
||||
|
||||
if (f_lseek(fp, NAND_PATROL_OFFSET) != FR_OK)
|
||||
goto out;
|
||||
|
||||
if (f_write_fast(fp, &nand_patrol, sizeof(fs_nand_patrol_t)) != FR_OK)
|
||||
goto out;
|
||||
|
||||
f_sync(fp);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
nand_patrol_checked = true;
|
||||
}
|
||||
}
|
||||
|
||||
void sdmmc_finalize(void)
|
||||
{
|
||||
if (!sdmmc_storage_end(&sd_storage))
|
||||
{
|
||||
fatal_abort(Fatal_InitSD);
|
||||
}
|
||||
|
||||
storageSDinitialized = false;
|
||||
}
|
||||
@ -137,14 +182,14 @@ static void _file_based_emmc_initialize(void)
|
||||
memcpy(path + path_len, "BOOT0", 6);
|
||||
if (f_open(&f_emu.fp_boot0, path, FA_READ | FA_WRITE) != FR_OK)
|
||||
fatal_abort(Fatal_FatfsFileOpen);
|
||||
if (!f_expand_cltbl(&f_emu.fp_boot0, 0x400, f_emu.clmt_boot0, f_size(&f_emu.fp_boot0)))
|
||||
if (!f_expand_cltbl(&f_emu.fp_boot0, EMUMMC_FP_CLMT_COUNT, f_emu.clmt_boot0, f_size(&f_emu.fp_boot0)))
|
||||
fatal_abort(Fatal_FatfsMemExhaustion);
|
||||
|
||||
// Open BOOT1 physical partition.
|
||||
memcpy(path + path_len, "BOOT1", 6);
|
||||
if (f_open(&f_emu.fp_boot1, path, FA_READ | FA_WRITE) != FR_OK)
|
||||
fatal_abort(Fatal_FatfsFileOpen);
|
||||
if (!f_expand_cltbl(&f_emu.fp_boot1, 0x400, f_emu.clmt_boot1, f_size(&f_emu.fp_boot1)))
|
||||
if (!f_expand_cltbl(&f_emu.fp_boot1, EMUMMC_FP_CLMT_COUNT, f_emu.clmt_boot1, f_size(&f_emu.fp_boot1)))
|
||||
fatal_abort(Fatal_FatfsMemExhaustion);
|
||||
|
||||
// Open handles for GPP physical partition files.
|
||||
@ -152,15 +197,14 @@ static void _file_based_emmc_initialize(void)
|
||||
|
||||
if (f_open(&f_emu.fp_gpp[0], path, FA_READ | FA_WRITE) != FR_OK)
|
||||
fatal_abort(Fatal_FatfsFileOpen);
|
||||
if (!f_expand_cltbl(&f_emu.fp_gpp[0], 0x400, &f_emu.clmt_gpp[0], f_size(&f_emu.fp_gpp[0])))
|
||||
if (!f_expand_cltbl(&f_emu.fp_gpp[0], EMUMMC_FP_CLMT_COUNT, &f_emu.clmt_gpp[0], f_size(&f_emu.fp_gpp[0])))
|
||||
fatal_abort(Fatal_FatfsMemExhaustion);
|
||||
|
||||
f_emu.part_size = f_size(&f_emu.fp_gpp[0]) >> 9;
|
||||
f_emu.part_size = (uint64_t)f_size(&f_emu.fp_gpp[0]) >> 9;
|
||||
f_emu.total_sect = f_emu.part_size;
|
||||
|
||||
// Iterate folder for split parts and stop if next doesn't exist.
|
||||
// Supports up to 32 parts of any size.
|
||||
// TODO: decide on max parts and define them. (hekate produces up to 30 parts on 1GB mode.)
|
||||
for (f_emu.parts = 1; f_emu.parts < 32; f_emu.parts++)
|
||||
for (f_emu.parts = 1; f_emu.parts < EMUMMC_FILE_MAX_PARTS; f_emu.parts++)
|
||||
{
|
||||
_file_based_update_filename(path, path_len, f_emu.parts);
|
||||
|
||||
@ -173,8 +217,13 @@ static void _file_based_emmc_initialize(void)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!f_expand_cltbl(&f_emu.fp_gpp[f_emu.parts], 0x400, &f_emu.clmt_gpp[f_emu.parts * 0x400], f_size(&f_emu.fp_gpp[f_emu.parts])))
|
||||
if (!f_expand_cltbl(&f_emu.fp_gpp[f_emu.parts], EMUMMC_FP_CLMT_COUNT,
|
||||
&f_emu.clmt_gpp[f_emu.parts * EMUMMC_FP_CLMT_COUNT], f_size(&f_emu.fp_gpp[f_emu.parts])))
|
||||
{
|
||||
fatal_abort(Fatal_FatfsMemExhaustion);
|
||||
}
|
||||
|
||||
f_emu.total_sect += (uint64_t)f_size(&f_emu.fp_gpp[f_emu.parts]) >> 9;
|
||||
}
|
||||
}
|
||||
|
||||
@ -189,7 +238,7 @@ bool sdmmc_initialize(void)
|
||||
{
|
||||
storageSDinitialized = true;
|
||||
|
||||
// File based emummc.
|
||||
// Init file based emummc.
|
||||
if ((emuMMC_ctx.EMMC_Type == emuMMC_SD_File) && !fat_mounted)
|
||||
{
|
||||
if (f_mount(&f_emu.sd_fs, "", 1) != FR_OK)
|
||||
@ -200,6 +249,9 @@ bool sdmmc_initialize(void)
|
||||
_file_based_emmc_initialize();
|
||||
}
|
||||
|
||||
// Check if nand patrol offset is inside limits.
|
||||
_nand_patrol_ensure_integrity();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -207,9 +259,7 @@ bool sdmmc_initialize(void)
|
||||
}
|
||||
|
||||
if (!storageSDinitialized)
|
||||
{
|
||||
fatal_abort(Fatal_InitSD);
|
||||
}
|
||||
}
|
||||
|
||||
return storageSDinitialized;
|
||||
@ -239,19 +289,17 @@ sdmmc_accessor_t *sdmmc_accessor_get(int mmc_id)
|
||||
void mutex_lock_handler(int mmc_id)
|
||||
{
|
||||
if (custom_driver)
|
||||
{
|
||||
lock_mutex(sd_mutex);
|
||||
}
|
||||
|
||||
lock_mutex(nand_mutex);
|
||||
}
|
||||
|
||||
void mutex_unlock_handler(int mmc_id)
|
||||
{
|
||||
unlock_mutex(nand_mutex);
|
||||
|
||||
if (custom_driver)
|
||||
{
|
||||
unlock_mutex(sd_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
int sdmmc_nand_get_active_partition_index()
|
||||
@ -271,12 +319,16 @@ int sdmmc_nand_get_active_partition_index()
|
||||
|
||||
static uint64_t emummc_read_write_inner(void *buf, unsigned int sector, unsigned int num_sectors, bool is_write)
|
||||
{
|
||||
if ((emuMMC_ctx.EMMC_Type == emuMMC_SD))
|
||||
if (emuMMC_ctx.EMMC_Type == emuMMC_SD_Raw)
|
||||
{
|
||||
// raw partition sector offset: emuMMC_ctx.EMMC_StoragePartitionOffset.
|
||||
sector += emuMMC_ctx.EMMC_StoragePartitionOffset;
|
||||
// Set physical partition offset.
|
||||
sector += (sdmmc_nand_get_active_partition_index() * BOOT_PARTITION_SIZE);
|
||||
|
||||
if (__builtin_expect(sector + num_sectors > sd_storage.sec_cnt, 0))
|
||||
return 0; // Out of bounds. Can only happen with Nand Patrol if resized.
|
||||
|
||||
if (!is_write)
|
||||
return sdmmc_storage_read(&sd_storage, sector, num_sectors, buf);
|
||||
else
|
||||
@ -290,32 +342,87 @@ static uint64_t emummc_read_write_inner(void *buf, unsigned int sector, unsigned
|
||||
case FS_EMMC_PARTITION_GPP:
|
||||
if (f_emu.parts)
|
||||
{
|
||||
if (__builtin_expect(sector + num_sectors > f_emu.total_sect, 0))
|
||||
return 0; // Out of bounds. Can only happen with Nand Patrol if resized.
|
||||
|
||||
fp = &f_emu.fp_gpp[sector / f_emu.part_size];
|
||||
sector = sector % f_emu.part_size;
|
||||
|
||||
// Special handling for reads/writes which cross file-boundaries.
|
||||
if (__builtin_expect(sector + num_sectors > f_emu.part_size, 0))
|
||||
{
|
||||
unsigned int remaining = num_sectors;
|
||||
while (remaining > 0) {
|
||||
const unsigned int cur_sectors = MIN(remaining, f_emu.part_size - sector);
|
||||
|
||||
if (f_lseek(fp, (uint64_t)sector << 9) != FR_OK)
|
||||
return 0; // Out of bounds.
|
||||
|
||||
if (!is_write)
|
||||
{
|
||||
if (f_read_fast(fp, buf, (uint64_t)cur_sectors << 9) != FR_OK)
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (f_write_fast(fp, buf, (uint64_t)cur_sectors << 9) != FR_OK)
|
||||
return 0;
|
||||
}
|
||||
|
||||
buf = (char *)buf + ((uint64_t)cur_sectors << 9);
|
||||
remaining -= cur_sectors;
|
||||
sector = 0;
|
||||
++fp;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fp = &f_emu.fp_gpp[0];
|
||||
}
|
||||
break;
|
||||
|
||||
case FS_EMMC_PARTITION_BOOT1:
|
||||
fp = &f_emu.fp_boot1;
|
||||
break;
|
||||
|
||||
case FS_EMMC_PARTITION_BOOT0:
|
||||
fp = &f_emu.fp_boot0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (f_lseek(fp, sector << 9) != FR_OK)
|
||||
return 0; // Out of bounds.
|
||||
if (f_lseek(fp, (uint64_t)sector << 9) != FR_OK)
|
||||
return 0; // Out of bounds. Can only happen with Nand Patrol if resized.
|
||||
|
||||
uint64_t res = 0;
|
||||
if (!is_write)
|
||||
res = !f_read_fast(fp, buf, num_sectors << 9);
|
||||
return !f_read_fast(fp, buf, (uint64_t)num_sectors << 9);
|
||||
else
|
||||
res = !f_write_fast(fp, buf, num_sectors << 9);
|
||||
return !f_write_fast(fp, buf, (uint64_t)num_sectors << 9);
|
||||
}
|
||||
|
||||
return res;
|
||||
// Controller open wrapper
|
||||
uint64_t sdmmc_wrapper_controller_open(int mmc_id)
|
||||
{
|
||||
uint64_t result;
|
||||
sdmmc_accessor_t *_this;
|
||||
_this = sdmmc_accessor_get(mmc_id);
|
||||
|
||||
if (_this != NULL)
|
||||
{
|
||||
// Lock eMMC xfer while SD card is being initialized by FS.
|
||||
if (mmc_id == FS_SDMMC_SD)
|
||||
mutex_lock_handler(FS_SDMMC_EMMC); // Recursive Mutex, handler will lock SD as well if custom_driver
|
||||
|
||||
result = _this->vtab->sdmmc_accessor_controller_open(_this);
|
||||
|
||||
// Unlock eMMC.
|
||||
if (mmc_id == FS_SDMMC_SD)
|
||||
mutex_unlock_handler(FS_SDMMC_EMMC);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
fatal_abort(Fatal_OpenAccessor);
|
||||
}
|
||||
|
||||
// Controller close wrapper
|
||||
@ -327,9 +434,7 @@ uint64_t sdmmc_wrapper_controller_close(int mmc_id)
|
||||
if (_this != NULL)
|
||||
{
|
||||
if (mmc_id == FS_SDMMC_SD)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mmc_id == FS_SDMMC_EMMC)
|
||||
{
|
||||
@ -389,7 +494,7 @@ uint64_t sdmmc_wrapper_read(void *buf, uint64_t bufSize, int mmc_id, unsigned in
|
||||
if (first_sd_read)
|
||||
{
|
||||
first_sd_read = false;
|
||||
if (emuMMC_ctx.EMMC_Type == emuMMC_SD)
|
||||
if (emuMMC_ctx.EMMC_Type == emuMMC_SD_Raw)
|
||||
{
|
||||
// Because some SD cards have issues with emuMMC's driver
|
||||
// we currently swap to FS's driver after first SD read
|
||||
@ -400,7 +505,7 @@ uint64_t sdmmc_wrapper_read(void *buf, uint64_t bufSize, int mmc_id, unsigned in
|
||||
}
|
||||
}
|
||||
|
||||
// Call hekates driver.
|
||||
// Call hekate's driver.
|
||||
if (sdmmc_storage_read(&sd_storage, sector, num_sectors, buf))
|
||||
{
|
||||
mutex_unlock_handler(mmc_id);
|
||||
@ -449,8 +554,6 @@ uint64_t sdmmc_wrapper_write(int mmc_id, unsigned int sector, unsigned int num_s
|
||||
mutex_lock_handler(mmc_id);
|
||||
_current_accessor = _this;
|
||||
|
||||
sector += 0;
|
||||
|
||||
// Call hekates driver.
|
||||
if (sdmmc_storage_write(&sd_storage, sector, num_sectors, buf))
|
||||
{
|
||||
|
13
emummc/source/emuMMC/emummc.h
vendored
13
emummc/source/emuMMC/emummc.h
vendored
@ -36,6 +36,9 @@ extern "C" {
|
||||
#include "../FS/FS.h"
|
||||
#include "../libs/fatfs/ff.h"
|
||||
|
||||
#define EMUMMC_FILE_MAX_PARTS 32
|
||||
#define EMUMMC_FP_CLMT_COUNT 1024
|
||||
|
||||
// FS typedefs
|
||||
typedef sdmmc_accessor_t *(*_sdmmc_accessor_gc)();
|
||||
typedef sdmmc_accessor_t *(*_sdmmc_accessor_sd)();
|
||||
@ -52,6 +55,7 @@ void mutex_lock_handler(int mmc_id);
|
||||
void mutex_unlock_handler(int mmc_id);
|
||||
|
||||
// Hooks
|
||||
uint64_t sdmmc_wrapper_controller_open(int mmc_id);
|
||||
uint64_t sdmmc_wrapper_controller_close(int mmc_id);
|
||||
uint64_t sdmmc_wrapper_read(void *buf, uint64_t bufSize, int mmc_id, unsigned int sector, unsigned int num_sectors);
|
||||
uint64_t sdmmc_wrapper_write(int mmc_id, unsigned int sector, unsigned int num_sectors, void *buf, uint64_t bufSize);
|
||||
@ -62,11 +66,12 @@ typedef struct _file_based_ctxt
|
||||
uint64_t parts;
|
||||
uint64_t part_size;
|
||||
FIL fp_boot0;
|
||||
DWORD clmt_boot0[0x400];
|
||||
DWORD clmt_boot0[EMUMMC_FP_CLMT_COUNT];
|
||||
FIL fp_boot1;
|
||||
DWORD clmt_boot1[0x400];
|
||||
FIL fp_gpp[32];
|
||||
DWORD clmt_gpp[0x8000];
|
||||
DWORD clmt_boot1[EMUMMC_FP_CLMT_COUNT];
|
||||
FIL fp_gpp[EMUMMC_FILE_MAX_PARTS];
|
||||
DWORD clmt_gpp[EMUMMC_FILE_MAX_PARTS * EMUMMC_FP_CLMT_COUNT];
|
||||
uint64_t total_sect;
|
||||
} file_based_ctxt;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
2
emummc/source/emuMMC/emummc_ctx.h
vendored
2
emummc/source/emuMMC/emummc_ctx.h
vendored
@ -30,7 +30,7 @@ enum emuMMC_Type
|
||||
emuMMC_EMMC = 0,
|
||||
|
||||
// SD Device raw
|
||||
emuMMC_SD,
|
||||
emuMMC_SD_Raw,
|
||||
// SD Device File
|
||||
emuMMC_SD_File,
|
||||
|
||||
|
13
emummc/source/main.c
vendored
13
emummc/source/main.c
vendored
@ -92,7 +92,7 @@ volatile __attribute__((aligned(0x1000))) emuMMC_ctx_t emuMMC_ctx = {
|
||||
.fs_ver = FS_VER_MAX,
|
||||
|
||||
// SD Default Metadata
|
||||
.SD_Type = emuMMC_SD,
|
||||
.SD_Type = emuMMC_SD_Raw,
|
||||
.SD_StoragePartitionOffset = 0,
|
||||
|
||||
// EMMC Default Metadata
|
||||
@ -155,8 +155,8 @@ void __initheap(void)
|
||||
static void _receive_process_handle_thread(void *_session_handle) {
|
||||
Result rc;
|
||||
|
||||
// Convert the argument to a handle we can use.
|
||||
Handle session_handle = (Handle)(uintptr_t)_session_handle;
|
||||
// Convert the argument to a handle copy we can use.
|
||||
Handle session_handle = *(Handle*)_session_handle;
|
||||
|
||||
// Receive the request from the client thread.
|
||||
memset(armGetTls(), 0, 0x10);
|
||||
@ -194,7 +194,7 @@ static void _init_process_handle(void) {
|
||||
|
||||
// Create a new thread to receive our handle.
|
||||
Handle thread_handle;
|
||||
rc = svcCreateThread(&thread_handle, _receive_process_handle_thread, (void *)(uintptr_t)server_handle, temp_thread_stack + sizeof(temp_thread_stack), 0x20, 3);
|
||||
rc = svcCreateThread(&thread_handle, _receive_process_handle_thread, &server_handle, temp_thread_stack + sizeof(temp_thread_stack), 0x20, 3);
|
||||
if (rc != 0)
|
||||
{
|
||||
fatal_abort(Fatal_BadResult);
|
||||
@ -285,6 +285,9 @@ void setup_hooks(void)
|
||||
INJECT_HOOK(fs_offsets->sdmmc_wrapper_read, sdmmc_wrapper_read);
|
||||
// sdmmc_wrapper_write hook
|
||||
INJECT_HOOK(fs_offsets->sdmmc_wrapper_write, sdmmc_wrapper_write);
|
||||
// sdmmc_wrapper_controller_open hook
|
||||
if (fs_offsets->sdmmc_accessor_controller_open)
|
||||
INJECT_HOOK(fs_offsets->sdmmc_accessor_controller_open, sdmmc_wrapper_controller_open);
|
||||
// sdmmc_wrapper_controller_close hook
|
||||
INJECT_HOOK(fs_offsets->sdmmc_accessor_controller_close, sdmmc_wrapper_controller_close);
|
||||
|
||||
@ -346,7 +349,7 @@ static void load_emummc_ctx(void)
|
||||
emuMMC_ctx.id = config.base_cfg.id;
|
||||
emuMMC_ctx.EMMC_Type = (enum emuMMC_Type)config.base_cfg.type;
|
||||
emuMMC_ctx.fs_ver = (enum FS_VER)config.base_cfg.fs_version;
|
||||
if (emuMMC_ctx.EMMC_Type == emuMMC_SD)
|
||||
if (emuMMC_ctx.EMMC_Type == emuMMC_SD_Raw)
|
||||
{
|
||||
emuMMC_ctx.EMMC_StoragePartitionOffset = config.partition_cfg.start_sector;
|
||||
}
|
||||
|
41
emummc/source/nx/smc.c
vendored
41
emummc/source/nx/smc.c
vendored
@ -59,6 +59,47 @@ Result smcGetConfig(SplConfigItem config_item, u64 *out_config)
|
||||
return rc;
|
||||
}
|
||||
|
||||
SplHardwareType splGetHardwareType(void)
|
||||
{
|
||||
u64 value;
|
||||
Result rc = smcGetConfig(SplConfigItem_HardwareType, &value);
|
||||
if (rc != 0)
|
||||
{
|
||||
fatal_abort(Fatal_BadResult);
|
||||
}
|
||||
return (SplHardwareType)value;
|
||||
}
|
||||
|
||||
SplSocType splGetSocType(void)
|
||||
{
|
||||
static SplSocType soc_type;
|
||||
static bool soc_type_set = false;
|
||||
|
||||
if (soc_type_set)
|
||||
return soc_type;
|
||||
|
||||
switch (splGetHardwareType())
|
||||
{
|
||||
case SplHardwareType_Icosa:
|
||||
case SplHardwareType_Copper:
|
||||
soc_type = SplSocType_Erista;
|
||||
break;
|
||||
case SplHardwareType_Hoag:
|
||||
case SplHardwareType_Iowa:
|
||||
case SplHardwareType_Calcio:
|
||||
case SplHardwareType_Five:
|
||||
soc_type = SplSocType_Mariko;
|
||||
break;
|
||||
default:
|
||||
fatal_abort(Fatal_InvalidEnum);
|
||||
}
|
||||
|
||||
soc_type_set = true;
|
||||
|
||||
return soc_type;
|
||||
}
|
||||
|
||||
|
||||
Result smcCopyToIram(uintptr_t iram_addr, const void *src_addr, u32 size)
|
||||
{
|
||||
SecmonArgs args;
|
||||
|
17
emummc/source/nx/smc.h
vendored
17
emummc/source/nx/smc.h
vendored
@ -37,6 +37,20 @@ typedef enum {
|
||||
SplConfigItem_HasRcmBugPatch = 65004,
|
||||
} SplConfigItem;
|
||||
|
||||
typedef enum {
|
||||
SplSocType_Erista = 0,
|
||||
SplSocType_Mariko = 1,
|
||||
} SplSocType;
|
||||
|
||||
typedef enum {
|
||||
SplHardwareType_Icosa = 0,
|
||||
SplHardwareType_Copper = 1,
|
||||
SplHardwareType_Hoag = 2,
|
||||
SplHardwareType_Iowa = 3,
|
||||
SplHardwareType_Calcio = 4,
|
||||
SplHardwareType_Five = 5,
|
||||
} SplHardwareType;
|
||||
|
||||
typedef enum {
|
||||
EXO_EMUMMC_TYPE_NONE = 0,
|
||||
EXO_EMUMMC_TYPE_PARTITION = 1,
|
||||
@ -69,6 +83,9 @@ typedef struct {
|
||||
|
||||
Result smcGetConfig(SplConfigItem config_item, u64 *out_config);
|
||||
|
||||
SplHardwareType splGetHardwareType(void);
|
||||
SplSocType splGetSocType(void);
|
||||
|
||||
void smcRebootToRcm(void);
|
||||
void smcRebootToIramPayload(void);
|
||||
void smcPerformShutdown(void);
|
||||
|
3
emummc/source/soc/clock.c
vendored
3
emummc/source/soc/clock.c
vendored
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@ -410,7 +411,7 @@ void clock_sdmmc_get_card_clock_div(u32 *pclock, u16 *pdivisor, u32 type)
|
||||
*pclock = 40800;
|
||||
*pdivisor = 1;
|
||||
break;
|
||||
case SDHCI_TIMING_MMC_DDR52: // Actual IO Freq: 49.92 MHz.
|
||||
case SDHCI_TIMING_MMC_HS102: // Actual IO Freq: 99.84 MHz.
|
||||
*pclock = 200000;
|
||||
*pdivisor = 2;
|
||||
break;
|
||||
|
1
emummc/source/soc/clock.h
vendored
1
emummc/source/soc/clock.h
vendored
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
172
emummc/source/soc/gpio.c
vendored
172
emummc/source/soc/gpio.c
vendored
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2019 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@ -17,78 +18,151 @@
|
||||
#include "../soc/gpio.h"
|
||||
#include "../soc/t210.h"
|
||||
|
||||
static const u16 _gpio_cnf[31] = {
|
||||
0x000, 0x004, 0x008, 0x00C,
|
||||
0x100, 0x104, 0x108, 0x10C,
|
||||
0x200, 0x204, 0x208, 0x20C,
|
||||
0x300, 0x304, 0x308, 0x30C,
|
||||
0x400, 0x404, 0x408, 0x40C,
|
||||
0x500, 0x504, 0x508, 0x50C,
|
||||
0x600, 0x604, 0x608, 0x60C,
|
||||
0x700, 0x704, 0x708
|
||||
};
|
||||
#define GPIO_BANK_IDX(port) ((port) >> 2)
|
||||
|
||||
static const u16 _gpio_oe[31] = {
|
||||
0x010, 0x014, 0x018, 0x01C,
|
||||
0x110, 0x114, 0x118, 0x11C,
|
||||
0x210, 0x214, 0x218, 0x21C,
|
||||
0x310, 0x314, 0x318, 0x31C,
|
||||
0x410, 0x414, 0x418, 0x41C,
|
||||
0x510, 0x514, 0x518, 0x51C,
|
||||
0x610, 0x614, 0x618, 0x61C,
|
||||
0x710, 0x714, 0x718
|
||||
};
|
||||
#define GPIO_CNF_OFFSET(port) (0x00 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_OE_OFFSET(port) (0x10 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_OUT_OFFSET(port) (0x20 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_IN_OFFSET(port) (0x30 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_INT_STA_OFFSET(port) (0x40 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_INT_ENB_OFFSET(port) (0x50 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_INT_LVL_OFFSET(port) (0x60 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_INT_CLR_OFFSET(port) (0x70 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
|
||||
static const u16 _gpio_out[31] = {
|
||||
0x020, 0x024, 0x028, 0x02C,
|
||||
0x120, 0x124, 0x128, 0x12C,
|
||||
0x220, 0x224, 0x228, 0x22C,
|
||||
0x320, 0x324, 0x328, 0x32C,
|
||||
0x420, 0x424, 0x428, 0x42C,
|
||||
0x520, 0x524, 0x528, 0x52C,
|
||||
0x620, 0x624, 0x628, 0x62C,
|
||||
0x720, 0x724, 0x728
|
||||
};
|
||||
#define GPIO_CNF_MASKED_OFFSET(port) (0x80 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_OE_MASKED_OFFSET(port) (0x90 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_OUT_MASKED_OFFSET(port) (0xA0 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_INT_STA_MASKED_OFFSET(port) (0xC0 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_INT_ENB_MASKED_OFFSET(port) (0xD0 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_INT_LVL_MASKED_OFFSET(port) (0xE0 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
|
||||
static const u16 _gpio_in[31] = {
|
||||
0x030, 0x034, 0x038, 0x03C,
|
||||
0x130, 0x134, 0x138, 0x13C,
|
||||
0x230, 0x234, 0x238, 0x23C,
|
||||
0x330, 0x334, 0x338, 0x33C,
|
||||
0x430, 0x434, 0x438, 0x43C,
|
||||
0x530, 0x534, 0x538, 0x53C,
|
||||
0x630, 0x634, 0x638, 0x63C,
|
||||
0x730, 0x734, 0x738
|
||||
#define GPIO_IRQ_BANK1 32
|
||||
#define GPIO_IRQ_BANK2 33
|
||||
#define GPIO_IRQ_BANK3 34
|
||||
#define GPIO_IRQ_BANK4 35
|
||||
#define GPIO_IRQ_BANK5 55
|
||||
#define GPIO_IRQ_BANK6 87
|
||||
#define GPIO_IRQ_BANK7 89
|
||||
#define GPIO_IRQ_BANK8 125
|
||||
|
||||
static u8 gpio_bank_irq_ids[8] = {
|
||||
GPIO_IRQ_BANK1, GPIO_IRQ_BANK2, GPIO_IRQ_BANK3, GPIO_IRQ_BANK4,
|
||||
GPIO_IRQ_BANK5, GPIO_IRQ_BANK6, GPIO_IRQ_BANK7, GPIO_IRQ_BANK8
|
||||
};
|
||||
|
||||
void gpio_config(u32 port, u32 pins, int mode)
|
||||
{
|
||||
u32 offset = GPIO_CNF_OFFSET(port);
|
||||
|
||||
if (mode)
|
||||
GPIO(_gpio_cnf[port]) |= pins;
|
||||
GPIO(offset) |= pins;
|
||||
else
|
||||
GPIO(_gpio_cnf[port]) &= ~pins;
|
||||
(void)GPIO(_gpio_cnf[port]);
|
||||
GPIO(offset) &= ~pins;
|
||||
|
||||
(void)GPIO(offset); // Commit the write.
|
||||
}
|
||||
|
||||
void gpio_output_enable(u32 port, u32 pins, int enable)
|
||||
{
|
||||
u32 port_offset = GPIO_OE_OFFSET(port);
|
||||
|
||||
if (enable)
|
||||
GPIO(_gpio_oe[port]) |= pins;
|
||||
GPIO(port_offset) |= pins;
|
||||
else
|
||||
GPIO(_gpio_oe[port]) &= ~pins;
|
||||
(void)GPIO(_gpio_oe[port]);
|
||||
GPIO(port_offset) &= ~pins;
|
||||
|
||||
(void)GPIO(port_offset); // Commit the write.
|
||||
}
|
||||
|
||||
void gpio_write(u32 port, u32 pins, int high)
|
||||
{
|
||||
u32 port_offset = GPIO_OUT_OFFSET(port);
|
||||
|
||||
if (high)
|
||||
GPIO(_gpio_out[port]) |= pins;
|
||||
GPIO(port_offset) |= pins;
|
||||
else
|
||||
GPIO(_gpio_out[port]) &= ~pins;
|
||||
(void)GPIO(_gpio_out[port]);
|
||||
GPIO(port_offset) &= ~pins;
|
||||
|
||||
(void)GPIO(port_offset); // Commit the write.
|
||||
}
|
||||
|
||||
int gpio_read(u32 port, u32 pins)
|
||||
{
|
||||
return (GPIO(_gpio_in[port]) & pins) ? 1 : 0;
|
||||
u32 port_offset = GPIO_IN_OFFSET(port);
|
||||
|
||||
return (GPIO(port_offset) & pins) ? 1 : 0;
|
||||
}
|
||||
|
||||
static void _gpio_interrupt_clear(u32 port, u32 pins)
|
||||
{
|
||||
u32 port_offset = GPIO_INT_CLR_OFFSET(port);
|
||||
|
||||
GPIO(port_offset) |= pins;
|
||||
|
||||
(void)GPIO(port_offset); // Commit the write.
|
||||
}
|
||||
|
||||
int gpio_interrupt_status(u32 port, u32 pins)
|
||||
{
|
||||
u32 port_offset = GPIO_INT_STA_OFFSET(port);
|
||||
u32 enabled = GPIO(GPIO_INT_ENB_OFFSET(port)) & pins;
|
||||
|
||||
int status = ((GPIO(port_offset) & pins) && enabled) ? 1 : 0;
|
||||
|
||||
// Clear the interrupt status.
|
||||
if (status)
|
||||
_gpio_interrupt_clear(port, pins);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void gpio_interrupt_enable(u32 port, u32 pins, int enable)
|
||||
{
|
||||
u32 port_offset = GPIO_INT_ENB_OFFSET(port);
|
||||
|
||||
// Clear any possible stray interrupt.
|
||||
_gpio_interrupt_clear(port, pins);
|
||||
|
||||
if (enable)
|
||||
GPIO(port_offset) |= pins;
|
||||
else
|
||||
GPIO(port_offset) &= ~pins;
|
||||
|
||||
(void)GPIO(port_offset); // Commit the write.
|
||||
}
|
||||
|
||||
void gpio_interrupt_level(u32 port, u32 pins, int high, int edge, int delta)
|
||||
{
|
||||
u32 port_offset = GPIO_INT_LVL_OFFSET(port);
|
||||
|
||||
u32 val = GPIO(port_offset);
|
||||
|
||||
if (high)
|
||||
val |= pins;
|
||||
else
|
||||
val &= ~pins;
|
||||
|
||||
if (edge)
|
||||
val |= pins << 8;
|
||||
else
|
||||
val &= ~(pins << 8);
|
||||
|
||||
if (delta)
|
||||
val |= pins << 16;
|
||||
else
|
||||
val &= ~(pins << 16);
|
||||
|
||||
GPIO(port_offset) = val;
|
||||
|
||||
(void)GPIO(port_offset); // Commit the write.
|
||||
|
||||
// Clear any possible stray interrupt.
|
||||
_gpio_interrupt_clear(port, pins);
|
||||
}
|
||||
|
||||
u32 gpio_get_bank_irq_id(u32 port)
|
||||
{
|
||||
u32 bank_idx = GPIO_BANK_IDX(port);
|
||||
|
||||
return gpio_bank_irq_ids[bank_idx];
|
||||
}
|
||||
|
20
emummc/source/soc/gpio.h
vendored
20
emummc/source/soc/gpio.h
vendored
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2019 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@ -21,10 +22,23 @@
|
||||
|
||||
#define GPIO_MODE_SPIO 0
|
||||
#define GPIO_MODE_GPIO 1
|
||||
|
||||
#define GPIO_OUTPUT_DISABLE 0
|
||||
#define GPIO_OUTPUT_ENABLE 1
|
||||
|
||||
#define GPIO_IRQ_DISABLE 0
|
||||
#define GPIO_IRQ_ENABLE 1
|
||||
|
||||
#define GPIO_LOW 0
|
||||
#define GPIO_HIGH 1
|
||||
#define GPIO_FALLING 0
|
||||
#define GPIO_RISING 1
|
||||
|
||||
#define GPIO_LEVEL 0
|
||||
#define GPIO_EDGE 1
|
||||
|
||||
#define GPIO_CONFIGURED_EDGE 0
|
||||
#define GPIO_ANY_EDGE_CHANGE 1
|
||||
|
||||
/*! GPIO pins (0-7 for each port). */
|
||||
#define GPIO_PIN_0 (1 << 0)
|
||||
@ -72,6 +86,10 @@
|
||||
void gpio_config(u32 port, u32 pins, int mode);
|
||||
void gpio_output_enable(u32 port, u32 pins, int enable);
|
||||
void gpio_write(u32 port, u32 pins, int high);
|
||||
int gpio_read(u32 port, u32 pins);
|
||||
int gpio_read(u32 port, u32 pins);
|
||||
int gpio_interrupt_status(u32 port, u32 pins);
|
||||
void gpio_interrupt_enable(u32 port, u32 pins, int enable);
|
||||
void gpio_interrupt_level(u32 port, u32 pins, int high, int edge, int delta);
|
||||
u32 gpio_get_bank_irq_id(u32 port);
|
||||
|
||||
#endif
|
||||
|
158
emummc/source/soc/i2c.c
vendored
158
emummc/source/soc/i2c.c
vendored
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@ -20,25 +21,88 @@
|
||||
#include "../utils/util.h"
|
||||
#include "t210.h"
|
||||
|
||||
// TODO: not hardcode I2C_5
|
||||
static u64 i2c_addrs[] = {
|
||||
0x7000C000, 0x7000C400, 0x7000C500,
|
||||
0x7000C700, 0x7000D000, 0x7000D100
|
||||
#define I2C_PACKET_PROT_I2C (1 << 4)
|
||||
#define I2C_HEADER_CONT_XFER (1 << 15)
|
||||
#define I2C_HEADER_REP_START (1 << 16)
|
||||
#define I2C_HEADER_IE_ENABLE (1 << 17)
|
||||
#define I2C_HEADER_READ (1 << 19)
|
||||
|
||||
#define I2C_CNFG (0x00 / 4)
|
||||
#define CMD1_WRITE (0 << 6)
|
||||
#define CMD1_READ (1 << 6)
|
||||
#define NORMAL_MODE_GO (1 << 9)
|
||||
#define PACKET_MODE_GO (1 << 10)
|
||||
#define NEW_MASTER_FSM (1 << 11)
|
||||
#define DEBOUNCE_CNT_4T (2 << 12)
|
||||
|
||||
#define I2C_CMD_ADDR0 (0x04 / 4)
|
||||
#define ADDR0_WRITE 0
|
||||
#define ADDR0_READ 1
|
||||
|
||||
#define I2C_CMD_DATA1 (0x0C / 4)
|
||||
#define I2C_CMD_DATA2 (0x10 / 4)
|
||||
|
||||
#define I2C_STATUS (0x1C / 4)
|
||||
#define I2C_STATUS_NOACK (0xF << 0)
|
||||
#define I2C_STATUS_BUSY (1 << 8)
|
||||
|
||||
#define I2C_TX_FIFO (0x50 / 4)
|
||||
#define I2C_RX_FIFO (0x54 / 4)
|
||||
|
||||
#define I2C_FIFO_CONTROL (0x5C / 4)
|
||||
#define RX_FIFO_FLUSH (1 << 0)
|
||||
#define TX_FIFO_FLUSH (1 << 1)
|
||||
|
||||
#define I2C_FIFO_STATUS (0x60 / 4)
|
||||
#define RX_FIFO_FULL_CNT (0xF << 0)
|
||||
#define TX_FIFO_EMPTY_CNT (0xF << 4)
|
||||
|
||||
#define I2C_INT_EN (0x64 / 4)
|
||||
#define I2C_INT_STATUS (0x68 / 4)
|
||||
#define I2C_INT_SOURCE (0x70 / 4)
|
||||
#define RX_FIFO_DATA_REQ (1 << 0)
|
||||
#define TX_FIFO_DATA_REQ (1 << 1)
|
||||
#define ARB_LOST (1 << 2)
|
||||
#define NO_ACK (1 << 3)
|
||||
#define RX_FIFO_UNDER (1 << 4)
|
||||
#define TX_FIFO_OVER (1 << 5)
|
||||
#define ALL_PACKETS_COMPLETE (1 << 6)
|
||||
#define PACKET_COMPLETE (1 << 7)
|
||||
#define BUS_CLEAR_DONE (1 << 11)
|
||||
|
||||
#define I2C_CLK_DIVISOR (0x6C / 4)
|
||||
|
||||
#define I2C_BUS_CLEAR_CONFIG (0x84 / 4)
|
||||
#define BC_ENABLE (1 << 0)
|
||||
#define BC_TERMINATE (1 << 1)
|
||||
|
||||
#define I2C_BUS_CLEAR_STATUS (0x88 / 4)
|
||||
|
||||
#define I2C_CONFIG_LOAD (0x8C / 4)
|
||||
#define MSTR_CONFIG_LOAD (1 << 0)
|
||||
#define TIMEOUT_CONFIG_LOAD (1 << 2)
|
||||
|
||||
static const u64 i2c_addrs[] = {
|
||||
0x7000C000, // I2C_1.
|
||||
0x7000C400, // I2C_2.
|
||||
0x7000C500, // I2C_3.
|
||||
0x7000C700, // I2C_4.
|
||||
0x7000D000, // I2C_5.
|
||||
0x7000D100 // I2C_6.
|
||||
};
|
||||
|
||||
static void _i2c_wait(vu32 *base)
|
||||
static void _i2c_load_cfg_wait(vu32 *base)
|
||||
{
|
||||
base[I2C_CONFIG_LOAD] = 0x25;
|
||||
|
||||
base[I2C_CONFIG_LOAD] = (1 << 5) | TIMEOUT_CONFIG_LOAD | MSTR_CONFIG_LOAD;
|
||||
for (u32 i = 0; i < 20; i++)
|
||||
{
|
||||
usleep(1);
|
||||
if (!(base[I2C_CONFIG_LOAD] & 1))
|
||||
if (!(base[I2C_CONFIG_LOAD] & MSTR_CONFIG_LOAD))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int _i2c_send_pkt(u32 idx, u32 x, u8 *buf, u32 size)
|
||||
static int _i2c_send_single(u32 i2c_idx, u32 dev_addr, u8 *buf, u32 size)
|
||||
{
|
||||
if (size > 4)
|
||||
return 0;
|
||||
@ -47,46 +111,58 @@ static int _i2c_send_pkt(u32 idx, u32 x, u8 *buf, u32 size)
|
||||
memcpy(&tmp, buf, size);
|
||||
|
||||
vu32 *base = (vu32 *)QueryIoMapping(i2c_addrs[I2C_5], 0x1000);
|
||||
base[I2C_CMD_ADDR0] = x << 1; //Set x (send mode).
|
||||
|
||||
// Set device address and send mode.
|
||||
base[I2C_CMD_ADDR0] = dev_addr << 1 | ADDR0_WRITE;
|
||||
base[I2C_CMD_DATA1] = tmp; //Set value.
|
||||
base[I2C_CNFG] = ((size - 1) << 1) | 0x2800; //Set size and send mode.
|
||||
_i2c_wait(base); //Kick transaction.
|
||||
// Set size and send mode.
|
||||
base[I2C_CNFG] = ((size - 1) << 1) | DEBOUNCE_CNT_4T | NEW_MASTER_FSM | CMD1_WRITE;
|
||||
|
||||
base[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFFDFF) | 0x200;
|
||||
// Load configuration.
|
||||
_i2c_load_cfg_wait(base);
|
||||
|
||||
u32 timeout = get_tmr_ms() + 1500;
|
||||
while (base[I2C_STATUS] & 0x100)
|
||||
// Initiate transaction on normal mode.
|
||||
base[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFF9FF) | NORMAL_MODE_GO;
|
||||
|
||||
u64 timeout = get_tmr_ms() + 100;
|
||||
while (base[I2C_STATUS] & I2C_STATUS_BUSY)
|
||||
{
|
||||
if (get_tmr_ms() > timeout)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (base[I2C_STATUS] << 28)
|
||||
if (base[I2C_STATUS] & I2C_STATUS_NOACK)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _i2c_recv_pkt(u32 idx, u8 *buf, u32 size, u32 x)
|
||||
static int _i2c_recv_single(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr)
|
||||
{
|
||||
if (size > 8)
|
||||
if (size > 4)
|
||||
return 0;
|
||||
|
||||
vu32 *base = (vu32 *)QueryIoMapping(i2c_addrs[I2C_5], 0x1000);
|
||||
base[I2C_CMD_ADDR0] = (x << 1) | 1; // Set x (recv mode).
|
||||
base[I2C_CNFG] = ((size - 1) << 1) | 0x2840; // Set size and recv mode.
|
||||
_i2c_wait(base); // Kick transaction.
|
||||
// Set device address and recv mode.
|
||||
base[I2C_CMD_ADDR0] = (dev_addr << 1) | ADDR0_READ;
|
||||
|
||||
base[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFFDFF) | 0x200;
|
||||
// Set size and recv mode.
|
||||
base[I2C_CNFG] = ((size - 1) << 1) | DEBOUNCE_CNT_4T | NEW_MASTER_FSM | CMD1_READ;
|
||||
|
||||
u32 timeout = get_tmr_ms() + 1500;
|
||||
while (base[I2C_STATUS] & 0x100)
|
||||
// Load configuration.
|
||||
_i2c_load_cfg_wait(base);
|
||||
|
||||
// Initiate transaction on normal mode.
|
||||
base[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFF9FF) | NORMAL_MODE_GO;
|
||||
|
||||
u64 timeout = get_tmr_ms() + 100;
|
||||
while (base[I2C_STATUS] & I2C_STATUS_BUSY)
|
||||
{
|
||||
if (get_tmr_ms() > timeout)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (base[I2C_STATUS] << 28)
|
||||
if (base[I2C_STATUS] & I2C_STATUS_NOACK)
|
||||
return 0;
|
||||
|
||||
u32 tmp = base[I2C_CMD_DATA1]; // Get LS value.
|
||||
@ -106,50 +182,52 @@ void i2c_init()
|
||||
{
|
||||
vu32 *base = (vu32 *)QueryIoMapping(i2c_addrs[I2C_5], 0x1000);
|
||||
|
||||
base[I2C_CLK_DIVISOR_REGISTER] = 0x50001;
|
||||
base[I2C_BUS_CLEAR_CONFIG] = 0x90003;
|
||||
_i2c_wait(base);
|
||||
base[I2C_CLK_DIVISOR] = (5 << 16) | 1; // SF mode Div: 6, HS mode div: 2.
|
||||
base[I2C_BUS_CLEAR_CONFIG] = (9 << 16) | BC_TERMINATE | BC_ENABLE;
|
||||
|
||||
// Load configuration.
|
||||
_i2c_load_cfg_wait(base);
|
||||
|
||||
for (u32 i = 0; i < 10; i++)
|
||||
{
|
||||
if (base[INTERRUPT_STATUS_REGISTER] & 0x800)
|
||||
if (base[I2C_INT_STATUS] & BUS_CLEAR_DONE)
|
||||
break;
|
||||
}
|
||||
|
||||
(vu32)base[I2C_BUS_CLEAR_STATUS];
|
||||
base[INTERRUPT_STATUS_REGISTER] = base[INTERRUPT_STATUS_REGISTER];
|
||||
base[I2C_INT_STATUS] = base[I2C_INT_STATUS];
|
||||
}
|
||||
|
||||
int i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size)
|
||||
int i2c_send_buf_small(u32 i2c_idx, u32 dev_addr, u32 reg, u8 *buf, u32 size)
|
||||
{
|
||||
u8 tmp[4];
|
||||
|
||||
if (size > 3)
|
||||
return 0;
|
||||
|
||||
tmp[0] = y;
|
||||
tmp[0] = reg;
|
||||
memcpy(tmp + 1, buf, size);
|
||||
|
||||
return _i2c_send_pkt(idx, x, tmp, size + 1);
|
||||
return _i2c_send_single(i2c_idx, dev_addr, tmp, size + 1);
|
||||
}
|
||||
|
||||
int i2c_recv_buf_small(u8 *buf, u32 size, u32 idx, u32 x, u32 y)
|
||||
int i2c_recv_buf_small(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr, u32 reg)
|
||||
{
|
||||
int res = _i2c_send_pkt(idx, x, (u8 *)&y, 1);
|
||||
int res = _i2c_send_single(i2c_idx, dev_addr, (u8 *)®, 1);
|
||||
if (res)
|
||||
res = _i2c_recv_pkt(idx, buf, size, x);
|
||||
res = _i2c_recv_single(i2c_idx, buf, size, dev_addr);
|
||||
return res;
|
||||
}
|
||||
|
||||
int i2c_send_byte(u32 idx, u32 x, u32 y, u8 b)
|
||||
int i2c_send_byte(u32 i2c_idx, u32 dev_addr, u32 reg, u8 val)
|
||||
{
|
||||
return i2c_send_buf_small(idx, x, y, &b, 1);
|
||||
return i2c_send_buf_small(i2c_idx, dev_addr, reg, &val, 1);
|
||||
}
|
||||
|
||||
u8 i2c_recv_byte(u32 idx, u32 x, u32 y)
|
||||
u8 i2c_recv_byte(u32 i2c_idx, u32 dev_addr, u32 reg)
|
||||
{
|
||||
u8 tmp = 0;
|
||||
i2c_recv_buf_small(&tmp, 1, idx, x, y);
|
||||
i2c_recv_buf_small(&tmp, 1, i2c_idx, dev_addr, reg);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
20
emummc/source/soc/i2c.h
vendored
20
emummc/source/soc/i2c.h
vendored
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2020 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@ -26,21 +27,10 @@
|
||||
#define I2C_5 4
|
||||
#define I2C_6 5
|
||||
|
||||
#define I2C_CNFG 0x00
|
||||
#define I2C_CMD_ADDR0 0x01
|
||||
#define I2C_CMD_DATA1 0x03
|
||||
#define I2C_CMD_DATA2 0x04
|
||||
#define I2C_STATUS 0x07
|
||||
#define INTERRUPT_STATUS_REGISTER 0x1A
|
||||
#define I2C_CLK_DIVISOR_REGISTER 0x1B
|
||||
#define I2C_BUS_CLEAR_CONFIG 0x21
|
||||
#define I2C_BUS_CLEAR_STATUS 0x22
|
||||
#define I2C_CONFIG_LOAD 0x23
|
||||
|
||||
void i2c_init();
|
||||
int i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size);
|
||||
int i2c_recv_buf_small(u8 *buf, u32 size, u32 idx, u32 x, u32 y);
|
||||
int i2c_send_byte(u32 idx, u32 x, u32 y, u8 b);
|
||||
u8 i2c_recv_byte(u32 idx, u32 x, u32 y);
|
||||
int i2c_send_buf_small(u32 i2c_idx, u32 dev_addr, u32 reg, u8 *buf, u32 size);
|
||||
int i2c_recv_buf_small(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr, u32 reg);
|
||||
int i2c_send_byte(u32 i2c_idx, u32 dev_addr, u32 reg, u8 val);
|
||||
u8 i2c_recv_byte(u32 i2c_idx, u32 dev_addr, u32 reg);
|
||||
|
||||
#endif
|
||||
|
15
emummc/source/soc/pinmux.h
vendored
15
emummc/source/soc/pinmux.h
vendored
@ -51,6 +51,18 @@
|
||||
#define PINMUX_AUX_GPIO_PE6 0x248
|
||||
#define PINMUX_AUX_GPIO_PH6 0x250
|
||||
#define PINMUX_AUX_GPIO_PZ1 0x280
|
||||
/* Only in T210B01 */
|
||||
#define PINMUX_AUX_SDMMC2_DAT0 0x294
|
||||
#define PINMUX_AUX_SDMMC2_DAT1 0x298
|
||||
#define PINMUX_AUX_SDMMC2_DAT2 0x29C
|
||||
#define PINMUX_AUX_SDMMC2_DAT3 0x2A0
|
||||
#define PINMUX_AUX_SDMMC2_DAT4 0x2A4
|
||||
#define PINMUX_AUX_SDMMC2_DAT5 0x2A8
|
||||
#define PINMUX_AUX_SDMMC2_DAT6 0x2AC
|
||||
#define PINMUX_AUX_SDMMC2_DAT7 0x2B0
|
||||
#define PINMUX_AUX_SDMMC2_CLK 0x2B4
|
||||
#define PINMUX_AUX_SDMMC2_CMD 0x2BC
|
||||
|
||||
/*! 0:UART-A, 1:UART-B, 3:UART-C, 3:UART-D */
|
||||
#define PINMUX_AUX_UARTX_TX(x) (0xE4 + 0x10 * (x))
|
||||
#define PINMUX_AUX_UARTX_RX(x) (0xE8 + 0x10 * (x))
|
||||
@ -78,7 +90,8 @@
|
||||
#define PINMUX_OPEN_DRAIN (1 << 11)
|
||||
#define PINMUX_SCHMT (1 << 12)
|
||||
|
||||
#define PINMUX_DRIVE_1X (0 << 13)
|
||||
#define PINMUX_DRIVE_MASK (3 << 13)
|
||||
#define PINMUX_DRIVE_1X (0 << 13)
|
||||
#define PINMUX_DRIVE_2X (1 << 13)
|
||||
#define PINMUX_DRIVE_3X (2 << 13)
|
||||
#define PINMUX_DRIVE_4X (3 << 13)
|
||||
|
1
emummc/source/utils/fatal.h
vendored
1
emummc/source/utils/fatal.h
vendored
@ -35,6 +35,7 @@ enum FatalReason
|
||||
Fatal_FatfsMount,
|
||||
Fatal_FatfsFileOpen,
|
||||
Fatal_FatfsMemExhaustion,
|
||||
Fatal_InvalidEnum,
|
||||
Fatal_Max
|
||||
};
|
||||
|
||||
|
2
emummc/source/utils/util.c
vendored
2
emummc/source/utils/util.c
vendored
@ -38,6 +38,7 @@ static inline uintptr_t _GetIoMapping(u64 io_addr, u64 io_size)
|
||||
u64 vaddr;
|
||||
u64 aligned_addr = (io_addr & ~0xFFFul);
|
||||
u64 aligned_size = io_size + (io_addr - aligned_addr);
|
||||
|
||||
if (emuMMC_ctx.fs_ver >= FS_VER_10_0_0) {
|
||||
u64 out_size;
|
||||
if (svcQueryIoMapping(&vaddr, &out_size, aligned_addr, aligned_size) != 0) {
|
||||
@ -48,6 +49,7 @@ static inline uintptr_t _GetIoMapping(u64 io_addr, u64 io_size)
|
||||
fatal_abort(Fatal_IoMappingLegacy);
|
||||
}
|
||||
}
|
||||
|
||||
return (uintptr_t)(vaddr + (io_addr - aligned_addr));
|
||||
}
|
||||
|
||||
|
3
emummc/tools/kip1converter.py
vendored
3
emummc/tools/kip1converter.py
vendored
@ -18,8 +18,7 @@ for i in range(6):
|
||||
if i < len(section_names):
|
||||
section["Name"] = section_names[i]
|
||||
|
||||
section["OutOffset"], section["DecompressedSize"], section["CompressedSize"], section["Attribute"] = unpack(
|
||||
"IIII", section_bytes)
|
||||
section["OutOffset"], section["DecompressedSize"], section["CompressedSize"], section["Attribute"] = unpack("IIII", section_bytes)
|
||||
sections.append(section)
|
||||
print(section)
|
||||
|
||||
|
@ -1,47 +1,75 @@
|
||||
TARGETS := exosphere.bin warmboot.bin program.lz4
|
||||
CLEAN_TARGETS := exosphere-clean program-clean boot_code-clean warmboot-clean
|
||||
ATMOSPHERE_BUILD_CONFIGS :=
|
||||
all: release
|
||||
|
||||
SUBFOLDERS := $(MODULES)
|
||||
define ATMOSPHERE_ADD_TARGET
|
||||
|
||||
all: exosphere.bin warmboot.bin
|
||||
ATMOSPHERE_BUILD_CONFIGS += $(strip $1)
|
||||
|
||||
clean: $(CLEAN_TARGETS)
|
||||
@rm -f exosphere.bin
|
||||
$(strip $1): exosphere$(strip $2).bin warmboot$(strip $2).bin mariko_fatal$(strip $2).bin
|
||||
|
||||
exosphere.bin: program.lz4 boot_code.lz4
|
||||
$(MAKE) -C loader_stub
|
||||
@cp loader_stub/loader_stub.bin exosphere.bin
|
||||
@printf LENY >> exosphere.bin
|
||||
@echo "Built exosphere.bin..."
|
||||
exosphere$(strip $2).bin: loader_stub/loader_stub$(strip $2).bin
|
||||
@cp loader_stub/loader_stub$(strip $2).bin exosphere$(strip $2).bin
|
||||
@printf LENY >> exosphere$(strip $2).bin
|
||||
@echo "Built exosphere$(strip $2).bin..."
|
||||
|
||||
program.lz4: build_program
|
||||
@cp program/program.lz4 program.lz4
|
||||
@cp program/boot_code.lz4 boot_code.lz4
|
||||
warmboot$(strip $2).bin: warmboot/warmboot$(strip $2).bin
|
||||
@cp warmboot/warmboot$(strip $2).bin warmboot$(strip $2).bin
|
||||
@echo "Built warmboot$(strip $2).bin..."
|
||||
|
||||
build_program:
|
||||
$(MAKE) -C program
|
||||
mariko_fatal$(strip $2).bin: mariko_fatal/mariko_fatal$(strip $2).bin
|
||||
@cp mariko_fatal/mariko_fatal$(strip $2).bin mariko_fatal$(strip $2).bin
|
||||
@echo "Built mariko_fatal$(strip $2).bin..."
|
||||
|
||||
warmboot.bin: build_warmboot
|
||||
@cp warmboot/warmboot.bin warmboot.bin
|
||||
check_program_$(strip $1):
|
||||
@$$(MAKE) -C program $(strip $1)
|
||||
|
||||
build_warmboot:
|
||||
$(MAKE) -C warmboot
|
||||
check_warmboot_$(strip $1):
|
||||
@$$(MAKE) -C warmboot $(strip $1)
|
||||
|
||||
boot_code.lz4: program.lz4
|
||||
check_mariko_fatal_$(strip $1):
|
||||
@$$(MAKE) -C mariko_fatal $(strip $1)
|
||||
|
||||
exosphere-clean:
|
||||
$(MAKE) -C loader_stub clean
|
||||
@rm -f exosphere.bin
|
||||
loader_stub/loader_stub$(strip $2).bin: check_program_$(strip $1)
|
||||
@$$(MAKE) -C loader_stub $(strip $1)
|
||||
|
||||
program-clean:
|
||||
$(MAKE) -C program clean
|
||||
@rm -f program.lz4
|
||||
warmboot/warmboot$(strip $2).bin: check_warmboot_$(strip $1)
|
||||
|
||||
warmboot-clean:
|
||||
$(MAKE) -C warmboot clean
|
||||
@rm -f warmboot.bin
|
||||
mariko_fatal/mariko_fatal$(strip $2).bin: check_mariko_fatal_$(strip $1)
|
||||
|
||||
boot_code-clean:
|
||||
@rm -f boot_code.lz4
|
||||
clean-$(strip $1): clean-program-$(strip $1) clean-loader_stub-$(strip $1) clean-warmboot-$(strip $1) clean-mariko_fatal-$(strip $1)
|
||||
@rm -rf exosphere$(strip $2).bin warmboot$(strip $2).bin mariko_fatal$(strip $2).bin
|
||||
|
||||
.PHONY: all clean build_program $(CLEAN_TARGETS)
|
||||
clean-program-$(strip $1):
|
||||
@$$(MAKE) -C program clean-$(strip $1)
|
||||
|
||||
clean-loader_stub-$(strip $1):
|
||||
@$$(MAKE) -C loader_stub clean-$(strip $1)
|
||||
|
||||
clean-warmboot-$(strip $1):
|
||||
@$$(MAKE) -C warmboot clean-$(strip $1)
|
||||
|
||||
clean-mariko_fatal-$(strip $1):
|
||||
@$$(MAKE) -C mariko_fatal clean-$(strip $1)
|
||||
|
||||
endef
|
||||
|
||||
$(eval $(call ATMOSPHERE_ADD_TARGET, release, ))
|
||||
$(eval $(call ATMOSPHERE_ADD_TARGET, debug, _debug))
|
||||
$(eval $(call ATMOSPHERE_ADD_TARGET, audit, _audit))
|
||||
|
||||
clean: clean-program clean-loader_stub clean-warmboot
|
||||
@rm -rf exosphere*.bin warmboot*.bin mariko_fatal*.bin
|
||||
|
||||
clean-program:
|
||||
@$(MAKE) -C program clean
|
||||
|
||||
clean-loader_stub:
|
||||
@$(MAKE) -C loader_stub clean
|
||||
|
||||
clean-warmboot:
|
||||
@$(MAKE) -C warmboot clean
|
||||
|
||||
clean-mariko_fatal:
|
||||
@$(MAKE) -C mariko_fatal clean
|
||||
|
||||
.PHONY: all clean clean-program clean-loader_stub clean-warmboot $(foreach config,$(ATMOSPHERE_BUILD_CONFIGS),check_program_$(config) check_warmboot_$(strip $1) clean-$(config) clean-program-$(config) clean-loader_stub-$(config) clean-warmboot-$(config))
|
||||
|
@ -7,28 +7,24 @@ export ATMOSPHERE_CPU := arm-cortex-a57
|
||||
#---------------------------------------------------------------------------------
|
||||
# pull in common atmosphere configuration
|
||||
#---------------------------------------------------------------------------------
|
||||
THIS_MAKEFILE := $(abspath $(lastword $(MAKEFILE_LIST)))
|
||||
CURRENT_DIRECTORY := $(abspath $(dir $(THIS_MAKEFILE)))
|
||||
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)))
|
||||
ifneq ($(__RECURSIVE__),1)
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OUTPUT := $(CURDIR)/$(TARGET)
|
||||
export TOPDIR := $(CURDIR)
|
||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||
|
||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir)) \
|
||||
$(TOPDIR)/../program
|
||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) $(CURDIR)/include \
|
||||
$(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)
|
||||
|
||||
BINFILES := program.lz4 boot_code.lz4
|
||||
BINFILES :=
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# use CXX for linking C++ projects, CC for standard C
|
||||
@ -44,70 +40,116 @@ else
|
||||
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 OFILES := $(OFILES_SRC) program.lz4.o boot_code.lz4.o
|
||||
|
||||
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))
|
||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/$(ATMOSPHERE_LIBRARY_DIR))
|
||||
|
||||
.PHONY: $(BUILD) clean all check_program
|
||||
export TOPDIR := $(CURRENT_DIRECTORY)
|
||||
|
||||
OUTPUT_BASE := $(TOPDIR)/$(notdir $(TOPDIR))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
all: $(BUILD) check_program
|
||||
|
||||
$(BUILD): check_program
|
||||
ATMOSPHERE_BUILD_CONFIGS :=
|
||||
all: release
|
||||
|
||||
define ATMOSPHERE_ADD_TARGET
|
||||
|
||||
ATMOSPHERE_BUILD_CONFIGS += $(strip $1)
|
||||
|
||||
$(strip $1): check_libexo_$(strip $1) $$(ATMOSPHERE_BUILD_DIR)/$(strip $1)
|
||||
@$$(MAKE) __RECURSIVE__=1 OUTPUT=$$(OUTPUT_BASE)$(strip $2) $(3) \
|
||||
ATMOSPHERE_BUILD_TARGET_IDENTIFIER=$(strip $1)\
|
||||
ATMOSPHERE_BUILD_TARGET_BINARY_SUFFIX=$(strip $2)\
|
||||
DEPSDIR=$$(CURDIR)/$$(ATMOSPHERE_BUILD_DIR)/$(strip $1) \
|
||||
LIBEXOSPHERE_NAME=exosphere$(strip $2) \
|
||||
--no-print-directory -C $$(ATMOSPHERE_BUILD_DIR)/$(strip $1) \
|
||||
-f $$(THIS_MAKEFILE)
|
||||
|
||||
check_libexo_$(strip $1):
|
||||
@$$(MAKE) --no-print-directory -C $$(ATMOSPHERE_LIBRARIES_DIR)/libexosphere $$(ATMOSPHERE_ARCH_NAME)-$(strip $1)
|
||||
|
||||
clean-$(strip $1):
|
||||
@echo clean $(strip $1) ...
|
||||
@rm -fr $$(ATMOSPHERE_BUILD_DIR)/$(strip $1) $$(OUTPUT_BASE)$(strip $2).bin $$(OUTPUT_BASE)$(strip $2).elf $$(OUTPUT_BASE)$(strip $2).lz4 boot_code$(strip $2).lz4
|
||||
|
||||
endef
|
||||
|
||||
$(eval $(call ATMOSPHERE_ADD_TARGET, release, , \
|
||||
ATMOSPHERE_BUILD_SETTINGS="-DAMS_FORCE_DISABLE_DETAILED_ASSERTIONS" \
|
||||
))
|
||||
|
||||
$(eval $(call ATMOSPHERE_ADD_TARGET, debug, _debug, \
|
||||
ATMOSPHERE_BUILD_SETTINGS="-DAMS_FORCE_DISABLE_DETAILED_ASSERTIONS -DAMS_BUILD_FOR_DEBUGGING" \
|
||||
))
|
||||
|
||||
$(eval $(call ATMOSPHERE_ADD_TARGET, audit, _audit, \
|
||||
ATMOSPHERE_BUILD_SETTINGS="-DAMS_FORCE_DISABLE_DETAILED_ASSERTIONS -DAMS_BUILD_FOR_AUDITING" \
|
||||
))
|
||||
|
||||
$(ATMOSPHERE_BUILD_DIR)/%:
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||
|
||||
check_program:
|
||||
@$(MAKE) -C ../program all
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
@echo clean ...
|
||||
@rm -fr $(BUILD) $(OUTPUT).bin $(OUTPUT).elf
|
||||
clean: $(foreach config,$(ATMOSPHERE_BUILD_CONFIGS),clean-$(config))
|
||||
|
||||
.PHONY: all clean $(foreach config,$(ATMOSPHERE_BUILD_CONFIGS),$(config) clean-$(config))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
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
|
||||
$(OUTPUT).elf : $(OFILES)
|
||||
|
||||
$(OFILES) : $(ATMOSPHERE_LIBRARIES_DIR)/libexosphere/$(ATMOSPHERE_LIBRARY_DIR)/lib$(LIBEXOSPHERE_NAME).a
|
||||
|
||||
|
||||
program.lz4.o: program_lz4.h
|
||||
|
||||
program_lz4.h: $(TOPDIR)/../program/program$(ATMOSPHERE_BUILD_TARGET_BINARY_SUFFIX).lz4
|
||||
@echo $(notdir $<)
|
||||
@rm -rf tmp_program_$(ATMOSPHERE_BUILD_TARGET_IDENTIFIER)
|
||||
@mkdir -p tmp_program_$(ATMOSPHERE_BUILD_TARGET_IDENTIFIER)
|
||||
@cp $(TOPDIR)/../program/program$(ATMOSPHERE_BUILD_TARGET_BINARY_SUFFIX).lz4 tmp_program_$(ATMOSPHERE_BUILD_TARGET_IDENTIFIER)/program.lz4
|
||||
@bin2s -a 8 -H program_lz4.h tmp_program_$(ATMOSPHERE_BUILD_TARGET_IDENTIFIER)/program.lz4 | $(AS) -o program.lz4.o
|
||||
@rm -rf tmp_program_$(ATMOSPHERE_BUILD_TARGET_IDENTIFIER)
|
||||
|
||||
$(TOPDIR)/../program/program$(ATMOSPHERE_BUILD_TARGET_BINARY_SUFFIX).lz4:
|
||||
@$(MAKE) __RECURSIVE__=0 --no-print-directory -C $(TOPDIR)/../program $(ATMOSPHERE_BUILD_TARGET_IDENTIFIER)
|
||||
|
||||
boot_code.lz4.o: boot_code_lz4.h
|
||||
|
||||
boot_code_lz4.h: $(TOPDIR)/../program/boot_code$(ATMOSPHERE_BUILD_TARGET_BINARY_SUFFIX).lz4
|
||||
@echo $(notdir $<)
|
||||
@rm -rf tmp_boot_code_$(ATMOSPHERE_BUILD_TARGET_IDENTIFIER)
|
||||
@mkdir -p tmp_boot_code_$(ATMOSPHERE_BUILD_TARGET_IDENTIFIER)
|
||||
@cp $(TOPDIR)/../program/boot_code$(ATMOSPHERE_BUILD_TARGET_BINARY_SUFFIX).lz4 tmp_boot_code_$(ATMOSPHERE_BUILD_TARGET_IDENTIFIER)/boot_code.lz4
|
||||
@bin2s -a 8 -H boot_code_lz4.h tmp_boot_code_$(ATMOSPHERE_BUILD_TARGET_IDENTIFIER)/boot_code.lz4 | $(AS) -o boot_code.lz4.o
|
||||
@rm -rf tmp_boot_code_$(ATMOSPHERE_BUILD_TARGET_IDENTIFIER)
|
||||
|
||||
$(TOPDIR)/../program/boot_code$(ATMOSPHERE_BUILD_TARGET_BINARY_SUFFIX).lz4: $(TOPDIR)/../program/program$(ATMOSPHERE_BUILD_TARGET_BINARY_SUFFIX).lz4
|
||||
|
||||
%.elf:
|
||||
@echo linking $(notdir $@)
|
||||
$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@
|
||||
@$(NM) -CSn $@ > $(notdir $*.lst)
|
||||
|
||||
$(OFILES_SRC) : $(HFILES_BIN)
|
||||
$(OFILES_SRC) : program_lz4.h boot_code_lz4.h
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# you need a rule like this for each extension you use as binary data
|
||||
#---------------------------------------------------------------------------------
|
||||
%.bin.o %_bin.h: %.bin
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
%.lz4.o %_lz4.h: %.lz4
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
-include $(DEPENDS)
|
||||
|
||||
|
@ -1,7 +1,4 @@
|
||||
%rename link old_link
|
||||
|
||||
*link:
|
||||
%(old_link) -T %:getenv(TOPDIR /loader_stub.ld) --gc-sections --nmagic -nostdlib -nostartfiles
|
||||
|
||||
*startfile:
|
||||
crti%O%s crtbegin%O%s
|
||||
%(old_link) -T %:getenv(TOPDIR /loader_stub.ld) --gc-sections --nmagic
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
* Copyright (c) Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user