Compare commits

...

11 Commits

Author SHA1 Message Date
Michael Scire
4859bcc0fe boot: use #embed for fusee 2025-05-04 13:23:38 -07:00
Michael Scire
0ecd822c26 exo: use #embed for loader stub 2025-05-04 13:23:19 -07:00
Michael Scire
b1e0dad506 fusee: use embed in mtc/sdram param scripts 2025-04-26 14:57:10 -07:00
Michael Scire
c55606cfdb ams: basic support for compiling with gcc 15 2025-04-26 14:53:08 -07:00
Michael Scire
6125f40bdb ams: various fixes to support booting debug configuration 2025-04-08 13:43:29 -07:00
Michael Scire
85fd13f724 kern: update KernelLdr for 19.0.0 (new checks, dummy function call).
Also, fix a few very embarassing mistakes in kernel ldr:
* We have been mapping the page table region RWX for a few years now, accidentally.
* My attempt at making initial page tables not use bit 58 was broken in multiple ways.
2025-04-07 16:49:10 -07:00
tomvita
4e99a5e08d Add extensions to dmnt cheat virtual machine (#2479)
* dmnt_extension

* update type 8 extension

* clearify that bit 27 does not correspond to a button

* update cheat.md with new code type 0xC4

* implement code type 0xC4

* Add type 1 extension

* remove C0Tcr6Ma aaaaaaaa VVVVVVVV (VVVVVVVV)

* Type 9 extension for floating point math

* updated according to review
2025-01-09 19:38:59 -07:00
Michael Scire
9f8d17b9e6 crypto: implement CmacGenerator 2024-10-30 18:08:29 -07:00
Michael Scire
3a5f70dceb fs: fix uninit warnings on windows localfilesystem 2024-10-29 20:00:08 -07:00
Michael Scire
e51e11a71c libstrat: re-nolto files when compiling for windows-audit 2024-10-29 19:30:30 -07:00
Michael Scire
57e15f3622 strat: ldr::PlatformId -> ncm::ContentMetaPlatform 2024-10-29 19:24:52 -07:00
144 changed files with 630 additions and 5473 deletions

View File

@@ -49,7 +49,7 @@ Code type 0x0 allows writing a static value to a memory address.
`0TMR00AA AAAAAAAA VVVVVVVV (VVVVVVVV)` `0TMR00AA AAAAAAAA VVVVVVVV (VVVVVVVV)`
+ T: Width of memory write (1, 2, 4, or 8 bytes). + T: Width of memory write (1, 2, 4, or 8 bytes).
+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr). + M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = non-relative).
+ R: Register to use as an offset from memory region base. + R: Register to use as an offset from memory region base.
+ A: Immediate offset to use from memory region base. + A: Immediate offset to use from memory region base.
+ V: Value to write. + V: Value to write.
@@ -62,11 +62,13 @@ Code type 0x1 performs a comparison of the contents of memory to a static value.
If the condition is not met, all instructions until the appropriate End or Else conditional block terminator are skipped. If the condition is not met, all instructions until the appropriate End or Else conditional block terminator are skipped.
#### Encoding #### Encoding
`1TMC00AA AAAAAAAA VVVVVVVV (VVVVVVVV)` `1TMCXrAA AAAAAAAA VVVVVVVV (VVVVVVVV)`
+ T: Width of memory write (1, 2, 4, or 8 bytes). + T: Width of memory read (1, 2, 4, or 8 bytes).
+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr). + M: Memory region to read from (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = non-relative).
+ C: Condition to use, see below. + C: Condition to use, see below.
+ X: Operand Type, see below.
+ r: Offset Register (operand types 1).
+ A: Immediate offset to use from memory region base. + A: Immediate offset to use from memory region base.
+ V: Value to compare to. + V: Value to compare to.
@@ -78,6 +80,9 @@ If the condition is not met, all instructions until the appropriate End or Else
+ 5: == + 5: ==
+ 6: != + 6: !=
#### Operand Type
+ 0: Memory Base + Relative Offset
+ 1: Memory Base + Offset Register + Relative Offset
--- ---
### Code Type 0x2: End Conditional Block ### Code Type 0x2: End Conditional Block
@@ -126,7 +131,7 @@ Code type 0x5 allows loading a value from memory into a register, either using a
`5TMR00AA AAAAAAAA` `5TMR00AA AAAAAAAA`
+ T: Width of memory read (1, 2, 4, or 8 bytes). + T: Width of memory read (1, 2, 4, or 8 bytes).
+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr). + M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = non-relative).
+ R: Register to load value into. + R: Register to load value into.
+ A: Immediate offset to use from memory region base. + A: Immediate offset to use from memory region base.
@@ -137,6 +142,22 @@ Code type 0x5 allows loading a value from memory into a register, either using a
+ R: Register to load value into. (This register is also used as the base memory address). + R: Register to load value into. (This register is also used as the base memory address).
+ A: Immediate offset to use from register R. + A: Immediate offset to use from register R.
#### Load from Register Address Encoding
`5T0R2SAA AAAAAAAA`
+ T: Width of memory read (1, 2, 4, or 8 bytes).
+ R: Register to load value into.
+ S: Register to use as the base memory address.
+ A: Immediate offset to use from register R.
#### Load From Fixed Address Encoding with offset register
`5TMR3SAA AAAAAAAA`
+ T: Width of memory read (1, 2, 4, or 8 bytes).
+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = non-relative).
+ R: Register to load value into.
+ S: Register to use as offset register.
+ A: Immediate offset to use from memory region base.
--- ---
### Code Type 0x6: Store Static Value to Register Memory Address ### Code Type 0x6: Store Static Value to Register Memory Address
@@ -250,7 +271,10 @@ Code type 0x9 allows performing arithmetic on registers.
+ 7: Logical Not (discards right-hand operand) + 7: Logical Not (discards right-hand operand)
+ 8: Logical Xor + 8: Logical Xor
+ 9: None/Move (discards right-hand operand) + 9: None/Move (discards right-hand operand)
+ 10: Float Addition, T==4 single T==8 double
+ 11: Float Subtraction, T==4 single T==8 double
+ 12: Float Multiplication, T==4 single T==8 double
+ 13: Float Division, T==4 single T==8 double
--- ---
### Code Type 0xA: Store Register to Memory Address ### Code Type 0xA: Store Register to Memory Address
@@ -380,6 +404,61 @@ Code type 0xC3 reads or writes a static register with a given register.
--- ---
### Code Type 0xC4: Begin Extended Keypress Conditional Block
Code type 0xC4 enters or skips a conditional block based on whether a key combination is pressed.
#### Encoding
`C4r00000 kkkkkkkk kkkkkkkk`
+ r: Auto-repeat, see below.
+ kkkkkkkkkk: Keypad mask to check against output of `hidKeysDown()`.
Note that for multiple button combinations, the bitmasks should be OR'd together.
#### Auto-repeat
+ 0: The conditional block executes only once when the keypad mask matches. The mask must stop matching to reset for the next trigger.
+ 1: The conditional block executes as long as the keypad mask matches.
#### Keypad Values
Note: This is the direct output of `hidKeysDown()`.
+ 000000001: A
+ 000000002: B
+ 000000004: X
+ 000000008: Y
+ 000000010: Left Stick Pressed
+ 000000020: Right Stick Pressed
+ 000000040: L
+ 000000080: R
+ 000000100: ZL
+ 000000200: ZR
+ 000000400: Plus
+ 000000800: Minus
+ 000001000: Left
+ 000002000: Up
+ 000004000: Right
+ 000008000: Down
+ 000010000: Left Stick Left
+ 000020000: Left Stick Up
+ 000040000: Left Stick Right
+ 000080000: Left Stick Down
+ 000100000: Right Stick Left
+ 000200000: Right Stick Up
+ 000400000: Right Stick Right
+ 000800000: Right Stick Down
+ 001000000: SL Left Joy-Con
+ 002000000: SR Left Joy-Con
+ 004000000: SL Right Joy-Con
+ 008000000: SR Right Joy-Con
+ 010000000: Top button on Poké Ball Plus (Palma) controller
+ 020000000: Verification
+ 040000000: B button on Left NES/HVC controller in Handheld mode
+ 080000000: Left C button in N64 controller
+ 100000000: Up C button in N64 controller
+ 200000000: Right C button in N64 controller
+ 400000000: Down C button in N64 controller
### Code Type 0xF0: Double Extended-Width Instruction ### Code Type 0xF0: Double Extended-Width Instruction
Code Type 0xF0 signals to the VM to treat the upper three nybbles of the first dword as instruction type, instead of just the upper nybble. Code Type 0xF0 signals to the VM to treat the upper three nybbles of the first dword as instruction type, instead of just the upper nybble.

