Skip to content

Instantly share code, notes, and snippets.

@SKGleba
Created September 3, 2022 15:39
Show Gist options
  • Save SKGleba/1b033c75494c5c4679983e4e8dcadc29 to your computer and use it in GitHub Desktop.
Save SKGleba/1b033c75494c5c4679983e4e8dcadc29 to your computer and use it in GitHub Desktop.
toggle use_qaf in syscon scratchpad, persists until power loss
#include <stdio.h>
#include <string.h>
#include <psp2kern/kernel/modulemgr.h>
#include <vitasdkkern.h>
void hexdump(uint8_t* data, int size) {
for (int i = 0; i < size; i -= -1) {
if (!(i % 0x10))
ksceDebugPrintf("\n %04X: ", i);
ksceDebugPrintf("%02X ", data[i]);
}
ksceDebugPrintf("\n");
}
int check_dipsw(int no, uint8_t* buf) {
return (*(uint32_t*)(buf + (no >> 5) * 4) >> (no & 31)) & 1;
}
int set_dipsw(int no, uint8_t* buf) {
*(uint32_t*)(buf + (no >> 5) * 4) = *(uint32_t*)(buf + (no >> 5) * 4) | 1 << (no & 0x1f);
return check_dipsw(no, buf);
}
int clear_dipsw(int no, uint8_t* buf) {
*(uint32_t*)(buf + (no >> 5) * 4) = *(uint32_t*)(buf + (no >> 5) * 4) & ~(1 << (no & 0x1f));
return check_dipsw(no, buf);
}
void _start() __attribute__((weak, alias("module_start")));
int module_start(SceSize argc, const void *args)
{
uint8_t cp_dipsw[0x20];
memset(cp_dipsw, 0, 0x20);
int ret = ksceSysconReadCommand(0xE0, cp_dipsw, 0x10); // sc_cmd_0x90(off, data, size)
ksceDebugPrintf("read_sc_scratch_E0 ret 0x%X\n", ret);
if (ret < 0)
return SCE_KERNEL_START_SUCCESS;
ret = ksceSysconReadCommand(0xF0, cp_dipsw + 0x10, 0x10); // sc_cmd_0x90(off, data, size)
ksceDebugPrintf("read_sc_scratch_F0 ret 0x%X\n", ret);
if (ret < 0)
return SCE_KERNEL_START_SUCCESS;
hexdump(cp_dipsw, 0x20);
ret = check_dipsw(0xF0, cp_dipsw);
ksceDebugPrintf("check_sc_dipsw ret 0x%X\n", ret);
if (ret) {
ksceDebugPrintf("clearing sc_dipsw 0xf0\n");
ret = clear_dipsw(0xF0, cp_dipsw);
ksceDebugPrintf("clear_sc_dipsw ret 0x%X\n", ret);
} else {
ksceDebugPrintf("setting sc_dipsw 0xf0\n");
ret = set_dipsw(0xF0, cp_dipsw);
ksceDebugPrintf("set_sc_dipsw ret 0x%X\n", ret);
}
hexdump(cp_dipsw, 0x20);
ret = ksceSysconSendCommand(0xE0, cp_dipsw, 0x10); // sc_cmd_0x91(off, data, size)
ksceDebugPrintf("write_sc_scratch_E0 ret 0x%X\n", ret);
ret = ksceSysconSendCommand(0xF0, cp_dipsw + 0x10, 0x10); // sc_cmd_0x91(off, data, size)
ksceDebugPrintf("write_sc_scratch_F0 ret 0x%X\n", ret);
return SCE_KERNEL_START_SUCCESS;
}
int module_stop(SceSize argc, const void *args)
{
return SCE_KERNEL_STOP_SUCCESS;
}
@SKGleba
Copy link
Author

SKGleba commented Sep 3, 2022

CMakeLists.txt :

cmake_minimum_required(VERSION 2.8)

set(CMAKE_SYSTEM_NAME "Generic")
set(CMAKE_C_COMPILER "arm-vita-eabi-gcc")
set(CMAKE_CXX_COMPILER "arm-vita-eabi-g++")

project(toggle_qaf)

set(CMAKE_C_FLAGS "-Wl,-q -Wall -O3 -std=gnu99")
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -std=c++11 -fno-rtti -fno-exceptions")

include_directories(
)

add_executable(kplugin.elf
	main.c
)

target_link_libraries(kplugin.elf
	SceDebugForDriver_stub
	SceSysconForDriver_stub
	SceSysclibForDriver_stub
)

set_target_properties(kplugin.elf
	PROPERTIES LINK_FLAGS "-nostdlib"
	COMPILE_FLAGS "-D__VITA_KERNEL__"
)

add_custom_target(toggle_qaf.skprx ALL
	COMMAND vita-elf-create -e ${CMAKE_SOURCE_DIR}/kplugin.yml kplugin.elf kplugin.velf
	COMMAND vita-make-fself -c kplugin.velf toggle_qaf.skprx
)
add_dependencies(toggle_qaf.skprx kplugin.elf)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment