Compare commits

...

147 Commits

Author SHA1 Message Date
Michael Scire
e6bddf8782 i2c: correct missing destruction 2020-11-14 03:37:17 -08:00
Michael Scire
d8bd3d16bb ams.mitm: provide different boot0-protection for custom public key 2020-11-10 23:25:24 -08:00
Michael Scire
80f567d46a wec: whoops 2020-11-10 18:32:21 -08:00
Michael Scire
b6580b3170 updater: don't overwrite custom-public-key BCTs 2020-11-10 16:53:19 -08:00
Michael Scire
df8ceb9b06 pinmux: whoops 2020-11-10 16:30:36 -08:00
Michael Scire
c5656d39d2 boot/powctl/i2c: more miscellaneous fixes 2020-11-10 05:50:13 -08:00
Michael Scire
62ff502979 boot: various bugfixes (b/w logo displays now) 2020-11-10 05:02:41 -08:00
Michael Scire
f135ee74f8 powctl: implement max17050 driver 2020-11-10 02:23:05 -08:00
Michael Scire
8c3e536e94 powctl: add battery driver logic (missing impl) 2020-11-10 01:27:35 -08:00
Michael Scire
35573c4d85 powctl: implement max17050 custom parameter init 2020-11-09 23:14:31 -08:00
Michael Scire
e6ef753bb6 powctl: implement full bq24193 driver 2020-11-09 21:50:41 -08:00
Michael Scire
eade15b34e i2c: add register acccessor helpers 2020-11-09 17:34:47 -08:00
Michael Scire
b9c5dab18a powctl: add ChargerDriver body (needs impl) 2020-11-09 17:09:25 -08:00
Michael Scire
d0a45b8f21 pinmux: implement updated initial config api 2020-11-09 02:01:29 -08:00
Michael Scire
e0ce035323 boot: update/refactor display management to support hw type 5/display 0x1040/0x2050 2020-11-08 17:56:49 -08:00
Michael Scire
2562700f34 dd: implement DeviceAddressSpaceType api 2020-11-08 15:27:55 -08:00
Michael Scire
e93c3cbf58 boot: refactor battery checking to use new powctl apis 2020-11-08 04:16:50 -08:00
Michael Scire
cd7d7894f1 powctl: implement client api (needs board-specific impl) 2020-11-02 18:13:36 -08:00
Michael Scire
aa63b1eab7 pwm: implement driver for boot sysmodule 2020-11-01 23:04:19 -08:00
Michael Scire
4cc4f5fdb0 gpio: add missing driver functions for boot 2020-11-01 23:04:01 -08:00
Michael Scire
22ae1d5bd3 i2c: implement remaining required driver logic 2020-11-01 00:52:02 -07:00
Michael Scire
43f7b10c0f i2c: command list format, get boot down to linker errors 2020-10-31 22:52:43 -07:00
Michael Scire
48784da42a i2c/gpio: hook up open session for sf interface 2020-10-31 21:50:21 -07:00
Michael Scire
f27d6f2fd8 i2c: implement driver init api 2020-10-31 20:14:41 -07:00
Michael Scire
6f7502dfef i2c: finish I2cBusAccessor 2020-10-31 19:14:43 -07:00
Michael Scire
2d2b11a2d2 i2c: implement BusAccessor::WriteHeader 2020-10-31 18:24:26 -07:00
Michael Scire
2744a614de i2c: implement BusAccessor except Send/Receive/WriteHeader 2020-10-31 17:58:38 -07:00
Michael Scire
27be1a548c boot: add rgltr/clkrst overrides, skel I2cBusAccessor 2020-10-31 16:34:06 -07:00
Michael Scire
91b2a233c4 i2c: add auto-generated bus/device map 2020-10-31 14:20:01 -07:00
Michael Scire
7636dd2d44 i2c: begin skeleton device driver framework 2020-10-31 04:55:11 -07:00
Michael Scire
c867975eb8 gpio: remove copy-pasted unused file 2020-10-31 03:23:30 -07:00
Michael Scire
5bc4abb92f gpio: implement more of server library for boot sysmodule client usage 2020-10-31 03:22:01 -07:00
Michael Scire
e1dccef7d1 wec: implement wec driver components for boot sysmodule 2020-10-31 00:47:45 -07:00
Michael Scire
17fa05a789 gpio: add (most of) driver framework for boot sysmodule usage 2020-10-30 23:57:21 -07:00
Michael Scire
5b617f4d2f ddsf: implement namespace 2020-10-30 15:36:11 -07:00
Michael Scire
d2e530c2aa libstrat: fix precompiled-header dependency detection 2020-10-30 11:56:12 -07:00
SciresM
166318ba77 sdmmc: implement driver suitable for fs + bootloader
* sdmmc: begin skeletoning sdmmc driver

* sdmmc: add most of SdHostStandardController

* sdmmc: implement most of SdmmcController

* sdmmc: Sdmmc2Controller

* sdmmc: skeleton implementation of Sdmmc1Controller

* sdmmc: complete abstract logic for Sdmmc1 power controller

* sdmmc: implement gpio handling for sdmmc1-register-control

* sdmmc: implement pinmux handling for sdmmc1-register-control

* sdmmc: fix building for arm32 and in stratosphere context

* sdmmc: implement voltage enable/set for sdmmc1-register-control

* util: move T(V)SNPrintf from kernel to util

* sdmmc: implement BaseDeviceAccessor

* sdmmc: implement MmcDeviceAccessor

* sdmmc: implement clock reset controller for register api

* sdmmc: fix bug in WaitWhileCommandInhibit, add mmc accessors

* exo: add sdmmc test program

* sdmmc: fix speed mode extension, add CheckMmcConnection for debug

* sdmmc: add DeviceDetector, gpio: implement client api

* gpio: modernize client api instead of doing it the lazy way

* sdmmc: SdCardDeviceAccessor impl

* sdmmc: update test program to read first two sectors of sd card

* sdmmc: fix vref sel

* sdmmc: finish outward-facing api (untested)

* ams: changes for libvapours including tegra register defs

* sdmmc: remove hwinit
2020-10-30 11:54:30 -07:00
SciresM
ac04e02a08 Meso build targets (#1196)
* meso: commit wip (thanks fincs) rewrite to support build targets

* meso: commit mostly-working build system

* meso: correct .o dependencies in kernel/kldr

* libstratosphere: fix building after PCH related build changes

Co-authored-by: fincs <fincs@devkitpro.org>
2020-10-27 13:55:19 -07:00
Michael Scire
1c71d12d9d ams.mitm: avoid inadvertently breaking ftpd/file listers 2020-10-27 10:28:51 -07:00
Michael Scire
37738699f2 docs: edit terminology to be hip to the jive 2020-10-26 16:14:25 -07:00
Michael Scire
e973ef7533 git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "10e9e0e8"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "10e9e0e8"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2020-10-26 16:03:40 -07:00
Michael Scire
2ee2a4f1ac docs/fatal error: update for 0.15.0 2020-10-26 16:00:34 -07:00
Michael Scire
2a2bffeb35 ams: fix building debug elf zip 2020-10-15 09:47:06 -07:00
Michael Scire
d04046ecaf ams: bump version to 0.15.0 (release slated for post-crown-tundra) 2020-10-15 09:41:49 -07:00
Michael Scire
f24171dc41 ams: build experimental zip in addition to standard one 2020-10-15 09:41:01 -07:00
Michael Scire
5b02c77400 ams: fix updater misbehavior before 0.15.0 releases 2020-10-14 12:28:26 -07:00
Michael Scire
2e7214b6fa kern: perform rescheduling on dispatch re-enable (closes #1169) 2020-10-13 23:07:51 -07:00
Michael Scire
d52179c708 util: follow 90fd771 to its natural conclusion (generic base rbtree) 2020-10-12 01:06:19 -07:00
Michael Scire
388f9e6455 kern: minor behavioral fixes to condvar/address arbiter 2020-10-12 01:06:19 -07:00
SciresM
c547c7f0e7 Note that we are a python 2 project. 2020-10-09 17:37:51 -07:00
Michael Scire
4138abbefa erpt: fix attachment-in-save paths (closes #1124, #1145) 2020-09-23 19:49:20 -07:00
Michael Scire
1275eb0bf3 erpt: add fixed-width format option 2020-09-23 17:52:08 -07:00
Michael Scire
5ac9e45d86 erpt: support older erpt binaries 2020-09-23 17:36:46 -07:00
Michael Scire
feba788bc6 erpt.py: remove idaapi usage 2020-09-23 16:05:27 -07:00
Michael Scire
f4d10a4481 set.mitm: much more aggressively cache locale (#1160) 2020-09-23 02:01:07 -07:00
Michael Scire
ff310a0647 fusee: try to alleviate a little suffering 2020-09-22 13:54:23 -07:00
Michael Scire
85505db9b7 loader: adjust thread priority for applet-hbl 2020-09-22 12:01:28 -07:00
Michael Scire
48b4dd48a4 ams: expose reboot payload for kernel panic 2020-09-18 00:43:55 -07:00
Michael Scire
8d46d901d9 ams: make mesosphere usage user-visible in display version 2020-09-17 21:18:44 -07:00
Michael Scire
1930880270 fusee: change ncm from opt-in to opt-out 2020-09-17 21:04:43 -07:00
Michael Scire
fa0df994ba git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "f6dac1e6"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "f6dac1e6"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2020-09-17 08:34:48 -07:00
Michael Scire
909a1767a6 ams: bump version to 0.14.4 2020-09-17 08:34:02 -07:00
Michael Scire
dbe59fd041 kern: fix KCodeMemory SVCs when Owner process != Generator process 2020-09-17 08:26:08 -07:00
Michael Scire
9b65daf439 kern: default to release config 2020-09-17 08:26:08 -07:00
Michael Scire
4acdc899f5 kern: generate fatal error on panic 2020-09-17 08:26:08 -07:00
Michael Scire
76957e502d kern: add build-define for logging to iram ringbuffer 2020-09-17 08:26:08 -07:00
Michael Scire
909397233c sm: Fix atmosphere-extension interaction with official JIT sysmodule usage 2020-09-17 08:24:47 -07:00
Michael Scire
211a828730 ro: fix process handle leak when using JitPlugin NROs 2020-09-17 08:17:11 -07:00
Michael Scire
28ceedb533 git subrepo push emummc
subrepo:
  subdir:   "emummc"
  merged:   "6a814ebb"
upstream:
  origin:   "https://github.com/m4xw/emuMMC"
  branch:   "exo2"
  commit:   "6a814ebb"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2020-09-14 18:21:38 -07:00
Michael Scire
f551ca4461 emummc: manually fix .gitrepo 2020-09-14 18:17:32 -07:00
Michael Scire
2cf5c65bc5 git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "48dbf480"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "48dbf480"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2020-09-14 18:14:05 -07:00
Michael Scire
47d0d5c6ab ams: support 10.2.0 (bump vers to 0.14.3) 2020-09-14 18:13:18 -07:00
Michael Scire
fd0e3e2160 docs: update changelog 2020-09-14 18:12:48 -07:00
Michael Scire
074364753f loader: improve verification terminology 2020-09-08 15:34:22 -07:00
Michael Scire
b7d99b732a ro: rename ModuleType to reflect reality 2020-09-08 15:05:15 -07:00
Michael Scire
1cccb6efc4 git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "04ef9bf8"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "04ef9bf8"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2020-09-07 10:52:49 -07:00
Michael Scire
f4cd4bcf03 ams: bump version to 0.14.2 2020-09-07 10:51:15 -07:00
Michael Scire
e36fe62fca kern: lps driver fixes, sleep confirmed working on 1.0.0 2020-09-07 10:43:35 -07:00
Michael Scire
870b589379 kern: fix c/p error 2020-09-07 10:43:35 -07:00
Michael Scire
acdce230da kern: add debug logging on smmu error interrupt 2020-09-07 10:43:35 -07:00
Michael Scire
34dc062c11 kern: finish 1.x lps driver 2020-09-07 10:43:35 -07:00
Michael Scire
ab2568ddfb kern: add most of 1.x lps driver 2020-09-07 10:43:35 -07:00
Michael Scire
4dc728824f kern: skeleton legacy lps driver 2020-09-07 10:43:35 -07:00
Michael Scire
cc6b8ea4d1 exo/kern: 1.0.0 requires access to bpmp smmu regs, userland (am) needs to map bpmp exception vectors 2020-09-07 10:43:35 -07:00
Michael Scire
49af4fae32 kern: begin 1.0.0 backwards compat changes (kips run, full boot fails) 2020-09-07 10:43:35 -07:00
Michael Scire
e8ffbe630f kern: support 2-pool layout on 2.x-4.x instead of modern 4-pool layout 2020-09-07 10:43:35 -07:00
Michael Scire
ce95af89ef kern: change terminology metadata -> management 2020-09-07 10:43:35 -07:00
Michael Scire
546e2de300 kern: pool management should be within carveout 2020-09-07 10:43:35 -07:00
Michael Scire
11b120b667 kern: fix phys/virt pool management mixup 2020-09-07 10:43:35 -07:00
Michael Scire
4da1fe545c kern: fix linear mapped dram -> pool partition check 2020-09-07 10:43:35 -07:00
Michael Scire
1983f86875 kern: revamp KMemoryRegionType to better encode derivation hierarchies 2020-09-07 10:43:35 -07:00
Michael Scire
d50c7c5c79 kern: PMC must be user-mappable for 1.0.0 compat 2020-09-07 10:43:35 -07:00
Michael Scire
496f93ccdb kern: expose mesosphere meta over GetInfo instead of GetSystemInfo 2020-09-07 10:43:35 -07:00
Michael Scire
25ba61adae loader: extend memory region descriptors a touch more gracefully 2020-09-07 10:43:35 -07:00
Michael Scire
79c9bed528 kern/pm: support for 5.x under mesosphere 2020-09-07 10:43:35 -07:00
Michael Scire
657470830f loader: support MapRegion capability as an atmosphere extension (normally kips-only) 2020-09-07 10:43:35 -07:00
Michael Scire
cd62d83586 fusee: fix sleep/wake on 6.x 2020-09-07 10:43:35 -07:00
Michael Scire
bb11c57e7d kern: fix warn-errors 2020-09-07 10:43:35 -07:00
Michael Scire
bb1cdd8c87 fusee: fixes for sd meso on lower firmwares 2020-09-07 10:43:35 -07:00
Michael Scire
ff9b9fc5ff fusee: change meso loading to parse INI from Nintendo's kernel 2020-09-07 10:43:35 -07:00
Michael Scire
99b5458539 sm: fix deadlock semantics surrounding mitm installation 2020-09-07 10:40:57 -07:00
Michael Scire
fac502aaa3 kern: fix KTypedAddress, strengthen assertions 2020-08-18 15:17:40 -07:00
Michael Scire
47f2e93a42 kern: add version bounds checking 2020-08-18 15:17:40 -07:00
Michael Scire
56ec55f3c4 kern: avoid hardcoding maximum board memory size 2020-08-18 15:17:40 -07:00
Michael Scire
1a262c1063 kern: improve resource region size definitions/calculations 2020-08-18 15:17:40 -07:00
Michael Scire
79201428b0 kern: resolve NonSecure definition TODO 2020-08-18 15:17:40 -07:00
Michael Scire
a75c16226e kern: correct thread termination atomicity 2020-08-18 15:17:40 -07:00
Michael Scire
e5d30217d3 kern: fix reference leak in KThread::GetThreadFromId callers 2020-08-18 15:17:40 -07:00
Michael Scire
f77a4fbf98 kern: non-loop cas-weak -> cas-strong 2020-08-18 15:17:40 -07:00
Michael Scire
717265a54c kern: fix bug in KScheduler::ClearPreviousThread 2020-08-18 15:17:40 -07:00
fincs
3ace441b1c arm64: set -march in cpu specific configuration 2020-08-18 15:17:40 -07:00
fincs
2effe130e3 kern: use size instead of phys addr as sentinel value in InitializeCore linear mapping logic 2020-08-18 15:17:40 -07:00
fincs
2cedf2bcf0 kern: remove accidentally copypasted code 2020-08-18 15:17:40 -07:00
fincs
68e29b56b6 kern: add stubbed KDevicePageTable implementation for systems without iommu 2020-08-18 15:17:40 -07:00
fincs
8e688de570 kern: move SetupPoolPartitionMemoryRegions into board specific implementation 2020-08-18 15:17:40 -07:00
fincs
b917ea283e kern: make GetTargetFirmware a compile-time constant when not building for Switch 2020-08-18 15:17:40 -07:00
Michael Scire
3c85e37667 kern: use std::atomic_ref instead of reinterpret_cast to std::atomic 2020-08-18 15:17:40 -07:00
Michael Scire
48e8562033 kern: use common GIC implementation for arm/arm64 2020-08-18 15:17:40 -07:00
Michael Scire
f07bd0e337 kern: correct flushing of init arguments 2020-08-18 15:17:40 -07:00
Michael Scire
4a35904d73 kern: simplify SetupForIpcClient cleanup 2020-08-18 15:17:40 -07:00
Michael Scire
b8c2782ede kern: SvcLegacyGetFutureThreadInfo 2020-08-18 15:17:40 -07:00
Michael Scire
3ec9a9e59f kern: rename CacheHelper operation for accuracy 2020-08-18 15:17:40 -07:00
Michael Scire
595c6dbe8f kern: KPageTableBase::WriteDebugMemory stores/invalidates cache 2020-08-18 15:17:40 -07:00
Michael Scire
b5f2698bf0 kern: fix multicore instruction cache invalidation 2020-08-18 15:17:40 -07:00
Michael Scire
f058536b59 kern: add tracing for irq/scheduling 2020-08-18 15:17:40 -07:00
Michael Scire
8e5c0a9663 kern: cleanup some KMemoryManager functions 2020-08-18 15:17:40 -07:00
Michael Scire
1b63002f91 kern: refactor KMemoryLayout 2020-08-18 15:17:40 -07:00
Michael Scire
90fd771fce IntrusiveRedBlackTree: refactor to add ->GetPrev(), ->GetNext() to BaseNode inheritors 2020-08-18 15:17:40 -07:00
Michael Scire
c3fa3bd5d6 kern: N reduced the slabheap gap size in 10.0.0 2020-08-18 15:17:40 -07:00
Michael Scire
cda15f08d8 kern: mark KThread/KProcess.GetId() final to save virtual calls 2020-08-18 15:17:40 -07:00
Michael Scire
e5b7eb89e5 kern: fix built-in usage for libc 2020-08-18 15:17:40 -07:00
Michael Scire
e1bd6fb874 kern: fix missing scheduler updates in KLightLock/Exception, fix RequestScheduleOnInterrupt 2020-08-18 15:17:40 -07:00
Michael Scire
920b017677 kern: implement svc trace 2020-08-18 15:17:40 -07:00
Michael Scire
f9d68db3f6 kern: SvcChangeKernelTraceState 2020-08-18 15:17:40 -07:00
Michael Scire
89f1c0ce33 kern: remove stray log in SetHeapSize 2020-08-18 15:17:40 -07:00
Michael Scire
e435f56367 exo: build with -Wextra 2020-08-17 14:39:18 -07:00
Michael Scire
73798cb812 kern: build with -Wextra 2020-08-17 14:20:24 -07:00
Michael Scire
d3014f6ed9 git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "2d522dc6"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "2d522dc6"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2020-08-15 09:20:46 -07:00
Michael Scire
35fffade4e libstrat: fix building of source/os/* 2020-08-15 09:20:11 -07:00
Michael Scire
2c6b7ce6c2 git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "5a60240f"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "5a60240f"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2020-08-14 17:37:03 -07:00
Michael Scire
7658c07492 strat: fix inclusion/ordering for some c headers 2020-08-14 17:33:49 -07:00
Michael Scire
51b5c3d87d ams: avoid UB infinite loops 2020-08-13 17:28:29 -07:00
Michael Scire
874208b44a sf: handle serialization errors more accurately and gracefully 2020-08-11 16:40:57 -07:00
Michael Scire
44c5cb9789 ams: add support for cpu-extension specific source files 2020-08-11 11:43:34 -07:00
Michael Scire
420bc7df9b ams: update build system to add generic-fallback support 2020-08-11 11:22:56 -07:00
Michael Scire
ee3e0fa537 fatal: use TimeSpan for timing 2020-08-03 19:52:53 -07:00
Aurora Wright
501280b6e5 fatal: Fix autoreboot logic 2020-08-03 19:44:14 -07:00
714 changed files with 43163 additions and 11974 deletions

View File

@@ -70,8 +70,8 @@ dist-no-debug: all
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 fusee/fusee-secondary/fusee-secondary-experimental.bin atmosphere-$(AMSVER)/atmosphere/fusee-secondary.bin
cp fusee/fusee-secondary/fusee-secondary-experimental.bin atmosphere-$(AMSVER)/sept/payload.bin
cp sept/sept-primary/sept-primary.bin atmosphere-$(AMSVER)/sept/sept-primary.bin
cp sept/sept-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
@@ -99,9 +99,13 @@ dist-no-debug: all
touch atmosphere-$(AMSVER)/atmosphere/contents/0100000000000037/flags/boot2.flag
cp troposphere/reboot_to_payload/reboot_to_payload.nro atmosphere-$(AMSVER)/switch/reboot_to_payload.nro
cp troposphere/daybreak/daybreak.nro atmosphere-$(AMSVER)/switch/daybreak.nro
cd atmosphere-$(AMSVER); zip -r ../atmosphere-EXPERIMENTAL-$(AMSVER).zip ./*; cd ../;
cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/atmosphere/fusee-secondary.bin
cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/sept/payload.bin
cd atmosphere-$(AMSVER); zip -r ../atmosphere-$(AMSVER).zip ./*; cd ../;
rm -r atmosphere-$(AMSVER)
mkdir out
mv atmosphere-EXPERIMENTAL-$(AMSVER).zip out/atmosphere-EXPERIMENTAL-$(AMSVER).zip
mv atmosphere-$(AMSVER).zip out/atmosphere-$(AMSVER).zip
cp fusee/fusee-primary/fusee-primary.bin out/fusee-primary.bin
@@ -120,7 +124,7 @@ dist: dist-no-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 fusee/fusee-secondary/fusee-secondary-experimental.elf atmosphere-$(AMSVER)-debug/fusee-secondary.elf
cp sept/sept-primary/sept-primary.elf atmosphere-$(AMSVER)-debug/sept-primary.elf
cp sept/sept-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

View File

@@ -9,4 +9,4 @@ stage2_entrypoint = 0xF0000000
; To force-enable nogc, add nogc = 1
; To force-disable nogc, add nogc = 0
; To opt in to using Atmosphere's NCM reimplementation, add enable_ncm = 1
; To opt out of using Atmosphere's NCM reimplementation, add disable_ncm = 1

View File

@@ -4,7 +4,7 @@ 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)
+ [PyCryptodome](https://pypi.org/project/pycryptodome) (optional)
## Instructions

View File

@@ -1,4 +1,54 @@
# Changelog
## 0.15.0
+ fusee-primary's panic display was updated to automatically identify and give suggestions to resolve many of the most common errors users encounter.
+ Having been tested as well as I can alone, `mesosphere` (atmosphère's reimplementation of the Nintendo Switch kernel) is now available for users interested in trying it.
+ Beginning in this release and until it is stable and well-tested, atmosphère will distribute two zips.
+ Users who wish to opt-in to mesosphere should download and extract the "cool kids" zip ("atmosphere-EXPERIMENTAL-").
+ Users who do not wish to use mesosphere should continue using the normal zip ("atmosphere-").
+ Users may detect whether mesosphere is active in system settings.
+ When mesosphere is active, the system version string will display "M.15.0" rather than "0.15.0", and so on for future releases.
+ Crash reports and the like will contain information on whether or not the user is using mesosphere, as well.
+ There are "probably" no material user-facing benefits to using mesosphere at this time.
+ Developers may be interested in the fact that mesosphere provides many newer SVC APIs even when on lower firmware versions.
+ The primary benefit to using mesosphere is that any issues you may encounter and report to me will be fixed.
+ All users who choose to opt in to using mesosphere have my deepest gratitude.
+ **Note:** If using hekate instead of fusee-primary, you will have to wait for the next hekate release for mesosphere to function, as hekate's support has not yet been included in an official release build.
+ This will be updated in the release notes when hekate provides a new release.
+ As mentioned in previous release notes, when mesosphere is stable and well-tested, it will be enabled by default and atmosphère's version will transition to 1.0.0.
+ Having been tested sufficiently over the last half-year, Atmosphere's NCM implementation is now opt-out, rather than opt in.
+ In the unlikely event that any issues are encountered, please report them to @SciresM.
+ Users interested in opting out of using our implementation should set `stratosphere!disable_ncm = 1` in BCT.ini.
+ The NCM implementation will stop being opt-out in a future update, probably around the same time that mesosphere becomes opt-out instead of opt-in.
+ Several bugs were fixed, including:
+ Loader now sets HBL's thread priority to a higher value when loading it in applet mode.
+ This fixes an extremely-slow launch ("hang") when using applet-HBL with certain games that do not suspend while inactive (e.g. Super Mario Sunshine).
+ set.mitm now caches user language configuration much more heavily.
+ This severely reduces lag in certain games which misuse the "nn::oe::GetDesiredLanguage()" API.
+ A bug was fixed that could cause erpt to fatal when loading an official save file that had error report attachments in it.
+ General system stability improvements to enhance the user's experience.
## 0.14.4
+ Several bugs were fixed involving the official jit sysmodule added in 10.0.0.
+ A Process handle leak was fixed when JitPlugin NRRs were registered with the `ro` sysmodule.
+ This prevented processes using jit from being able to exit, causing a full system freeze.
+ The `sm` atmosphere extension to not unregister services when the server's connection is closed was special-case disabled for `jit:u`.
+ This extension is normally desirable in order to allow more concurrent processes to exist (as only 0x40 sm connections may ever be concurrently open), but official jit sysmodule relies on the behavior.
+ This would cause crashes on attempts to launch a program using jit services more than once per reboot.
+ General system stability improvements to enhance the user's experience.
## 0.14.3
+ 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.

View File

@@ -29,11 +29,11 @@ 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:
### NCM opt-out
Atmosphère provides a reimplementation of the [ncm](../components/modules/ncm.md) system module. If you wish to disable this reimplementation add the following line to the `stratosphere` section:
```
[stratosphere]
enable_ncm = 1
disable_ncm = 1
```
### Logging

View File

@@ -6,7 +6,7 @@
[subrepo]
remote = https://github.com/m4xw/emuMMC
branch = exo2
commit = 06ab9b895c4264ecc14d3bf9be1260e2096f6037
parent = dccd41f6d25498c191a157123a27724203d3bc37
commit = 6a814ebbe72cf5245b863b9edea9cd3801437a12
parent = f551ca4461a79908c37307db10cd8cacf8b98f17
method = rebase
cmdver = 0.4.1

View File

@@ -47,6 +47,8 @@
#include "offsets/910_exfat.h"
#include "offsets/1000.h"
#include "offsets/1000_exfat.h"
#include "offsets/1020.h"
#include "offsets/1020_exfat.h"
#include "../utils/fatal.h"
#define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers
@@ -104,6 +106,8 @@ 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);
const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
switch (version) {
@@ -169,6 +173,10 @@ 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));
default:
fatal_abort(Fatal_UnknownVersion);
}

View File

@@ -68,6 +68,9 @@ 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_MAX,
};

View File

@@ -0,0 +1,58 @@
/*
* 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_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__

View File

@@ -0,0 +1,58 @@
/*
* 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_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__

View File

@@ -24,23 +24,9 @@ export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir)) \
$(TOPDIR)/../program
CFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.c)) $(notdir $(wildcard $(dir)/*.board.*.c)) $(notdir $(wildcard $(dir)/*.os.*.c)), \
$(notdir $(wildcard $(dir)/*.c))))
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).c)))
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).c)))
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).c)))
CPPFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.cpp)) $(notdir $(wildcard $(dir)/*.board.*.cpp)) $(notdir $(wildcard $(dir)/*.os.*.cpp)), \
$(notdir $(wildcard $(dir)/*.cpp))))
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).cpp)))
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).cpp)))
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).cpp)))
SFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.s)) $(notdir $(wildcard $(dir)/*.board.*.s)) $(notdir $(wildcard $(dir)/*.os.*.s)), \
$(notdir $(wildcard $(dir)/*.s))))
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).s)))
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).s)))
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).s)))
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

View File

@@ -19,10 +19,12 @@
namespace ams::diag {
NORETURN void AbortImpl(const char *file, int line, const char *func, const char *expr, u64 value, const char *format, ...) {
AMS_UNUSED(file, line, func, expr, value, format);
ams::secmon::loader::ErrorReboot();
}
NORETURN void AbortImpl(const char *file, int line, const char *func, const char *expr, u64 value) {
AMS_UNUSED(file, line, func, expr, value);
ams::secmon::loader::ErrorReboot();
}

View File

@@ -25,23 +25,9 @@ export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(TOPDIR)/sc7fw \
$(TOPDIR)/rebootstub
CFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.c)) $(notdir $(wildcard $(dir)/*.board.*.c)) $(notdir $(wildcard $(dir)/*.os.*.c)), \
$(notdir $(wildcard $(dir)/*.c))))
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).c)))
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).c)))
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).c)))
CPPFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.cpp)) $(notdir $(wildcard $(dir)/*.board.*.cpp)) $(notdir $(wildcard $(dir)/*.os.*.cpp)), \
$(notdir $(wildcard $(dir)/*.cpp))))
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).cpp)))
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).cpp)))
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).cpp)))
SFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.s)) $(notdir $(wildcard $(dir)/*.board.*.s)) $(notdir $(wildcard $(dir)/*.os.*.s)), \
$(notdir $(wildcard $(dir)/*.s))))
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).s)))
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).s)))
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).s)))
CFILES := $(call FIND_SOURCE_FILES,$(SOURCES),c)
CPPFILES := $(call FIND_SOURCE_FILES,$(SOURCES),cpp)
SFILES := $(call FIND_SOURCE_FILES,$(SOURCES),s)
BINFILES := sc7fw.bin rebootstub.bin

View File

@@ -23,23 +23,9 @@ export DEPSDIR := $(CURDIR)/$(BUILD)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
CFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.c)) $(notdir $(wildcard $(dir)/*.board.*.c)) $(notdir $(wildcard $(dir)/*.os.*.c)), \
$(notdir $(wildcard $(dir)/*.c))))
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).c)))
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).c)))
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).c)))
CPPFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.cpp)) $(notdir $(wildcard $(dir)/*.board.*.cpp)) $(notdir $(wildcard $(dir)/*.os.*.cpp)), \
$(notdir $(wildcard $(dir)/*.cpp))))
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).cpp)))
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).cpp)))
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).cpp)))
SFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.s)) $(notdir $(wildcard $(dir)/*.board.*.s)) $(notdir $(wildcard $(dir)/*.os.*.s)), \
$(notdir $(wildcard $(dir)/*.s))))
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).s)))
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).s)))
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).s)))
CFILES := $(call FIND_SOURCE_FILES,$(SOURCES),c)
CPPFILES := $(call FIND_SOURCE_FILES,$(SOURCES),cpp)
SFILES := $(call FIND_SOURCE_FILES,$(SOURCES),s)
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C

View File

@@ -23,23 +23,9 @@ export DEPSDIR := $(CURDIR)/$(BUILD)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
CFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.c)) $(notdir $(wildcard $(dir)/*.board.*.c)) $(notdir $(wildcard $(dir)/*.os.*.c)), \
$(notdir $(wildcard $(dir)/*.c))))
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).c)))
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).c)))
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).c)))
CPPFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.cpp)) $(notdir $(wildcard $(dir)/*.board.*.cpp)) $(notdir $(wildcard $(dir)/*.os.*.cpp)), \
$(notdir $(wildcard $(dir)/*.cpp))))
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).cpp)))
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).cpp)))
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).cpp)))
SFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.s)) $(notdir $(wildcard $(dir)/*.board.*.s)) $(notdir $(wildcard $(dir)/*.os.*.s)), \
$(notdir $(wildcard $(dir)/*.s))))
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).s)))
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).s)))
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).s)))
CFILES := $(call FIND_SOURCE_FILES,$(SOURCES),c)
CPPFILES := $(call FIND_SOURCE_FILES,$(SOURCES),cpp)
SFILES := $(call FIND_SOURCE_FILES,$(SOURCES),s)
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C

View File

@@ -90,7 +90,7 @@ namespace ams::sc7fw {
reg::ReadWrite(PMC + APBDEV_PMC_DPD_ENABLE, PMC_REG_BITS_ENUM(DPD_ENABLE_ON, ENABLE));
/* Wait forever until we're asleep. */
while (true) { /* ... */ }
AMS_INFINITE_LOOP();
}
}
@@ -102,7 +102,9 @@ namespace ams::sc7fw {
NORETURN void ExceptionHandler() {
/* Write enable to MAIN_RESET. */
reg::Write(PMC + APBDEV_PMC_CNTRL, PMC_REG_BITS_ENUM(CNTRL_MAIN_RESET, ENABLE));
while (true) { /* ... */ }
/* Wait forever until we're reset. */
AMS_INFINITE_LOOP();
}
}

View File

@@ -85,6 +85,8 @@ namespace ams::secmon::boot {
if constexpr (false) {
/* TODO: Consider implementing this as a reference. */
}
AMS_UNUSED(is_prod);
}
/* NOTE: These are just latest-master-kek encrypted with BEK. */
@@ -406,6 +408,7 @@ namespace ams::secmon::boot {
constexpr void UnmapDramImpl(u64 *l1, u64 *l2, u64 *l3) {
/* Unmap the L1 entry corresponding to to the Dram entries. */
AMS_UNUSED(l2, l3);
InvalidateL1Entries(l1, MemoryRegionDram.GetAddress(), MemoryRegionDram.GetSize());
}

View File

@@ -41,6 +41,7 @@ namespace ams::secmon {
constexpr void UnmapBootCodeImpl(u64 *l1, u64 *l2, u64 *l3, uintptr_t boot_code, size_t boot_code_size) {
/* Unmap the L3 entries corresponding to the boot code. */
AMS_UNUSED(l1, l2);
InvalidateL3Entries(l3, boot_code, boot_code_size);
}
@@ -95,10 +96,6 @@ namespace ams::secmon {
util::ClearMemory(reinterpret_cast<void *>(address + size / 2), size / 2);
}
bool IsPhysicalMemoryAddress(uintptr_t address) {
return (address - MemoryRegionDram.GetAddress()) < GetPhysicalMemorySize();
}
}
void ClearBootCodeHigh() {
@@ -129,6 +126,10 @@ namespace ams::secmon {
}
}
bool IsPhysicalMemoryAddress(uintptr_t address) {
return (address - MemoryRegionDram.GetAddress()) < GetPhysicalMemorySize();
}
void UnmapTzram() {
/* Get the tables. */
u64 * const l1 = MemoryRegionVirtualTzramL1PageTable.GetPointer<u64>();

View File

@@ -18,6 +18,7 @@
namespace ams::secmon {
bool IsPhysicalMemoryAddress(uintptr_t address);
size_t GetPhysicalMemorySize();
void UnmapTzram();

View File

@@ -648,7 +648,7 @@ namespace ams::secmon {
reg::Read (MC + MC_SMMU_TLB_CONFIG);
/* Flush the entire page table cache, and read TLB_CONFIG to ensure the flush takes. */
reg::Write(MC + MC_SMMU_PTC_FLUSH, 0);
reg::Write(MC + MC_SMMU_PTC_FLUSH_0, 0);
reg::Read (MC + MC_SMMU_TLB_CONFIG);
/* Flush the entire translation lookaside buffer, and read TLB_CONFIG to ensure the flush takes. */
@@ -907,7 +907,7 @@ namespace ams::secmon {
reg::Write(MC + MC_SMMU_PPCS1_ASID, MC_REG_BITS_ENUM(SMMU_PPCS1_ASID_PPCS1_SMMU_ENABLE, ENABLE), MC_REG_BITS_VALUE(SMMU_PPCS1_ASID_PPCS1_ASID, BpmpAsid));
/* Flush the entire page table cache, and read TLB_CONFIG to ensure the flush takes. */
reg::Write(MC + MC_SMMU_PTC_FLUSH, 0);
reg::Write(MC + MC_SMMU_PTC_FLUSH_0, 0);
reg::Read (MC + MC_SMMU_TLB_CONFIG);
/* Flush the entire translation lookaside buffer, and read TLB_CONFIG to ensure the flush takes. */

View File

@@ -22,7 +22,7 @@ SetRegisterAllowed(MC_SMMU_CONFIG); /* 0x010 */
SetRegisterAllowed(MC_SMMU_PTB_ASID); /* 0x01C */
SetRegisterAllowed(MC_SMMU_PTB_DATA); /* 0x020 */
SetRegisterAllowed(MC_SMMU_TLB_FLUSH); /* 0x030 */
SetRegisterAllowed(MC_SMMU_PTC_FLUSH); /* 0x034 */
SetRegisterAllowed(MC_SMMU_PTC_FLUSH_0); /* 0x034 */
SetRegisterAllowed(MC_EMEM_CFG); /* 0x050 */
SetRegisterAllowed(MC_EMEM_ADR_CFG); /* 0x054 */
SetRegisterAllowed(MC_EMEM_ARB_CFG); /* 0x090 */
@@ -53,7 +53,7 @@ SetRegisterAllowed(MC_SMMU_DCB_ASID); /* 0x244 */
SetRegisterAllowed(MC_SMMU_HC_ASID); /* 0x250 */
SetRegisterAllowed(MC_SMMU_HDA_ASID); /* 0x254 */
SetRegisterAllowed(MC_SMMU_ISP2_ASID); /* 0x258 */
SetRegisterAllowed(MC_SMMU_NVENC_ASID); /* 0x264 */
SetRegisterAllowed(MC_SMMU_MSENC_NVENC_ASID); /* 0x264 */
SetRegisterAllowed(MC_SMMU_NV_ASID); /* 0x268 */
SetRegisterAllowed(MC_SMMU_NV2_ASID); /* 0x26C */
SetRegisterAllowed(MC_SMMU_PPCS_ASID); /* 0x270 */

View File

@@ -141,6 +141,9 @@ namespace ams::secmon::smc {
{ 0xC3000006, Restriction_Normal, SmcShowError },
{ 0xC3000007, Restriction_Normal, SmcSetKernelCarveoutRegion },
{ 0xC3000008, Restriction_Normal, SmcReadWriteRegister },
/* NOTE: Atmosphere extension for mesosphere. This ID is subject to change at any time. */
{ 0xC3000409, Restriction_Normal, SmcSetConfig },
};
constinit HandlerInfo g_ams_handlers[] = {

View File

@@ -15,6 +15,7 @@
*/
#include <exosphere.hpp>
#include "../secmon_error.hpp"
#include "../secmon_map.hpp"
#include "../secmon_misc.hpp"
#include "../secmon_page_mapper.hpp"
#include "../secmon_user_power_management.hpp"
@@ -157,6 +158,8 @@ namespace ams::secmon::smc {
return value.value;
}
constinit u64 g_payload_address = 0;
SmcResult GetConfig(SmcArguments &args, bool kern) {
switch (static_cast<ConfigItem>(args.r[1])) {
case ConfigItem::DisableProgramVerification:
@@ -267,6 +270,14 @@ namespace ams::secmon::smc {
/* NOTE: This may return values other than 1 in the future. */
args.r[1] = (GetEmummcConfiguration().IsEmummcActive() ? 1 : 0);
break;
case ConfigItem::ExospherePayloadAddress:
/* Gets the physical address of the reboot payload buffer, if one exists. */
if (g_payload_address != 0) {
args.r[1] = g_payload_address;
} else {
return SmcResult::NotInitialized;
}
break;
default:
return SmcResult::InvalidArgument;
}
@@ -309,6 +320,17 @@ namespace ams::secmon::smc {
return SmcResult::NotImplemented;
}
break;
case ConfigItem::ExospherePayloadAddress:
if (g_payload_address == 0) {
if (secmon::IsPhysicalMemoryAddress(args.r[2])) {
g_payload_address = args.r[2];
} else {
return SmcResult::InvalidArgument;
}
} else {
return SmcResult::Busy;
}
break;
default:
return SmcResult::InvalidArgument;
}

View File

@@ -48,6 +48,7 @@ namespace ams::secmon::smc {
ExosphereBlankProdInfo = 65005,
ExosphereAllowCalWrites = 65006,
ExosphereEmummcType = 65007,
ExospherePayloadAddress = 65008,
};
SmcResult SmcGetConfigUser(SmcArguments &args);

View File

@@ -69,6 +69,7 @@ namespace ams::secmon::smc {
SmcResult SmcWriteAddress(SmcArguments &args) {
/* NOTE: This smc was deprecated in Atmosphère 0.13.0. */
AMS_UNUSED(args);
return SmcResult::NotImplemented;
}

View File

@@ -492,6 +492,8 @@ namespace ams::secmon::smc {
}
SmcResult SmcPowerOffCpu(SmcArguments &args) {
AMS_UNUSED(args);
/* Get the current core id. */
const auto core_id = hw::GetCurrentCoreId();

View File

@@ -155,10 +155,27 @@ namespace ams::secmon::smc {
/* Find the access table. */
const AccessTableEntry * const entry = GetAccessTableEntry(address);
/* If we have a table, perform the write. */
/* Translate our entry into an address to access. */
uintptr_t virtual_address = 0;
if (entry != nullptr) {
/* Get the address to read or write. */
const uintptr_t virtual_address = entry->virtual_address + (address - entry->address);
virtual_address = entry->virtual_address + (address - entry->address);
} else {
/* For no clearly discernable reason, SmcReadWriteRegister returns success despite not doing the read/write */
/* when accessing the SMMU controls for the BPMP and for APB-DMA. */
/* This is "probably" to fuck with hackers who got access to the SMC and are trying to get control of the */
/* BPMP to exploit jamais vu, deja vu, or other related DMA/wake-from-sleep vulnerabilities. */
constexpr uintptr_t MC = MemoryRegionPhysicalDeviceMemoryController.GetAddress();
SMC_R_UNLESS((address == (MC + MC_SMMU_AVPC_ASID) || address == (MC + MC_SMMU_PPCS1_ASID)), InvalidArgument);
/* For backwards compatibility, we'll allow access to these devices on 1.0.0. */
if (GetTargetFirmware() < TargetFirmware_2_0_0) {
virtual_address = MemoryRegionVirtualDeviceMemoryController.GetAddress() + (address - MC);
}
}
/* Perform the read or write, if we should. */
if (virtual_address != 0) {
u32 out = 0;
if (mask != ~static_cast<u32>(0)) {
@@ -169,13 +186,6 @@ namespace ams::secmon::smc {
}
args.r[1] = out;
} else {
/* For no clearly discernable reason, SmcReadWriteRegister returns success despite not doing the read/write */
/* when accessing the SMMU controls for the BPMP and for APB-DMA. */
/* This is "probably" to fuck with hackers who got access to the SMC and are trying to get control of the */
/* BPMP to exploit jamais vu, deja vu, or other related DMA/wake-from-sleep vulnerabilities. */
constexpr uintptr_t MC = MemoryRegionPhysicalDeviceMemoryController.GetAddress();
SMC_R_UNLESS((address == (MC + MC_SMMU_AVPC_ASID) || address == (MC + MC_SMMU_PPCS1_ASID)), InvalidArgument);
}
return SmcResult::Success;

View File

@@ -75,6 +75,7 @@ namespace ams::secmon::smc {
u8 msg[se::RsaSize];
public:
void Set(const void *m, size_t m_size) {
AMS_UNUSED(m_size);
std::memcpy(this->msg, m, sizeof(this->msg));
}

View File

@@ -0,0 +1,108 @@
#---------------------------------------------------------------------------------
# Define the atmosphere board and cpu
#---------------------------------------------------------------------------------
export ATMOSPHERE_BOARD := nx-hac-001
export ATMOSPHERE_CPU := arm7tdmi
#---------------------------------------------------------------------------------
# pull in common atmosphere configuration
#---------------------------------------------------------------------------------
include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../../libraries/config/templates/exosphere.mk
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export OUTPUT := $(CURDIR)/$(TARGET)
export TOPDIR := $(CURDIR)
export DEPSDIR := $(CURDIR)/$(BUILD)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
CFILES := $(call FIND_SOURCE_FILES,$(SOURCES),c)
CPPFILES := $(call FIND_SOURCE_FILES,$(SOURCES),cpp)
SFILES := $(call FIND_SOURCE_FILES,$(SOURCES),s)
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
#---------------------------------------------------------------------------------
export LD := $(CC)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
export LD := $(CXX)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(subst -,_,$(BINFILES))))
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I.
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib -L$(dir)/$(ATMOSPHERE_LIBRARY_DIR))
.PHONY: $(BUILD) clean all
#---------------------------------------------------------------------------------
all: $(BUILD) check_libexo
$(BUILD): check_libexo
@[ -d $@ ] || mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
check_libexo:
@$(MAKE) --no-print-directory -C ../../libraries/libexosphere arm
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr $(BUILD) $(OUTPUT).bin $(OUTPUT).elf *.lz4
#---------------------------------------------------------------------------------
else
.PHONY: all
DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
all : $(OUTPUT).bin
$(OUTPUT).bin : $(OUTPUT).elf
$(OBJCOPY) -S -O binary --set-section-flags .bss=alloc,load,contents $< $@
@echo built ... $(notdir $@)
$(OUTPUT).elf : $(OFILES) ../../../libraries/libexosphere/$(ATMOSPHERE_LIBRARY_DIR)/libexosphere.a
%.elf:
@echo linking $(notdir $@)
$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@
@$(NM) -CSn $@ > $(notdir $*.lst)
$(OFILES_SRC) : $(HFILES_BIN)
#---------------------------------------------------------------------------------
# you need a rule like this for each extension you use as binary data
#---------------------------------------------------------------------------------
%.bin.o %_bin.h: %.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
-include $(DEPENDS)
#---------------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------------

View File

@@ -0,0 +1,194 @@
OUTPUT_ARCH(arm)
ENTRY(_ZN3ams10sdmmc_test5StartEv)
MEMORY
{
NULL : ORIGIN = 0, LENGTH = 4K
test_fw : ORIGIN = 0x40010000, LENGTH = 32K
}
SECTIONS
{
/* =========== CODE section =========== */
PROVIDE(__start__ = ORIGIN(test_fw));
. = __start__;
__code_start = . ;
.crt0 :
{
KEEP (*(.crt0 .crt0.*))
. = ALIGN(8);
} >test_fw
.vectors :
{
KEEP (*(.vectors .vectors.*))
. = ALIGN(8);
} >test_fw
.text :
{
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
*(.text.hot .text.hot.*)
*(.text .stub .text.* .gnu.linkonce.t.*)
. = ALIGN(8);
} >test_fw
.init :
{
KEEP( *(.init) )
. = ALIGN(8);
} >test_fw
.plt :
{
*(.plt)
*(.iplt)
. = ALIGN(8);
} >test_fw
.fini :
{
KEEP( *(.fini) )
. = ALIGN(8);
} >test_fw
/* =========== RODATA section =========== */
. = ALIGN(8);
__rodata_start = . ;
.rodata :
{
*(.rodata .rodata.* .gnu.linkonce.r.*)
. = ALIGN(8);
} >test_fw
.eh_frame_hdr : { __eh_frame_hdr_start = .; *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) __eh_frame_hdr_end = .; } >test_fw
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) } >test_fw
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } >test_fw
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } >test_fw
.hash : { *(.hash) } >test_fw
/* =========== DATA section =========== */
. = ALIGN(8);
__data_start = . ;
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) } >test_fw
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } >test_fw
.gnu_extab : ONLY_IF_RW { *(.gnu_extab*) } >test_fw
.exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) } >test_fw
.preinit_array ALIGN(8) :
{
PROVIDE (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE (__preinit_array_end = .);
} >test_fw
.init_array ALIGN(8) :
{
PROVIDE (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
PROVIDE (__init_array_end = .);
} >test_fw
.fini_array ALIGN(8) :
{
PROVIDE (__fini_array_start = .);
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
PROVIDE (__fini_array_end = .);
} >test_fw
.ctors ALIGN(8) :
{
KEEP (*crtbegin.o(.ctors)) /* MUST be first -- GCC requires it */
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
} >test_fw
.dtors ALIGN(8) :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
} >test_fw
__got_start__ = .;
.got : { *(.got) *(.igot) } >test_fw
.got.plt : { *(.got.plt) *(.igot.plt) } >test_fw
__got_end__ = .;
.data ALIGN(8) :
{
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
} >test_fw
__bss_start__ = .;
.bss ALIGN(8) :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(16);
} >test_fw
__bss_end__ = .;
__end__ = ABSOLUTE(.) ;
__total_size__ = (__end__ - __start__);
__stack_top__ = 0x40031000;
__stack_bottom__ = 0x40030000;
/* ==================
==== Metadata ====
================== */
/* Discard sections that difficult post-processing */
/DISCARD/ : { *(.group .comment .note .interp) }
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
}

View File

@@ -0,0 +1,7 @@
%rename link old_link
*link:
%(old_link) -T %:getenv(TOPDIR /sdmmc_test.ld) --gc-sections --nmagic -nostdlib -nostartfiles
*startfile:
crti%O%s crtbegin%O%s

View File

@@ -0,0 +1,146 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <exosphere.hpp>
namespace ams::sdmmc_test {
namespace {
constexpr inline const uintptr_t PMC = secmon::MemoryRegionPhysicalDevicePmc.GetAddress();
constexpr inline auto Port = sdmmc::Port_SdCard0;
alignas(8) constinit u8 g_sd_work_buffer[sdmmc::SdCardWorkBufferSize];
constexpr inline u32 SectorIndex = 0;
constexpr inline u32 SectorCount = 2;
NORETURN void PmcMainReboot() {
/* Write enable to MAIN_RESET. */
reg::Write(PMC + APBDEV_PMC_CNTRL, PMC_REG_BITS_ENUM(CNTRL_MAIN_RESET, ENABLE));
/* Wait forever until we're reset. */
AMS_INFINITE_LOOP();
}
void CheckResult(const Result result) {
volatile u32 * const DEBUG = reinterpret_cast<volatile u32 *>(0x4003C000);
if (R_FAILED(result)) {
DEBUG[1] = result.GetValue();
PmcMainReboot();
}
}
}
void Main() {
/* Perform butchered hwinit. */
/* TODO: replace with simpler, non-C logic. */
/* nx_hwinit(); */
/* Clear output buffer for debug. */
std::memset((void *)0x40038000, 0xAA, 0x400);
/* Normally, these pins get configured by boot sysmodule during initial pinmux config. */
/* However, they're required to access the SD card. */
{
const uintptr_t apb_misc = dd::QueryIoMapping(0x70000000, 0x4000);
reg::ReadWrite(apb_misc + PINMUX_AUX_SDMMC1_CLK, PINMUX_REG_BITS_ENUM(AUX_E_INPUT, ENABLE),
PINMUX_REG_BITS_ENUM(AUX_TRISTATE, PASSTHROUGH),
PINMUX_REG_BITS_ENUM(AUX_PUPD, PULL_DOWN),
PINMUX_REG_BITS_ENUM(AUX_SDMMC1_CLK_PM, SDMMC1));
reg::ReadWrite(apb_misc + PINMUX_AUX_SDMMC1_CMD, PINMUX_REG_BITS_ENUM(AUX_E_INPUT, ENABLE),
PINMUX_REG_BITS_ENUM(AUX_TRISTATE, PASSTHROUGH),
PINMUX_REG_BITS_ENUM(AUX_PUPD, PULL_UP),
PINMUX_REG_BITS_ENUM(AUX_SDMMC1_CMD_PM, SDMMC1));
reg::ReadWrite(apb_misc + PINMUX_AUX_SDMMC1_DAT3, PINMUX_REG_BITS_ENUM(AUX_E_INPUT, ENABLE),
PINMUX_REG_BITS_ENUM(AUX_TRISTATE, PASSTHROUGH),
PINMUX_REG_BITS_ENUM(AUX_PUPD, PULL_UP),
PINMUX_REG_BITS_ENUM(AUX_SDMMC1_DAT3_PM, SDMMC1));
reg::ReadWrite(apb_misc + PINMUX_AUX_SDMMC1_DAT2, PINMUX_REG_BITS_ENUM(AUX_E_INPUT, ENABLE),
PINMUX_REG_BITS_ENUM(AUX_TRISTATE, PASSTHROUGH),
PINMUX_REG_BITS_ENUM(AUX_PUPD, PULL_UP),
PINMUX_REG_BITS_ENUM(AUX_SDMMC1_DAT2_PM, SDMMC1));
reg::ReadWrite(apb_misc + PINMUX_AUX_SDMMC1_DAT1, PINMUX_REG_BITS_ENUM(AUX_E_INPUT, ENABLE),
PINMUX_REG_BITS_ENUM(AUX_TRISTATE, PASSTHROUGH),
PINMUX_REG_BITS_ENUM(AUX_PUPD, PULL_UP),
PINMUX_REG_BITS_ENUM(AUX_SDMMC1_DAT1_PM, SDMMC1));
reg::ReadWrite(apb_misc + PINMUX_AUX_SDMMC1_DAT0, PINMUX_REG_BITS_ENUM(AUX_E_INPUT, ENABLE),
PINMUX_REG_BITS_ENUM(AUX_TRISTATE, PASSTHROUGH),
PINMUX_REG_BITS_ENUM(AUX_PUPD, PULL_UP),
PINMUX_REG_BITS_ENUM(AUX_SDMMC1_DAT0_PM, SDMMC1));
reg::ReadWrite(apb_misc + PINMUX_AUX_DMIC3_CLK, PINMUX_REG_BITS_ENUM(AUX_E_OD, DISABLE),
PINMUX_REG_BITS_ENUM(AUX_E_INPUT, DISABLE),
PINMUX_REG_BITS_ENUM(AUX_TRISTATE, PASSTHROUGH),
PINMUX_REG_BITS_ENUM(AUX_SDMMC1_DAT0_PM, RSVD2));
}
/* Debug signaler. */
volatile u32 * const DEBUG = reinterpret_cast<volatile u32 *>(0x4003C000);
DEBUG[0] = 0;
DEBUG[1] = 0xAAAAAAAA;
/* Initialize sdmmc library. */
sdmmc::Initialize(Port);
DEBUG[0] = 1;
sdmmc::SetSdCardWorkBuffer(Port, g_sd_work_buffer, sizeof(g_sd_work_buffer));
DEBUG[0] = 2;
Result result = sdmmc::Activate(Port);
DEBUG[0] = 3;
CheckResult(result);
/* Read the first two sectors from disk. */
void * const sector_dst = reinterpret_cast<void *>(0x40038000);
result = sdmmc::Read(sector_dst, SectorCount * sdmmc::SectorSize, Port, SectorIndex, SectorCount);
DEBUG[0] = 4;
CheckResult(result);
/* Get the connection status. */
sdmmc::SpeedMode speed_mode;
sdmmc::BusWidth bus_width;
result = sdmmc::CheckSdCardConnection(std::addressof(speed_mode), std::addressof(bus_width), Port);
/* Save status for debug. */
DEBUG[0] = 5;
DEBUG[1] = result.GetValue();
DEBUG[2] = static_cast<u32>(speed_mode);
DEBUG[3] = static_cast<u32>(bus_width);
/* Perform a reboot. */
PmcMainReboot();
}
NORETURN void ExceptionHandler() {
PmcMainReboot();
}
}
namespace ams::diag {
void AbortImpl() {
sdmmc_test::ExceptionHandler();
}
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
.section .crt0.text._ZN3ams10sdmmc_test5StartEv, "ax", %progbits
.align 3
.global _ZN3ams10sdmmc_test5StartEv
_ZN3ams10sdmmc_test5StartEv:
/* Switch to system mode, mask all interrupts, clear all flags */
msr cpsr_cxsf, #0xDF
/* Set the stack pointer. */
ldr sp, =__stack_top__
/* Set our link register to the exception handler. */
ldr lr, =_ZN3ams10sdmmc_test16ExceptionHandlerEv
/* Call init array functions. */
bl __libc_init_array
/* Invoke main. */
b _ZN3ams10sdmmc_test4MainEv
/* Infinite loop. */
2: b 2b

View File

@@ -23,23 +23,9 @@ export DEPSDIR := $(CURDIR)/$(BUILD)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
CFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.c)) $(notdir $(wildcard $(dir)/*.board.*.c)) $(notdir $(wildcard $(dir)/*.os.*.c)), \
$(notdir $(wildcard $(dir)/*.c))))
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).c)))
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).c)))
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).c)))
CPPFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.cpp)) $(notdir $(wildcard $(dir)/*.board.*.cpp)) $(notdir $(wildcard $(dir)/*.os.*.cpp)), \
$(notdir $(wildcard $(dir)/*.cpp))))
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).cpp)))
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).cpp)))
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).cpp)))
SFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.s)) $(notdir $(wildcard $(dir)/*.board.*.s)) $(notdir $(wildcard $(dir)/*.os.*.s)), \
$(notdir $(wildcard $(dir)/*.s))))
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).s)))
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).s)))
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).s)))
CFILES := $(call FIND_SOURCE_FILES,$(SOURCES),c)
CPPFILES := $(call FIND_SOURCE_FILES,$(SOURCES),cpp)
SFILES := $(call FIND_SOURCE_FILES,$(SOURCES),s)
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C

View File

@@ -90,7 +90,9 @@ namespace ams::warmboot {
NORETURN void ExceptionHandler() {
/* Write enable to MAIN_RESET. */
reg::Write(PMC + APBDEV_PMC_CNTRL, PMC_REG_BITS_ENUM(CNTRL_MAIN_RESET, ENABLE));
while (true) { /* ... */ }
/* Wait forever until we're reset. */
AMS_INFINITE_LOOP();
}
}

View File

@@ -30,7 +30,7 @@ _ZN3ams8warmboot5StartEv:
/* Invoke main. */
ldr r0, =_metadata
bl _ZN3ams8warmboot4MainEPKNS0_8MetadataE
b _ZN3ams8warmboot4MainEPKNS0_8MetadataE
/* Infinite loop. */
1: b 1b

View File

@@ -24,6 +24,9 @@
#include "lib/log.h"
#include "display/video_fb.h"
#define PROGRAM_ID_AMS_MITM 0x010041544D530000ull
#define PROGRAM_ID_BOOT 0x0100000000000005ull
static uint32_t g_panic_code = 0;
static const char *get_error_desc_str(uint32_t error_desc) {
@@ -42,6 +45,8 @@ static const char *get_error_desc_str(uint32_t error_desc) {
return "SError";
case 0x301:
return "Bad SVC";
case 0xF00:
return "Kernel Panic";
case 0xFFD:
return "Stack overflow";
case 0xFFE:
@@ -51,6 +56,61 @@ static const char *get_error_desc_str(uint32_t error_desc) {
}
}
static void _try_suggest_fix(const atmosphere_fatal_error_ctx *ctx) {
/* Try to recognize certain errors automatically, and suggest fixes for them. */
const char *suggestion = NULL;
if (ctx->error_desc == 0xFFE) {
if (ctx->program_id == PROGRAM_ID_AMS_MITM) {
/* When a user has archive bits set improperly, attempting to create an automatic backup will fail */
/* to create the file path with error 0x202 (fs::ResultPathNotFound()) */
if (ctx->gprs[0] == 0x202) {
/* When the archive bit error is occurring, it manifests as failure to create automatic backup. */
/* Thus, we can search the stack for the automatic backups path. */
const char * const automatic_backups_prefix = "automatic_backups/X" /* ..... */;
const int prefix_len = strlen(automatic_backups_prefix);
for (size_t i = 0; i + prefix_len < ctx->stack_dump_size; ++i) {
if (memcmp(&ctx->stack_dump[i], automatic_backups_prefix, prefix_len) == 0) {
suggestion = "The atmosphere directory may improperly have archive\n"
"bits set. Please try running an archive bit fixer tool\n"
"(for example, the one in Hekate).\n";
break;
}
}
} else if (ctx->gprs[0] == 0x249A02) { /* fs::ResultResultExFatUnavailable() */
/* When a user installs non-exFAT firm but has an exFAT formatted SD card, this error will */
/* be returned on attempt to access the SD card. */
suggestion = "Your console has non-exFAT firmware installed, but your SD card\n"
"is formatted as exFAT. Format your SD card as FAT32, or manually\n"
"flash exFAT firmware to package2.\n";
}
} else if (ctx->program_id == PROGRAM_ID_BOOT) {
/* 9.x -> 10.x updated the API for SvcQueryIoMapping. */
/* This can cause the kernel to reject incorrect-ABI calls by boot when a partial update is applied */
/* (older kernel in package2, for some reason). */
for (size_t i = 0; i < 8; ++i) {
if (ctx->gprs[i] == 0xF201) {
suggestion = "A partial update may have been improperly performed.\n"
"To fix, try manually flashing latest package2 to MMC.\n"
"\n"
"For help doing this, seek support in the ReSwitched or\n"
"Nintendo Homebrew discord servers.\n";
break;
}
}
}
} else if (ctx->error_desc == 0xF00) { /* Kernel Panic */
suggestion = "Please contact SciresM#0524 on Discord, or create an issue\n"
"on the Atmosphere GitHub issue tracker. Thank you very much\n"
"for helping to test mesosphere.\n";
}
if (suggestion != NULL) {
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "\n%s", suggestion);
}
}
static void _check_and_display_atmosphere_fatal_error(void) {
/* Check for valid magic. */
if (ATMOSPHERE_FATAL_ERROR_CONTEXT->magic != ATMOSPHERE_REBOOT_TO_FATAL_MAGIC &&
@@ -84,7 +144,7 @@ static void _check_and_display_atmosphere_fatal_error(void) {
ATMOSPHERE_FATAL_ERROR_CONTEXT->magic = 0xCCCCCCCC;
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "A fatal error occurred when running Atmosph\xe8re.\n");
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "Title ID: %016llx\n", ctx.title_id);
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "Program ID: %016llx\n", ctx.program_id);
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "Error Desc: %s (0x%x)\n", get_error_desc_str(ctx.error_desc), ctx.error_desc);
/* Save context to the SD card. */
@@ -99,6 +159,9 @@ static void _check_and_display_atmosphere_fatal_error(void) {
}
}
/* Try to print a fix suggestion via automatic error detection. */
_try_suggest_fix(&ctx);
/* Display error. */
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "\nPress POWER to reboot\n");
}

View File

