diff --git a/Makefile b/Makefile index 471cdd7..3e52b2c 100644 --- a/Makefile +++ b/Makefile @@ -43,6 +43,7 @@ dir_arm11 := arm11 dir_chainloader := chainloader dir_exceptions := exceptions dir_arm9_exceptions := $(dir_exceptions)/arm9 +dir_k11_extension := k11_extension dir_sysmodules := sysmodules dir_loader := $(dir_sysmodules)/loader dir_rosalina := $(dir_sysmodules)/rosalina @@ -57,8 +58,7 @@ objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \ $(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \ $(call rwildcard, $(dir_source), *.s *.c))) -bundled = $(dir_build)/reboot.bin.o $(dir_build)/emunand.bin.o $(dir_build)/mmuHook.bin.o $(dir_build)/k11MainHook.bin.o $(dir_build)/svcConnectToPortInitHook.bin.o $(dir_build)/svcCustomBackdoor.bin.o\ - $(dir_build)/chainloader.bin.o $(dir_build)/arm9_exceptions.bin.o +bundled = $(dir_build)/reboot.bin.o $(dir_build)/emunand.bin.o $(dir_build)/chainloader.bin.o $(dir_build)/arm9_exceptions.bin.o modules = $(dir_build)/loader.cxi $(dir_build)/rosalina.cxi @@ -80,6 +80,7 @@ clean: @$(MAKE) -C $(dir_arm11) clean @$(MAKE) -C $(dir_chainloader) clean @$(MAKE) -C $(dir_arm9_exceptions) clean + @$(MAKE) -C $(dir_k11_extension) clean @$(MAKE) -C $(dir_loader) clean @$(MAKE) -C $(dir_rosalina) clean @rm -rf $(dir_out) $(dir_build) @@ -89,6 +90,7 @@ clean: .PHONY: $(dir_arm11) .PHONY: $(dir_chainloader) .PHONY: $(dir_arm9_exceptions) +.PHONY: $(dir_k11_extension) .PHONY: $(dir_loader) .PHONY: $(dir_rosalina) @@ -96,9 +98,9 @@ $(dir_out)/$(name)$(revision).7z: all @mkdir -p "$(@D)" @7z a -mx $@ ./$(@D)/* ./$(dir_exceptions)/exception_dump_parser.py -$(dir_out)/boot.firm: $(dir_build)/modules.bin $(dir_build)/arm11.elf $(dir_build)/main.elf +$(dir_out)/boot.firm: $(dir_build)/modules.bin $(dir_build)/arm11.elf $(dir_build)/main.elf $(dir_build)/k11_extension.bin @mkdir -p "$(@D)" - @firmtool build $@ -D $^ -A 0x1FF60000 -C XDMA XDMA NDMA + @firmtool build $@ -D $^ -A 0x1FF60000 0x18000000 -C XDMA XDMA NDMA XDMA $(dir_build)/modules.bin: $(modules) @mkdir -p "$(@D)" @@ -111,6 +113,10 @@ $(dir_build)/arm11.elf: $(dir_arm11) $(dir_build)/main.elf: $(bundled) $(objects) $(LINK.o) -T linker.ld $(OUTPUT_OPTION) $^ +$(dir_build)/k11_extension.bin: $(dir_k11_extension) + @mkdir -p "$(@D)" + @$(MAKE) -C $< + $(dir_build)/loader.cxi: $(dir_loader) @mkdir -p "$(@D)" @$(MAKE) -C $< diff --git a/sysmodules/rosalina/kernel_extension/Makefile b/k11_extension/Makefile similarity index 94% rename from sysmodules/rosalina/kernel_extension/Makefile rename to k11_extension/Makefile index 45d916c..893b2e6 100644 --- a/sysmodules/rosalina/kernel_extension/Makefile +++ b/k11_extension/Makefile @@ -6,7 +6,7 @@ endif include $(DEVKITARM)/base_tools -name := kernel_extension +name := k11_extension dir_source := source dir_include := include @@ -16,7 +16,7 @@ ARCH := -mcpu=mpcore -mfpu=vfp ASFLAGS := $(ARCH) CFLAGS := -Wall -Wextra -MMD -MP -marm $(ASFLAGS) -I$(dir_include) -fno-builtin -std=c11 -Wno-main -O2 -flto -ffast-math \ -mword-relocations -ffunction-sections -fdata-sections -LDFLAGS := -nostdlib -Wl,--gc-sections $(ARCH) +LDFLAGS := -nostdlib -Wl,--gc-sections,--nmagic $(ARCH) objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \ $(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \ diff --git a/sysmodules/rosalina/kernel_extension/include/config.h b/k11_extension/include/config.h similarity index 100% rename from sysmodules/rosalina/kernel_extension/include/config.h rename to k11_extension/include/config.h diff --git a/sysmodules/rosalina/kernel_extension/include/fatalExceptionHandlers.h b/k11_extension/include/fatalExceptionHandlers.h similarity index 100% rename from sysmodules/rosalina/kernel_extension/include/fatalExceptionHandlers.h rename to k11_extension/include/fatalExceptionHandlers.h diff --git a/sysmodules/rosalina/kernel_extension/include/globals.h b/k11_extension/include/globals.h similarity index 94% rename from sysmodules/rosalina/kernel_extension/include/globals.h rename to k11_extension/include/globals.h index bad4de0..ae014e4 100644 --- a/sysmodules/rosalina/kernel_extension/include/globals.h +++ b/k11_extension/include/globals.h @@ -76,8 +76,6 @@ extern bool (*kernelToUsrMemcpy8)(void *dst, const void *src, u32 len); extern bool (*kernelToUsrMemcpy32)(u32 *dst, const u32 *src, u32 len); extern s32 (*kernelToUsrStrncpy)(char *dst, const char *src, u32 len); -extern Result (*CustomBackdoor)(void *function, ...); - extern void (*svcFallbackHandler)(u8 svcId); extern void (*kernelpanic)(void); extern void (*PostprocessSvc)(void); @@ -90,11 +88,16 @@ extern u32 *exceptionStackTop; extern u32 TTBCR; extern u32 L1MMUTableAddrs[4]; -extern u32 kernelVersion; extern void *kernelUsrCopyFuncsStart, *kernelUsrCopyFuncsEnd; extern bool *isDevUnit; +extern vu8 *configPage; +extern u32 kernelVersion; +extern u32 nbSection0Modules; + +extern Result (*InterruptManager__MapInterrupt)(InterruptManager *manager, KBaseInterruptEvent *iEvent, u32 interruptID, + u32 coreID, u32 priority, bool disableUponReceipt, bool levelHighActive); extern InterruptManager *interruptManager; extern KBaseInterruptEvent *customInterruptEvent; diff --git a/sysmodules/rosalina/kernel_extension/include/ipc.h b/k11_extension/include/ipc.h similarity index 100% rename from sysmodules/rosalina/kernel_extension/include/ipc.h rename to k11_extension/include/ipc.h diff --git a/sysmodules/rosalina/kernel_extension/include/kernel.h b/k11_extension/include/kernel.h similarity index 99% rename from sysmodules/rosalina/kernel_extension/include/kernel.h rename to k11_extension/include/kernel.h index 52d0ef1..bf64b39 100644 --- a/sysmodules/rosalina/kernel_extension/include/kernel.h +++ b/k11_extension/include/kernel.h @@ -28,6 +28,8 @@ #include "types.h" +extern u32 kernelVersion; + struct KMutex; struct KProcessO3DS; struct KProcessN3DS; @@ -1124,7 +1126,6 @@ typedef union KCacheMaintenanceInterruptEvent extern bool isN3DS; extern void *officialSVCs[0x7E]; -extern u32 kernelVersion; #define KPROCESS_OFFSETOF(field) (isN3DS ? offsetof(KProcessN3DS, field) :\ ((kernelVersion >= SYSTEM_VERSION(2, 44, 6)) ? offsetof(KProcessO3DS8x, field) :\ offsetof(KProcessO3DSPre8x, field))) diff --git a/sysmodules/rosalina/kernel_extension/include/memory.h b/k11_extension/include/memory.h similarity index 100% rename from sysmodules/rosalina/kernel_extension/include/memory.h rename to k11_extension/include/memory.h diff --git a/sysmodules/rosalina/kernel_extension/include/svc.h b/k11_extension/include/svc.h similarity index 100% rename from sysmodules/rosalina/kernel_extension/include/svc.h rename to k11_extension/include/svc.h diff --git a/sysmodules/rosalina/kernel_extension/include/svc/Backdoor.h b/k11_extension/include/svc/Backdoor.h similarity index 100% rename from sysmodules/rosalina/kernel_extension/include/svc/Backdoor.h rename to k11_extension/include/svc/Backdoor.h diff --git a/sysmodules/rosalina/kernel_extension/include/svc/Break.h b/k11_extension/include/svc/Break.h similarity index 100% rename from sysmodules/rosalina/kernel_extension/include/svc/Break.h rename to k11_extension/include/svc/Break.h diff --git a/sysmodules/rosalina/kernel_extension/include/svc/ConnectToPort.h b/k11_extension/include/svc/ConnectToPort.h similarity index 100% rename from sysmodules/rosalina/kernel_extension/include/svc/ConnectToPort.h rename to k11_extension/include/svc/ConnectToPort.h diff --git a/sysmodules/rosalina/kernel_extension/include/svc/ControlMemory.h b/k11_extension/include/svc/ControlMemory.h similarity index 100% rename from sysmodules/rosalina/kernel_extension/include/svc/ControlMemory.h rename to k11_extension/include/svc/ControlMemory.h diff --git a/sysmodules/rosalina/kernel_extension/include/svc/ControlService.h b/k11_extension/include/svc/ControlService.h similarity index 100% rename from sysmodules/rosalina/kernel_extension/include/svc/ControlService.h rename to k11_extension/include/svc/ControlService.h diff --git a/sysmodules/rosalina/kernel_extension/include/svc/CopyHandle.h b/k11_extension/include/svc/CopyHandle.h similarity index 100% rename from sysmodules/rosalina/kernel_extension/include/svc/CopyHandle.h rename to k11_extension/include/svc/CopyHandle.h diff --git a/k11_extension/include/svc/CustomBackdoor.h b/k11_extension/include/svc/CustomBackdoor.h new file mode 100644 index 0000000..4b3aa6b --- /dev/null +++ b/k11_extension/include/svc/CustomBackdoor.h @@ -0,0 +1,33 @@ +/* +* This file is part of Luma3DS +* Copyright (C) 2016-2017 Aurora Wright, TuxSH +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +* Additional Terms 7.b and 7.c of GPLv3 apply to this file: +* * Requiring preservation of specified reasonable legal notices or +* author attributions in that material or in the Appropriate Legal +* Notices displayed by works containing it. +* * Prohibiting misrepresentation of the origin of that material, +* or requiring that modified versions of such material be marked in +* reasonable ways as different from the original version. +*/ + +#pragma once + +#include "utils.h" +#include "kernel.h" +#include "svc.h" + +void CustomBackdoor(void *function, ...); diff --git a/sysmodules/rosalina/kernel_extension/include/svc/GetCFWInfo.h b/k11_extension/include/svc/GetCFWInfo.h similarity index 100% rename from sysmodules/rosalina/kernel_extension/include/svc/GetCFWInfo.h rename to k11_extension/include/svc/GetCFWInfo.h diff --git a/sysmodules/rosalina/kernel_extension/include/svc/GetProcessInfo.h b/k11_extension/include/svc/GetProcessInfo.h similarity index 100% rename from sysmodules/rosalina/kernel_extension/include/svc/GetProcessInfo.h rename to k11_extension/include/svc/GetProcessInfo.h diff --git a/sysmodules/rosalina/kernel_extension/include/svc/GetSystemInfo.h b/k11_extension/include/svc/GetSystemInfo.h similarity index 100% rename from sysmodules/rosalina/kernel_extension/include/svc/GetSystemInfo.h rename to k11_extension/include/svc/GetSystemInfo.h diff --git a/sysmodules/rosalina/kernel_extension/include/svc/GetThreadInfo.h b/k11_extension/include/svc/GetThreadInfo.h similarity index 100% rename from sysmodules/rosalina/kernel_extension/include/svc/GetThreadInfo.h rename to k11_extension/include/svc/GetThreadInfo.h diff --git a/sysmodules/rosalina/kernel_extension/include/svc/KernelSetState.h b/k11_extension/include/svc/KernelSetState.h similarity index 100% rename from sysmodules/rosalina/kernel_extension/include/svc/KernelSetState.h rename to k11_extension/include/svc/KernelSetState.h diff --git a/sysmodules/rosalina/kernel_extension/include/svc/MapProcessMemoryEx.h b/k11_extension/include/svc/MapProcessMemoryEx.h similarity index 100% rename from sysmodules/rosalina/kernel_extension/include/svc/MapProcessMemoryEx.h rename to k11_extension/include/svc/MapProcessMemoryEx.h diff --git a/sysmodules/rosalina/kernel_extension/include/svc/SendSyncRequest.h b/k11_extension/include/svc/SendSyncRequest.h similarity index 100% rename from sysmodules/rosalina/kernel_extension/include/svc/SendSyncRequest.h rename to k11_extension/include/svc/SendSyncRequest.h diff --git a/sysmodules/rosalina/kernel_extension/include/svc/SetGpuProt.h b/k11_extension/include/svc/SetGpuProt.h similarity index 100% rename from sysmodules/rosalina/kernel_extension/include/svc/SetGpuProt.h rename to k11_extension/include/svc/SetGpuProt.h diff --git a/sysmodules/rosalina/kernel_extension/include/svc/SetWifiEnabled.h b/k11_extension/include/svc/SetWifiEnabled.h similarity index 100% rename from sysmodules/rosalina/kernel_extension/include/svc/SetWifiEnabled.h rename to k11_extension/include/svc/SetWifiEnabled.h diff --git a/sysmodules/rosalina/kernel_extension/include/svc/TranslateHandle.h b/k11_extension/include/svc/TranslateHandle.h similarity index 100% rename from sysmodules/rosalina/kernel_extension/include/svc/TranslateHandle.h rename to k11_extension/include/svc/TranslateHandle.h diff --git a/sysmodules/rosalina/kernel_extension/include/svc/UnmapProcessMemoryEx.h b/k11_extension/include/svc/UnmapProcessMemoryEx.h similarity index 100% rename from sysmodules/rosalina/kernel_extension/include/svc/UnmapProcessMemoryEx.h rename to k11_extension/include/svc/UnmapProcessMemoryEx.h diff --git a/sysmodules/rosalina/kernel_extension/include/svcHandler.h b/k11_extension/include/svcHandler.h similarity index 100% rename from sysmodules/rosalina/kernel_extension/include/svcHandler.h rename to k11_extension/include/svcHandler.h diff --git a/sysmodules/rosalina/kernel_extension/include/synchronization.h b/k11_extension/include/synchronization.h similarity index 100% rename from sysmodules/rosalina/kernel_extension/include/synchronization.h rename to k11_extension/include/synchronization.h diff --git a/sysmodules/rosalina/kernel_extension/include/types.h b/k11_extension/include/types.h similarity index 100% rename from sysmodules/rosalina/kernel_extension/include/types.h rename to k11_extension/include/types.h diff --git a/sysmodules/rosalina/kernel_extension/include/utils.h b/k11_extension/include/utils.h similarity index 100% rename from sysmodules/rosalina/kernel_extension/include/utils.h rename to k11_extension/include/utils.h diff --git a/k11_extension/linker.ld b/k11_extension/linker.ld new file mode 100644 index 0000000..2ed3ef2 --- /dev/null +++ b/k11_extension/linker.ld @@ -0,0 +1,19 @@ +OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") +OUTPUT_ARCH(arm) + +ENTRY(_start) +SECTIONS +{ + . = 0x40000000; + + __start__ = .; + + .text : ALIGN(4) { *(.text.start) *(.text*); . = ALIGN(4); } + .rodata : ALIGN(4) { *(.rodata*); . = ALIGN(4); } + .data : ALIGN(4) { *(.data*); . = ALIGN(4); } + .bss : ALIGN(8) { __bss_start__ = .; *(.bss* COMMON); . = ALIGN(8); __bss_end__ = .; } + + . = ALIGN(0x1000); + + __end__ = .; +} diff --git a/sysmodules/rosalina/kernel_extension/source/fatalExceptionHandlers.s b/k11_extension/source/fatalExceptionHandlers.s similarity index 100% rename from sysmodules/rosalina/kernel_extension/source/fatalExceptionHandlers.s rename to k11_extension/source/fatalExceptionHandlers.s diff --git a/sysmodules/rosalina/kernel_extension/source/fatalExceptionHandlersMain.c b/k11_extension/source/fatalExceptionHandlersMain.c similarity index 99% rename from sysmodules/rosalina/kernel_extension/source/fatalExceptionHandlersMain.c rename to k11_extension/source/fatalExceptionHandlersMain.c index 6353675..ddbfafb 100644 --- a/sysmodules/rosalina/kernel_extension/source/fatalExceptionHandlersMain.c +++ b/k11_extension/source/fatalExceptionHandlersMain.c @@ -35,7 +35,7 @@ bool isExceptionFatal(u32 spsr, u32 *regs, u32 index) { - //if(CONFIG(DISABLEVECTORS)) return false; + if(CONFIG(DISABLEVECTORS)) return false; if((spsr & 0x1f) != 0x10) return true; diff --git a/sysmodules/rosalina/kernel_extension/source/globals.c b/k11_extension/source/globals.c similarity index 94% rename from sysmodules/rosalina/kernel_extension/source/globals.c rename to k11_extension/source/globals.c index f6fa070..63e55f6 100644 --- a/sysmodules/rosalina/kernel_extension/source/globals.c +++ b/k11_extension/source/globals.c @@ -72,8 +72,6 @@ bool (*kernelToUsrMemcpy8)(void *dst, const void *src, u32 len); bool (*kernelToUsrMemcpy32)(u32 *dst, const u32 *src, u32 len); s32 (*kernelToUsrStrncpy)(char *dst, const char *src, u32 len); -Result (*CustomBackdoor)(void *function, ...); - void (*svcFallbackHandler)(u8 svcId); void (*kernelpanic)(void); void (*PostprocessSvc)(void); @@ -86,11 +84,16 @@ u32 *exceptionStackTop; u32 TTBCR; u32 L1MMUTableAddrs[4]; -u32 kernelVersion; void *kernelUsrCopyFuncsStart, *kernelUsrCopyFuncsEnd; bool *isDevUnit; +vu8 *configPage; +u32 kernelVersion; +u32 nbSection0Modules; + +Result (*InterruptManager__MapInterrupt)(InterruptManager *manager, KBaseInterruptEvent *iEvent, u32 interruptID, + u32 coreID, u32 priority, bool disableUponReceipt, bool levelHighActive); InterruptManager *interruptManager; KBaseInterruptEvent *customInterruptEvent; diff --git a/sysmodules/rosalina/kernel_extension/source/ipc.c b/k11_extension/source/ipc.c similarity index 99% rename from sysmodules/rosalina/kernel_extension/source/ipc.c rename to k11_extension/source/ipc.c index 148d6eb..2e4289e 100644 --- a/sysmodules/rosalina/kernel_extension/source/ipc.c +++ b/k11_extension/source/ipc.c @@ -257,7 +257,7 @@ Result doPublishToProcessHook(Handle handle, u32 *cmdbuf) ((KAutoObject *)process)->vtable->DecrementReferenceCount((KAutoObject *)process); } - if(terminateRosalina) + if(terminateRosalina && nbSection0Modules == 6) { Handle rosalinaProcessHandle; res = OpenProcess(&rosalinaProcessHandle, 5); diff --git a/sysmodules/rosalina/kernel_extension/source/main.c b/k11_extension/source/main.c similarity index 68% rename from sysmodules/rosalina/kernel_extension/source/main.c rename to k11_extension/source/main.c index 237e917..3c08f93 100644 --- a/sysmodules/rosalina/kernel_extension/source/main.c +++ b/k11_extension/source/main.c @@ -33,68 +33,87 @@ #include "svcHandler.h" #include "memory.h" -static const u32 *const exceptionsPage = (const u32 *)0xFFFF0000; void *originalHandlers[8] = {NULL}; -enum VECTORS { RESET = 0, UNDEFINED_INSTRUCTION, SVC, PREFETCH_ABORT, DATA_ABORT, RESERVED, IRQ, FIQ }; +extern u8 __start__[], __end__[], __bss_start__[], __bss_end__[]; -static void setupSGI0Handler(void) +struct KExtParameters { - for(u32 i = 0; i < getNumberOfCores(); i++) - interruptManager->N3DS.privateInterrupts[i][0].interruptEvent = customInterruptEvent; + u32 ALIGN(0x400) L2MMUTableFor0x40000000[256]; + u32 basePA; + void *originalHandlers[4]; + u32 L1MMUTableAddrs[4]; + + CfwInfo cfwInfo; +} kExtParameters = { .basePA = 0x12345678 }; // place this in .data + +void relocateAndSetupMMU(u32 coreId, u32 *L1Table) +{ + struct KExtParameters *p0 = (struct KExtParameters *)((u32)&kExtParameters - 0x40000000 + 0x18000000); + struct KExtParameters *p = (struct KExtParameters *)((u32)&kExtParameters - 0x40000000 + p0->basePA); + + if(coreId == 0) + { + // Relocate ourselves, and clear BSS + memcpy((void *)p0->basePA, (const void *)0x18000000, __bss_start__ - __start__); + memset32((u32 *)(p0->basePA + (__bss_start__ - __start__)), 0, __bss_end__ - __bss_start__); + + // Map the kernel ext to 0x40000000 + // 4KB extended small pages: [SYS:RW USR:-- X TYP:NORMAL SHARED OUTER NOCACHE, INNER CACHED WB WA] + for(u32 offset = 0; offset < (u32)(__end__ - __start__); offset += 0x1000) + p->L2MMUTableFor0x40000000[offset >> 12] = (p0->basePA + offset) | 0x516; + + __asm__ __volatile__ ("sev"); + } + else + __asm__ __volatile__ ("wfe"); + + // bit31 idea thanks to SALT + // Maps physmem so that, if addr is in physmem(0, 0x30000000), it can be accessed uncached&rwx as addr|(1<<31) + u32 attribs = 0x40C02; // supersection (rwx for all) of strongly ordered memory, shared + for(u32 PA = 0; PA < 0x30000000; PA += 0x01000000) + { + u32 VA = (1 << 31) | PA; + for(u32 i = 0; i < 16; i++) + L1Table[i + (VA >> 20)] = PA | attribs; + } + + L1Table[0x40000000 >> 20] = (u32)p->L2MMUTableFor0x40000000 | 1; + + p->L1MMUTableAddrs[coreId] = (u32)L1Table; } -static inline void **getHandlerDestination(enum VECTORS vector) +void bindSGI0Hook(void) { - u32 *branch_dst = (u32 *)decodeARMBranch((u32 *)exceptionsPage + (u32)vector); - return (void **)(branch_dst + 2); + if(InterruptManager__MapInterrupt(interruptManager, customInterruptEvent, 0, getCurrentCoreID(), 0, false, false) != 0) + __asm__ __volatile__ ("bkpt 0xdead"); } -static inline void swapHandlerInVeneer(enum VECTORS vector, void *handler) +void configHook(vu8 *cfgPage) { - void **dst = getHandlerDestination(vector); - originalHandlers[(u32)vector] = *dst; - if(handler != NULL) - *(void**)PA_FROM_VA_PTR(dst) = handler; -} + configPage = cfgPage; -static bool **enableUserExceptionHandlersForCPUExcLoc; -static bool enableUserExceptionHandlersForCPUExc = true; - -static void setupSvcHandler(void) -{ - swapHandlerInVeneer(SVC, svcHandler); - - void **arm11SvcTable = (void**)originalHandlers[(u32)SVC]; - while(*arm11SvcTable != NULL) arm11SvcTable++; //Look for SVC0 (NULL) - memcpy(officialSVCs, arm11SvcTable, 4 * 0x7E); - - officialSVCs[0x2D] = *((void **)officialSVCs[0x2D] + 1); - - CustomBackdoor = (Result (*)(void *, ...))((u32 *)officialSVCs[0x2F] + 2); - officialSVCs[0x2F] = *((void **)officialSVCs[0x2F] + 1); - - u32 *off = (u32 *)originalHandlers[(u32) SVC]; - while(*off++ != 0xE1A00009); - svcFallbackHandler = (void (*)(u8))decodeARMBranch(off); - for(; *off != 0xE92D000F; off++); - PostprocessSvc = (void (*)(void))decodeARMBranch(off + 1); -} - -static void setupExceptionHandlers(void) -{ - swapHandlerInVeneer(FIQ, FIQHandler); - swapHandlerInVeneer(UNDEFINED_INSTRUCTION, undefinedInstructionHandler); - swapHandlerInVeneer(PREFETCH_ABORT, prefetchAbortHandler); - swapHandlerInVeneer(DATA_ABORT, dataAbortHandler); - - setupSvcHandler(); + kernelVersion = *(vu32 *)configPage; + *isDevUnit = true; // enable debug features } static void findUsefulSymbols(void) { u32 *off; + for(off = (u32 *)0xFFFF0000; *off != 0xE1A0D002; off++); + off += 3; + initFPU = (void (*) (void))off; + + for(; *off != 0xE3A0A0C2; off++); + mcuReboot = (void (*) (void))--off; + coreBarrier = (void (*) (void))decodeARMBranch(off - 4); + + for(off = (u32 *)originalHandlers[2]; *off != 0xE1A00009; off++); + svcFallbackHandler = (void (*)(u8))decodeARMBranch(off + 1); + for(; *off != 0xE92D000F; off++); + PostprocessSvc = (void (*)(void))decodeARMBranch(off + 1); + KProcessHandleTable__ToKProcess = (KProcess * (*)(KProcessHandleTable *, Handle))decodeARMBranch(5 + (u32 *)officialSVCs[0x76]); for(off = (u32 *)KProcessHandleTable__ToKProcess; *off != 0xE28DD014; off++); @@ -131,6 +150,9 @@ static void findUsefulSymbols(void) KProcessHandleTable__ToKThread = (KThread * (*)(KProcessHandleTable *, Handle))decodeARMBranch((u32 *)decodeARMBranch((u32 *)officialSVCs[0x37] + 3) /* GetThreadId */ + 5); + for(off = (u32 *)officialSVCs[0x50]; off[0] != 0xE1A05000 || off[1] != 0xE2100102 || off[2] != 0x5A00000B; off++); + InterruptManager__MapInterrupt = (Result (*)(InterruptManager *, KBaseInterruptEvent *, u32, u32, u32, bool, bool))decodeARMBranch(--off); + interruptManager = *(InterruptManager **)(off - 4 + (off[-6] & 0xFFF) / 4); for(off = (u32 *)officialSVCs[0x54]; *off != 0xE8BD8008; off++); flushDataCacheRange = (void (*)(void *, u32))(*(u32 **)(off[1]) + 3); @@ -145,7 +167,7 @@ static void findUsefulSymbols(void) for(; *off != 0xE320F000; off++); KObjectMutex__ErrorOccured = (void (*)(void))decodeARMBranch(off + 1); - for(off = (u32 *)originalHandlers[(u32) DATA_ABORT]; *off != (u32)exceptionStackTop; off++); + for(off = (u32 *)originalHandlers[4]; *off != (u32)exceptionStackTop; off++); kernelUsrCopyFuncsStart = (void *)off[1]; kernelUsrCopyFuncsEnd = (void *)off[2]; @@ -202,16 +224,14 @@ static void findUsefulSymbols(void) for(off = (u32 *)0xFFFF0000; off[0] != 0xE3A01002 || off[1] != 0xE3A00004; off++); SignalDebugEvent = (Result (*)(DebugEventType type, u32 info, ...))decodeARMBranch(off + 2); - for(off = (u32 *)PA_FROM_VA_PTR(off); *off != 0x96007F9; off++); + for(; *off != 0x96007F9; off++); isDevUnit = *(bool **)(off - 1); - enableUserExceptionHandlersForCPUExcLoc = (bool **)(off + 1); /////////////////////////////////////////// // Shitty/lazy heuristic but it works on even 4.5, so... - u32 textStart = ((u32)originalHandlers[(u32) SVC]) & ~0xFFFF; - u32 rodataStart = (u32)(interruptManager->N3DS.privateInterrupts[0][6].interruptEvent->vtable) & ~0xFFF; - + u32 textStart = ((u32)originalHandlers[2]) & ~0xFFFF; + u32 rodataStart = (u32)(interruptManager->N3DS.privateInterrupts[1][0x1D].interruptEvent->vtable) & ~0xFFF; u32 textSize = rodataStart - textStart; for(off = (u32 *)textStart; off < (u32 *)(textStart + textSize - 12); off++) { @@ -228,76 +248,28 @@ static void findUsefulSymbols(void) } } -struct Parameters +void main(void) { - void (*SGI0HandlerCallback)(struct Parameters *, u32 *); - InterruptManager *interruptManager; - u32 *L2MMUTable; // bit31 mapping + struct KExtParameters *p = &kExtParameters; + u32 TTBCR_; + s64 nb; - void (*initFPU)(void); - void (*mcuReboot)(void); - void (*coreBarrier)(void); - - u32 TTBCR; - u32 L1MMUTableAddrs[4]; - - u32 kernelVersion; - - CfwInfo cfwInfo; -}; - -static void enableDebugFeatures(void) -{ - *isDevUnit = true; // for debug SVCs and user exc. handlers, etc. - *enableUserExceptionHandlersForCPUExcLoc = &enableUserExceptionHandlersForCPUExc; - - u32 *off; - for(off = (u32 *)PA_FROM_VA_PTR(KernelSetState); off[0] != 0xE5D00001 || off[1] != 0xE3500000; off++); - off[2] = 0xE1A00000; // in case 6: beq -> nop - - for(off = (u32 *)PA_FROM_VA_PTR(DebugActiveProcess); *off != 0xE3110001; off++); - *off = 0xE3B01001; // tst r1, #1 -> movs r1, #1 -} - -static void doOtherPatches(void) -{ - u32 *kpanic = (u32 *)kernelpanic; - *(u32 *)PA_FROM_VA_PTR(kpanic) = 0xE12FFF7E; // bkpt 0xFFFE - - u32 *off; - for(off = (u32 *)PA_FROM_VA_PTR(ControlMemory); (off[0] & 0xFFF0FFFF) != 0xE3500001 || (off[1] & 0xFFFF0FFF) != 0x13A00000; off++); - off -= 2; - - /* - Here we replace currentProcess->processID == 1 by additionnalParameter == 1. - This patch should be generic enough to work even on firmware version 5.0. - - It effectively changes the prototype of the ControlMemory function which - only caller is the svc 0x01 handler on OFW. - */ - *(u32 *)PA_FROM_VA_PTR(off) = 0xE59D0000 | (*off & 0x0000F000) | (8 + computeARMFrameSize((u32 *)PA_FROM_VA_PTR(ControlMemory))); // ldr r0, [sp, #(frameSize + 8)] -} - -void main(volatile struct Parameters *p) -{ + __asm__ volatile("mrc p15, 0, %0, c2, c0, 2" : "=r"(TTBCR_)); + TTBCR = TTBCR_; isN3DS = getNumberOfCores() == 4; - interruptManager = p->interruptManager; - - initFPU = p->initFPU; - mcuReboot = p->mcuReboot; - coreBarrier = p->coreBarrier; - - TTBCR = p->TTBCR; memcpy(L1MMUTableAddrs, (const void *)p->L1MMUTableAddrs, 16); exceptionStackTop = (u32 *)0xFFFF2000 + (1 << (32 - TTBCR - 20)); - kernelVersion = p->kernelVersion; cfwInfo = p->cfwInfo; - setupSGI0Handler(); - setupExceptionHandlers(); + memcpy(originalHandlers + 1, p->originalHandlers, 16); + void **arm11SvcTable = (void**)originalHandlers[2]; + while(*arm11SvcTable != NULL) arm11SvcTable++; //Look for SVC0 (NULL) + memcpy(officialSVCs, arm11SvcTable, 4 * 0x7E); + findUsefulSymbols(); - enableDebugFeatures(); - doOtherPatches(); + + GetSystemInfo(&nb, 26, 0); + nbSection0Modules = (u32)nb; rosalinaState = 0; hasStartedRosalinaNetworkFuncsOnce = false; diff --git a/sysmodules/rosalina/kernel_extension/source/memory.c b/k11_extension/source/memory.c similarity index 100% rename from sysmodules/rosalina/kernel_extension/source/memory.c rename to k11_extension/source/memory.c diff --git a/sysmodules/rosalina/source/kernel_extension.s b/k11_extension/source/start.s similarity index 55% rename from sysmodules/rosalina/source/kernel_extension.s rename to k11_extension/source/start.s index dc37eb4..c1e970f 100644 --- a/sysmodules/rosalina/source/kernel_extension.s +++ b/k11_extension/source/start.s @@ -22,40 +22,57 @@ @ or requiring that modified versions of such material be marked in @ reasonable ways as different from the original version. -.text -.arm +.section .text.start .balign 4 +.global _start +_start: + b start + b startPhys -.global svc0x2F -.type svc0x2F, %function -svc0x2F: - @ custom backdoor before kernel ext. is installed - svc 0x2F + b _bindSGI0Hook + b configHook + + b undefinedInstructionHandler + b svcHandler + b prefetchAbortHandler + b dataAbortHandler + + .word __end__ + .word kExtParameters + .word 1 @ enableUserExceptionHandlersForCPUExc + +start: + @ Only core0 executes this, the other cores are running coreBarrier + + @ Skipped instruction: + str r1, [r4, #0x8] + + push {r0-r12, lr} + + @ Adjust the size of the SYSTEM memregion + sub r4, #8 + ldr r0, [r4, #0xC] + ldr r1, =__end__ + ldr r2, =__start__ + sub r1, r2 + sub r0, r1 + str r0, [r4, #0xC] + + bl main + + pop {r0-r12, pc} + +startPhys: + push {r0-r12, lr} + mrc p15, 0, r0, c0, c0, 5 @ CPUID register + and r0, #3 + mov r1, r2 + bl relocateAndSetupMMU + pop {r0-r12, lr} + mov r12, #0x20000000 @ instruction that has been patched bx lr -.global convertVAToPA -.type convertVAToPA, %function -convertVAToPA: - @ needs to be executed in supervisor mode - mov r1, #0x1000 - sub r1, #1 - and r2, r0, r1 - bic r0, r1 - mcr p15, 0, r0, c7, c8, 0 @ VA to PA translation with privileged read permission check - mrc p15, 0, r0, c7, c4, 0 @ read PA register - tst r0, #1 @ failure bit - bic r0, r1 - addeq r0, r2 - movne r0, #0 - bx lr - -.section .data - -.p2align 12 -.global kernel_extension -kernel_extension: .incbin "build/kernel_extension.bin" -.p2align 12 -kernel_extension_end: - -.global kernel_extension_size -kernel_extension_size: .word kernel_extension_end - kernel_extension +_bindSGI0Hook: + push {r0-r12, lr} + bl bindSGI0Hook + pop {r0-r12, pc} diff --git a/sysmodules/rosalina/kernel_extension/source/svc.c b/k11_extension/source/svc.c similarity index 99% rename from sysmodules/rosalina/kernel_extension/source/svc.c rename to k11_extension/source/svc.c index 835ed71..fe0f38f 100644 --- a/sysmodules/rosalina/kernel_extension/source/svc.c +++ b/k11_extension/source/svc.c @@ -37,6 +37,7 @@ #include "svc/SetWifiEnabled.h" #include "svc/Backdoor.h" #include "svc/KernelSetState.h" +#include "svc/CustomBackdoor.h" #include "svc/MapProcessMemoryEx.h" #include "svc/UnmapProcessMemoryEx.h" #include "svc/ControlService.h" @@ -51,7 +52,7 @@ static inline void yieldDuringRosalinaMenu(void) u64 titleId = codeSetOfProcess(currentProcess)->titleId; u32 highTitleId = (u32)(titleId >> 32), lowTitleId = (u32)titleId; - while((rosalinaState & 1) && idOfProcess(currentProcess) >= 6 && + while((rosalinaState & 1) && idOfProcess(currentProcess) >= nbSection0Modules && (highTitleId != 0x00040130 || (highTitleId == 0x00040130 && (lowTitleId == 0x1A02 || lowTitleId == 0x1C02)))) SleepThread(25 * 1000 * 1000LL); } diff --git a/sysmodules/rosalina/kernel_extension/source/svc/Backdoor.s b/k11_extension/source/svc/Backdoor.s similarity index 100% rename from sysmodules/rosalina/kernel_extension/source/svc/Backdoor.s rename to k11_extension/source/svc/Backdoor.s diff --git a/sysmodules/rosalina/kernel_extension/source/svc/Break.s b/k11_extension/source/svc/Break.s similarity index 100% rename from sysmodules/rosalina/kernel_extension/source/svc/Break.s rename to k11_extension/source/svc/Break.s diff --git a/sysmodules/rosalina/kernel_extension/source/svc/ConnectToPort.c b/k11_extension/source/svc/ConnectToPort.c similarity index 100% rename from sysmodules/rosalina/kernel_extension/source/svc/ConnectToPort.c rename to k11_extension/source/svc/ConnectToPort.c diff --git a/sysmodules/rosalina/kernel_extension/source/svc/ControlMemory.c b/k11_extension/source/svc/ControlMemory.c similarity index 100% rename from sysmodules/rosalina/kernel_extension/source/svc/ControlMemory.c rename to k11_extension/source/svc/ControlMemory.c diff --git a/sysmodules/rosalina/kernel_extension/source/svc/ControlService.c b/k11_extension/source/svc/ControlService.c similarity index 100% rename from sysmodules/rosalina/kernel_extension/source/svc/ControlService.c rename to k11_extension/source/svc/ControlService.c diff --git a/sysmodules/rosalina/kernel_extension/source/svc/CopyHandle.c b/k11_extension/source/svc/CopyHandle.c similarity index 100% rename from sysmodules/rosalina/kernel_extension/source/svc/CopyHandle.c rename to k11_extension/source/svc/CopyHandle.c diff --git a/sysmodules/rosalina/kernel_extension/source/start.s b/k11_extension/source/svc/CustomBackdoor.s similarity index 72% rename from sysmodules/rosalina/kernel_extension/source/start.s rename to k11_extension/source/svc/CustomBackdoor.s index f401779..9078bac 100644 --- a/sysmodules/rosalina/kernel_extension/source/start.s +++ b/k11_extension/source/svc/CustomBackdoor.s @@ -22,38 +22,17 @@ @ or requiring that modified versions of such material be marked in @ reasonable ways as different from the original version. -.section .text.start +.text +.arm .balign 4 -.global _start -_start: - b start - b ConnectToPortHookWrapper -start: +.global CustomBackdoor +.type CustomBackdoor, %function +CustomBackdoor: push {r4, lr} - - mrc p15, 0, r4, c0, c0, 5 @ CPUID register - and r4, #3 - cmp r4, #1 - beq _core1_only - - _waitLoop: - wfe - ldr r0, =_setupFinished - ldr r0, [r0] - cmp r0, #0 - beq _waitLoop - b end - - _core1_only: - bl main - ldr r0, =_setupFinished - str r4, [r0] - sev - - end: + mov r4, r0 + mov r0, r1 + mov r1, r2 + mov r2, r3 + blx r4 pop {r4, pc} - -.bss -.balign 4 -_setupFinished: .word 0 diff --git a/sysmodules/rosalina/kernel_extension/source/svc/GetCFWInfo.c b/k11_extension/source/svc/GetCFWInfo.c similarity index 100% rename from sysmodules/rosalina/kernel_extension/source/svc/GetCFWInfo.c rename to k11_extension/source/svc/GetCFWInfo.c diff --git a/sysmodules/rosalina/kernel_extension/source/svc/GetProcessInfo.c b/k11_extension/source/svc/GetProcessInfo.c similarity index 100% rename from sysmodules/rosalina/kernel_extension/source/svc/GetProcessInfo.c rename to k11_extension/source/svc/GetProcessInfo.c diff --git a/sysmodules/rosalina/kernel_extension/source/svc/GetSystemInfo.c b/k11_extension/source/svc/GetSystemInfo.c similarity index 100% rename from sysmodules/rosalina/kernel_extension/source/svc/GetSystemInfo.c rename to k11_extension/source/svc/GetSystemInfo.c diff --git a/sysmodules/rosalina/kernel_extension/source/svc/GetThreadInfo.c b/k11_extension/source/svc/GetThreadInfo.c similarity index 100% rename from sysmodules/rosalina/kernel_extension/source/svc/GetThreadInfo.c rename to k11_extension/source/svc/GetThreadInfo.c diff --git a/sysmodules/rosalina/kernel_extension/source/svc/KernelSetState.c b/k11_extension/source/svc/KernelSetState.c similarity index 100% rename from sysmodules/rosalina/kernel_extension/source/svc/KernelSetState.c rename to k11_extension/source/svc/KernelSetState.c diff --git a/sysmodules/rosalina/kernel_extension/source/svc/MapProcessMemoryEx.c b/k11_extension/source/svc/MapProcessMemoryEx.c similarity index 100% rename from sysmodules/rosalina/kernel_extension/source/svc/MapProcessMemoryEx.c rename to k11_extension/source/svc/MapProcessMemoryEx.c diff --git a/sysmodules/rosalina/kernel_extension/source/svc/SendSyncRequest.c b/k11_extension/source/svc/SendSyncRequest.c similarity index 100% rename from sysmodules/rosalina/kernel_extension/source/svc/SendSyncRequest.c rename to k11_extension/source/svc/SendSyncRequest.c diff --git a/sysmodules/rosalina/kernel_extension/source/svc/SetGpuProt.c b/k11_extension/source/svc/SetGpuProt.c similarity index 100% rename from sysmodules/rosalina/kernel_extension/source/svc/SetGpuProt.c rename to k11_extension/source/svc/SetGpuProt.c diff --git a/sysmodules/rosalina/kernel_extension/source/svc/SetWifiEnabled.c b/k11_extension/source/svc/SetWifiEnabled.c similarity index 100% rename from sysmodules/rosalina/kernel_extension/source/svc/SetWifiEnabled.c rename to k11_extension/source/svc/SetWifiEnabled.c diff --git a/sysmodules/rosalina/kernel_extension/source/svc/TranslateHandle.c b/k11_extension/source/svc/TranslateHandle.c similarity index 100% rename from sysmodules/rosalina/kernel_extension/source/svc/TranslateHandle.c rename to k11_extension/source/svc/TranslateHandle.c diff --git a/sysmodules/rosalina/kernel_extension/source/svc/UnmapProcessMemoryEx.c b/k11_extension/source/svc/UnmapProcessMemoryEx.c similarity index 100% rename from sysmodules/rosalina/kernel_extension/source/svc/UnmapProcessMemoryEx.c rename to k11_extension/source/svc/UnmapProcessMemoryEx.c diff --git a/sysmodules/rosalina/kernel_extension/source/svc/wrappers.s b/k11_extension/source/svc/wrappers.s similarity index 100% rename from sysmodules/rosalina/kernel_extension/source/svc/wrappers.s rename to k11_extension/source/svc/wrappers.s diff --git a/sysmodules/rosalina/kernel_extension/source/svcHandler.s b/k11_extension/source/svcHandler.s similarity index 100% rename from sysmodules/rosalina/kernel_extension/source/svcHandler.s rename to k11_extension/source/svcHandler.s diff --git a/sysmodules/rosalina/kernel_extension/source/synchronization.c b/k11_extension/source/synchronization.c similarity index 100% rename from sysmodules/rosalina/kernel_extension/source/synchronization.c rename to k11_extension/source/synchronization.c diff --git a/sysmodules/rosalina/kernel_extension/source/utils.s b/k11_extension/source/utils.s similarity index 100% rename from sysmodules/rosalina/kernel_extension/source/utils.s rename to k11_extension/source/utils.s diff --git a/patches/k11MainHook.s b/patches/k11MainHook.s deleted file mode 100644 index e0c5ffa..0000000 --- a/patches/k11MainHook.s +++ /dev/null @@ -1,66 +0,0 @@ -.arm.little - -.create "build/k11MainHook.bin", 0 -.arm - -bindSGI0: - ; hook __kernel_main to bind SGI0 for own purposes - push {r0-r4, lr} - sub sp, #16 ; 3 args passed through the stack + alignment - adr r0, parameters - ldr r0, [r0, #4] - adr r1, interruptEvent - mov r2, #0 - mrc p15, 0, r3, c0, c0, 5 - and r3, #3 - mov r4, #0 - str r4, [sp] - str r4, [sp, #4] - str r4, [sp, #8] - - ldr r12, [InterruptManager_MapInterrupt] - blx r12 - cmp r0, #0 - blt . - - add sp, #16 - pop {r0-r4, pc} - -executeCustomHandler: - push {r4, lr} - mrs r4, cpsr - adr r0, parameters - bl convertVAToPA - orr r0, #(1 << 31) - ldr r12, [r0] - - blx r12 - - mov r0, #0 - msr cpsr_cx, r4 - pop {r4, pc} - -convertVAToPA: - mov r1, #0x1000 - sub r1, #1 - and r2, r0, r1 - bic r0, r1 - mcr p15, 0, r0, c7, c8, 0 ; VA to PA translation with privileged read permission check - mrc p15, 0, r0, c7, c4, 0 ; read PA register - tst r0, #1 ; failure bit - bic r0, r1 - addeq r0, r2 - movne r0, #0 - bx lr - -.pool - -; Result InterruptManager::MapInterrupt(InterruptManager *this, InterruptEvent *iEvent, u32 interruptID, u32 coreID, s32 priority, bool willBeMasked, bool isLevelHighActive); -InterruptManager_MapInterrupt: .ascii "bind" - -_vtable: .word executeCustomHandler -interruptEvent: .word _vtable - -parameters: - -.close diff --git a/patches/mmuHook.s b/patches/mmuHook.s deleted file mode 100644 index 5a6b989..0000000 --- a/patches/mmuHook.s +++ /dev/null @@ -1,36 +0,0 @@ -.arm.little - -.create "build/mmuHook.bin", 0 -.arm - ; r2 = L1 table - ; Thanks @Dazzozo for giving me that idea - ; Maps physmem so that, if addr is in physmem(0, 0x30000000), it can be accessed uncached&rwx as addr|(1<<31) - ; Save the value of all registers - - push {r0-r1, r3-r7} - mov r0, #0 - mov r1, #0x30000000 ; end address - ldr r3, =#0x40C02 ; supersection (rwx for all) of strongly ordered memory, shared - loop: - orr r4, r0, #0x80000000 - orr r5, r0, r3 - - mov r6, #0 ; - loop2: - add r7, r6, r4,lsr #20 - str r5, [r2, r7,lsl #2] - add r6, #1 - cmp r6, #16 - blo loop2 - - add r0, #0x01000000 - cmp r0, r1 - blo loop - pop {r0-r1, r3-r7} - - mov r3, #0xe0000000 ; instruction that has been patched - bx lr - - -.pool -.close diff --git a/patches/svcConnectToPortInitHook.s b/patches/svcConnectToPortInitHook.s deleted file mode 100644 index 258794c..0000000 --- a/patches/svcConnectToPortInitHook.s +++ /dev/null @@ -1,32 +0,0 @@ -.arm.little - -.create "build/svcConnectToPortInitHook.bin", 0 -.arm - b skip_vars -vars: - orig: .word 0 - SleepThread: .word 0 -skip_vars: - push {r0-r4, lr} - ldr r4, =0x1ff81108 - - loop: - ldrb r12, [r4] - cmp r12, #0 - bne loop_end - - ldr r12, [SleepThread] - ldr r0, =(10 * 1000 * 1000) - mov r1, #0 - blx r12 - b loop - - loop_end: - pop {r0-r4, lr} - mov r12, #0x40000000 - add r12, #4 - bx r12 - -.pool - -.close diff --git a/patches/svcCustomBackdoor.s b/patches/svcCustomBackdoor.s deleted file mode 100644 index 6ab4f55..0000000 --- a/patches/svcCustomBackdoor.s +++ /dev/null @@ -1,20 +0,0 @@ -.arm.little - -.create "build/svcCustomBackdoor.bin", 0 -.arm - -; Result svcCustomBackdoor(void *func, ... ) -svcCustomBackdoor: - b skip_orig -orig: .word 0 -skip_orig: - push {r4, lr} - mov r4, r0 - mov r0, r1 - mov r1, r2 - mov r2, r3 - blx r4 - pop {r4, pc} - -.pool -.close diff --git a/source/exceptions.h b/source/exceptions.h index e7fee45..387b77d 100644 --- a/source/exceptions.h +++ b/source/exceptions.h @@ -28,9 +28,6 @@ #include "types.h" -#define MAKE_BRANCH(src,dst) (0xEA000000 | ((u32)((((u8 *)(dst) - (u8 *)(src)) >> 2) - 2) & 0xFFFFFF)) -#define MAKE_BRANCH_LINK(src,dst) (0xEB000000 | ((u32)((((u8 *)(dst) - (u8 *)(src)) >> 2) - 2) & 0xFFFFFF)) - void installArm9Handlers(void); u32 installArm11Handlers(u32 *exceptionsPage, u32 stackAddress, u32 codeSetOffset, u32 *dAbtHandler, u32 dAbtHandlerMemAddress); void detectAndProcessExceptionDumps(void); diff --git a/source/firm.c b/source/firm.c index 7031331..f46efd5 100755 --- a/source/firm.c +++ b/source/firm.c @@ -227,10 +227,8 @@ u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, bool loadFromStora u32 kernel9Size = (u32)(process9Offset - arm9Section) - sizeof(Cxi) - 0x200, ret = 0; - installMMUHook(arm11Section1, firm->section[1].size, &freeK11Space); - installK11MainHook(arm11Section1, firm->section[1].size, isSafeMode, baseK11VA, arm11SvcTable, arm11ExceptionsPage, &freeK11Space); - installSvcConnectToPortInitHook(arm11SvcTable, arm11ExceptionsPage, &freeK11Space); - installSvcCustomBackdoor(arm11SvcTable, &freeK11Space, arm11ExceptionsPage); + ret += installK11Extension(arm11Section1, firm->section[1].size, isSafeMode, baseK11VA, arm11ExceptionsPage, &freeK11Space); + ret += patchKernel11(arm11Section1, firm->section[1].size, baseK11VA, arm11SvcTable, arm11ExceptionsPage); //Apply signature patches ret += patchSignatureChecks(process9Offset, process9Size); @@ -276,6 +274,7 @@ u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, bool loadFromStora mergeSection0(NATIVE_FIRM, loadFromStorage); firm->section[0].size = 0; + fileWrite(arm11Section1, "/luma/testsection1.bin", firm->section[1].size); return ret; } diff --git a/source/patches.c b/source/patches.c index 4abca77..f1b1df7 100644 --- a/source/patches.c +++ b/source/patches.c @@ -78,37 +78,39 @@ u32 *getKernel11Info(u8 *pos, u32 size, u32 *baseK11VA, u8 **freeK11Space, u32 * return arm11SvcTable; } -void installMMUHook(u8 *pos, u32 size, u8 **freeK11Space) +// For ARM prologs in the form of: push {regs} ... sub sp, #off (this obviously doesn't intend to cover all cases) +static inline u32 computeARMFrameSize(const u32 *prolog) { - static const u8 pattern[] = {0x0E, 0x32, 0xA0, 0xE3, 0x02, 0xC2, 0xA0, 0xE3}; + const u32 *off; - u32 *off = (u32 *)memsearch(pos, pattern, size, 8); + for(off = prolog; (*off >> 16) != 0xE92D; off++); // look for stmfd sp! = push + u32 nbPushedRegs = 0; + for(u32 val = *off & 0xFFFF; val != 0; val >>= 1) // 1 bit = 1 pushed register + nbPushedRegs += val & 1; + for(; (*off >> 8) != 0xE24DD0; off++); // look for sub sp, #offset + u32 localVariablesSpaceSize = *off & 0xFF; - memcpy(*freeK11Space, mmuHook_bin, mmuHook_bin_size); - *off = MAKE_BRANCH_LINK(off, *freeK11Space); - - (*freeK11Space) += mmuHook_bin_size; + return 4 * nbPushedRegs + localVariablesSpaceSize; } -void installK11MainHook(u8 *pos, u32 size, bool isSafeMode, u32 baseK11VA, u32 *arm11SvcTable, u32 *arm11ExceptionsPage, u8 **freeK11Space) +static inline u32 *getKernel11HandlerVAPos(u8 *pos, u32 *arm11ExceptionsPage, u32 baseK11VA, u32 id) +{ + u32 off = ((-((arm11ExceptionsPage[id] & 0xFFFFFF) << 2)) & (0xFFFFFF << 2)) - 8; + u32 pointedInstructionVA = 0xFFFF0000 + 4 * id - off; + return (u32 *)(pos + pointedInstructionVA - baseK11VA + 8); +} + +u32 installK11Extension(u8 *pos, u32 size, bool isSafeMode, u32 baseK11VA, u32 *arm11ExceptionsPage, u8 **freeK11Space) { //The parameters to be passed on to the kernel ext - //Please keep that in sync with the definition in kernel_extension_setup.c and kernel_extension/main.c + //Please keep that in sync with the definition in k11_extension/source/main.c struct KExtParameters { - void (*SGI0HandlerCallback)(struct KExtParameters *, u32 *); - void *interruptManager; - u32 *L2MMUTable; //bit31 mapping - - void (*initFPU)(void); - void (*mcuReboot)(void); - void (*coreBarrier)(void); - - u32 TTBCR; + u32 __attribute__((aligned(0x400))) L2MMUTableFor0x40000000[256]; + u32 basePA; + void *originalHandlers[4]; u32 L1MMUTableAddrs[4]; - u32 kernelVersion; - struct CfwInfo { char magic[4]; @@ -124,42 +126,61 @@ void installK11MainHook(u8 *pos, u32 size, bool isSafeMode, u32 baseK11VA, u32 * } __attribute__((packed)) info; }; - static const u8 pattern[] = {0x00, 0x00, 0xA0, 0xE1, 0x03, 0xF0, 0x20, 0xE3, 0xFD, 0xFF, 0xFF, 0xEA}; + static const u8 patternHook1[] = {0x02, 0xC2, 0xA0, 0xE3, 0xFF}; //MMU setup hook + static const u8 patternHook2[] = {0x08, 0x00, 0xA4, 0xE5, 0x02, 0x10, 0x80, 0xE0, 0x08, 0x10, 0x84, 0xE5}; //FCRAM layout setup hook + static const u8 patternHook3_4[] = {0x00, 0x00, 0xA0, 0xE1, 0x03, 0xF0, 0x20, 0xE3, 0xFD, 0xFF, 0xFF, 0xEA}; //SGI0 setup code, etc. - u32 *off = (u32 *)memsearch(pos, pattern, size, 12); - //look for cpsie i and place our function call in the nop 2 instructions before - while(*off != 0xF1080080) off--; - off -= 2; - - memcpy(*freeK11Space, k11MainHook_bin, k11MainHook_bin_size); + //Our kernel11 extension is initially loaded in VRAM + u32 kextTotalSize = *(u32 *)0x18000020 - 0x40000000; + u32 dstKextPA = (ISN3DS ? 0x2E000000 : 0x26C00000) - kextTotalSize; + u32 *hookVeneers = (u32 *)*freeK11Space; u32 relocBase = 0xFFFF0000 + (*freeK11Space - (u8 *)arm11ExceptionsPage); - *off = MAKE_BRANCH_LINK(baseK11VA + ((u8 *)off - pos), relocBase); + + hookVeneers[0] = 0xE51FF004; //ldr pc, [pc, #-8+4] + hookVeneers[1] = 0x18000004; + hookVeneers[2] = 0xE51FF004; + hookVeneers[3] = 0x40000000; + hookVeneers[4] = 0xE51FF004; + hookVeneers[5] = 0x40000008; + hookVeneers[6] = 0xE51FF004; + hookVeneers[7] = 0x4000000C; - off = (u32 *)(pos + (arm11SvcTable[0x50] - baseK11VA)); //svcBindInterrupt - while(off[0] != 0xE1A05000 || off[1] != 0xE2100102 || off[2] != 0x5A00000B) off++; - off--; + (*freeK11Space) += 32; - signed int offset = (*off & 0xFFFFFF) << 2; - offset = offset << 6 >> 6; //sign extend - offset += 8; + //MMU setup hook + u32 *off = (u32 *)memsearch(pos, patternHook1, size, sizeof(patternHook1)); + if(off == NULL) return 1; + *off = MAKE_BRANCH_LINK(off, hookVeneers); - u32 InterruptManager_MapInterrupt = baseK11VA + ((u8 *)off - pos) + offset; - u32 interruptManager = *(u32 *)(off - 4 + (*(off - 6) & 0xFFF) / 4); + //Most important hook: FCRAM layout setup hook + off = (u32 *)memsearch(pos, patternHook2, size, sizeof(patternHook2)); + if(off == NULL) return 1; + off += 2; + *off = MAKE_BRANCH_LINK(baseK11VA + ((u8 *)off - pos), relocBase + 8); - off = (u32 *)memsearch(*freeK11Space, "bind", k11MainHook_bin_size, 4); + //Bind SGI0 hook + //Look for cpsie i and place our hook in the nop 2 instructions before + off = (u32 *)memsearch(pos, patternHook3_4, size, 12); + if(off == NULL) return 1; + for(; *off != 0xF1080080; off--); + off -= 2; + *off = MAKE_BRANCH_LINK(baseK11VA + ((u8 *)off - pos), relocBase + 16); - off[0] = InterruptManager_MapInterrupt; + //Config hook (after the configuration memory fields have been filled) + for(; *off != 0xE1A00000; off++); + off += 4; + *off = MAKE_BRANCH_LINK(baseK11VA + ((u8 *)off - pos), relocBase + 24); - //Relocate stuff - off[1] += relocBase; - off[2] += relocBase; + struct KExtParameters *p = (struct KExtParameters *)(*(u32 *)0x18000024 - 0x40000000 + 0x18000000); + p->basePA = dstKextPA; - struct KExtParameters *p = (struct KExtParameters *)(off + 3); - memset(p, 0, sizeof(struct KExtParameters)); - memcpy((void *)&p->SGI0HandlerCallback, "hdlr", 4); - - p->interruptManager = (void *)interruptManager; + for(u32 i = 0; i < 4; i++) + { + u32 *handlerPos = getKernel11HandlerVAPos(pos, arm11ExceptionsPage, baseK11VA, 1 + i); + p->originalHandlers[i] = (void *)*handlerPos; + *handlerPos = 0x40000010 + 4 * i; + } struct CfwInfo *info = &p->info; memcpy(&info->magic, "LUMA", 4); @@ -174,32 +195,52 @@ void installK11MainHook(u8 *pos, u32 size, bool isSafeMode, u32 baseK11VA, u32 * if(isSafeMode) info->flags |= 1 << 5; if(isSdMode) info->flags |= 1 << 6; - (*freeK11Space) += (k11MainHook_bin_size + sizeof(struct KExtParameters)); - (*freeK11Space) += 4 - ((u32)(*freeK11Space) % 4); + return 0; } -void installSvcConnectToPortInitHook(u32 *arm11SvcTable, u32 *arm11ExceptionsPage, u8 **freeK11Space) +u32 patchKernel11(u8 *pos, u32 size, u32 baseK11VA, u32 *arm11SvcTable, u32 *arm11ExceptionsPage) { - u32 addr = 0xFFFF0000 + (u32)*freeK11Space - (u32)arm11ExceptionsPage; - u32 svcSleepThreadAddr = arm11SvcTable[0x0A], svcConnectToPortAddr = arm11SvcTable[0x2D]; + static const u8 patternKPanic[] = {0x02, 0x0B, 0x44, 0xE2}; - arm11SvcTable[0x2D] = addr; - memcpy(*freeK11Space, svcConnectToPortInitHook_bin, svcConnectToPortInitHook_bin_size); + //Assumption: ControlMemory, DebugActiveProcess and KernelSetState are in the first 0x20000 bytes + //Patch ControlMemory + u8 *instrPos = pos + (arm11SvcTable[1] + 20 - baseK11VA); + s32 displ = (*(u32 *)instrPos & 0xFFFFFF) << 2; + displ = (displ << 6) >> 6; // sign extend - u32 *off = (u32 *)(*freeK11Space); - off[1] = svcConnectToPortAddr; - off[2] = svcSleepThreadAddr; + u8 *ControlMemoryPos = instrPos + 8 + displ; + u32 *off; - (*freeK11Space) += svcConnectToPortInitHook_bin_size; -} + /* + Here we replace currentProcess->processID == 1 by additionnalParameter == 1. + This patch should be generic enough to work even on firmware version 5.0. + It effectively changes the prototype of the ControlMemory function which + only caller is the svc 0x01 handler on OFW. + */ + for(off = (u32 *)ControlMemoryPos; (off[0] & 0xFFF0FFFF) != 0xE3500001 || (off[1] & 0xFFFF0FFF) != 0x13A00000; off++); + off -= 2; + *off = 0xE59D0000 | (*off & 0x0000F000) | (8 + computeARMFrameSize((u32 *)ControlMemoryPos)); // ldr r0, [sp, #(frameSize + 8)] -void installSvcCustomBackdoor(u32 *arm11SvcTable, u8 **freeK11Space, u32 *arm11ExceptionsPage) -{ - memcpy(*freeK11Space, svcCustomBackdoor_bin, svcCustomBackdoor_bin_size); - *((u32 *)*freeK11Space + 1) = arm11SvcTable[0x2F]; // temporary location - arm11SvcTable[0x2F] = 0xFFFF0000 + *freeK11Space - (u8 *)arm11ExceptionsPage; - (*freeK11Space) += svcCustomBackdoor_bin_size; + //Patch DebugActiveProcess + for(off = (u32 *)(pos + (arm11SvcTable[0x60] - baseK11VA)); *off != 0xE3110001; off++); + *off = 0xE3B01001; // tst r1, #1 -> movs r1, #1 + + for(off = (u32 *)(pos + (arm11SvcTable[0x7C] - baseK11VA)); off[0] != 0xE5D00001 || off[1] != 0xE3500000; off++); + off[2] = 0xE1A00000; // in case 6: beq -> nop + + //Patch kernelpanic + off = (u32 *)memsearch(pos, patternKPanic, size, sizeof(patternKPanic)); + if(off == NULL) + return 1; + + off[-6] = 0xE12FFF7E; + + //Redirect enableUserExceptionHandlersForCPUExc (= true) + for(off = arm11ExceptionsPage; *off != 0x96007F9; off++); + off[1] = 0x40000028; + + return 0; } u32 patchSignatureChecks(u8 *pos, u32 size) diff --git a/source/patches.h b/source/patches.h index 4574447..797e92c 100644 --- a/source/patches.h +++ b/source/patches.h @@ -41,10 +41,8 @@ extern CfgData configData; u8 *getProcess9Info(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr); u32 *getKernel11Info(u8 *pos, u32 size, u32 *baseK11VA, u8 **freeK11Space, u32 **arm11SvcHandler, u32 **arm11ExceptionsPage); -void installMMUHook(u8 *pos, u32 size, u8 **freeK11Space); -void installK11MainHook(u8 *pos, u32 size, bool isSafeMode, u32 baseK11VA, u32 *arm11SvcTable, u32 *arm11ExceptionsPage, u8 **freeK11Space); -void installSvcConnectToPortInitHook(u32 *arm11SvcTable, u32 *arm11ExceptionsPage, u8 **freeK11Space); -void installSvcCustomBackdoor(u32 *arm11SvcTable, u8 **freeK11Space, u32 *arm11ExceptionsPage); +u32 installK11Extension(u8 *pos, u32 size, bool isSafeMode, u32 baseK11VA, u32 *arm11ExceptionsPage, u8 **freeK11Space); +u32 patchKernel11(u8 *pos, u32 size, u32 baseK11VA, u32 *arm11SvcTable, u32 *arm11ExceptionsPage); u32 patchSignatureChecks(u8 *pos, u32 size); u32 patchOldSignatureChecks(u8 *pos, u32 size); u32 patchFirmlaunches(u8 *pos, u32 size, u32 process9MemAddr); diff --git a/source/utils.h b/source/utils.h index 00ca57e..3756e20 100644 --- a/source/utils.h +++ b/source/utils.h @@ -36,6 +36,9 @@ #define REG_TIMER_CNT(i) *(vu16 *)(0x10003002 + 4 * i) #define REG_TIMER_VAL(i) *(vu16 *)(0x10003000 + 4 * i) +#define MAKE_BRANCH(src,dst) (0xEA000000 | ((u32)((((u8 *)(dst) - (u8 *)(src)) >> 2) - 2) & 0xFFFFFF)) +#define MAKE_BRANCH_LINK(src,dst) (0xEB000000 | ((u32)((((u8 *)(dst) - (u8 *)(src)) >> 2) - 2) & 0xFFFFFF)) + u32 waitInput(bool isMenu); void mcuPowerOff(void); void wait(u64 amount); diff --git a/sysmodules/loader/source/loader.c b/sysmodules/loader/source/loader.c index d3b6892..abe1699 100644 --- a/sysmodules/loader/source/loader.c +++ b/sysmodules/loader/source/loader.c @@ -204,12 +204,15 @@ static Result loader_GetProgramInfo(exheader_header *exheader, u64 prog_handle) if (R_SUCCEEDED(res)) { + s64 nbSection0Modules; + svcGetSystemInfo(&nbSection0Modules, 26, 0); + // Force always having sdmc:/ and nand:/rw permission exheader->arm11systemlocalcaps.storageinfo.accessinfo[0] |= 0x480; exheader->accessdesc.arm11systemlocalcaps.storageinfo.accessinfo[0] |= 0x480; // Tweak 3dsx placeholder title exheader - if (exheader->arm11systemlocalcaps.programid == HBLDR_3DSX_TID) + if (nbSection0Modules == 6 && exheader->arm11systemlocalcaps.programid == HBLDR_3DSX_TID) { Handle hbldr = 0; res = HBLDR_Init(&hbldr); diff --git a/sysmodules/loader/source/patcher.c b/sysmodules/loader/source/patcher.c index 05ec618..ae5d2f7 100644 --- a/sysmodules/loader/source/patcher.c +++ b/sysmodules/loader/source/patcher.c @@ -736,10 +736,16 @@ void patchCode(u64 progId, u16 progVer, u8 *code, u32 size, u32 textSize, u32 ro } } - // Makes ErrDisp to not start up - static const u64 errDispTid = 0x0004003000008A02ULL; - u32 *errDispTidLoc = (u32 *)memsearch(code, &errDispTid, size, sizeof(errDispTid)); - *(errDispTidLoc - 6) = 0xE3A00000; // mov r0, #0 + s64 nbSection0Modules; + svcGetSystemInfo(&nbSection0Modules, 26, 0); + + if(nbSection0Modules == 6) + { + // Makes ErrDisp to not start up + static const u64 errDispTid = 0x0004003000008A02ULL; + u32 *errDispTidLoc = (u32 *)memsearch(code, &errDispTid, size, sizeof(errDispTid)); + *(errDispTidLoc - 6) = 0xE3A00000; // mov r0, #0 + } } else if(progId == 0x0004013000001702LL) //CFG diff --git a/sysmodules/rosalina/Makefile b/sysmodules/rosalina/Makefile index 16b444f..807bad9 100644 --- a/sysmodules/rosalina/Makefile +++ b/sysmodules/rosalina/Makefile @@ -17,7 +17,6 @@ dir_source := source dir_include := include dir_build := build dir_out := ../../$(dir_build) -dir_kernel_extension := kernel_extension LIBS := -lctru LIBDIRS := $(CTRULIB) @@ -42,21 +41,14 @@ all: $(dir_out)/$(name).cxi .PHONY: clean clean: - @$(MAKE) -C $(dir_kernel_extension) clean @rm -rf $(dir_build) -.PHONY: $(dir_kernel_extension) - $(dir_out)/$(name).cxi: $(dir_build)/$(name).elf @makerom -f ncch -rsf rosalina.rsf -nocodepadding -o $@ -elf $< $(dir_build)/$(name).elf: $(objects) $(LINK.o) $(OUTPUT_OPTION) $^ $(LIBPATHS) $(LIBS) -$(dir_build)/kernel_extension.bin: $(dir_kernel_extension) - @mkdir -p "$(@D)" - @$(MAKE) -C $< - $(dir_build)/xml_data.h: $(xml_files) @ echo "" > $(@) @$(foreach f, $(xml_files),\ @@ -66,7 +58,6 @@ $(dir_build)/xml_data.h: $(xml_files) ) $(dir_build)/gdb/xfer.o: $(dir_build)/xml_data.h $(dir_build)/memory.o : CFLAGS += -O3 -$(dir_build)/kernel_extension.o: $(dir_build)/kernel_extension.bin $(dir_build)/%.o: $(dir_source)/%.c @mkdir -p "$(@D)" diff --git a/sysmodules/rosalina/kernel_extension/linker.ld b/sysmodules/rosalina/kernel_extension/linker.ld deleted file mode 100644 index f11a495..0000000 --- a/sysmodules/rosalina/kernel_extension/linker.ld +++ /dev/null @@ -1,14 +0,0 @@ -OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") -OUTPUT_ARCH(arm) - -ENTRY(_start) -SECTIONS -{ - . = 0x40000000; - - .text : ALIGN(4) { *(.text.start) *(.text*); . = ALIGN(4); } - .rodata : ALIGN(4) { *(.rodata*); . = ALIGN(4); } - .data : ALIGN(4) { *(.data*); . = ALIGN(8); *(.bss* COMMON); . = ALIGN(8); } - - . = ALIGN(4); -} diff --git a/sysmodules/rosalina/source/errdisp.c b/sysmodules/rosalina/source/errdisp.c index 5a1d195..fe4fbf3 100644 --- a/sysmodules/rosalina/source/errdisp.c +++ b/sysmodules/rosalina/source/errdisp.c @@ -146,7 +146,7 @@ void ERRF_DisplayError(ERRF_FatalErrInfo *info) switch(info->type) { case ERRF_ERRTYPE_CARD_REMOVED: - desc = "The Game Card was removed."; + desc = "The card was removed."; break; case ERRF_ERRTYPE_MEM_CORRUPT: desc = "The System Memory has been damaged."; diff --git a/sysmodules/rosalina/source/kernel_extension_setup.c b/sysmodules/rosalina/source/kernel_extension_setup.c deleted file mode 100644 index d0ed5fa..0000000 --- a/sysmodules/rosalina/source/kernel_extension_setup.c +++ /dev/null @@ -1,148 +0,0 @@ -/* -* This file is part of Luma3DS -* Copyright (C) 2016-2017 Aurora Wright, TuxSH -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Additional Terms 7.b and 7.c of GPLv3 apply to this file: -* * Requiring preservation of specified reasonable legal notices or -* author attributions in that material or in the Appropriate Legal -* Notices displayed by works containing it. -* * Prohibiting misrepresentation of the origin of that material, -* or requiring that modified versions of such material be marked in -* reasonable ways as different from the original version. -*/ - -#include "kernel_extension.h" -#include "kernel_extension_setup.h" - -#define MPCORE_REGS_BASE ((u32)PA_PTR(0x17E00000)) -#define MPCORE_GID_REGS_BASE (MPCORE_REGS_BASE + 0x1000) -#define MPCORE_GID_SGI (*(vu32 *)(MPCORE_GID_REGS_BASE + 0xF00)) - -struct Parameters -{ - void (*SGI0HandlerCallback)(struct Parameters *, u32 *); - void *interruptManager; - u32 *L2MMUTable; // bit31 mapping - - void (*initFPU)(void); - void (*mcuReboot)(void); - void (*coreBarrier)(void); - - u32 TTBCR; - u32 L1MMUTableAddrs[4]; - - u32 kernelVersion; - - struct CfwInfo - { - char magic[4]; - - u8 versionMajor; - u8 versionMinor; - u8 versionBuild; - u8 flags; - - u32 commitHash; - - u32 config; - } __attribute__((packed)) info; -}; - - -static void K_SGI0HandlerCallback(volatile struct Parameters *p) -{ - u32 L1MMUTableAddr; - vu32 *L1MMUTable; - u32 coreId; - - __asm__ volatile("cpsid aif"); // disable interrupts - - p->coreBarrier(); - - __asm__ volatile("mrc p15, 0, %0, c0, c0, 5" : "=r"(coreId)); - coreId &= 3; - - __asm__ volatile("mrc p15, 0, %0, c2, c0, 1" : "=r"(L1MMUTableAddr)); - L1MMUTableAddr &= ~0x3FFF; - p->L1MMUTableAddrs[coreId] = L1MMUTableAddr; - L1MMUTable = (vu32 *)(L1MMUTableAddr | (1 << 31)); - - // Actually map the kernel ext - u32 L2MMUTableAddr = (u32)(p->L2MMUTable) & ~(1 << 31); - L1MMUTable[0x40000000 >> 20] = L2MMUTableAddr | 1; - - __asm__ __volatile__("mcr p15, 0, %[val], c7, c10, 4" :: [val] "r" (0) : "memory"); - ((void (*)(volatile struct Parameters *))0x40000000)(p); - - p->coreBarrier(); -} - -static u32 ALIGN(0x400) L2MMUTableFor0x40000000[256] = { 0 }; -u32 TTBCR; -static void K_ConfigureSGI0(void) -{ - // see /patches/k11MainHook.s - u32 *off; - u32 *initFPU, *mcuReboot, *coreBarrier; - - // Search for stuff in the 0xFFFF0000 page - for(initFPU = (u32 *)0xFFFF0000; initFPU < (u32 *)0xFFFF1000 && *initFPU != 0xE1A0D002; initFPU++); - initFPU += 3; - - for(mcuReboot = initFPU; mcuReboot < (u32 *)0xFFFF1000 && *mcuReboot != 0xE3A0A0C2; mcuReboot++); - mcuReboot--; - coreBarrier = (u32 *)decodeARMBranch(mcuReboot - 4); - - for(off = mcuReboot; off < (u32 *)0xFFFF1000 && *off != 0x726C6468; off++); // "hdlr" - - volatile struct Parameters *p = (struct Parameters *)PA_FROM_VA_PTR(off); // Caches? What are caches? - p->SGI0HandlerCallback = (void (*)(struct Parameters *, u32 *))PA_FROM_VA_PTR(K_SGI0HandlerCallback); - p->L2MMUTable = (u32 *)PA_FROM_VA_PTR(L2MMUTableFor0x40000000); - p->initFPU = (void (*) (void))initFPU; - p->mcuReboot = (void (*) (void))mcuReboot; - p->coreBarrier = (void (*) (void))coreBarrier; - - __asm__ volatile("mrc p15, 0, %0, c2, c0, 2" : "=r"(TTBCR)); - p->TTBCR = TTBCR; - - p->kernelVersion = *(vu32 *)0x1FF80000; - - // Now let's configure the L2 table - - //4KB extended small pages: [SYS:RW USR:-- X TYP:NORMAL SHARED OUTER NOCACHE, INNER CACHED WB WA] - for(u32 offset = 0; offset < kernel_extension_size; offset += 0x1000) - L2MMUTableFor0x40000000[offset >> 12] = (u32)convertVAToPA(kernel_extension + offset) | 0x516; -} - -static void K_SendSGI0ToAllCores(void) -{ - MPCORE_GID_SGI = 0xF0000; // http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0360f/CACGDJJC.html -} - -static inline void flushAllCaches(void) -{ - svcUnmapProcessMemory(CUR_PROCESS_HANDLE, 0, 0); // this SVC flush both caches entirely (and properly) even when returing an error -} - -void installKernelExtension(void) -{ - svc0x2F(K_ConfigureSGI0); - flushAllCaches(); - svc0x2F(K_SendSGI0ToAllCores); - flushAllCaches(); - - *(volatile bool *)0x1FF81108 = true; -} diff --git a/sysmodules/rosalina/source/main.c b/sysmodules/rosalina/source/main.c index 7458cd6..1714101 100644 --- a/sysmodules/rosalina/source/main.c +++ b/sysmodules/rosalina/source/main.c @@ -33,7 +33,6 @@ #include "hbloader.h" #include "utils.h" #include "MyThread.h" -#include "kernel_extension_setup.h" #include "menus/process_patches.h" // this is called before main @@ -67,18 +66,15 @@ void __ctru_exit() __appExit(); __sync_fini(); __libc_fini_array(); - svcSleepThread(-1LL); // kernel-loaded sysmodules except PXI are not supposed to terminate anyways + for(;;) svcSleepThread(0); // kernel-loaded sysmodules except PXI are not supposed to terminate anyways svcExitProcess(); } void initSystem() { - __libc_init_array(); - HBLDR_3DSX_TID = HBLDR_DEFAULT_3DSX_TID; - installKernelExtension(); - + __libc_init_array(); __sync_init(); __appInit(); }