mirror of
https://github.com/wiiu-env/homebrew_launcher.git
synced 2024-11-05 20:45:08 +01:00
208 lines
5.1 KiB
ArmAsm
208 lines
5.1 KiB
ArmAsm
#if ((VER == 532) || (VER == 540))
|
|
#define BAT_SETUP_HOOK_ADDR 0xFFF1D638
|
|
|
|
# not all of those NOP address are required for every firmware
|
|
# mainly these should stop the kernel from removing our IBAT4 and DBAT5
|
|
#define BAT_SET_NOP_ADDR_1 0xFFF06A14
|
|
#define BAT_SET_NOP_ADDR_2 0xFFF06AA0
|
|
#define BAT_SET_NOP_ADDR_3 0xFFF003C8
|
|
#define BAT_SET_NOP_ADDR_4 0xFFF003CC
|
|
#define BAT_SET_NOP_ADDR_5 0xFFF1D720
|
|
#define BAT_SET_NOP_ADDR_6 0xFFF1D73C
|
|
#define BAT_SET_NOP_ADDR_7 0xFFF1D840
|
|
|
|
#define BAT_SET_NOP_ADDR_8 0xFFEE10B8
|
|
#define BAT_SET_NOP_ADDR_9 0xFFEE10BC
|
|
|
|
#elif ((VER == 500) || (VER == 510))
|
|
#define BAT_SETUP_HOOK_ADDR 0xFFF1D518
|
|
#elif ( (VER == 400) || (VER == 410) )
|
|
#define BAT_SETUP_HOOK_ADDR 0xFFF1AD00
|
|
#else
|
|
#error Please define valid values for kernel setup.
|
|
#endif
|
|
|
|
#ifdef USE_SD_LOADER
|
|
#define BAT_SETUP_HOOK_ENTRY 0x00800000
|
|
#else
|
|
#define BAT_SETUP_HOOK_ENTRY (0x00800000 + 0x2000)
|
|
#endif
|
|
|
|
#define BAT4U_VAL 0x008000FF
|
|
#define BAT4L_VAL 0x30800012
|
|
|
|
#define SET_R4_TO_ADDR(addr) \
|
|
lis r3, addr@h ; \
|
|
ori r3, r3, addr@l ; \
|
|
stw r4, 0(r3) ; \
|
|
dcbf 0, r3 ; \
|
|
icbi 0, r3 ;
|
|
|
|
.globl Syscall_0x36
|
|
Syscall_0x36:
|
|
mflr r0
|
|
stwu r1, -0x10(r1)
|
|
stw r30, 0x4(r1)
|
|
stw r31, 0x8(r1)
|
|
mr r5, r0
|
|
mr r6, r1
|
|
li r0, 0x3600
|
|
sc
|
|
nop
|
|
mr r0, r5
|
|
mr r1, r6
|
|
lwz r30, 0x04(r1)
|
|
lwz r31, 0x08(r1)
|
|
addi r1, r1, 0x10
|
|
mtlr r0
|
|
blr
|
|
|
|
.globl KernelPatches
|
|
KernelPatches:
|
|
# store the old DBAT0
|
|
mfdbatu r30, 0
|
|
mfdbatl r31, 0
|
|
|
|
# memory barrier
|
|
eieio
|
|
isync
|
|
|
|
# setup DBAT0 for access to kernel code memory
|
|
lis r3, 0xFFF0
|
|
ori r3, r3, 0x0002
|
|
mtdbatu 0, r3
|
|
lis r3, 0xFFF0
|
|
ori r3, r3, 0x0032
|
|
mtdbatl 0, r3
|
|
|
|
# memory barrier
|
|
eieio
|
|
isync
|
|
|
|
# SaveAndResetDataBATs_And_SRs hook setup, but could be any BAT function though
|
|
# just chosen because its simple
|
|
lis r3, BAT_SETUP_HOOK_ADDR@h
|
|
ori r3, r3, BAT_SETUP_HOOK_ADDR@l
|
|
|
|
# make the kernel setup our section in IBAT4 and
|
|
# jump to our function to restore the replaced instructions
|
|
lis r4, 0x3ce0 # lis r7, BAT4L_VAL@h
|
|
ori r4, r4, BAT4L_VAL@h
|
|
stw r4, 0x00(r3)
|
|
lis r4, 0x60e7 # ori r7, r7, BAT4L_VAL@l
|
|
ori r4, r4, BAT4L_VAL@l
|
|
stw r4, 0x04(r3)
|
|
lis r4, 0x7cf1 # mtspr 561, r7
|
|
ori r4, r4, 0x8ba6
|
|
stw r4, 0x08(r3)
|
|
lis r4, 0x3ce0 # lis r7, BAT4U_VAL@h
|
|
ori r4, r4, BAT4U_VAL@h
|
|
stw r4, 0x0C(r3)
|
|
lis r4, 0x60e7 # ori r7, r7, BAT4U_VAL@l
|
|
ori r4, r4, BAT4U_VAL@l
|
|
stw r4, 0x10(r3)
|
|
lis r4, 0x7cf0 # mtspr 560, r7
|
|
ori r4, r4, 0x8ba6
|
|
stw r4, 0x14(r3)
|
|
lis r4, 0x7c00 # eieio
|
|
ori r4, r4, 0x06ac
|
|
stw r4, 0x18(r3)
|
|
lis r4, 0x4c00 # isync
|
|
ori r4, r4, 0x012c
|
|
stw r4, 0x1C(r3)
|
|
lis r4, 0x7ce8 # mflr r7
|
|
ori r4, r4, 0x02a6
|
|
stw r4, 0x20(r3)
|
|
lis r4, (BAT_SETUP_HOOK_ENTRY | 0x48000003)@h # bla BAT_SETUP_HOOK_ENTRY
|
|
ori r4, r4, (BAT_SETUP_HOOK_ENTRY | 0x48000003)@l
|
|
stw r4, 0x24(r3)
|
|
|
|
# flush and invalidate the replaced instructions
|
|
lis r3, (BAT_SETUP_HOOK_ADDR & ~31)@h
|
|
ori r3, r3, (BAT_SETUP_HOOK_ADDR & ~31)@l
|
|
dcbf 0, r3
|
|
icbi 0, r3
|
|
lis r3, ((BAT_SETUP_HOOK_ADDR + 0x20) & ~31)@h
|
|
ori r3, r3, ((BAT_SETUP_HOOK_ADDR + 0x20) & ~31)@l
|
|
dcbf 0, r3
|
|
icbi 0, r3
|
|
sync
|
|
|
|
# setup IBAT4 for core 1 at this position (not really required but wont hurt)
|
|
# IBATL 4
|
|
lis r3, BAT4L_VAL@h
|
|
ori r3, r3, BAT4L_VAL@l
|
|
mtspr 561, r3
|
|
|
|
# IBATU 4
|
|
lis r3, BAT4U_VAL@h
|
|
ori r3, r3, BAT4U_VAL@l
|
|
mtspr 560, r3
|
|
|
|
# memory barrier
|
|
eieio
|
|
isync
|
|
|
|
# write "nop" to some positions
|
|
lis r4, 0x6000
|
|
# nop on IBATU 4 and DBAT 5 set/reset
|
|
#ifdef BAT_SET_NOP_ADDR_1
|
|
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_1)
|
|
#endif
|
|
#ifdef BAT_SET_NOP_ADDR_2
|
|
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_2)
|
|
#endif
|
|
#ifdef BAT_SET_NOP_ADDR_3
|
|
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_3)
|
|
#endif
|
|
#ifdef BAT_SET_NOP_ADDR_4
|
|
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_4)
|
|
#endif
|
|
#ifdef BAT_SET_NOP_ADDR_5
|
|
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_5)
|
|
#endif
|
|
#ifdef BAT_SET_NOP_ADDR_6
|
|
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_6)
|
|
#endif
|
|
#ifdef BAT_SET_NOP_ADDR_7
|
|
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_7)
|
|
#endif
|
|
|
|
#if (defined(BAT_SET_NOP_ADDR_8) && defined(BAT_SET_NOP_ADDR_9))
|
|
# memory barrier
|
|
eieio
|
|
isync
|
|
|
|
# setup DBAT0 for access to kernel code memory
|
|
lis r3, 0xFFEE
|
|
ori r3, r3, 0x0002
|
|
mtdbatu 0, r3
|
|
lis r3, 0xFFEE
|
|
ori r3, r3, 0x0032
|
|
mtdbatl 0, r3
|
|
|
|
# memory barrier
|
|
eieio
|
|
isync
|
|
|
|
# write "nop" to some positions
|
|
lis r4, 0x6000
|
|
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_8)
|
|
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_9)
|
|
#endif
|
|
|
|
# memory barrier
|
|
eieio
|
|
isync
|
|
|
|
# restore DBAT 0 and return from interrupt
|
|
mtdbatu 0, r30
|
|
mtdbatl 0, r31
|
|
|
|
# memory barrier
|
|
eieio
|
|
isync
|
|
|
|
rfi
|
|
|