@@ -36,7 +36,7 @@
typedef struct {
uint32_t magic;
uint32_t error_desc;
uint64_t title_id;
uint64_t program_id;
union {
uint64_t gprs[32];
struct {

View File

@@ -89,7 +89,7 @@ export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir)) \
$(AMS)/exosphere $(AMS)/exosphere/warmboot $(AMS)/exosphere/program/rebootstub \
$(AMS)/thermosphere $(AMS)/fusee/fusee-primary $(AMS)/sept/sept-primary \
$(AMS)/sept/sept-secondary $(AMS)/emummc $(AMS)/mesosphere/kernel_ldr $(KIPDIRS)
$(AMS)/sept/sept-secondary $(AMS)/emummc $(AMS)/mesosphere $(AMS)/mesosphere/kernel_ldr $(KIPDIRS)
export DEPSDIR := $(CURDIR)/$(BUILD)
@@ -100,7 +100,7 @@ KIPFILES := loader.kip ncm.kip pm.kip sm.kip ams_mitm.kip spl.kip boot.kip
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) fusee-primary.bin \
exosphere.bin warmboot.bin rebootstub.bin thermosphere.bin splash_screen.bmp \
sept-primary.bin sept-secondary_00.enc sept-secondary_01.enc emummc.kip \
sept-secondary_dev_00.enc sept-secondary_dev_01.enc kernel_ldr.bin $(KIPFILES)
sept-secondary_dev_00.enc sept-secondary_dev_01.enc mesosphere.bin kernel_ldr.bin $(KIPFILES)
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
@@ -186,11 +186,15 @@ DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
all : $(OUTPUT).bin
$(OUTPUT).bin : $(OUTPUT).elf
$(OUTPUT).bin : $(OUTPUT)-experimental.bin
@python $(TOPDIR)/fusee_make_standard.py $(OUTPUT)-experimental.bin $(OUTPUT).bin
@echo built ... $(notdir $@)
$(OUTPUT)-experimental.bin : $(OUTPUT)-experimental.elf
$(OBJCOPY) -S -O binary $< $@
@echo built ... $(notdir $@)
$(OUTPUT).elf : $(OFILES)
$(OUTPUT)-experimental.elf : $(OFILES)
%.elf: $(OFILES)
@echo linking $(notdir $@)

View File

@@ -0,0 +1,37 @@
#!/usr/bin/env python
import sys, os
from struct import pack as pk, unpack as up
def make_standard(exp):
std = exp[:]
_, metadata_offset, is_exp = up('<III', exp[:12])
assert is_exp == 1
# Patch the experimental flag to zero.
std = std[:8] + pk('<I', 0) + std[12:]
# Locate the mesosphere content header, patch to be experimental.
magic, size, code_ofs, content_ofs, num_contents, ver, sup_ver, rev = up('<IIIIIIII', exp[metadata_offset:metadata_offset + 0x20])
for i in range(num_contents):
start, size, cnt_type, flag0, flag1, flag2, pad = up('<IIBBBBI', exp[content_ofs + 0x20 * i:content_ofs + 0x20 * i + 0x10])
if cnt_type == 10: # CONTENT_TYPE_KRN
assert exp[content_ofs + 0x20 * i + 0x10:content_ofs + 0x20 * i + 0x10 + len(b'mesosphere') + 1] == (b'mesosphere\x00')
assert flag0 == 0 and flag1 == 0 and flag2 == 0
std = std[:content_ofs + 0x20 * i] + pk('<IIBBBBI', start, size, cnt_type, flag0 | 0x1, flag1, flag2, pad) + std[content_ofs + 0x20 * i + 0x10:]
return std
def main(argc, argv):
if argc != 3:
print('Usage: %s input output' % argv[0])
return 1
with open(argv[1], 'rb') as f:
experimental = f.read()
with open(argv[2], 'wb') as f:
f.write(make_standard(experimental))
return 0
if __name__ == '__main__':
sys.exit(main(len(sys.argv), sys.argv))

View File

@@ -254,4 +254,6 @@ SECTIONS
PROVIDE(__emummc_kip_size__ = emummc_kip_end - emummc_kip);
PROVIDE(__kernel_ldr_bin_start__ = kernel_ldr_bin - __start__);
PROVIDE(__kernel_ldr_bin_size__ = kernel_ldr_bin_end - kernel_ldr_bin);
PROVIDE(__mesosphere_bin_start__ = mesosphere_bin - __start__);
PROVIDE(__mesosphere_bin_size__ = mesosphere_bin_end - mesosphere_bin);
}

View File

@@ -37,23 +37,27 @@
/* Clock and reset devices. */
typedef enum {
CARDEVICE_UARTA = ((0 << 5) | 0x6),
CARDEVICE_UARTB = ((0 << 5) | 0x7),
CARDEVICE_UARTC = ((1 << 5) | 0x17),
CARDEVICE_I2C1 = ((0 << 5) | 0xC),
CARDEVICE_I2C5 = ((1 << 5) | 0xF),
CARDEVICE_TZRAM = ((3 << 5) | 0x1E),
CARDEVICE_SE = ((3 << 5) | 0x1F),
CARDEVICE_HOST1X = ((0 << 5) | 0x1C),
CARDEVICE_TSEC = ((2 << 5) | 0x13),
CARDEVICE_SOR_SAFE = ((6 << 5) | 0x1E),
CARDEVICE_SOR0 = ((5 << 5) | 0x16),
CARDEVICE_SOR1 = ((5 << 5) | 0x17),
CARDEVICE_KFUSE = ((1 << 5) | 0x8),
CARDEVICE_CL_DVFS = ((4 << 5) | 0x1B),
CARDEVICE_BPMP = ((0 << 5) | 0x1),
CARDEVICE_UARTA = ((0 << 5) | 0x6),
CARDEVICE_UARTB = ((0 << 5) | 0x7),
CARDEVICE_I2C1 = ((0 << 5) | 0xC),
CARDEVICE_USBD = ((0 << 5) | 0x16),
CARDEVICE_HOST1X = ((0 << 5) | 0x1C),
CARDEVICE_AHBDMA = ((1 << 5) | 0x1),
CARDEVICE_APBDMA = ((1 << 5) | 0x2),
CARDEVICE_KFUSE = ((1 << 5) | 0x8),
CARDEVICE_I2C5 = ((1 << 5) | 0xF),
CARDEVICE_UARTC = ((1 << 5) | 0x17),
CARDEVICE_USB2 = ((1 << 5) | 0x1A),
CARDEVICE_CORESIGHT = ((2 << 5) | 0x9),
CARDEVICE_ACTMON = ((3 << 5) | 0x17),
CARDEVICE_BPMP = ((0 << 5) | 0x1)
CARDEVICE_TSEC = ((2 << 5) | 0x13),
CARDEVICE_ACTMON = ((3 << 5) | 0x17),
CARDEVICE_TZRAM = ((3 << 5) | 0x1E),
CARDEVICE_SE = ((3 << 5) | 0x1F),
CARDEVICE_CL_DVFS = ((4 << 5) | 0x1B),
CARDEVICE_SOR0 = ((5 << 5) | 0x16),
CARDEVICE_SOR1 = ((5 << 5) | 0x17),
CARDEVICE_SOR_SAFE = ((6 << 5) | 0x1E),
} CarDevice;
/* Clock/Reset Controller (CLK_RST_CONTROLLER_) regs */

View File

@@ -85,6 +85,9 @@ typedef enum {
FS_VER_10_0_0,
FS_VER_10_0_0_EXFAT,
FS_VER_10_2_0,
FS_VER_10_2_0_EXFAT,
FS_VER_MAX,
} emummc_fs_ver_t;

View File