View File

@@ -18,6 +18,7 @@
#define _TYPES_H_ #define _TYPES_H_
#include <stdint.h> #include <stdint.h>
#include <stdbool.h>
#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
#define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b))
@@ -58,12 +59,6 @@ typedef u32 Result; ///< Function error code result type.
#define INVALID_HANDLE ((Handle) 0) #define INVALID_HANDLE ((Handle) 0)
#define CUR_PROCESS_HANDLE ((Handle) 0xFFFF8001) #define CUR_PROCESS_HANDLE ((Handle) 0xFFFF8001)
#ifndef __cplusplus
typedef int bool;
#define true 1
#define false 0
#endif /* __cplusplus */
#define BOOT_CFG_AUTOBOOT_EN (1 << 0) #define BOOT_CFG_AUTOBOOT_EN (1 << 0)
#define BOOT_CFG_FROM_LAUNCH (1 << 1) #define BOOT_CFG_FROM_LAUNCH (1 << 1)
#define BOOT_CFG_SEPT_RUN (1 << 7) #define BOOT_CFG_SEPT_RUN (1 << 7)

View File

@@ -15,13 +15,12 @@ ifneq ($(__RECURSIVE__),1)
export ATMOSPHERE_TOPDIR := $(CURRENT_DIRECTORY) export ATMOSPHERE_TOPDIR := $(CURRENT_DIRECTORY)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) $(CURDIR)/include \ export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) $(CURDIR)/include \
$(foreach dir,$(DATA),$(CURDIR)/$(dir)) \ $(foreach dir,$(DATA),$(CURDIR)/$(dir))
$(CURRENT_DIRECTORY)/../program/$(ATMOSPHERE_OUT_DIR)
CFILES := $(call FIND_SOURCE_FILES,$(SOURCES),c) CFILES := $(call FIND_SOURCE_FILES,$(SOURCES),c)
CPPFILES := $(call FIND_SOURCE_FILES,$(SOURCES),cpp) CPPFILES := $(call FIND_SOURCE_FILES,$(SOURCES),cpp)
SFILES := $(call FIND_SOURCE_FILES,$(SOURCES),s) SFILES := $(call FIND_SOURCE_FILES,$(SOURCES),s)
BINFILES := program.lz4 boot_code.lz4 BINFILES :=
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C # use CXX for linking C++ projects, CC for standard C
@@ -102,13 +101,7 @@ $(OUTPUT).elf : $(OFILES)
$(OFILES) : $(ATMOSPHERE_LIBRARIES_DIR)/libexosphere/$(ATMOSPHERE_LIBRARY_DIR)/libexosphere.a $(OFILES) : $(ATMOSPHERE_LIBRARIES_DIR)/libexosphere/$(ATMOSPHERE_LIBRARY_DIR)/libexosphere.a
program.lz4.o: program.lz4 secmon_loader_main.o: CXXFLAGS += --embed-dir="$(CURRENT_DIRECTORY)/../program/$(ATMOSPHERE_OUT_DIR)/"
@echo $(notdir $<)
@$(bin2o)
boot_code.lz4.o: boot_code.lz4
@echo $(notdir $<)
@$(bin2o)
%.elf: %.elf:
@echo linking $(notdir $@) @echo linking $(notdir $@)
@@ -117,14 +110,6 @@ boot_code.lz4.o: boot_code.lz4
$(OFILES_SRC) : $(OFILES_BIN) $(OFILES_SRC) : $(OFILES_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) -include $(DEPENDS)
#--------------------------------------------------------------------------------------- #---------------------------------------------------------------------------------------

