]> Chaos Git - corbenik/corbenik.git/commitdiff
Experimental shite.
authorchaoskagami <chaos.kagami@gmail.com>
Mon, 23 May 2016 17:56:57 +0000 (13:56 -0400)
committerchaoskagami <chaos.kagami@gmail.com>
Mon, 23 May 2016 17:56:57 +0000 (13:56 -0400)
The kernel doesn't get passed CPU flags from the functions called here.
Assuming the kernel doesn't seek backwards from the exheader pointer,
the CPU state should already have been set by AM, which means loader
can override what was previously set.

That being the case, if I am correct, setting the CPU speed from
loader should technically persist to application launch. This needs
testing, obviously, but I believe granular CPU speed control is
possible from here.

external/loader/source/exheader.h
external/loader/source/ksetstate.s [new file with mode: 0644]
external/loader/source/loader.c
external/loader/source/patcher.c
external/loader/source/patcher.h
host/compile_header.c
modules/Makefile
modules/template/Makefile

index be23527c6d8481f1b684e30e50d9aa5baec33ac4..dccb083144162805c40f29019ebc685a6ad2ed60 100644 (file)
@@ -50,6 +50,8 @@ typedef struct
        u8 otherattributes;
 } PACKED exheader_storageinfo;
 
+// New3DS speed is flags[1]:1
+
 typedef struct
 {
        u64 programid;
@@ -75,18 +77,12 @@ typedef struct
 
 typedef struct
 {
-       // systemcontrol info {
-       //   coreinfo {
        exheader_codesetinfo codesetinfo;
        exheader_dependencylist deplist;
-       //   }
        exheader_systeminfo systeminfo;
-       // }
-       // accesscontrolinfo {
        exheader_arm11systemlocalcaps arm11systemlocalcaps;
        exheader_arm11kernelcapabilities arm11kernelcaps;
        exheader_arm9accesscontrol arm9accesscontrol;
-       // }
        struct {
                u8 signature[0x100];
                u8 ncchpubkeymodulus[0x100];
diff --git a/external/loader/source/ksetstate.s b/external/loader/source/ksetstate.s
new file mode 100644 (file)
index 0000000..51f0bc4
--- /dev/null
@@ -0,0 +1,5 @@
+.section .text
+.global KernelSetState
+KernelSetState:
+       svc 0x7C // KernelSetState
+       bx lr // return;
index c6075e607e127207c8a95f7e786d971468d5154a..6fc32d27989bc339c0106c8ee239d3930f547d8e 100644 (file)
@@ -184,6 +184,16 @@ static Result loader_GetProgramInfo(exheader_header *exheader, u64 prog_handle)
   }
 }
 
+extern void KernelSetState(unsigned int, unsigned int, unsigned int, unsigned int);
+
+static void ConfigureNew3DSCPU(u8 mode) {
+  // 10 -> r0 (Type)
+  // mode -> r1 (Mode)
+  // svc 0x7C
+
+  KernelSetState(10, mode, 0, 0); // Yes, we syscall directly. Problem?
+}
+
 static Result loader_LoadProcess(Handle *process, u64 prog_handle)
 {
   Result res;
@@ -229,6 +239,15 @@ static Result loader_LoadProcess(Handle *process, u64 prog_handle)
 
   load_config(); // First order of business - we need the config file.
 
+  // Check and set the CPU mode. Possible values: 0 - Keep o3ds speed, 1 - n3ds speed, -1 force o3ds
+  // This is A-OK because the CPU speed parameter isn't passed through to any kernel function; meaning it has already been set.
+  u8 n3ds_mode = g_exheader.arm11systemlocalcaps.flags[1] & 0x3;
+  u8 cpu_mode  = get_cpumode(progid);
+  if (cpu_mode != 0xFF) { // Skip?
+    u8 mode = n3ds_mode | cpu_mode; // Keep flags set by exheader.
+    ConfigureNew3DSCPU(mode); // We do not use PXIPM because we are a sysmodule. It doesn't make sense.
+  }
+
   // What the addressing info would be if not for expansion. This is passed to patchCode.
   original_vaddr.text_size = (g_exheader.codesetinfo.text.codesize + 4095) >> 12; // (Text size + one page) >> page size
   original_vaddr.ro_size = (g_exheader.codesetinfo.ro.codesize + 4095) >> 12;
@@ -554,7 +573,7 @@ int main()
         g_active_handles--;
         reply_target = 0;
       }
-      else 
+      else
       {
         svcBreak(USERBREAK_ASSERT);
       }
index ef0cd652aad1be8aab7224948e40f186552c7b6a..f76cf25c6252b78cae6d587f60eb263404959d70 100644 (file)
@@ -458,3 +458,8 @@ u32 get_ro_extend(u64 progId, u32 size_orig) {
 u32 get_data_extend(u64 progId, u32 size_orig) {
        return 0; // Stub - nothing needs this yet
 }
+
+// Get CPU speed for progId.
+u8 get_cpumode(u64 progId) {
+  return 0xff; // Skip.
+}
index ad83c8dfa7eb8e0058d3751fec2af694b252d39b..5b56b17d8223ee2af179f76b63aa720a7b77191d 100644 (file)
@@ -13,3 +13,5 @@ u32 get_data_extend(u64 progId, u32 size_orig);
 void load_config();
 
 u32 patchMemory(u8 *start, u32 size, const void *pattern, u32 patSize, int offset, const void *replace, u32 repSize, u32 count);
+
+u8 get_cpumode(u64 progId);
index 049ff7d1c71c746e1a556c51fea9acffe4d45ccd..8ec44546625d72b3f9057e09ee5ae95b304d3cea 100644 (file)
@@ -4,7 +4,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "../../../source/patch_format.h"
+#include "../source/patch_format.h"
 
 void read_file_u64(char* name, uint64_t* to) {
        FILE* hdl = fopen(name, "rb");
index a9afaaa8fff065b7ffa9dd13b1afa665f80f4f2f..4a85dfd2ef507062b175ffc7581ecaa5cda3bbf1 100644 (file)
@@ -1,25 +1,16 @@
 .PHONY: all copyout
-all: template signatures
+all: template
        mkdir -p ../out/corbenik/bin
        cp template/out/patch.vco ../out/corbenik/bin/example.vco
-       cp signatures/out/patch.vco ../out/corbenik/bin/signatures.vco
 
 .PHONY: clean
-clean: clean_template clean_signatures
+clean: clean_template
        rm -rf ../out/corbenik/bin
 
 .PHONY: template
 template:
        make -C template
 
-.PHONY: signatures
-signatures:
-       make -C signatures
-
 .PHONY: clean_template
 clean_template:
        make -C template clean
-
-.PHONY: clean_signatures
-clean_signatures:
-       make -C signatures clean
index de1a361ae0e02ae94624335684eccb12d484f36c..972f9eed1dcbf2088fd56d0343d1ef2b9ae3f03a 100644 (file)
@@ -31,7 +31,7 @@ patchbin: tool $(dir_out)/patch.bin
 
 .PHONY: tool
 tool:
-       $(HOST_CC) -o compile_header tool/compile_header.c
+       $(HOST_CC) -o compile_header ../../host/compile_header.c
 
 
 .PHONY: clean