@@ -420,6 +420,9 @@ static const uint8_t g_fs_hashes[FS_VER_MAX][0x8] = {
"\x3E\xEB\xD9\xB7\xBC\xD1\xB5\xE0", /* FS_VER_10_0_0 */
"\x81\x7E\xA2\xB0\xB7\x02\xC1\xF3", /* FS_VER_10_0_0_EXFAT */
"\xA9\x52\xB6\x57\xAD\xF9\xC2\xBA", /* FS_VER_10_2_0 */
"\x16\x0D\x3E\x10\x4E\xAD\x61\x76", /* FS_VER_10_2_0_EXFAT */
};
kip1_header_t *apply_kip_ips_patches(kip1_header_t *kip, size_t kip_size, emummc_fs_ver_t *out_fs_ver) {

View File

@@ -963,11 +963,6 @@ void package2_patch_kernel(void *_kernel, size_t *kernel_size, bool is_sd_kernel
}
if (kernel_info == NULL && is_sd_kernel) {
/* If the kernel is mesosphere, patch it. */
if (*(volatile uint32_t *)((uintptr_t)_kernel + 4) == 0x3053534D) {
*out_ini1 = (void *)((uintptr_t)_kernel + *(volatile uint32_t *)((uintptr_t)_kernel + 8));
*(volatile uint64_t *)((uintptr_t)_kernel + 8) = (uint64_t)*kernel_size;
}
return;
}

View File

@@ -24,6 +24,7 @@
#include "nxboot.h"
#include "nxfs.h"
#include "bct.h"
#include "car.h"
#include "di.h"
#include "mc.h"
#include "se.h"
@@ -54,6 +55,7 @@
#define u8 uint8_t
#define u32 uint32_t
#include "exosphere_bin.h"
#include "mesosphere_bin.h"
#include "sept_secondary_00_enc.h"
#include "sept_secondary_01_enc.h"
#include "sept_secondary_dev_00_enc.h"
@@ -65,6 +67,8 @@
extern const uint8_t warmboot_bin[];
extern int fusee_is_experimental(void);
static const uint8_t retail_pkc_modulus[0x100] = {
0xF7, 0x86, 0x47, 0xAB, 0x71, 0x89, 0x81, 0xB5, 0xCF, 0x0C, 0xB0, 0xE8, 0x48, 0xA7, 0xFD, 0xAD,
0xCB, 0x4E, 0x4A, 0x52, 0x0B, 0x1A, 0x8E, 0xDE, 0x41, 0x87, 0x6F, 0xB7, 0x31, 0x05, 0x5F, 0xAA,
@@ -208,11 +212,11 @@ static int stratosphere_ini_handler(void *user, const char *section, const char
strat_cfg->has_nogc_config = true;
sscanf(value, "%d", &tmp);
strat_cfg->enable_nogc = tmp != 0;
} else if (strcmp(name, STRATOSPHERE_ENABLE_NCM_KEY) == 0) {
} else if (strcmp(name, STRATOSPHERE_DISABLE_NCM_KEY) == 0) {
sscanf(value, "%d", &tmp);
strat_cfg->ncm_enabled = tmp != 0;
if (strat_cfg->ncm_enabled) {
stratosphere_enable_ncm();
strat_cfg->ncm_disabled = tmp != 0;
if (strat_cfg->ncm_disabled) {
stratosphere_disable_ncm();
}
} else {
return 0;
@@ -235,6 +239,7 @@ static uint32_t nxboot_get_specific_target_firmware(uint32_t target_firmware){
#define CHECK_NCA(NCA_ID, VERSION) do { if (is_nca_present(NCA_ID)) { return ATMOSPHERE_TARGET_FIRMWARE_##VERSION; } } while(0)
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_10_0_0) {
CHECK_NCA("26325de4db3909e0ef2379787c7e671d", 10_2_0);
CHECK_NCA("5077973537f6735b564dd7475b779f87", 10_1_1); /* Exclusive to China. */
CHECK_NCA("fd1faed0ca750700d254c0915b93d506", 10_1_0);
CHECK_NCA("34728c771299443420820d8ae490ea41", 10_0_4);
@@ -622,6 +627,7 @@ static nx_keyblob_t __attribute__((aligned(16))) g_keyblobs[32];
uint32_t nxboot_main(void) {
volatile tegra_pmc_t *pmc = pmc_get_regs();
loader_ctx_t *loader_ctx = get_loader_ctx();
const bool is_experimental = fusee_is_experimental();
package2_header_t *package2;
size_t package2_size;
void *tsec_fw;
@@ -633,6 +639,8 @@ uint32_t nxboot_main(void) {
void *warmboot_memaddr;
void *package1loader;
size_t package1loader_size;
void *mesosphere;
size_t mesosphere_size;
void *emummc;
size_t emummc_size;
uint32_t available_revision;
@@ -928,6 +936,41 @@ uint32_t nxboot_main(void) {
pmc->scratch1 = (uint32_t)warmboot_memaddr;
}
/* Configure mesosphere. */
{
size_t sd_meso_size = get_file_size("atmosphere/mesosphere.bin");
if (sd_meso_size != 0) {
if (sd_meso_size > PACKAGE2_SIZE_MAX) {
fatal_error("Error: atmosphere/mesosphere.bin is too large!\n");
}
mesosphere = malloc(sd_meso_size);
if (mesosphere == NULL) {
fatal_error("Error: failed to allocate mesosphere!\n");
}
if (read_from_file(mesosphere, sd_meso_size, "atmosphere/mesosphere.bin") != sd_meso_size) {
fatal_error("Error: failed to read atmosphere/mesosphere.bin!\n");
}
mesosphere_size = sd_meso_size;
} else if (is_experimental) {
mesosphere_size = mesosphere_bin_size;
mesosphere = malloc(mesosphere_size);
if (mesosphere == NULL) {
fatal_error("[NXBOOT] Out of memory!\n");
}
memcpy(mesosphere, mesosphere_bin, mesosphere_size);
if (mesosphere_size == 0) {
fatal_error("[NXBOOT] Could not read embedded mesosphere!\n");
}
} else {
mesosphere = NULL;
mesosphere_size = 0;
}
}
print(SCREEN_LOG_LEVEL_INFO, "[NXBOOT] Rebuilding package2...\n");
/* Parse stratosphere config. */
@@ -936,7 +979,7 @@ uint32_t nxboot_main(void) {
print(SCREEN_LOG_LEVEL_INFO, u8"[NXBOOT] Configured Stratosphere...\n");
/* Patch package2, adding Thermosphère + custom KIPs. */
package2_rebuild_and_copy(package2, MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware, emummc, emummc_size);
package2_rebuild_and_copy(package2, MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware, mesosphere, mesosphere_size, emummc, emummc_size);
/* Set detected FS version. */
MAILBOX_EXOSPHERE_CONFIGURATION->emummc_cfg.base_cfg.fs_version = stratosphere_get_fs_version();
@@ -991,6 +1034,12 @@ uint32_t nxboot_main(void) {
/* Wait for the splash screen to have been displayed for as long as it should be. */
splash_screen_wait_delay();
/* Set reset for USBD, USB2, AHBDMA, and APBDMA. */
rst_enable(CARDEVICE_USBD);
rst_enable(CARDEVICE_USB2);
rst_enable(CARDEVICE_AHBDMA);
rst_enable(CARDEVICE_APBDMA);
/* Return the memory address for booting CPU0. */
return (uint32_t)exosphere_memaddr;
}

View File

@@ -44,7 +44,7 @@ static inline size_t align_to_4(size_t s) {
return ((s + 3) >> 2) << 2;
}
void package2_rebuild_and_copy(package2_header_t *package2, uint32_t target_firmware, void *emummc, size_t emummc_size) {
void package2_rebuild_and_copy(package2_header_t *package2, uint32_t target_firmware, void *mesosphere, size_t mesosphere_size, void *emummc, size_t emummc_size) {
package2_header_t *rebuilt_package2;
size_t rebuilt_package2_size;
void *kernel;
@@ -95,10 +95,28 @@ void package2_rebuild_and_copy(package2_header_t *package2, uint32_t target_firm
fatal_error("Error: inappropriate kernel embedded ini context");
}
/* Use mesosphere instead of Nintendo's kernel when present. */
const bool is_mesosphere = mesosphere != NULL && mesosphere_size != 0;
if (is_mesosphere) {
kernel = mesosphere;
kernel_size = mesosphere_size;
/* Patch mesosphere to use our rebuilt ini. */
*(volatile uint64_t *)((uintptr_t)mesosphere + 8) = (uint64_t)mesosphere_size;
/* Place the kernel section at the correct location. */
package2->metadata.section_offsets[PACKAGE2_SECTION_KERNEL] = 0x60000;
package2->metadata.entrypoint = 0x60000;
print(SCREEN_LOG_LEVEL_DEBUG, "Using Mesosphere...\n");
}
print(SCREEN_LOG_LEVEL_DEBUG, "Rebuilding the INI1 section...\n");
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_8_0_0) {
package2_get_src_section((void *)&orig_ini1, package2, PACKAGE2_SECTION_INI1);
} else {
}
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_8_0_0 || is_mesosphere) {
/* On 8.0.0, place INI1 right after kernelldr for our sanity. */
package2->metadata.section_offsets[PACKAGE2_SECTION_INI1] = package2->metadata.section_offsets[PACKAGE2_SECTION_KERNEL] + kernel_size;
}

View File

@@ -94,6 +94,6 @@ static inline uint8_t package2_meta_get_header_version(const package2_meta_t *me
return (uint8_t)((metadata->ctr_dwords[1] ^ (metadata->ctr_dwords[1] >> 16) ^ (metadata->ctr_dwords[1] >> 24)) & 0xFF);
}
void package2_rebuild_and_copy(package2_header_t *package2, uint32_t target_firmware, void *emummc, size_t emummc_size);
void package2_rebuild_and_copy(package2_header_t *package2, uint32_t target_firmware, void *mesosphere, size_t mesosphere_size, void *emummc, size_t emummc_size);
#endif

View File

@@ -30,6 +30,9 @@ _start:
.word (_metadata - _start)
_is_experimental:
.word 0x00000001 /* is experimental */
_crt0:
/* Switch to system mode, mask all interrupts, clear all flags */
msr cpsr_cxsf, #0xDF
@@ -68,6 +71,14 @@ _crt0:
ldr r1, [r1]
b main
.arm
.global fusee_is_experimental
.type fusee_is_experimental, %function
fusee_is_experimental:
ldr r0, =_is_experimental
ldr r0, [r0]
bx lr
/* Fusee-secondary header. */
.align 5
_metadata:
@@ -135,6 +146,17 @@ _content_headers:
.asciz "exosphere"
.align 5
/* mesosphere content header */
.word __mesosphere_bin_start__
.word __mesosphere_bin_size__
.byte CONTENT_TYPE_KRN
.byte CONTENT_FLAG_NONE
.byte CONTENT_FLAG_NONE
.byte CONTENT_FLAG_NONE
.word 0xCCCCCCCC
.asciz "mesosphere"
.align 5
/* fusee_primary content header */
.word __fusee_primary_bin_start__
.word __fusee_primary_bin_size__
@@ -249,7 +271,7 @@ _content_headers:
.word __ncm_kip_start__
.word __ncm_kip_size__
.byte CONTENT_TYPE_KIP
.byte CONTENT_FLAG0_EXPERIMENTAL
.byte CONTENT_FLAG_NONE
.byte CONTENT_FLAG_NONE
.byte CONTENT_FLAG_NONE
.word 0xCCCCCCCC
@@ -267,17 +289,6 @@ _content_headers:
.asciz "emummc"
.align 5
/* kernel_ldr content header */
.word __kernel_ldr_bin_start__
.word __kernel_ldr_bin_size__
.byte CONTENT_TYPE_KLD
.byte CONTENT_FLAG_NONE
.byte CONTENT_FLAG_NONE
.byte CONTENT_FLAG_NONE
.word 0xCCCCCCCC
.asciz "kernel_ldr"
.align 5
/* splash_screen content header */
.word __splash_screen_bmp_start__
.word __splash_screen_bmp_size__

View File

@@ -48,7 +48,7 @@ static bool g_stratosphere_pm_enabled = true;
static bool g_stratosphere_ams_mitm_enabled = true;
static bool g_stratosphere_spl_enabled = true;
static bool g_stratosphere_boot_enabled = true;
static bool g_stratosphere_ncm_enabled = false;
static bool g_stratosphere_ncm_enabled = true;
extern const uint8_t loader_kip[], pm_kip[], sm_kip[], spl_kip[], boot_kip[], ncm_kip[], ams_mitm_kip[];
@@ -58,17 +58,17 @@ emummc_fs_ver_t stratosphere_get_fs_version(void) {
return g_fs_ver;
}
void stratosphere_enable_ncm(void) {
void stratosphere_disable_ncm(void) {
/* The Atmosphere team believes our implementation of NCM to be extremely accurate, */
/* and does not think it likely there is any possibility of undesirable behavior */
/* when using the NCM reimplementation. However, because NCM manages critical save games */
/* the implementation will default to off for some time, until the code has been thoroughly */
/* tested in practice. */
/* the implementation may be optionally disabled for those not comfortable using it. */
/* PLEASE NOTE: The default behavior will be NCM on in a future atmosphere release, */
/* and this opt-in functionality will be removed at that time. */
g_stratosphere_ncm_enabled = true;
/* PLEASE NOTE: The NCM reimplementation has been well-tested, and correspondingly opt-out */
/* functionality will be removed in Atmosphere 1.0.0. */
g_stratosphere_ncm_enabled = false;
}
/* GCC doesn't consider the size as const... we have to write it ourselves. */

View File

@@ -30,7 +30,7 @@ ini1_header_t *stratosphere_get_ini1(uint32_t target_firmware);
ini1_header_t *stratosphere_get_sd_files_ini1(void);
void stratosphere_free_ini1(void);
void stratosphere_enable_ncm(void);
void stratosphere_disable_ncm(void);
emummc_fs_ver_t stratosphere_get_fs_version(void);
@@ -39,10 +39,10 @@ ini1_header_t *stratosphere_merge_inis(ini1_header_t **inis, unsigned int num_in
typedef struct {
bool has_nogc_config;
bool enable_nogc;
bool ncm_enabled;
bool ncm_disabled;
} stratosphere_cfg_t;
#define STRATOSPHERE_NOGC_KEY "nogc"
#define STRATOSPHERE_ENABLE_NCM_KEY "enable_ncm"
#define STRATOSPHERE_DISABLE_NCM_KEY "disable_ncm"
#endif

View File

@@ -6,7 +6,7 @@
[subrepo]
remote = https://github.com/Atmosphere-NX/Atmosphere-libs
branch = master
commit = cac5957d3f4b1417cf76a83cf704a14a254dd4dc
parent = 3726def6ecc547e64912ddb050737ebd296366e7
commit = 10e9e0e8f926b11c2c7de16ffe15bea7d7ec2cdf
parent = 2ee2a4f1ac04bc7f15de8be8d57ad04d7e73f735
method = merge
cmdver = 0.4.1

View File

@@ -5,7 +5,7 @@ endif
include $(DEVKITPRO)/devkitA64/base_rules
export ATMOSPHERE_DEFINES += -DATMOSPHERE_ARCH_ARM64
export ATMOSPHERE_SETTINGS += -march=armv8-a+crc+crypto -mtp=soft
export ATMOSPHERE_SETTINGS += -mtp=soft
export ATMOSPHERE_CFLAGS +=
export ATMOSPHERE_CXXFLAGS +=
export ATMOSPHERE_ASFLAGS +=

View File

@@ -1,5 +1,5 @@
export ATMOSPHERE_DEFINES += -DATMOSPHERE_CPU_ARM_CORTEX_A57
export ATMOSPHERE_SETTINGS += -mtune=cortex-a57
export ATMOSPHERE_SETTINGS += -march=armv8-a+crc+crypto -mtune=cortex-a57
export ATMOSPHERE_CFLAGS +=
export ATMOSPHERE_CXXFLAGS +=
export ATMOSPHERE_ASFLAGS +=

View File

@@ -10,13 +10,15 @@ ifeq ($(strip $(ATMOSPHERE_BOARD)),)
export ATMOSPHERE_BOARD := nx-hac-001
ifeq ($(strip $(ATMOSPHERE_CPU)),)
export ATMOSPHERE_CPU := arm-cortex-a57
export ATMOSPHERE_CPU := arm-cortex-a57
endif
endif
ATMOSPHERE_BUILD_SETTINGS ?=
export ATMOSPHERE_DEFINES := -DATMOSPHERE
export ATMOSPHERE_SETTINGS := -fPIE -g
export ATMOSPHERE_SETTINGS := -fPIE -g $(ATMOSPHERE_BUILD_SETTINGS)
export ATMOSPHERE_CFLAGS := -Wall -ffunction-sections -fdata-sections -fno-strict-aliasing -fwrapv \
-fno-asynchronous-unwind-tables -fno-unwind-tables -fno-stack-protector \
-Wno-format-truncation -Wno-format-zero-length -Wno-stringop-truncation
@@ -28,40 +30,44 @@ export ATMOSPHERE_ASFLAGS :=
ifeq ($(ATMOSPHERE_BOARD),nx-hac-001)
ifeq ($(ATMOSPHERE_CPU),arm-cortex-a57)
export ATMOSPHERE_ARCH_DIR := arch/arm64
export ATMOSPHERE_BOARD_DIR := board/nintendo/nx
export ATMOSPHERE_OS_DIR := os/horizon
export ATMOSPHERE_ARCH_DIR := arm64
export ATMOSPHERE_BOARD_DIR := nintendo/nx
export ATMOSPHERE_OS_DIR := horizon
export ATMOSPHERE_ARCH_NAME := arm64
export ATMOSPHERE_BOARD_NAME := nintendo_nx
export ATMOSPHERE_OS_NAME := horizon
export ATMOSPHERE_CPU_EXTENSIONS := arm_crypto_extension aarch64_crypto_extension
else ifeq ($(ATMOSPHERE_CPU),arm7tdmi)
export ATMOSPHERE_ARCH_DIR := arch/arm
export ATMOSPHERE_BOARD_DIR := board/nintendo/nx_bpmp
export ATMOSPHERE_OS_DIR := os/horizon
export ATMOSPHERE_ARCH_DIR := arm
export ATMOSPHERE_BOARD_DIR := nintendo/nx_bpmp
export ATMOSPHERE_OS_DIR := horizon
export ATMOSPHERE_ARCH_NAME := arm
export ATMOSPHERE_BOARD_NAME := nintendo_nx
export ATMOSPHERE_OS_NAME := horizon
export ATMOSPHERE_CPU_EXTENSIONS :=
endif
endif
ifeq ($(ATMOSPHERE_CPU),arm-cortex-a57)
export ATMOSPHERE_CPU_DIR := arch/arm64/cpu/cortex_a57
export ATMOSPHERE_CPU_DIR := cortex_a57
export ATMOSPHERE_CPU_NAME := arm_cortex_a57
endif
ifeq ($(ATMOSPHERE_CPU),arm7tdmi)
export ATMOSPHERE_CPU_DIR := arch/arm/cpu/arm7tdmi
export ATMOSPHERE_CPU_DIR := arm7tdmi
export ATMOSPHERE_CPU_NAME := arm7tdmi
endif
export ATMOSPHERE_ARCH_MAKE_DIR := $(ATMOSPHERE_CONFIG_MAKE_DIR)/$(ATMOSPHERE_ARCH_DIR)
export ATMOSPHERE_BOARD_MAKE_DIR := $(ATMOSPHERE_CONFIG_MAKE_DIR)/$(ATMOSPHERE_BOARD_DIR)
export ATMOSPHERE_OS_MAKE_DIR := $(ATMOSPHERE_CONFIG_MAKE_DIR)/$(ATMOSPHERE_OS_DIR)
export ATMOSPHERE_CPU_MAKE_DIR := $(ATMOSPHERE_CONFIG_MAKE_DIR)/$(ATMOSPHERE_CPU_DIR)
export ATMOSPHERE_ARCH_MAKE_DIR := $(ATMOSPHERE_CONFIG_MAKE_DIR)/arch/$(ATMOSPHERE_ARCH_DIR)
export ATMOSPHERE_BOARD_MAKE_DIR := $(ATMOSPHERE_CONFIG_MAKE_DIR)/board/$(ATMOSPHERE_BOARD_DIR)
export ATMOSPHERE_OS_MAKE_DIR := $(ATMOSPHERE_CONFIG_MAKE_DIR)/os/$(ATMOSPHERE_OS_DIR)
export ATMOSPHERE_CPU_MAKE_DIR := $(ATMOSPHERE_ARCH_MAKE_DIR)/cpu/$(ATMOSPHERE_CPU_DIR)
export ATMOSPHERE_LIBRARY_DIR := lib_$(ATMOSPHERE_BOARD_NAME)_$(ATMOSPHERE_ARCH_NAME)
export ATMOSPHERE_BUILD_DIR := build_$(ATMOSPHERE_BOARD_NAME)_$(ATMOSPHERE_ARCH_NAME)
@@ -102,16 +108,41 @@ BUILD := build
DATA := data
INCLUDES := include
GENERAL_SOURCE_DIRS=$1 $(foreach d,$(filter-out $1/arch $1/board $1,$(wildcard $1/*)),$(if $(wildcard $d/.),$(call DIR_WILDCARD,$d) $d,))
SPECIFIC_SOURCE_DIRS=$(if $(wildcard $1/$2/.*),$1/$2 $(call DIR_WILDCARD,$1/$2),)
ALL_SOURCE_DIRS=$(call GENERAL_SOURCE_DIRS,$1) $(call SPECIFIC_SOURCE_DIRS,$1,$(ATMOSPHERE_ARCH_DIR)) $(call SPECIFIC_SOURCE_DIRS,$1,$(ATMOSPHERE_BOARD_DIR)) $(call SPECIFIC_SOURCE_DIRS,$1,$(ATMOSPHERE_OS_DIR))
GENERAL_SOURCE_DIRS=$1 $(foreach d,$(filter-out $1/arch $1/board $1/os $1/cpu $1,$(wildcard $1/*)),$(if $(wildcard $d/.),$(call DIR_WILDCARD,$d) $d,))
SPECIFIC_SOURCE_DIRS=$(if $(wildcard $1/$2/$3/.*),$1/$2/$3 $(call DIR_WILDCARD,$1/$2/$3),$(if $(wildcard $1/$2/generic/.*), $1/$2/generic $(call DIR_WILDCARD,$1/$2/generic),))
UNFILTERED_SOURCE_DIRS=$1 $(foreach d,$(wildcard $1/*),$(if $(wildcard $d/.),$(call DIR_WILDCARD,$d) $d,))
ALL_SOURCE_DIRS=$(call GENERAL_SOURCE_DIRS,$1) \
$(call SPECIFIC_SOURCE_DIRS,$1,arch,$(ATMOSPHERE_ARCH_DIR)) \
$(call SPECIFIC_SOURCE_DIRS,$1,board,$(ATMOSPHERE_BOARD_DIR)) \
$(call SPECIFIC_SOURCE_DIRS,$1,os,$(ATMOSPHERE_OS_DIR)) \
$(call SPECIFIC_SOURCE_DIRS,$1,cpu,$(ATMOSPHERE_ARCH_DIR)/$(ATMOSPHERE_CPU_DIR))
SOURCES ?= $(call ALL_SOURCE_DIRS,source)
FIND_SPECIFIC_SOURCE_FILES= $(notdir $(wildcard $1/*.$2.$3.$4)) $(filter-out $(subst .$2.$3.,.$2.generic.,$(notdir $(wildcard $1/*.$2.$3.$4))),$(notdir $(wildcard $1/*.$2.generic.$4)))
FIND_SPECIFIC_SOURCE_FILES_EX=$(foreach ext,$3,$(notdir $(wildcard $1/*.$2.$(ext).$4))) $(filter-out $(foreach ext,$3,$(subst .$2.$(ext).,.$2.generic.,$(notdir $(wildcard $1/*.$2.$(ext).$4)))),$(notdir $(wildcard $1/*.$2.generic.$4)))
FIND_SOURCE_FILES=$(foreach dir,$1,$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.$2)) \
$(notdir $(wildcard $(dir)/*.board.*.$2)) \
$(notdir $(wildcard $(dir)/*.os.*.$2)) \
$(notdir $(wildcard $(dir)/.cpu.*.$2)), \
$(notdir $(wildcard $(dir)/*.$2)))) \
$(foreach dir,$1,$(call FIND_SPECIFIC_SOURCE_FILES,$(dir),arch,$(ATMOSPHERE_ARCH_NAME),$2)) \
$(foreach dir,$1,$(call FIND_SPECIFIC_SOURCE_FILES,$(dir),board,$(ATMOSPHERE_BOARD_NAME),$2)) \
$(foreach dir,$1,$(call FIND_SPECIFIC_SOURCE_FILES,$(dir),os,$(ATMOSPHERE_OS_NAME),$2)) \
$(foreach dir,$1,$(call FIND_SPECIFIC_SOURCE_FILES_EX,$(dir),cpu,$(ATMOSPHERE_CPU_NAME) $(ATMOSPHERE_CPU_EXTENSIONS),$2))
ATMOSPHERE_GCH_IDENTIFIER ?= ams_placeholder_gch_identifier
#---------------------------------------------------------------------------------
# Rules for compiling pre-compiled headers
#---------------------------------------------------------------------------------
%.gch: %.hpp
@echo $<
$(CXX) -w -x c++-header -MMD -MP -MF $(DEPSDIR)/$*.d $(CXXFLAGS) -c $< -o $@ $(ERROR_FILTER)
@cp $@ $(<).gch
%.hpp.gch/$(ATMOSPHERE_GCH_IDENTIFIER): %.hpp | %.hpp.gch
@echo Precompiling $(notdir $<) for $(ATMOSPHERE_GCH_IDENTIFIER)
$(SILENTCMD)$(CXX) -w -x c++-header -MMD -MP -MQ$@ -MF $(DEPSDIR)/$(notdir $*).d $(CXXFLAGS) -c $< -o $@ $(ERROR_FILTER)
%.hpp.gch: %.hpp
@echo Precompiling $(notdir $<)
$(SILENTCMD)$(CXX) -w -x c++-header -MMD -MP -MQ$@ -MF $(DEPSDIR)/$(notdir $*).d $(CXXFLAGS) -c $< -o $@ $(ERROR_FILTER)

View File

@@ -8,7 +8,7 @@ include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../common.mk
#---------------------------------------------------------------------------------
ifeq ($(strip $(ATMOSPHERE_ARCH_NAME)),arm64)
DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_EXOSPHERE
SETTINGS := $(ATMOSPHERE_SETTINGS) -mgeneral-regs-only -ffixed-x18 -Os -Werror -fno-non-call-exceptions
SETTINGS := $(ATMOSPHERE_SETTINGS) -mgeneral-regs-only -ffixed-x18 -Os -Wextra -Werror -fno-non-call-exceptions
CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit
ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS)

View File

@@ -7,10 +7,10 @@ include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../common.mk
# options for code generation
#---------------------------------------------------------------------------------
export DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_MESOSPHERE
export SETTINGS := $(ATMOSPHERE_SETTINGS) -O2 -mgeneral-regs-only -ffixed-x18 -Werror -fno-non-call-exceptions
export SETTINGS := $(ATMOSPHERE_SETTINGS) -O2 -mgeneral-regs-only -ffixed-x18 -Wextra -Werror -fno-non-call-exceptions
export CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
export CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit
export ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES)
export ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
export LDFLAGS = -specs=$(TOPDIR)/$(notdir $(TOPDIR)).specs -fno-asynchronous-unwind-tables -fno-unwind-tables -nostdlib -nostartfiles -g $(SETTINGS) -Wl,-Map,$(notdir $*.map) -Wl,-z,relro,-z,now
@@ -29,7 +29,7 @@ export CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \
-Wl,--wrap,_ZSt20__throw_length_errorPKc \
-Wl,--wrap,_ZNSt11logic_errorC2EPKc
export LIBS := -lmesosphere
export LIBS := -l$(LIBMESOSPHERE_NAME)
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing

View File

@@ -14,7 +14,7 @@ include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../config/common.mk
#---------------------------------------------------------------------------------
DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_EXOSPHERE
SETTINGS := $(ATMOSPHERE_SETTINGS) -Os -Werror -flto -fno-non-call-exceptions
SETTINGS := $(ATMOSPHERE_SETTINGS) -Os -Wextra -Werror -flto -fno-non-call-exceptions
CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit
ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS)
@@ -39,23 +39,9 @@ ifneq ($(BUILD),$(notdir $(CURDIR)))
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) $(CURDIR)/include \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
CFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.c)) $(notdir $(wildcard $(dir)/*.board.*.c)) $(notdir $(wildcard $(dir)/*.os.*.c)), \
$(notdir $(wildcard $(dir)/*.c))))
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).c)))
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).c)))
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).c)))
CPPFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.cpp)) $(notdir $(wildcard $(dir)/*.board.*.cpp)) $(notdir $(wildcard $(dir)/*.os.*.cpp)), \
$(notdir $(wildcard $(dir)/*.cpp))))
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).cpp)))
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).cpp)))
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).cpp)))
SFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.s)) $(notdir $(wildcard $(dir)/*.board.*.s)) $(notdir $(wildcard $(dir)/*.os.*.s)), \
$(notdir $(wildcard $(dir)/*.s))))
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).s)))
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).s)))
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).s)))
CFILES := $(call FIND_SOURCE_FILES,$(SOURCES),c)
CPPFILES := $(call FIND_SOURCE_FILES,$(SOURCES),cpp)
SFILES := $(call FIND_SOURCE_FILES,$(SOURCES),s)
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
@@ -126,6 +112,7 @@ $(OFILES) : $(GCH_FILES)
$(OFILES_SRC) : $(HFILES_BIN)
libc.o: CFLAGS += -fno-builtin -fno-lto
libgcc_division.arch.arm.o: CFLAGS += -fno-builtin -fno-lto
#---------------------------------------------------------------------------------
%_bin.h %.bin.o : %.bin

View File

@@ -14,7 +14,7 @@ include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../config/common.mk
#---------------------------------------------------------------------------------
DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_EXOSPHERE
SETTINGS := $(ATMOSPHERE_SETTINGS) -mgeneral-regs-only -ffixed-x18 -Os -Werror -fno-non-call-exceptions
SETTINGS := $(ATMOSPHERE_SETTINGS) -mgeneral-regs-only -ffixed-x18 -Os -Wextra -Werror -fno-non-call-exceptions
CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit
ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS)
@@ -39,23 +39,9 @@ ifneq ($(BUILD),$(notdir $(CURDIR)))
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) $(CURDIR)/include \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
CFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.c)) $(notdir $(wildcard $(dir)/*.board.*.c)) $(notdir $(wildcard $(dir)/*.os.*.c)), \
$(notdir $(wildcard $(dir)/*.c))))
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).c)))
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).c)))
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).c)))
CPPFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.cpp)) $(notdir $(wildcard $(dir)/*.board.*.cpp)) $(notdir $(wildcard $(dir)/*.os.*.cpp)), \
$(notdir $(wildcard $(dir)/*.cpp))))
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).cpp)))
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).cpp)))
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).cpp)))
SFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.s)) $(notdir $(wildcard $(dir)/*.board.*.s)) $(notdir $(wildcard $(dir)/*.os.*.s)), \
$(notdir $(wildcard $(dir)/*.s))))
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).s)))
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).s)))
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).s)))
CFILES := $(call FIND_SOURCE_FILES,$(SOURCES),c)
CPPFILES := $(call FIND_SOURCE_FILES,$(SOURCES),cpp)
SFILES := $(call FIND_SOURCE_FILES,$(SOURCES),s)
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C

View File

@@ -17,7 +17,6 @@
#include <vapours.hpp>
#include <exosphere/common.hpp>
#include <exosphere/reg.hpp>
#include <exosphere/hw.hpp>
#include <exosphere/util.hpp>
#include <exosphere/mmu.hpp>
@@ -41,4 +40,3 @@
#include <exosphere/actmon.hpp>
#include <exosphere/pmc.hpp>
#include <exosphere/secmon.hpp>
#include <exosphere/tegra.hpp>

View File

@@ -89,7 +89,13 @@ namespace ams::secmon {
constexpr inline const SecureMonitorConfiguration DefaultSecureMonitorConfiguration = {
.target_firmware = ams::TargetFirmware_Current,
.key_generation = {},
.hardware_type = {},
.soc_type = {},
.hardware_state = {},
.pad_0B = {},
.flags = SecureMonitorConfigurationFlag_Default,
.reserved = {},
};
}

View File

@@ -1,34 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours.hpp>
#include <exosphere/tegra/tegra_ahb_arbc.hpp>
#include <exosphere/tegra/tegra_apb_misc.hpp>
#include <exosphere/tegra/tegra_avp_cache.hpp>
#include <exosphere/tegra/tegra_clkrst.hpp>
#include <exosphere/tegra/tegra_emc.hpp>
#include <exosphere/tegra/tegra_evp.hpp>
#include <exosphere/tegra/tegra_flow_ctlr.hpp>
#include <exosphere/tegra/tegra_ictlr.hpp>
#include <exosphere/tegra/tegra_mc.hpp>
#include <exosphere/tegra/tegra_mselect.hpp>
#include <exosphere/tegra/tegra_pinmux.hpp>
#include <exosphere/tegra/tegra_pg_up.hpp>
#include <exosphere/tegra/tegra_pmc.hpp>
#include <exosphere/tegra/tegra_sb.hpp>
#include <exosphere/tegra/tegra_sysctr0.hpp>
#include <exosphere/tegra/tegra_timer.hpp>

View File

@@ -20,14 +20,6 @@ namespace ams::util {
void SetRegisterAddress(uintptr_t address);
u32 GetMicroSeconds();
void WaitMicroSeconds(int us);
void ClearMemory(void *ptr, size_t size);
template<typename T, typename U> requires std::integral<T> && std::integral<U>
constexpr T DivideUp(T x, U y) {
return (x + (y - 1)) / y;
}
}

View File

@@ -33,6 +33,8 @@ namespace ams::crypto::impl {
template<size_t KeySize>
void AesImpl<KeySize>::Initialize(const void *key, size_t key_size, bool is_encrypt) {
static_assert(IsSupportedKeySize(KeySize));
AMS_ASSERT(key_size == sizeof(int));
AMS_UNUSED(is_encrypt);
/* Set the security engine keyslot. */
this->slot = *static_cast<const int *>(key);
@@ -50,9 +52,11 @@ namespace ams::crypto::impl {
} else if constexpr (KeySize == 24) {
/* Aes 192. */
/* TODO: se::EncryptAes192(dst, dst_size, this->slot, src, src_size); */
AMS_UNUSED(dst, dst_size, src, src_size);
} else if constexpr (KeySize == 32) {
/* Aes 256. */
/* TODO: se::EncryptAes256(dst, dst_size, this->slot, src, src_size); */
AMS_UNUSED(dst, dst_size, src, src_size);
} else {
/* Invalid key size. */
static_assert(!std::is_same<AesImpl<KeySize>, AesImpl<KeySize>>::value);
@@ -71,9 +75,11 @@ namespace ams::crypto::impl {
} else if constexpr (KeySize == 24) {
/* Aes 192. */
/* TODO: se::DecryptAes192(dst, dst_size, this->slot, src, src_size); */
AMS_UNUSED(dst, dst_size, src, src_size);
} else if constexpr (KeySize == 32) {
/* Aes 256. */
/* TODO: se::DecryptAes256(dst, dst_size, this->slot, src, src_size); */
AMS_UNUSED(dst, dst_size, src, src_size);
} else {
/* Invalid key size. */
static_assert(!std::is_same<AesImpl<KeySize>, AesImpl<KeySize>>::value);

View File

@@ -14,7 +14,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <exosphere.hpp>
#include "i2c_registers.hpp"
namespace ams::i2c {
@@ -88,6 +87,8 @@ namespace ams::i2c {
}
bool Write(uintptr_t base_address, Port port, int address, const void *src, size_t src_size, bool unused) {
AMS_UNUSED(port, unused);
/* Ensure we don't write too much. */
u32 data = 0;
if (src_size > MaxTransferSize) {
@@ -125,6 +126,8 @@ namespace ams::i2c {
}
bool Read(uintptr_t base_address, Port port, void *dst, size_t dst_size, int address, bool unused) {
AMS_UNUSED(port, unused);
/* Ensure we don't read too much. */
if (dst_size > MaxTransferSize) {
return false;

View File

@@ -1,77 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <exosphere.hpp>
namespace ams::i2c {
#define I2C_I2C_CNFG (0x000)
#define I2C_I2C_CMD_ADDR0 (0x004)
#define I2C_I2C_CMD_DATA1 (0x00C)
#define I2C_I2C_STATUS (0x01C)
#define I2C_INTERRUPT_STATUS_REGISTER (0x068)
#define I2C_CLK_DIVISOR_REGISTER (0x06C)
#define I2C_BUS_CLEAR_CONFIG (0x084)
#define I2C_BUS_CLEAR_STATUS (0x088)
#define I2C_CONFIG_LOAD (0x08C)
#define I2C_REG_BITS_MASK(NAME) REG_NAMED_BITS_MASK (I2C, NAME)
#define I2C_REG_BITS_VALUE(NAME, VALUE) REG_NAMED_BITS_VALUE (I2C, NAME, VALUE)
#define I2C_REG_BITS_ENUM(NAME, ENUM) REG_NAMED_BITS_ENUM (I2C, NAME, ENUM)
#define I2C_REG_BITS_ENUM_SEL(NAME, __COND__, TRUE_ENUM, FALSE_ENUM) REG_NAMED_BITS_ENUM_SEL(I2C, NAME, __COND__, TRUE_ENUM, FALSE_ENUM)
#define DEFINE_I2C_REG(NAME, __OFFSET__, __WIDTH__) REG_DEFINE_NAMED_REG (I2C, NAME, __OFFSET__, __WIDTH__)
#define DEFINE_I2C_REG_BIT_ENUM(NAME, __OFFSET__, ZERO, ONE) REG_DEFINE_NAMED_BIT_ENUM (I2C, NAME, __OFFSET__, ZERO, ONE)
#define DEFINE_I2C_REG_TWO_BIT_ENUM(NAME, __OFFSET__, ZERO, ONE, TWO, THREE) REG_DEFINE_NAMED_TWO_BIT_ENUM (I2C, NAME, __OFFSET__, ZERO, ONE, TWO, THREE)
#define DEFINE_I2C_REG_THREE_BIT_ENUM(NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN) REG_DEFINE_NAMED_THREE_BIT_ENUM(I2C, NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN)
#define DEFINE_I2C_REG_FOUR_BIT_ENUM(NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, ELEVEN, TWELVE, THIRTEEN, FOURTEEN, FIFTEEN) REG_DEFINE_NAMED_FOUR_BIT_ENUM (I2C, NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, ELEVEN, TWELVE, THIRTEEN, FOURTEEN, FIFTEEN)
/* I2C_CNFG */
DEFINE_I2C_REG(I2C_CNFG_LENGTH, 1, 3);
DEFINE_I2C_REG_BIT_ENUM(I2C_CNFG_CMD1, 6, WRITE, READ);
DEFINE_I2C_REG_BIT_ENUM(I2C_CNFG_SEND, 9, NOP, GO);
DEFINE_I2C_REG_BIT_ENUM(I2C_CNFG_NEW_MASTER_FSM, 11, DISABLE, ENABLE);
DEFINE_I2C_REG_THREE_BIT_ENUM(I2C_CNFG_DEBOUNCE_CNT, 12, NO_DEBOUNCE, DEBOUNCE_2T, DEBOUNCE_4T, DEBOUNCE_6T, DEBOUNCE_8T, DEBOUNCE_10T, DEBOUNCE_12T, DEBOUNCE_14T);
/* I2C_CMD_ADDR0 */
DEFINE_I2C_REG_BIT_ENUM(I2C_CMD_ADDR0_7BIT_RW, 0, WRITE, READ);
DEFINE_I2C_REG(I2C_CMD_ADDR0_7BIT_ADDR, 1, 7);
/* I2C_STATUS */
DEFINE_I2C_REG_FOUR_BIT_ENUM(I2C_STATUS_CMD1_STAT, 0, SL1_XFER_SUCCESSFUL, SL1_NOACK_FOR_BYTE1, SL1_NOACK_FOR_BYTE2, SL1_NOACK_FOR_BYTE3, SL1_NOACK_FOR_BYTE4, SL1_NOACK_FOR_BYTE5, SL1_NOACK_FOR_BYTE6, SL1_NOACK_FOR_BYTE7, SL1_NOACK_FOR_BYTE8, SL1_NOACK_FOR_BYTE9, SL1_NOACK_FOR_BYTE10, RESERVED11, RESERVED12, RESERVED13, RESERVED14, RESERVED15);
DEFINE_I2C_REG_FOUR_BIT_ENUM(I2C_STATUS_CMD2_STAT, 4, SL2_XFER_SUCCESSFUL, SL2_NOACK_FOR_BYTE1, SL2_NOACK_FOR_BYTE2, SL2_NOACK_FOR_BYTE3, SL2_NOACK_FOR_BYTE4, SL2_NOACK_FOR_BYTE5, SL2_NOACK_FOR_BYTE6, SL2_NOACK_FOR_BYTE7, SL2_NOACK_FOR_BYTE8, SL2_NOACK_FOR_BYTE9, SL2_NOACK_FOR_BYTE10, RESERVED11, RESERVED12, RESERVED13, RESERVED14, RESERVED15);
DEFINE_I2C_REG_BIT_ENUM(I2C_STATUS_BUSY, 8, NOT_BUSY, BUSY);
/* INTERRUPT_STATUS_REGISTER */
DEFINE_I2C_REG_BIT_ENUM(INTERRUPT_STATUS_REGISTER_BUS_CLEAR_DONE, 11, UNSET, SET);
/* CLK_DIVISOR_REGISTER */
DEFINE_I2C_REG(CLK_DIVISOR_REGISTER_HSMODE, 0, 16);
DEFINE_I2C_REG(CLK_DIVISOR_REGISTER_STD_FAST_MODE, 16, 16);
/* BUS_CLEAR_CONFIG */
DEFINE_I2C_REG_BIT_ENUM(BUS_CLEAR_CONFIG_BC_ENABLE, 0, DISABLE, ENABLE);
DEFINE_I2C_REG_BIT_ENUM(BUS_CLEAR_CONFIG_BC_TERMINATE, 1, THRESHOLD, IMMEDIATE);
DEFINE_I2C_REG_BIT_ENUM(BUS_CLEAR_CONFIG_BC_STOP_COND, 2, NO_STOP, STOP);
DEFINE_I2C_REG(BUS_CLEAR_CONFIG_BC_SCLK_THRESHOLD, 16, 8);
/* CONFIG_LOAD */
DEFINE_I2C_REG_BIT_ENUM(CONFIG_LOAD_MSTR_CONFIG_LOAD, 0, DISABLE, ENABLE);
DEFINE_I2C_REG_BIT_ENUM(CONFIG_LOAD_SLV_CONFIG_LOAD, 1, DISABLE, ENABLE);
DEFINE_I2C_REG_BIT_ENUM(CONFIG_LOAD_TIMEOUT_CONFIG_LOAD, 2, DISABLE, ENABLE);
DEFINE_I2C_REG(CONFIG_LOAD_RESERVED_BIT_5, 5, 1);
}

View File

@@ -0,0 +1,27 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <exosphere.hpp>
#ifdef __cplusplus
extern "C" {
#endif
/* cxx implementation details to be stubbed here, as needed. */
void __cxa_pure_virtual() { AMS_ABORT("pure virtual function call"); }
#ifdef __cplusplus
} /* extern "C" */
#endif

View File

@@ -0,0 +1,160 @@
// SPDX-License-Identifier: BSD-2-Clause
/*
* Copyright (c) 2014, STMicroelectronics International N.V.
*/
/*
* Form ABI specifications:
* int __aeabi_idiv(int numerator, int denominator);
* unsigned __aeabi_uidiv(unsigned numerator, unsigned denominator);
*
* typedef struct { int quot; int rem; } idiv_return;
* typedef struct { unsigned quot; unsigned rem; } uidiv_return;
*
* __value_in_regs idiv_return __aeabi_idivmod(int numerator,
* int *denominator);
* __value_in_regs uidiv_return __aeabi_uidivmod(unsigned *numerator,
* unsigned denominator);
*/
#ifdef __cplusplus
extern "C" {
#endif
/* struct qr - stores qutient/remainder to handle divmod EABI interfaces. */
struct qr {
unsigned q; /* computed quotient */
unsigned r; /* computed remainder */
unsigned q_n; /* specficies if quotient shall be negative */
unsigned r_n; /* specficies if remainder shall be negative */
};
static void uint_div_qr(unsigned numerator, unsigned denominator,
struct qr *qr);
/* returns in R0 and R1 by tail calling an asm function */
unsigned __aeabi_uidivmod(unsigned numerator, unsigned denominator);
unsigned __aeabi_uidiv(unsigned numerator, unsigned denominator);
/* returns in R0 and R1 by tail calling an asm function */
signed __aeabi_idivmod(signed numerator, signed denominator);
signed __aeabi_idiv(signed numerator, signed denominator);
/*
* __ste_idivmod_ret_t __aeabi_idivmod(signed numerator, signed denominator)
* Numerator and Denominator are received in R0 and R1.
* Where __ste_idivmod_ret_t is returned in R0 and R1.
*
* __ste_uidivmod_ret_t __aeabi_uidivmod(unsigned numerator,
* unsigned denominator)
* Numerator and Denominator are received in R0 and R1.
* Where __ste_uidivmod_ret_t is returned in R0 and R1.
*/
#ifdef __GNUC__
signed ret_idivmod_values(signed quotient, signed remainder);
unsigned ret_uidivmod_values(unsigned quotient, unsigned remainder);
#else
#error "Compiler not supported"
#endif
static void division_qr(unsigned n, unsigned p, struct qr *qr)
{
unsigned i = 1, q = 0;
if (p == 0) {
qr->r = 0xFFFFFFFF; /* division by 0 */
return;
}
while ((p >> 31) == 0) {
i = i << 1; /* count the max division steps */
p = p << 1; /* increase p until it has maximum size*/
}
while (i > 0) {
q = q << 1; /* write bit in q at index (size-1) */
if (n >= p)
{
n -= p;
q++;
}
p = p >> 1; /* decrease p */
i = i >> 1; /* decrease remaining size in q */
}
qr->r = n;
qr->q = q;
}
static void uint_div_qr(unsigned numerator, unsigned denominator, struct qr *qr)
{
division_qr(numerator, denominator, qr);
/* negate quotient and/or remainder according to requester */
if (qr->q_n)
qr->q = -qr->q;
if (qr->r_n)
qr->r = -qr->r;
}
unsigned __aeabi_uidiv(unsigned numerator, unsigned denominator)
{
struct qr qr = { .q_n = 0, .r_n = 0 };
uint_div_qr(numerator, denominator, &qr);
return qr.q;
}
unsigned __aeabi_uidivmod(unsigned numerator, unsigned denominator)
{
struct qr qr = { .q_n = 0, .r_n = 0 };
uint_div_qr(numerator, denominator, &qr);
return ret_uidivmod_values(qr.q, qr.r);
}
signed __aeabi_idiv(signed numerator, signed denominator)
{
struct qr qr = { .q_n = 0, .r_n = 0 };
if (((numerator < 0) && (denominator > 0)) ||
((numerator > 0) && (denominator < 0)))
qr.q_n = 1; /* quotient shall be negate */
if (numerator < 0) {
numerator = -numerator;
qr.r_n = 1; /* remainder shall be negate */
}
if (denominator < 0)
denominator = -denominator;
uint_div_qr(numerator, denominator, &qr);
return qr.q;
}
signed __aeabi_idivmod(signed numerator, signed denominator)
{
struct qr qr = { .q_n = 0, .r_n = 0 };
if (((numerator < 0) && (denominator > 0)) ||
((numerator > 0) && (denominator < 0)))
qr.q_n = 1; /* quotient shall be negate */
if (numerator < 0) {
numerator = -numerator;
qr.r_n = 1; /* remainder shall be negate */
}
if (denominator < 0)
denominator = -denominator;
uint_div_qr(numerator, denominator, &qr);
return ret_idivmod_values(qr.q, qr.r);
}
#ifdef __cplusplus
} /* extern "C" */
#endif

View File

@@ -0,0 +1,30 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Copyright (c) 2014, STMicroelectronics International N.V.
*/
/*
* signed ret_idivmod_values(signed quot, signed rem);
* return quotient and remaining the EABI way (regs r0,r1)
*/
.section .text.ret_idivmod_values, "ax", %progbits
.globl ret_idivmod_values
.align 0
.syntax unified
ret_idivmod_values:
bx lr
.type ret_idivmod_values, %function
.size ret_idivmod_values, .-ret_idivmod_values
/*
* unsigned ret_uidivmod_values(unsigned quot, unsigned rem);
* return quotient and remaining the EABI way (regs r0,r1)
*/
.section .text.ret_uidivmod_values, "ax", %progbits
.globl ret_uidivmod_values
.align 0
.syntax unified
ret_uidivmod_values:
bx lr
.type ret_uidivmod_values, %function
.size ret_uidivmod_values, .-ret_uidivmod_values

View File

@@ -0,0 +1,35 @@
/* Copyright (C) 1995-2018 Free Software Foundation, Inc.
This file is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3, or (at your option) any
later version.
This file is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
.section .text.__gnu_thumb1_case_uqi, "ax", %progbits
.globl __gnu_thumb1_case_uqi
.align 0
.thumb_func
.syntax unified
__gnu_thumb1_case_uqi:
push {r1}
mov r1, lr
lsrs r1, r1, #1
lsls r1, r1, #1
ldrb r1, [r1, r0]
lsls r1, r1, #1
add lr, lr, r1
pop {r1}
bx lr
.type __gnu_thumb1_case_uqi, %function
.size __gnu_thumb1_case_uqi, .-__gnu_thumb1_case_uqi

View File

@@ -81,7 +81,8 @@ namespace ams::wdt {
/* Enable the counters. */
reg::Write(registers + 0x188, 0x1);
while (true) { /* ... */ }
/* Wait forever until the reboot takes. */
AMS_INFINITE_LOOP();
}
#endif

View File

@@ -1,18 +1,20 @@
#---------------------------------------------------------------------------------
# pull in common atmosphere configuration
#---------------------------------------------------------------------------------
include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../config/common.mk
THIS_MAKEFILE := $(abspath $(lastword $(MAKEFILE_LIST)))
CURRENT_DIRECTORY := $(abspath $(dir $(THIS_MAKEFILE)))
include $(CURRENT_DIRECTORY)/../config/common.mk
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
PRECOMPILED_HEADERS := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/include/mesosphere.hpp
PRECOMPILED_HEADERS := include/mesosphere.hpp
DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_MESOSPHERE
SETTINGS := $(ATMOSPHERE_SETTINGS) -O2 -mgeneral-regs-only -ffixed-x18 -Werror -fno-non-call-exceptions
SETTINGS := $(ATMOSPHERE_SETTINGS) -O2 -mgeneral-regs-only -ffixed-x18 -Wextra -Werror -fno-non-call-exceptions
CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit -flto
ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS)
ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
SOURCES += $(call ALL_SOURCE_DIRS,../libvapours/source)
@@ -28,29 +30,15 @@ LIBDIRS := $(ATMOSPHERE_LIBRARIES_DIR)/libvapours
# 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 VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) $(CURDIR)/include \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
CFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.c)) $(notdir $(wildcard $(dir)/*.board.*.c)) $(notdir $(wildcard $(dir)/*.os.*.c)), \
$(notdir $(wildcard $(dir)/*.c))))
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).c)))
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).c)))
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).c)))
CPPFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.cpp)) $(notdir $(wildcard $(dir)/*.board.*.cpp)) $(notdir $(wildcard $(dir)/*.os.*.cpp)), \
$(notdir $(wildcard $(dir)/*.cpp))))
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).cpp)))
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).cpp)))
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).cpp)))
SFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.s)) $(notdir $(wildcard $(dir)/*.board.*.s)) $(notdir $(wildcard $(dir)/*.os.*.s)), \
$(notdir $(wildcard $(dir)/*.s))))
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).s)))
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).s)))
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).s)))
CFILES := $(call FIND_SOURCE_FILES,$(SOURCES),c)
CPPFILES := $(call FIND_SOURCE_FILES,$(SOURCES),cpp)
SFILES := $(call FIND_SOURCE_FILES,$(SOURCES),s)
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
@@ -68,7 +56,7 @@ endif
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
export GCH_FILES := $(foreach hdr,$(PRECOMPILED_HEADERS:.hpp=.gch),$(notdir $(hdr)))
export GCH_DIRS := $(PRECOMPILED_HEADERS:.hpp=.hpp.gch)
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
@@ -76,41 +64,70 @@ export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I.
.PHONY: clean all
#---------------------------------------------------------------------------------
ATMOSPHERE_BUILD_CONFIGS :=
all: release
define ATMOSPHERE_ADD_TARGET
ATMOSPHERE_BUILD_CONFIGS += $(strip $1)
$(strip $1): $$(ATMOSPHERE_LIBRARY_DIR)/$(strip $2)
$$(ATMOSPHERE_LIBRARY_DIR)/$(strip $2) : $$(ATMOSPHERE_LIBRARY_DIR) $$(ATMOSPHERE_BUILD_DIR)/$(strip $1) $$(SOURCES) $$(INCLUDES) $$(GCH_DIRS)
@$$(MAKE) __RECURSIVE__=1 OUTPUT=$$(CURDIR)/$$@ $(3) \
ATMOSPHERE_GCH_IDENTIFIER="$$(ATMOSPHERE_BOARD_NAME)_$$(ATMOSPHERE_ARCH_NAME)_$(strip $1)" \
DEPSDIR=$$(CURDIR)/$$(ATMOSPHERE_BUILD_DIR)/$(strip $1) \
--no-print-directory -C $$(ATMOSPHERE_BUILD_DIR)/$(strip $1) \
-f $$(THIS_MAKEFILE)
clean-$(strip $1):
@echo clean $(strip $1) ...
@rm -fr $$(ATMOSPHERE_BUILD_DIR)/$(strip $1) $$(ATMOSPHERE_LIBRARY_DIR)/$(strip $2)
@rm -fr $$(foreach hdr,$$(GCH_DIRS),$$(hdr)/$$(ATMOSPHERE_BOARD_NAME)_$$(ATMOSPHERE_ARCH_NAME)_$(strip $1))
@for i in $$(GCH_DIRS) $$(ATMOSPHERE_BUILD_DIR) $$(ATMOSPHERE_LIBRARY_DIR); do [ -d $$$$i ] && rmdir --ignore-fail-on-non-empty $$$$i || true; done
endef
$(eval $(call ATMOSPHERE_ADD_TARGET, release, $(TARGET).a, \
ATMOSPHERE_BUILD_SETTINGS="" \
))
$(eval $(call ATMOSPHERE_ADD_TARGET, debug, $(TARGET)_debug.a, \
ATMOSPHERE_BUILD_SETTINGS="-DMESOSPHERE_BUILD_FOR_DEBUGGING" \
))
$(eval $(call ATMOSPHERE_ADD_TARGET, audit, $(TARGET)_audit.a, \
ATMOSPHERE_BUILD_SETTINGS="-DMESOSPHERE_BUILD_FOR_AUDITING" \
))
#---------------------------------------------------------------------------------
all: lib/$(TARGET).a
lib:
-include $(ATMOSPHERE_BOARD_NAME)_$(ATMOSPHERE_ARCH_NAME).mk
ALL_GCH_IDENTIFIERS := $(foreach config,$(ATMOSPHERE_BUILD_CONFIGS),$(ATMOSPHERE_BOARD_NAME)_$(ATMOSPHERE_ARCH_NAME)_$(config))
ALL_GCH_FILES := $(foreach hdr,$(PRECOMPILED_HEADERS:.hpp=.hpp.gch),$(foreach id,$(ALL_GCH_IDENTIFIERS),$(hdr)/$(id)))
.PHONY: clean all $(foreach config,$(ATMOSPHERE_BUILD_CONFIGS),$(config) clean-$(config))
$(ATMOSPHERE_LIBRARY_DIR) $(GCH_DIRS):
@[ -d $@ ] || mkdir -p $@
release:
$(ATMOSPHERE_BUILD_DIR)/%:
@[ -d $@ ] || mkdir -p $@
lib/$(TARGET).a : lib release $(SOURCES) $(INCLUDES)
@$(MAKE) BUILD=release OUTPUT=$(CURDIR)/$@ \
BUILD_CFLAGS="-DNDEBUG=1 -O2" \
DEPSDIR=$(CURDIR)/release \
--no-print-directory -C release \
-f $(CURDIR)/Makefile
dist-bin: all
@tar --exclude=*~ -cjf $(TARGET).tar.bz2 include lib
dist-src:
@tar --exclude=*~ -cjf $(TARGET)-src.tar.bz2 include source Makefile
dist: dist-src dist-bin
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr release lib *.bz2
@rm -fr $(ATMOSPHERE_BUILD_DIR) $(ATMOSPHERE_LIBRARY_DIR) *.bz2 $(ALL_GCH_FILES)
@for i in $(GCH_DIRS); do [ -d $$i ] && rmdir --ignore-fail-on-non-empty $$i || true; done
#---------------------------------------------------------------------------------
else
DEPENDS := $(OFILES:.o=.d) $(GCH_FILES:.gch=.d)
GCH_FILES := $(foreach hdr,$(PRECOMPILED_HEADERS:.hpp=.hpp.gch),$(CURRENT_DIRECTORY)/$(hdr)/$(ATMOSPHERE_GCH_IDENTIFIER))
DEPENDS := $(OFILES:.o=.d) $(foreach hdr,$(GCH_FILES),$(notdir $(patsubst %.hpp.gch/,%.d,$(dir $(hdr)))))
#---------------------------------------------------------------------------------
# main targets

View File

@@ -27,6 +27,9 @@
#include <mesosphere/kern_initial_process.hpp>
#include <mesosphere/kern_k_exception_context.hpp>
/* Tracing functionality. */
#include <mesosphere/kern_k_trace.hpp>
/* Core pre-initialization includes. */
#include <mesosphere/kern_select_cpu.hpp>
#include <mesosphere/kern_select_system_control.hpp>

View File

@@ -0,0 +1,279 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours.hpp>
#include <mesosphere/kern_select_cpu.hpp>
#include <mesosphere/kern_k_typed_address.hpp>
namespace ams::kern::arch::arm {
struct GicDistributor {
u32 ctlr;
u32 typer;
u32 iidr;
u32 reserved_0x0c;
u32 statusr;
u32 reserved_0x14[3];
u32 impldef_0x20[8];
u32 setspi_nsr;
u32 reserved_0x44;
u32 clrspi_nsr;
u32 reserved_0x4c;
u32 setspi_sr;
u32 reserved_0x54;
u32 clrspi_sr;
u32 reserved_0x5c[9];
u32 igroupr[32];
u32 isenabler[32];
u32 icenabler[32];
u32 ispendr[32];
u32 icpendr[32];
u32 isactiver[32];
u32 icactiver[32];
union {
u8 bytes[1020];
u32 words[255];
} ipriorityr;
u32 _0x7fc;
union {
u8 bytes[1020];
u32 words[255];
} itargetsr;
u32 _0xbfc;
u32 icfgr[64];
u32 igrpmodr[32];
u32 _0xd80[32];
u32 nsacr[64];
u32 sgir;
u32 _0xf04[3];
u32 cpendsgir[4];
u32 spendsgir[4];
u32 reserved_0xf30[52];
static constexpr size_t SgirCpuTargetListShift = 16;
enum SgirTargetListFilter : u32 {
SgirTargetListFilter_CpuTargetList = (0 << 24),
SgirTargetListFilter_Others = (1 << 24),
SgirTargetListFilter_Self = (2 << 24),
SgirTargetListFilter_Reserved = (3 << 24),
};
};
static_assert(util::is_pod<GicDistributor>::value);
static_assert(sizeof(GicDistributor) == 0x1000);
struct GicCpuInterface {
u32 ctlr;
u32 pmr;
u32 bpr;
u32 iar;
u32 eoir;
u32 rpr;
u32 hppir;
u32 abpr;
u32 aiar;
u32 aeoir;
u32 ahppir;
u32 statusr;
u32 reserved_30[4];
u32 impldef_40[36];
u32 apr[4];
u32 nsapr[4];
u32 reserved_f0[3];
u32 iidr;
u32 reserved_100[960];
u32 dir;
u32 _0x1004[1023];
};
static_assert(util::is_pod<GicCpuInterface>::value);
static_assert(sizeof(GicCpuInterface) == 0x2000);
struct KInterruptController {
NON_COPYABLE(KInterruptController);
NON_MOVEABLE(KInterruptController);
public:
static constexpr s32 NumSoftwareInterrupts = 16;
static constexpr s32 NumLocalInterrupts = NumSoftwareInterrupts + 16;
static constexpr s32 NumGlobalInterrupts = 988;
static constexpr s32 NumInterrupts = NumLocalInterrupts + NumGlobalInterrupts;
static constexpr s32 NumPriorityLevels = 4;
public:
struct LocalState {
u32 isenabler[NumLocalInterrupts / 32];
u32 ipriorityr[NumLocalInterrupts / 4];
u32 itargetsr[NumLocalInterrupts / 4];
u32 icfgr[NumLocalInterrupts / 16];
};
struct GlobalState {
u32 isenabler[NumGlobalInterrupts / 32];
u32 ipriorityr[NumGlobalInterrupts / 4];
u32 itargetsr[NumGlobalInterrupts / 4];
u32 icfgr[NumGlobalInterrupts / 16];
};
enum PriorityLevel : u8 {
PriorityLevel_High = 0,
PriorityLevel_Low = NumPriorityLevels - 1,
PriorityLevel_Timer = 1,
PriorityLevel_Scheduler = 2,
};
private:
static inline u32 s_mask[cpu::NumCores];
private:
volatile GicDistributor *gicd;
volatile GicCpuInterface *gicc;
public:
constexpr KInterruptController() : gicd(nullptr), gicc(nullptr) { /* ... */ }
void Initialize(s32 core_id);
void Finalize(s32 core_id);
void SaveCoreLocal(LocalState *state) const;
void SaveGlobal(GlobalState *state) const;
void RestoreCoreLocal(const LocalState *state) const;
void RestoreGlobal(const GlobalState *state) const;
public:
u32 GetIrq() const {
return this->gicc->iar;
}
static constexpr s32 ConvertRawIrq(u32 irq) {
return (irq == 0x3FF) ? -1 : (irq & 0x3FF);
}
void Enable(s32 irq) const {
this->gicd->isenabler[irq / BITSIZEOF(u32)] = (1u << (irq % BITSIZEOF(u32)));
}
void Disable(s32 irq) const {
this->gicd->icenabler[irq / BITSIZEOF(u32)] = (1u << (irq % BITSIZEOF(u32)));
}
void Clear(s32 irq) const {
this->gicd->icpendr[irq / BITSIZEOF(u32)] = (1u << (irq % BITSIZEOF(u32)));
}
void SetTarget(s32 irq, s32 core_id) const {
this->gicd->itargetsr.bytes[irq] = this->gicd->itargetsr.bytes[irq] | GetGicMask(core_id);
}
void ClearTarget(s32 irq, s32 core_id) const {
this->gicd->itargetsr.bytes[irq] = this->gicd->itargetsr.bytes[irq] & ~GetGicMask(core_id);
}
void SetPriorityLevel(s32 irq, s32 level) const {
MESOSPHERE_ASSERT(PriorityLevel_High <= level && level <= PriorityLevel_Low);
this->gicd->ipriorityr.bytes[irq] = ToGicPriorityValue(level);
}
s32 GetPriorityLevel(s32 irq) const {
return FromGicPriorityValue(this->gicd->ipriorityr.bytes[irq]);
}
void SetPriorityLevel(s32 level) const {
MESOSPHERE_ASSERT(PriorityLevel_High <= level && level <= PriorityLevel_Low);
this->gicc->pmr = ToGicPriorityValue(level);
}
void SetEdge(s32 irq) const {
u32 cfg = this->gicd->icfgr[irq / (BITSIZEOF(u32) / 2)];
cfg &= ~(0x3 << (2 * (irq % (BITSIZEOF(u32) / 2))));
cfg |= (0x2 << (2 * (irq % (BITSIZEOF(u32) / 2))));
this->gicd->icfgr[irq / (BITSIZEOF(u32) / 2)] = cfg;
}
void SetLevel(s32 irq) const {
u32 cfg = this->gicd->icfgr[irq / (BITSIZEOF(u32) / 2)];
cfg &= ~(0x3 << (2 * (irq % (BITSIZEOF(u32) / 2))));
cfg |= (0x0 << (2 * (irq % (BITSIZEOF(u32) / 2))));
this->gicd->icfgr[irq / (BITSIZEOF(u32) / 2)] = cfg;
}
void SendInterProcessorInterrupt(s32 irq, u64 core_mask) {
MESOSPHERE_ASSERT(IsSoftware(irq));
this->gicd->sgir = GetCpuTargetListMask(irq, core_mask);
}
void SendInterProcessorInterrupt(s32 irq) {
MESOSPHERE_ASSERT(IsSoftware(irq));
this->gicd->sgir = GicDistributor::SgirTargetListFilter_Others | irq;
}
void EndOfInterrupt(u32 irq) const {
this->gicc->eoir = irq;
}
bool IsInterruptDefined(s32 irq) const {
const s32 num_interrupts = std::min(32 + 32 * (this->gicd->typer & 0x1F), static_cast<u32>(NumInterrupts));
return (0 <= irq && irq < num_interrupts);
}
public:
static constexpr ALWAYS_INLINE bool IsSoftware(s32 id) {
MESOSPHERE_ASSERT(0 <= id && id < NumInterrupts);
return id < NumSoftwareInterrupts;
}
static constexpr ALWAYS_INLINE bool IsLocal(s32 id) {
MESOSPHERE_ASSERT(0 <= id && id < NumInterrupts);
return id < NumLocalInterrupts;
}
static constexpr ALWAYS_INLINE bool IsGlobal(s32 id) {
MESOSPHERE_ASSERT(0 <= id && id < NumInterrupts);
return NumLocalInterrupts <= id;
}
static constexpr size_t GetGlobalInterruptIndex(s32 id) {
MESOSPHERE_ASSERT(IsGlobal(id));
return id - NumLocalInterrupts;
}
static constexpr size_t GetLocalInterruptIndex(s32 id) {
MESOSPHERE_ASSERT(IsLocal(id));
return id;
}
private:
static constexpr size_t PriorityShift = BITSIZEOF(u8) - __builtin_ctz(NumPriorityLevels);
static_assert(PriorityShift < BITSIZEOF(u8));
static constexpr ALWAYS_INLINE u8 ToGicPriorityValue(s32 level) {
return (level << PriorityShift) | ((1 << PriorityShift) - 1);
}
static constexpr ALWAYS_INLINE s32 FromGicPriorityValue(u8 priority) {
return (priority >> PriorityShift) & (NumPriorityLevels - 1);
}
static constexpr ALWAYS_INLINE s32 GetCpuTargetListMask(s32 irq, u64 core_mask) {
MESOSPHERE_ASSERT(IsSoftware(irq));
MESOSPHERE_ASSERT(core_mask < (1ul << cpu::NumCores));
return GicDistributor::SgirTargetListFilter_CpuTargetList | irq | (static_cast<u16>(core_mask) << GicDistributor::SgirCpuTargetListShift);
}
static ALWAYS_INLINE s32 GetGicMask(s32 core_id) {
return s_mask[core_id];
}
ALWAYS_INLINE void SetGicMask(s32 core_id) const {
s_mask[core_id] = this->gicd->itargetsr.bytes[0];
}
NOINLINE void SetupInterruptLines(s32 core_id) const;
};
}

View File

@@ -0,0 +1,29 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours.hpp>
#include <mesosphere/kern_select_cpu.hpp>
#include <mesosphere/kern_k_typed_address.hpp>
#if 1
#include <mesosphere/arch/arm/kern_generic_interrupt_controller.hpp>
#else
#error "Unknown board for KInterruptController"
#endif

View File

@@ -0,0 +1,25 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* All architectures must define NumArchitectureDeviceRegions. */
constexpr inline const auto NumArchitectureDeviceRegions = 3;
constexpr inline const auto KMemoryRegionType_Uart = KMemoryRegionType_ArchDeviceBase.DeriveSparse(0, NumArchitectureDeviceRegions, 0);
constexpr inline const auto KMemoryRegionType_InterruptCpuInterface = KMemoryRegionType_ArchDeviceBase.DeriveSparse(0, NumArchitectureDeviceRegions, 1).SetAttribute(KMemoryRegionAttr_NoUserMap);
constexpr inline const auto KMemoryRegionType_InterruptDistributor = KMemoryRegionType_ArchDeviceBase.DeriveSparse(0, NumArchitectureDeviceRegions, 2).SetAttribute(KMemoryRegionAttr_NoUserMap);
static_assert(KMemoryRegionType_Uart .GetValue() == (0x1D));
static_assert(KMemoryRegionType_InterruptCpuInterface.GetValue() == (0x2D | KMemoryRegionAttr_NoUserMap));
static_assert(KMemoryRegionType_InterruptDistributor .GetValue() == (0x4D | KMemoryRegionAttr_NoUserMap));

View File

@@ -74,6 +74,10 @@ namespace ams::kern::arch::arm64::init {
static ALWAYS_INLINE void ClearNewPageTable(KPhysicalAddress address) {
ClearPhysicalMemory(address, PageSize);
}
public:
static consteval size_t GetMaximumOverheadSize(size_t size) {
return (util::DivideUp(size, L1BlockSize) + util::DivideUp(size, L2BlockSize)) * PageSize;
}
private:
size_t NOINLINE GetBlockCount(KVirtualAddress virt_addr, size_t size, size_t block_size) {
const KVirtualAddress end_virt_addr = virt_addr + size;

View File

@@ -59,11 +59,6 @@ namespace ams::kern::arch::arm64::cpu {
InstructionMemoryBarrier();
}
ALWAYS_INLINE void InvalidateEntireInstructionCache() {
__asm__ __volatile__("ic iallu" ::: "memory");
EnsureInstructionConsistency();
}
ALWAYS_INLINE void Yield() {
__asm__ __volatile__("yield" ::: "memory");
}
@@ -179,6 +174,7 @@ namespace ams::kern::arch::arm64::cpu {
void ClearPageToZeroImpl(void *);
void FlushEntireDataCacheSharedForInit();
void FlushEntireDataCacheLocalForInit();
void InvalidateEntireInstructionCacheForInit();
void StoreEntireCacheForInit();
void FlushEntireDataCache();
@@ -188,6 +184,8 @@ namespace ams::kern::arch::arm64::cpu {
Result FlushDataCache(const void *addr, size_t size);
Result InvalidateInstructionCache(void *addr, size_t size);
void InvalidateEntireInstructionCache();
ALWAYS_INLINE void ClearPageToZero(void *page) {
MESOSPHERE_ASSERT(util::IsAligned(reinterpret_cast<uintptr_t>(page), PageSize));
MESOSPHERE_ASSERT(page != nullptr);

View File

@@ -33,7 +33,7 @@ namespace ams::kern::arch::arm64 {
explicit KDebug() { /* ... */ }
virtual ~KDebug() { /* ... */ }
static void PostDestroy(uintptr_t arg) { /* ... */ }
static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ }
public:
virtual Result GetThreadContextImpl(ams::svc::ThreadContext *out, KThread *thread, u32 context_flags) override;
virtual Result SetThreadContextImpl(const ams::svc::ThreadContext &ctx, KThread *thread, u32 context_flags) override;

View File

@@ -18,261 +18,19 @@
#include <mesosphere/kern_select_cpu.hpp>
#include <mesosphere/kern_k_typed_address.hpp>
namespace ams::kern::arch::arm64 {
#if 1
struct GicDistributor {
u32 ctlr;
u32 typer;
u32 iidr;
u32 reserved_0x0c;
u32 statusr;
u32 reserved_0x14[3];
u32 impldef_0x20[8];
u32 setspi_nsr;
u32 reserved_0x44;
u32 clrspi_nsr;
u32 reserved_0x4c;
u32 setspi_sr;
u32 reserved_0x54;
u32 clrspi_sr;
u32 reserved_0x5c[9];
u32 igroupr[32];
u32 isenabler[32];
u32 icenabler[32];
u32 ispendr[32];
u32 icpendr[32];
u32 isactiver[32];
u32 icactiver[32];
union {
u8 bytes[1020];
u32 words[255];
} ipriorityr;
u32 _0x7fc;
union {
u8 bytes[1020];
u32 words[255];
} itargetsr;
u32 _0xbfc;
u32 icfgr[64];
u32 igrpmodr[32];
u32 _0xd80[32];
u32 nsacr[64];
u32 sgir;
u32 _0xf04[3];
u32 cpendsgir[4];
u32 spendsgir[4];
u32 reserved_0xf30[52];
#include <mesosphere/arch/arm/kern_generic_interrupt_controller.hpp>
namespace ams::kern::arch::arm64 {
static constexpr size_t SgirCpuTargetListShift = 16;
using ams::kern::arch::arm::GicDistributor;
using ams::kern::arch::arm::GicCpuInterface;
using ams::kern::arch::arm::KInterruptController;
enum SgirTargetListFilter : u32 {
SgirTargetListFilter_CpuTargetList = (0 << 24),
SgirTargetListFilter_Others = (1 << 24),
SgirTargetListFilter_Self = (2 << 24),
SgirTargetListFilter_Reserved = (3 << 24),
};
};
static_assert(util::is_pod<GicDistributor>::value);
static_assert(sizeof(GicDistributor) == 0x1000);
}
struct GicCpuInterface {
u32 ctlr;
u32 pmr;
u32 bpr;
u32 iar;
u32 eoir;
u32 rpr;
u32 hppir;
u32 abpr;
u32 aiar;
u32 aeoir;
u32 ahppir;
u32 statusr;
u32 reserved_30[4];
u32 impldef_40[36];
u32 apr[4];
u32 nsapr[4];
u32 reserved_f0[3];
u32 iidr;
u32 reserved_100[960];
u32 dir;
u32 _0x1004[1023];
};
static_assert(util::is_pod<GicCpuInterface>::value);
static_assert(sizeof(GicCpuInterface) == 0x2000);
#else
struct KInterruptController {
NON_COPYABLE(KInterruptController);
NON_MOVEABLE(KInterruptController);
public:
static constexpr s32 NumSoftwareInterrupts = 16;
static constexpr s32 NumLocalInterrupts = NumSoftwareInterrupts + 16;
static constexpr s32 NumGlobalInterrupts = 988;
static constexpr s32 NumInterrupts = NumLocalInterrupts + NumGlobalInterrupts;
static constexpr s32 NumPriorityLevels = 4;
public:
struct LocalState {
u32 isenabler[NumLocalInterrupts / 32];
u32 ipriorityr[NumLocalInterrupts / 4];
u32 itargetsr[NumLocalInterrupts / 4];
u32 icfgr[NumLocalInterrupts / 16];
};
#error "Unknown board for KInterruptController"
struct GlobalState {
u32 isenabler[NumGlobalInterrupts / 32];
u32 ipriorityr[NumGlobalInterrupts / 4];
u32 itargetsr[NumGlobalInterrupts / 4];
u32 icfgr[NumGlobalInterrupts / 16];
};
enum PriorityLevel : u8 {
PriorityLevel_High = 0,
PriorityLevel_Low = NumPriorityLevels - 1,
PriorityLevel_Timer = 1,
PriorityLevel_Scheduler = 2,
};
private:
static inline u32 s_mask[cpu::NumCores];
private:
volatile GicDistributor *gicd;
volatile GicCpuInterface *gicc;
public:
constexpr KInterruptController() : gicd(nullptr), gicc(nullptr) { /* ... */ }
void Initialize(s32 core_id);
void Finalize(s32 core_id);
void SaveCoreLocal(LocalState *state) const;
void SaveGlobal(GlobalState *state) const;
void RestoreCoreLocal(const LocalState *state) const;
void RestoreGlobal(const GlobalState *state) const;
public:
u32 GetIrq() const {
return this->gicc->iar;
}
static constexpr s32 ConvertRawIrq(u32 irq) {
return (irq == 0x3FF) ? -1 : (irq & 0x3FF);
}
void Enable(s32 irq) const {
this->gicd->isenabler[irq / BITSIZEOF(u32)] = (1u << (irq % BITSIZEOF(u32)));
}
void Disable(s32 irq) const {
this->gicd->icenabler[irq / BITSIZEOF(u32)] = (1u << (irq % BITSIZEOF(u32)));
}
void Clear(s32 irq) const {
this->gicd->icpendr[irq / BITSIZEOF(u32)] = (1u << (irq % BITSIZEOF(u32)));
}
void SetTarget(s32 irq, s32 core_id) const {
this->gicd->itargetsr.bytes[irq] = this->gicd->itargetsr.bytes[irq] | GetGicMask(core_id);
}
void ClearTarget(s32 irq, s32 core_id) const {
this->gicd->itargetsr.bytes[irq] = this->gicd->itargetsr.bytes[irq] & ~GetGicMask(core_id);
}
void SetPriorityLevel(s32 irq, s32 level) const {
MESOSPHERE_ASSERT(PriorityLevel_High <= level && level <= PriorityLevel_Low);
this->gicd->ipriorityr.bytes[irq] = ToGicPriorityValue(level);
}
s32 GetPriorityLevel(s32 irq) const {
return FromGicPriorityValue(this->gicd->ipriorityr.bytes[irq]);
}
void SetPriorityLevel(s32 level) const {
MESOSPHERE_ASSERT(PriorityLevel_High <= level && level <= PriorityLevel_Low);
this->gicc->pmr = ToGicPriorityValue(level);
}
void SetEdge(s32 irq) const {
u32 cfg = this->gicd->icfgr[irq / (BITSIZEOF(u32) / 2)];
cfg &= ~(0x3 << (2 * (irq % (BITSIZEOF(u32) / 2))));
cfg |= (0x2 << (2 * (irq % (BITSIZEOF(u32) / 2))));
this->gicd->icfgr[irq / (BITSIZEOF(u32) / 2)] = cfg;
}
void SetLevel(s32 irq) const {
u32 cfg = this->gicd->icfgr[irq / (BITSIZEOF(u32) / 2)];
cfg &= ~(0x3 << (2 * (irq % (BITSIZEOF(u32) / 2))));
cfg |= (0x0 << (2 * (irq % (BITSIZEOF(u32) / 2))));
this->gicd->icfgr[irq / (BITSIZEOF(u32) / 2)] = cfg;
}
void SendInterProcessorInterrupt(s32 irq, u64 core_mask) {
MESOSPHERE_ASSERT(IsSoftware(irq));
this->gicd->sgir = GetCpuTargetListMask(irq, core_mask);
}
void SendInterProcessorInterrupt(s32 irq) {
MESOSPHERE_ASSERT(IsSoftware(irq));
this->gicd->sgir = GicDistributor::SgirTargetListFilter_Others | irq;
}
void EndOfInterrupt(u32 irq) const {
this->gicc->eoir = irq;
}
bool IsInterruptDefined(s32 irq) const {
const s32 num_interrupts = std::min(32 + 32 * (this->gicd->typer & 0x1F), static_cast<u32>(NumInterrupts));
return (0 <= irq && irq < num_interrupts);
}
public:
static constexpr ALWAYS_INLINE bool IsSoftware(s32 id) {
MESOSPHERE_ASSERT(0 <= id && id < NumInterrupts);
return id < NumSoftwareInterrupts;
}
static constexpr ALWAYS_INLINE bool IsLocal(s32 id) {
MESOSPHERE_ASSERT(0 <= id && id < NumInterrupts);
return id < NumLocalInterrupts;
}
static constexpr ALWAYS_INLINE bool IsGlobal(s32 id) {
MESOSPHERE_ASSERT(0 <= id && id < NumInterrupts);
return NumLocalInterrupts <= id;
}
static constexpr size_t GetGlobalInterruptIndex(s32 id) {
MESOSPHERE_ASSERT(IsGlobal(id));
return id - NumLocalInterrupts;
}
static constexpr size_t GetLocalInterruptIndex(s32 id) {
MESOSPHERE_ASSERT(IsLocal(id));
return id;
}
private:
static constexpr size_t PriorityShift = BITSIZEOF(u8) - __builtin_ctz(NumPriorityLevels);
static_assert(PriorityShift < BITSIZEOF(u8));
static constexpr ALWAYS_INLINE u8 ToGicPriorityValue(s32 level) {
return (level << PriorityShift) | ((1 << PriorityShift) - 1);
}
static constexpr ALWAYS_INLINE s32 FromGicPriorityValue(u8 priority) {
return (priority >> PriorityShift) & (NumPriorityLevels - 1);
}
static constexpr ALWAYS_INLINE s32 GetCpuTargetListMask(s32 irq, u64 core_mask) {
MESOSPHERE_ASSERT(IsSoftware(irq));
MESOSPHERE_ASSERT(core_mask < (1ul << cpu::NumCores));
return GicDistributor::SgirTargetListFilter_CpuTargetList | irq | (static_cast<u16>(core_mask) << GicDistributor::SgirCpuTargetListShift);
}
static ALWAYS_INLINE s32 GetGicMask(s32 core_id) {
return s_mask[core_id];
}
ALWAYS_INLINE void SetGicMask(s32 core_id) const {
s_mask[core_id] = this->gicd->itargetsr.bytes[0];
}
NOINLINE void SetupInterruptLines(s32 core_id) const;
};
}
#endif

View File

@@ -0,0 +1,25 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* All architectures must define NumArchitectureDeviceRegions. */
constexpr inline const auto NumArchitectureDeviceRegions = 3;
constexpr inline const auto KMemoryRegionType_Uart = KMemoryRegionType_ArchDeviceBase.DeriveSparse(0, NumArchitectureDeviceRegions, 0);
constexpr inline const auto KMemoryRegionType_InterruptCpuInterface = KMemoryRegionType_ArchDeviceBase.DeriveSparse(0, NumArchitectureDeviceRegions, 1).SetAttribute(KMemoryRegionAttr_NoUserMap);
constexpr inline const auto KMemoryRegionType_InterruptDistributor = KMemoryRegionType_ArchDeviceBase.DeriveSparse(0, NumArchitectureDeviceRegions, 2).SetAttribute(KMemoryRegionAttr_NoUserMap);
static_assert(KMemoryRegionType_Uart .GetValue() == (0x1D));
static_assert(KMemoryRegionType_InterruptCpuInterface.GetValue() == (0x2D | KMemoryRegionAttr_NoUserMap));
static_assert(KMemoryRegionType_InterruptDistributor .GetValue() == (0x4D | KMemoryRegionAttr_NoUserMap));

View File

@@ -0,0 +1,47 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <mesosphere/kern_common.hpp>
#include <mesosphere/kern_k_page_group.hpp>
#include <mesosphere/kern_k_memory_manager.hpp>
#include <mesosphere/kern_select_page_table.hpp>
namespace ams::kern::board::generic {
using KDeviceVirtualAddress = u64;
class KDevicePageTable {
public:
constexpr KDevicePageTable() { /* ... */ }
Result ALWAYS_INLINE Initialize(u64 space_address, u64 space_size) { return ams::kern::svc::ResultNotImplemented(); }
void ALWAYS_INLINE Finalize() { /* ... */ }
Result ALWAYS_INLINE Attach(ams::svc::DeviceName device_name, u64 space_address, u64 space_size) { return ams::kern::svc::ResultNotImplemented(); }
Result ALWAYS_INLINE Detach(ams::svc::DeviceName device_name) { return ams::kern::svc::ResultNotImplemented(); }
Result ALWAYS_INLINE Map(size_t *out_mapped_size, const KPageGroup &pg, KDeviceVirtualAddress device_address, ams::svc::MemoryPermission device_perm, bool refresh_mappings) { return ams::kern::svc::ResultNotImplemented(); }
Result ALWAYS_INLINE Unmap(const KPageGroup &pg, KDeviceVirtualAddress device_address) { return ams::kern::svc::ResultNotImplemented(); }
public:
static ALWAYS_INLINE void Initialize() { /* ... */ }
static ALWAYS_INLINE void Lock() { /* ... */ }
static ALWAYS_INLINE void Unlock() { /* ... */ }
static ALWAYS_INLINE void Sleep() { /* ... */ }
static ALWAYS_INLINE void Wakeup() { /* ... */ }
};
}

View File

@@ -36,11 +36,13 @@ namespace ams::kern::board::nintendo::nx {
u32 hs_detached_value;
private:
static ALWAYS_INLINE bool IsHeapVirtualAddress(KVirtualAddress addr) {
return KMemoryLayout::IsHeapVirtualAddress(nullptr, addr);
const KMemoryRegion *hint = nullptr;
return KMemoryLayout::IsHeapVirtualAddress(hint, addr);
}
static ALWAYS_INLINE bool IsHeapPhysicalAddress(KPhysicalAddress addr) {
return KMemoryLayout::IsHeapPhysicalAddress(nullptr, addr);
const KMemoryRegion *hint = nullptr;
return KMemoryLayout::IsHeapPhysicalAddress(hint, addr);
}
static ALWAYS_INLINE KVirtualAddress GetHeapVirtualAddress(KPhysicalAddress addr) {

View File

@@ -18,6 +18,7 @@
namespace ams::kern {
constexpr inline size_t MainMemorySize = 4_GB;
constexpr inline size_t MainMemorySize = 4_GB;
constexpr inline size_t MainMemorySizeMax = 8_GB;
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* All architectures must define NumBoardDeviceRegions. */
constexpr inline const auto NumBoardDeviceRegions = 6;
/* UNUSED: .Derive(NumBoardDeviceRegions, 0); */
constexpr inline const auto KMemoryRegionType_MemoryController = KMemoryRegionType_BoardDeviceBase.Derive(NumBoardDeviceRegions, 1).SetAttribute(KMemoryRegionAttr_NoUserMap);
constexpr inline const auto KMemoryRegionType_MemoryController1 = KMemoryRegionType_BoardDeviceBase.Derive(NumBoardDeviceRegions, 2).SetAttribute(KMemoryRegionAttr_NoUserMap);
constexpr inline const auto KMemoryRegionType_MemoryController0 = KMemoryRegionType_BoardDeviceBase.Derive(NumBoardDeviceRegions, 3).SetAttribute(KMemoryRegionAttr_NoUserMap);
constexpr inline const auto KMemoryRegionType_PowerManagementController = KMemoryRegionType_BoardDeviceBase.Derive(NumBoardDeviceRegions, 4).DeriveTransition();
constexpr inline const auto KMemoryRegionType_LegacyLpsDevices = KMemoryRegionType_BoardDeviceBase.Derive(NumBoardDeviceRegions, 5);
static_assert(KMemoryRegionType_MemoryController .GetValue() == (0x55 | KMemoryRegionAttr_NoUserMap));
static_assert(KMemoryRegionType_MemoryController1 .GetValue() == (0x65 | KMemoryRegionAttr_NoUserMap));
static_assert(KMemoryRegionType_MemoryController0 .GetValue() == (0x95 | KMemoryRegionAttr_NoUserMap));
static_assert(KMemoryRegionType_PowerManagementController.GetValue() == (0x1A5));
static_assert(KMemoryRegionType_LegacyLpsDevices.GetValue() == 0xC5);
constexpr inline const auto NumLegacyLpsDevices = 7;
constexpr inline const auto KMemoryRegionType_LegacyLpsExceptionVectors = KMemoryRegionType_LegacyLpsDevices.Derive(NumLegacyLpsDevices, 0);
constexpr inline const auto KMemoryRegionType_LegacyLpsIram = KMemoryRegionType_LegacyLpsDevices.Derive(NumLegacyLpsDevices, 1);
constexpr inline const auto KMemoryRegionType_LegacyLpsFlowController = KMemoryRegionType_LegacyLpsDevices.Derive(NumLegacyLpsDevices, 2);
constexpr inline const auto KMemoryRegionType_LegacyLpsPrimaryICtlr = KMemoryRegionType_LegacyLpsDevices.Derive(NumLegacyLpsDevices, 3);
constexpr inline const auto KMemoryRegionType_LegacyLpsSemaphore = KMemoryRegionType_LegacyLpsDevices.Derive(NumLegacyLpsDevices, 4);
constexpr inline const auto KMemoryRegionType_LegacyLpsAtomics = KMemoryRegionType_LegacyLpsDevices.Derive(NumLegacyLpsDevices, 5);
constexpr inline const auto KMemoryRegionType_LegacyLpsClkRst = KMemoryRegionType_LegacyLpsDevices.Derive(NumLegacyLpsDevices, 6);
static_assert(KMemoryRegionType_LegacyLpsExceptionVectors.GetValue() == 0x3C5);
static_assert(KMemoryRegionType_LegacyLpsIram .GetValue() == 0x5C5);
static_assert(KMemoryRegionType_LegacyLpsFlowController .GetValue() == 0x6C5);
static_assert(KMemoryRegionType_LegacyLpsPrimaryICtlr .GetValue() == 0x9C5);
static_assert(KMemoryRegionType_LegacyLpsSemaphore .GetValue() == 0xAC5);
static_assert(KMemoryRegionType_LegacyLpsAtomics .GetValue() == 0xCC5);
static_assert(KMemoryRegionType_LegacyLpsClkRst .GetValue() == 0x11C5);

View File

@@ -39,7 +39,7 @@ namespace ams::kern::board::nintendo::nx {
/* Initialization. */
static NOINLINE void InitializePhase1();
static NOINLINE void InitializePhase2();
static NOINLINE u32 GetInitialProcessBinaryPool();
static NOINLINE u32 GetCreateProcessMemoryPool();
/* Randomness. */
static void GenerateRandomBytes(void *dst, size_t size);
@@ -63,7 +63,7 @@ namespace ams::kern::board::nintendo::nx {
/* Power management. */
static void SleepSystem();
static NORETURN void StopSystem();
static NORETURN void StopSystem(void *arg = nullptr);
/* User access. */
static void CallSecureMonitorFromUser(ams::svc::lp64::SecureMonitorArguments *args);

View File

@@ -26,6 +26,5 @@ namespace ams::kern::init {
KPhysicalAddress GetInitArgumentsAddress(s32 core_id);
void SetInitArguments(s32 core_id, KPhysicalAddress address, uintptr_t arg);
void StoreInitArguments();
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#if defined(AMS_BUILD_FOR_AUDITING)
#define MESOSPHERE_BUILD_FOR_AUDITING
#endif
#if defined(MESOSPHERE_BUILD_FOR_AUDITING) || defined(AMS_BUILD_FOR_DEBUGGING)
#define MESOSPHERE_BUILD_FOR_DEBUGGING
#endif
#ifdef MESOSPHERE_BUILD_FOR_DEBUGGING
#define MESOSPHERE_ENABLE_ASSERTIONS
#define MESOSPHERE_ENABLE_DEBUG_PRINT
#endif
//#define MESOSPHERE_BUILD_FOR_TRACING
#define MESOSPHERE_ENABLE_PANIC_REGISTER_DUMP

View File

@@ -15,26 +15,19 @@
*/
#pragma once
#include <vapours.hpp>
#include <mesosphere/kern_build_config.hpp>
#include <mesosphere/svc/kern_svc_results.hpp>
namespace ams::kern {
constexpr size_t PageSize = 4_KB;
#ifdef ATMOSPHERE_BOARD_NINTENDO_NX
ams::TargetFirmware GetTargetFirmware();
#else
consteval ALWAYS_INLINE ams::TargetFirmware GetTargetFirmware() {
return ams::TargetFirmware_Current;
}
#endif
}
#if 1 || defined(AMS_BUILD_FOR_AUDITING)
#define MESOSPHERE_BUILD_FOR_AUDITING
#endif
#if defined(MESOSPHERE_BUILD_FOR_AUDITING) || defined(AMS_BUILD_FOR_DEBUGGING)
#define MESOSPHERE_BUILD_FOR_DEBUGGING
#endif
#ifdef MESOSPHERE_BUILD_FOR_DEBUGGING
#define MESOSPHERE_ENABLE_ASSERTIONS
#define MESOSPHERE_ENABLE_DEBUG_PRINT
#endif
#include <mesosphere/svc/kern_svc_results.hpp>

View File

@@ -40,7 +40,7 @@ namespace ams::kern {
#ifndef MESOSPHERE_DEBUG_LOG_SELECTED
#ifdef ATMOSPHERE_BOARD_NINTENDO_NX
#define MESOSPHERE_DEBUG_LOG_USE_UART_C
#define MESOSPHERE_DEBUG_LOG_USE_UART_A
#else
#error "Unknown board for Default Debug Log Source"
#endif

View File

@@ -20,7 +20,7 @@
namespace ams::kern {
constexpr u32 InitialProcessBinaryMagic = util::FourCC<'I','N','I','1'>::Code;
constexpr size_t InitialProcessBinarySizeMax = 0xC00000;
constexpr size_t InitialProcessBinarySizeMax = 12_MB;
struct InitialProcessBinaryHeader {
u32 magic;
@@ -34,5 +34,6 @@ namespace ams::kern {
u64 GetInitialProcessIdMin();
u64 GetInitialProcessIdMax();
size_t GetInitialProcessesSecureMemorySize();
}

View File

@@ -354,6 +354,10 @@ namespace ams::kern {
constexpr bool CanForceDebug() const {
return this->debug_capabilities.Get<DebugFlags::ForceDebug>();
}
constexpr u32 GetIntendedKernelMajorVersion() const { return this->intended_kernel_version.Get<KernelVersion::MajorVersion>(); }
constexpr u32 GetIntendedKernelMinorVersion() const { return this->intended_kernel_version.Get<KernelVersion::MinorVersion>(); }
constexpr u32 GetIntendedKernelVersion() const { return ams::svc::EncodeKernelVersion(this->GetIntendedKernelMajorVersion(), this->GetIntendedKernelMinorVersion()); }
};
}

View File

@@ -35,7 +35,7 @@ namespace ams::kern {
}
virtual void Destroy() override;
static void PostDestroy(uintptr_t arg) { /* ... */ }
static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ }
constexpr KSession *GetParent() const { return this->parent; }

View File

@@ -46,7 +46,7 @@ namespace ams::kern {
Result UnmapFromOwner(KProcessAddress address, size_t size);
virtual bool IsInitialized() const override { return this->is_initialized; }
static void PostDestroy(uintptr_t arg) { /* ... */ }
static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ }
KProcess *GetOwner() const { return this->owner; }
KProcessAddress GetSourceAddress() { return this->address; }

View File

@@ -37,7 +37,7 @@ namespace ams::kern {
virtual void Finalize() override;
virtual bool IsInitialized() const override { return this->is_initialized; }
static void PostDestroy(uintptr_t arg) { /* ... */ }
static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ }
Result Attach(ams::svc::DeviceName device_name);
Result Detach(ams::svc::DeviceName device_name);

View File

@@ -46,9 +46,9 @@ namespace ams::kern {
/* We need to have positive size. */
R_UNLESS(sz > 0, svc::ResultOutOfMemory());
/* Calculate metadata overhead. */
const size_t metadata_size = KPageBitmap::CalculateMetadataOverheadSize(sz / sizeof(PageBuffer));
const size_t allocatable_size = sz - metadata_size;
/* Calculate management overhead. */
const size_t management_size = KPageBitmap::CalculateManagementOverheadSize(sz / sizeof(PageBuffer));
const size_t allocatable_size = sz - management_size;
/* Set tracking fields. */
this->address = memory;
@@ -56,12 +56,12 @@ namespace ams::kern {
this->count = allocatable_size / sizeof(PageBuffer);
R_UNLESS(this->count > 0, svc::ResultOutOfMemory());
/* Clear the metadata region. */
u64 *metadata_ptr = GetPointer<u64>(this->address + allocatable_size);
std::memset(metadata_ptr, 0, metadata_size);
/* Clear the management region. */
u64 *management_ptr = GetPointer<u64>(this->address + allocatable_size);
std::memset(management_ptr, 0, management_size);
/* Initialize the bitmap. */
this->page_bitmap.Initialize(metadata_ptr, this->count);
this->page_bitmap.Initialize(management_ptr, this->count);
/* Free the pages to the bitmap. */
std::memset(GetPointer<PageBuffer>(this->address), 0, this->count * sizeof(PageBuffer));

View File

@@ -41,7 +41,7 @@ namespace ams::kern {
virtual bool IsInitialized() const override { return this->is_initialized; }
static void PostDestroy(uintptr_t arg) { /* ... */ }
static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ }
constexpr s32 GetInterruptId() const { return this->interrupt_id; }
};

View File

@@ -35,7 +35,7 @@ namespace ams::kern {
}
virtual void Destroy() override;
static void PostDestroy(uintptr_t arg) { /* ... */ }
static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ }
constexpr const KLightSession *GetParent() const { return this->parent; }

Some files were not shown because too many files have changed in this diff Show More