View File

@@ -15,21 +15,31 @@
*/ */
#include <exosphere.hpp> #include <exosphere.hpp>
#include "secmon_loader_uncompress.hpp" #include "secmon_loader_uncompress.hpp"
#include "program_lz4.h"
#include "boot_code_lz4.h"
namespace ams::secmon::loader { namespace ams::secmon::loader {
NORETURN void UncompressAndExecute(const void *program, const void *boot_code) { namespace {
constexpr const u8 SecmonProgramLz4[] = {
#embed <program.lz4>
};
constexpr const u8 SecmonBootCodeLz4[] = {
#embed <boot_code.lz4>
};
}
NORETURN void UncompressAndExecute() {
/* Uncompress the program image. */ /* Uncompress the program image. */
Uncompress(secmon::MemoryRegionPhysicalTzramFullProgramImage.GetPointer(), secmon::MemoryRegionPhysicalTzramFullProgramImage.GetSize(), program, program_lz4_size); Uncompress(secmon::MemoryRegionPhysicalTzramFullProgramImage.GetPointer(), secmon::MemoryRegionPhysicalTzramFullProgramImage.GetSize(), SecmonProgramLz4, sizeof(SecmonProgramLz4));
/* Copy the boot image to the end of IRAM */ /* Copy the boot image to the end of IRAM */
u8 *relocated_boot_code = secmon::MemoryRegionPhysicalIramBootCodeImage.GetEndPointer<u8>() - boot_code_lz4_size; u8 *relocated_boot_code = secmon::MemoryRegionPhysicalIramBootCodeImage.GetEndPointer<u8>() - sizeof(SecmonBootCodeLz4);
std::memcpy(relocated_boot_code, boot_code, boot_code_lz4_size); std::memcpy(relocated_boot_code, SecmonBootCodeLz4, sizeof(SecmonBootCodeLz4));
/* Uncompress the boot image. */ /* Uncompress the boot image. */
Uncompress(secmon::MemoryRegionPhysicalIramBootCodeImage.GetPointer(), secmon::MemoryRegionPhysicalIramBootCodeImage.GetSize(), relocated_boot_code, boot_code_lz4_size); Uncompress(secmon::MemoryRegionPhysicalIramBootCodeImage.GetPointer(), secmon::MemoryRegionPhysicalIramBootCodeImage.GetSize(), relocated_boot_code, sizeof(SecmonBootCodeLz4));
/* Jump to the boot image. */ /* Jump to the boot image. */
reinterpret_cast<void (*)()>(secmon::MemoryRegionPhysicalIramBootCodeImage.GetAddress())(); reinterpret_cast<void (*)()>(secmon::MemoryRegionPhysicalIramBootCodeImage.GetAddress())();

View File

@@ -98,8 +98,5 @@ _start:
ldr x20, =0x7C020000 ldr x20, =0x7C020000
mov sp, x20 mov sp, x20
adr x0, program_lz4
adr x1, boot_code_lz4
/* Uncompress the program and iram boot code images. */ /* Uncompress the program and iram boot code images. */
b _ZN3ams6secmon6loader20UncompressAndExecuteEPKvS3_ b _ZN3ams6secmon6loader20UncompressAndExecuteEv

View File

@@ -106,6 +106,7 @@ SECTIONS
.debug_code : { .debug_code : {
KEEP (*(.text._ZN3ams3log6PrintfEPKcz .text._ZN3ams3log7VPrintfEPKcSt9__va_list .text._ZN3ams3log4DumpEPKvm)) KEEP (*(.text._ZN3ams3log6PrintfEPKcz .text._ZN3ams3log7VPrintfEPKcSt9__va_list .text._ZN3ams3log4DumpEPKvm))
KEEP (*(.text._ZN3ams4util10TVSNPrintfEPcmPKcSt9__va_list .text._ZN3ams4util12_GLOBAL__N_114TVSNPrintfImplEPcmPKcSt9__va_list .text._ZZN3ams4util12_GLOBAL__N_114TVSNPrintfImplEPcmPKcSt9__va_listENKUlbmE3_clEbm)) KEEP (*(.text._ZN3ams4util10TVSNPrintfEPcmPKcSt9__va_list .text._ZN3ams4util12_GLOBAL__N_114TVSNPrintfImplEPcmPKcSt9__va_list .text._ZZN3ams4util12_GLOBAL__N_114TVSNPrintfImplEPcmPKcSt9__va_listENKUlbmE3_clEbm))
KEEP (*(.text._ZN3ams4util12_GLOBAL__N_1L14TVSNPrintfImplEPcmPKcSt9__va_list .text._ZZN3ams4util12_GLOBAL__N_1L14TVSNPrintfImplEPcmPKcSt9__va_listENKUlbmE_clEbm))
KEEP(secmon_exception_handler.o(.text*)) KEEP(secmon_exception_handler.o(.text*))
secmon_exception_handler.o(.rodata*) secmon_exception_handler.o(.rodata*)
secmon_exception_handler.o(.data*) secmon_exception_handler.o(.data*)

View File

@@ -421,6 +421,7 @@ constexpr const u8 EmcRamTrainingPatternData[] {
0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03,
0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03
}; };
static_assert(sizeof(EmcRamTrainingPatternData) % sizeof(EmcRamTrainingPattern) == 0);
ALWAYS_INLINE const EmcRamTrainingPattern *GetEmcRamTrainingPattern() { ALWAYS_INLINE const EmcRamTrainingPattern *GetEmcRamTrainingPattern() {
return reinterpret_cast<const EmcRamTrainingPattern *>(EmcRamTrainingPatternData); return reinterpret_cast<const EmcRamTrainingPattern *>(EmcRamTrainingPatternData);

File diff suppressed because it is too large Load Diff

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