diff --git a/resources/extldr/Makefile b/resources/extldr/Makefile index 060b382a..6c300489 100644 --- a/resources/extldr/Makefile +++ b/resources/extldr/Makefile @@ -19,7 +19,7 @@ TARGET_LINKED = boot.elf TARGET = extldr.bin CFILES = string.c ios.c utils.c cache.c usbgecko.c main.c -OBJS = crt0.o string.o ios.o utils.o cache.o usbgecko.o main.o +OBJS = crt0.o memory.o string.o ios.o utils.o cache.o usbgecko.o main.o DEPDIR = .deps diff --git a/resources/extldr/crt0.s b/resources/extldr/crt0.s index 82d1aaa2..90e2e04d 100644 --- a/resources/extldr/crt0.s +++ b/resources/extldr/crt0.s @@ -9,31 +9,135 @@ .set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29; .set r30,30; .set r31,31; -.extern _main +#include "hw.h" + .globl _start _start: - # Disable interrupts - mfmsr r3 - rlwinm r3,r3,0,17,15 - mtmsr r3 + mfmsr r3 + rlwinm r4,r3,0,17,15 # MSR_EE + rlwinm r4,r4,0,26,24 # MSR_IP + mtmsr r4 isync + lis r3,_setup@h + ori r3,r3,_setup@l + clrlwi r3,r3,2 + mtsrr0 r3 + mfmsr r3 + li r4,MSR_IR|MSR_DR + andc r3,r3,r4 + mtsrr1 r3 + rfi - # Reset our registers - bl __init_registers +#0001 0001 0000 1100 0110 0100 +#BHT,BTIC,DCFA,DCFI,ICFI,NHR,DPM +_setup: + lis r3,0x11 + ori r3,r3,0xC64 #0x110C64 + mtspr rHID0,r3 + isync + li r4,MSR_FP + mtmsr r4 + ori r3,r3,HID0_ICE|HID0_DCE + mtspr rHID0,r3 + isync + li r0,0 + mtibatu 0,r0 + mtibatu 1,r0 + mtibatu 2,r0 + mtibatu 3,r0 + mtdbatu 0,r0 + mtdbatu 1,r0 + mtdbatu 2,r0 + mtdbatu 3,r0 + #mtibatl 0,r0 + mtspr 560,r0 + mtspr 562,r0 + mtspr 564,r0 + mtspr 566,r0 + mtspr 568,r0 + mtspr 570,r0 + mtspr 572,r0 + mtspr 574,r0 + isync + lis r0,0x8000 + mtsr 0,r0 + mtsr 1,r0 + mtsr 2,r0 + mtsr 3,r0 + mtsr 4,r0 + mtsr 5,r0 + mtsr 6,r0 + mtsr 7,r0 + mtsr 8,r0 + mtsr 9,r0 + mtsr 10,r0 + mtsr 11,r0 + mtsr 12,r0 + mtsr 13,r0 + mtsr 14,r0 + mtsr 15,r0 + isync + li r3,2 #0x00000000|PP=2 + lis r4,0x8000 + ori r4,r4,0x1FFF #0x80000000|256Mbytes|VS|VP + mtibatl 0,r3 + mtibatu 0,r4 + mtdbatl 0,r3 + mtdbatu 0,r4 + isync + addis r3,r3,0x1000 #0x10000000|PP=2 + addis r4,r4,0x1000 #0x90000000|256Mbytes|VS|VP + mtspr 561,r3 + mtspr 560,r4 + mtspr 569,r3 + mtspr 568,r4 + isync + li r3,0x2A #0x00000000|I|G|PP=2 + lis r4,0xC000 + ori r4,r4,0x1FFF #0xC0000000|256Mbytes|VS|VP + mtdbatu 1,r3 + mtdbatu 1,r4 + isync + addis r3,r3,0x1000 #0x10000000|I|G|PP=2 + addis r4,r4,0x1000 #0xD0000000|256Mbytes|VS|VP + mtspr 571,r3 + mtspr 570,r4 + isync + lis r3,0x8200 + mtspr 1011,r3 + lis r3,_init@h + ori r3,r3,_init@l + mtsrr0 r3 + mfmsr r3 + ori r3,r3,MSR_DR|MSR_IR + mtsrr1 r3 + rfi - # Clear BSS. - lis r3,__bss_start@h - ori r3,r3,__bss_start@l +.extern _main +#TODO - fixup memset +_init: + bl __init_registers + bl __init_memory + bl __init_syscall + bl __init_sprs + lis r3,__bss_start@h + ori r3,r3,__bss_start@l + li r4,0 + lis r5,__bss_end@h + ori r5,r5,__bss_end@l + subf r5,r3,r5 + bl _memset + lis r3,__stack_end@h + ori r3,r3,__stack_end@l li r4,0 - lis r5,__bss_end@h - ori r5,r5,__bss_end@l + lis r5,__stack_top@h + ori r5,r5,__stack_top@l subf r5,r3,r5 bl _memset + bl _main +0: + b 0b - # Go! - bl _main - -#thanks to megazig for that __init_registers: li r0,0 li r3,0 @@ -74,3 +178,79 @@ __init_registers: lis r13,0 ori r13,r13,0x8000 blr + +_memset: + clrlwi. r6,r5,29 + rlwinm r5,r5,30,2,31 + addi r3,r3,-4 + mtctr r5 +0: + stwu r4,4(r3) + bdnz+ 0b + cmplwi r6,0 + beq- 2f +1: + stbu r4,1(r3) + addic. r6,r6,-1 + bne+ 1b +2: + blr + +__init_memory: + mflr r0 + stw r0, 0x04(r1) + stwu r1,-0x10(r1) + stw r31,0x0C(r1) + mfspr r3,rHID0 + rlwinm r0,r3,0,16,16 #HID0[ICE] + cmplwi r0,0 + bne- 0f + bl ICacheEnable +0: + mfspr r3,rHID0 + rlwinm r0,r3,0,17,17 #HID0[DCE] + cmplwi r0,0 + bne- 1f + bl DCacheEnable +1: + mfl2cr r3 + rlwinm r0,r3,0,0,0 #L2CR[L2E] + cmplwi r0,0 + bne- 2f + bl L2_Init + bl L2_Enable +2: + lwz r0, 0x14(r1) + lwz r31,0x0C(r1) + addi r1,r1,0x10 + mtlr r0 + blr + +__init_sprs: + mflr r0 + stw r0, 0x04(r1) + stwu r1,-0x18(r1) + stw r31,0x14(r1) + stw r30,0x10(r1) + stw r29,0x0C(r1) + li r3,0 + mtmmcr0 r3 + mtmmcr1 r3 + mtpmc1 r3 + mtpmc2 r3 + mtpmc3 r3 + mtpmc4 r3 + mfspr r3,rHID0 + ori r3,r3,HID0_SPD #HID0[SPD] + mtspr rHID0,r3 + mfspr r3,rHID2 + rlwinm r3,r3,0,2,0 #HID2[WPE] + mtspr rHID2,r3 + lwz r0, 0x1C(r1) + lwz r31,0x14(r1) + lwz r30,0x10(r1) + lwz r29,0x0C(r1) + addi r1,r1,0x18 + mtlr r0 + blr + diff --git a/resources/extldr/hw.h b/resources/extldr/hw.h new file mode 100644 index 00000000..f4486baa --- /dev/null +++ b/resources/extldr/hw.h @@ -0,0 +1,107 @@ +#ifndef __HW_H__ +#define __HW_H__ + +#define MSR_POW (1<<18) +#define MSR_ILE (1<<16) +#define MSR_EE (1<<15) +#define MSR_PR (1<<14) +#define MSR_FP (1<<13) +#define MSR_ME (1<<12) +#define MSR_FE0 (1<<11) +#define MSR_SE (1<<10) +#define MSR_BE (1<< 9) +#define MSR_FE1 (1<< 8) +#define MSR_IP (1<< 6) +#define MSR_IR (1<< 5) +#define MSR_DR (1<< 4) +#define MSR_RI (1<< 1) +#define MSR_LE (1<< 0) + +#define HID0_EMCP (1<<31) +#define HID0_DBP (1<<30) +#define HID0_EBA (1<<29) +#define HID0_EBD (1<<28) +#define HID0_BCLK (1<<27) +#define HID0_ECLK (1<<25) +#define HID0_PAR (1<<24) +#define HID0_DOZE (1<<23) +#define HID0_NAP (1<<22) +#define HID0_SLEEP (1<<21) +#define HID0_DPM (1<<20) +#define HID0_NHR (1<<16) +#define HID0_ICE (1<<15) +#define HID0_DCE (1<<14) +#define HID0_ILOCK (1<<13) +#define HID0_DLOCK (1<<12) +#define HID0_ICFI (1<<11) +#define HID0_DCFI (1<<10) +#define HID0_SPD (1<< 9) +#define HID0_IFEM (1<< 8) +#define HID0_SGE (1<< 7) +#define HID0_DCFA (1<< 6) +#define HID0_BTIC (1<< 5) +#define HID0_ABE (1<< 3) +#define HID0_BHT (1<< 2) +#define HID0_NOOPTI (1<< 0) + +#define HID2_LSQE (1<<31) +#define HID2_WPE (1<<30) +#define HID2_PSE (1<<29) +#define HID2_LCE (1<<28) + +#define L2CR_L2E (1<<31) +#define L2CR_L2CE (1<<30) +#define L2CR_L2DO (1<<22) +#define L2CR_L2I (1<<21) +#define L2CR_L2WT (1<<19) +#define L2CR_L2TS (1<<18) +#define L2CR_L2IP (1<< 0) + +#define DMAU_MEM_ADDR_MASK 0xFFFFFFE0 +#define DMAU_LENU(x) (x & 0x1F) +#define DMAL_LC_ADDR_MASK 0xFFFFFFE0 +#define DMAL_LD (1<< 4) +#define DMAL_LENL(x) (x & 0xC) +#define DMAL_T (1<< 1) +#define DMAL_F (1<< 0) + +#define BATU_BEPI_MASK 0xFFFC0000 +#define BATU_BL(x) (x & 0x00001FFC) +#define BATU_VS (1<< 1) +#define BATU_VP (1<< 0) +#define BATL_BRPN_MASK 0xFFFC0000 +#define BATL_WIMG_MASK 0x78 +#define BATL_PP (1<< 0) + +// BATU - 0x80001FFF == 256Mbytes +// 1000 0000 000x xxx0 0001 1111 1111 11xx +// 0x80000000|256Mbytes|VS|VP +// BATL - 0x00000002 +// 0000 0000 0000 000x xxxx xxxx x000 0x10 +// PP=b10 +// +// BATU - 0xC0001FFF == 256Mbytes +// BATL - 0x0000002a +// 0000 0000 0000 000x xxxx xxxx x010 1x10 +// WIMG=b0101|PP=b10 +// + +#define rHID2 920 +#define rDMAU 922 +#define rDMAL 923 +#define rHID0 1008 +#define rHID1 1009 +#define rHID4 1011 + +/* + * Upper PTE + * 0|1-24|25|26-31 + * V|VSID|H |API + * + * Lower PTE + * 0-19|20-22|23|24|25-28|29|30-31 + * RPN |000 |R |C |WIMG |0 |PP +*/ + +#endif + diff --git a/resources/extldr/ios.c b/resources/extldr/ios.c index d2df75b2..47938337 100644 --- a/resources/extldr/ios.c +++ b/resources/extldr/ios.c @@ -84,15 +84,6 @@ static void ipc_wait_reply(void) ios_delay(); } -static u32 ipc_wait(void) -{ - u32 ret; - while(!((ret = ipc_read(1)) & 0x6)) - ; - ios_delay(); - return ret; -} - // Mid-level IPC access. struct ipc { @@ -118,27 +109,6 @@ static void ipc_send_request(void) ipc_bell(2); } -static int ipc_send_twoack(void) -{ - sync_after_write(&ipc, 0x40); - ios_delay(); - - ipc_write(0, (u32)virt_to_phys(&ipc)); - ipc_bell(1); - - if(ipc_wait() & 4) - return 0; - - ipc_bell(2); - - if(ipc_wait() & 4) - return 0; - - ipc_bell(2); - ipc_bell(8); - return 1; -} - static void ipc_recv_reply(void) { for (;;) @@ -162,49 +132,6 @@ static void ipc_recv_reply(void) // High-level IPC access. -void ios_cleanup() -{ - int loops = 0xA; - do - { - if ((ipc_read(1) & 0x22) == 0x22) - { - ipc_write(1, (ipc_read(1)&~0x30) | 2); - } - if ((ipc_read(1) & 0x14) == 0x14) - { - ipc_read(2); - ipc_write(1, (ipc_read(1)&~0x30) | 4); - ipc_write(12, 0x4000); - ipc_write(1, (ipc_read(1)&~0x30) | 8); - } - ipc_write(12, 0x4000); - usleep(1000); - loops--; - } while(loops != 0); - - int fd; - for (fd = 0; fd != 31; fd++) - { - ios_close(fd); - } -} - -int ios_open(const char *filename, u32 mode) -{ - sync_after_write((void*)filename, 0x20); - - ipc.cmd = 1; - ipc.fd = 0; - ipc.arg[0] = (u32)virt_to_phys(filename); - ipc.arg[1] = mode; - - ipc_send_request(); - ipc_recv_reply(); - - return ipc.result; -} - int ios_close(int fd) { ipc.cmd = 2; @@ -216,77 +143,11 @@ int ios_close(int fd) return ipc.result; } -static void ios_std(int fd, int cmd) +void ios_cleanup() { - ipc.cmd = cmd; - ipc.fd = fd; - - ipc_send_request(); - ipc_recv_reply(); -} - -int ios_read(int fd, void *buf, u32 size) -{ - ipc.arg[0] = (u32)virt_to_phys(buf); - ipc.arg[1] = size; - - ios_std(fd, 3); - - sync_before_read(buf, size); - - return ipc.result; -} - -int _ios_ioctlv(int fd, u32 n, u32 in_count, u32 out_count, struct ioctlv *vec, int reboot) -{ - u32 i; - - for (i = 0; i < in_count + out_count; i++) + int fd; + for (fd = 0; fd != 31; fd++) { - if (vec[i].data) - { - sync_after_write(vec[i].data, vec[i].len); - vec[i].data = (void *)virt_to_phys(vec[i].data); - } + ios_close(fd); } - - sync_after_write(vec, (in_count + out_count) * sizeof *vec); - - ipc.cmd = 7; - ipc.fd = fd; - ipc.arg[0] = n; - ipc.arg[1] = in_count; - ipc.arg[2] = out_count; - ipc.arg[3] = (u32)virt_to_phys(vec); - - if(reboot) - { - if(ipc_send_twoack()) - return 0; - } - else - ipc_send_request(); - ipc_recv_reply(); - - for(i = in_count; i < in_count + out_count; i++) - { - if (vec[i].data) - { - vec[i].data = phys_to_virt((u32)vec[i].data); - sync_before_read(vec[i].data, vec[i].len); - } - } - if(reboot && (ipc.result >= 0)) - return -100; - return ipc.result; -} - -int ios_ioctlv(int fd, u32 n, u32 in_count, u32 out_count, struct ioctlv *vec) -{ - return _ios_ioctlv(fd, n, in_count, out_count, vec, 0); -} - -int ios_ioctlvreboot(int fd, u32 n, u32 in_count, u32 out_count, struct ioctlv *vec) -{ - return _ios_ioctlv(fd, n, in_count, out_count, vec, 1); } diff --git a/resources/extldr/ios.h b/resources/extldr/ios.h index 1b11c957..4b2b9da9 100644 --- a/resources/extldr/ios.h +++ b/resources/extldr/ios.h @@ -10,19 +10,7 @@ // Copyright 2008-2009 Hector Martin -#include "types.h" - -struct ioctlv { - void *data; - u32 len; -}; - void ios_cleanup(void); -int ios_open(const char *filename, u32 mode); -int ios_close(int fd); -int ios_ioctlv(int fd, u32 n, u32 in_count, u32 out_count, struct ioctlv *vec); -int ios_ioctlvreboot(int fd, u32 n, u32 in_count, u32 out_count, struct ioctlv *vec); -int ios_read(int fd, void *buf, u32 size); #endif diff --git a/resources/extldr/link.ld b/resources/extldr/link.ld index fc419114..1a1d9a4d 100644 --- a/resources/extldr/link.ld +++ b/resources/extldr/link.ld @@ -20,6 +20,7 @@ SECTIONS { __bss_end = .; . = ALIGN(0x40); + __stack_end = .; .stack : { . += 0x8000; __stack_top = .; diff --git a/resources/extldr/main.c b/resources/extldr/main.c index 321db8bb..9a9268a2 100644 --- a/resources/extldr/main.c +++ b/resources/extldr/main.c @@ -3,14 +3,13 @@ #include "cache.h" #include "ios.h" #include "usbgecko.h" -u8 *start = (u8*)0x80A80000; -u8 *buffer = (u8*)0x90110000; void _main(void) { usbgecko_init(); ios_cleanup(); //hopefully that wont disable any features gprintf("Copying External Booter...\n"); - _memcpy(start, buffer, 0xF0000); //960kb safe copying of booter + u8 *start = (u8*)0x80A80000; + _memcpy(start, (u8*)0x90110000, 0xF0000); //960kb safe copying of booter sync_after_write(start, 0xF0000); gprintf("Done! Jumping to Entrypoint...\n"); asm volatile ( @@ -20,4 +19,21 @@ void _main(void) "mtlr %r3\n" "blr\n" ); +} +#include "memory.h" +#define SYSCALL_VECTOR ((u8*)0x80000C00) +void __init_syscall() +{ + u8* sc_vector = SYSCALL_VECTOR; + u32 bytes = (u32)DCFlashInvalidate - (u32)__temp_abe; + u8* from = (u8*)__temp_abe; + for ( ; bytes != 0 ; --bytes ) + { + *sc_vector = *from; + sc_vector++; + from++; + } + + sync_after_write(SYSCALL_VECTOR, 0x100); + ICInvalidateRange(SYSCALL_VECTOR, 0x100); } \ No newline at end of file diff --git a/resources/extldr/memory.S b/resources/extldr/memory.S new file mode 100644 index 00000000..1cb1c917 --- /dev/null +++ b/resources/extldr/memory.S @@ -0,0 +1,192 @@ +.set r0,0; .set r1,1; .set r2,2; .set r3,3; .set r4,4; +.set r5,5; .set r6,6; .set r7,7; .set r8,8; .set r9,9; +.set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14; +.set r15,15; .set r16,16; .set r17,17; .set r18,18; .set r19,19; +.set r20,20; .set r21,21; .set r22,22; .set r23,23; .set r24,24; +.set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29; +.set r30,30; .set r31,31; + +#include "hw.h" + +.global __temp_abe +__temp_abe: + mfspr r3,rHID0 + ori r4,r3,HID0_ABE #HID0[ABE] + mtspr rHID0,r4 + isync + sync + mtspr rHID0,r3 + rfi + +.global DCFlashInvalidate +DCFlashInvalidate: + nop + mfspr r3,rHID0 + ori r3,r3,HID0_DCFI #HID0[DCFI] + mtspr rHID0,r3 + blr + +.global DCacheEnable +DCacheEnable: + sync + mfspr r3,rHID0 + ori r3,r3,HID0_DCE #HID0[DCE] + mtspr rHID0,r3 + blr + +.global DCBlockInvalidate +DCBlockInvalidate: + cmplwi r4,0 + blelr + clrlwi. r5,r3,27 + beq- 0f + addi r4,r4,0x20 +0: + addi r4,r4,0x1F + rlwinm r4,r4,27,5,31 + mtctr r4 +1: + dcbi r0,r3 + addi r3,r3,0x20 + bdnz+ 1b + blr + +DCBlockFlushSc: + cmplwi r4,0 + blelr + clrlwi. r5,r3,27 + beq- 0f + addi r4,r4,0x20 +0: + addi r4,r4,0x1F + rlwinm r4,r4,27,5,31 + mtctr r4 +1: + dcbf r0,r3 + addi r3,r3,0x20 + bdnz+ 1b + sc + blr + +DCBlockFlush: + cmplwi r4,0 + blelr + clrlwi. r5,r3,27 + beq- 0f + addi r4,r4,0x20 +0: + addi r4,r4,0x1F + rlwinm r4,r4,27,5,31 + mtctr r4 +1: + dcbf r0,r3 + addi r3,r3,0x20 + bdnz+ 1b + blr + +.global ICInvalidateRange +ICInvalidateRange: + cmplwi r4,0 + blelr + clrlwi. r5,r3,27 + beq- 0f + addi r4,r4,0x20 +0: + addi r4,r4,0x1F + rlwinm r4,r4,27,5,31 + mtctr r4 +1: + icbi r0,r3 + addi r3,r3,0x20 + bdnz+ 1b + sync + isync + blr + +ICFlashInvalidate: + mfspr r3,rHID0 + ori r3,r3,HID0_ICFI #HID0[ICFI] + mtspr rHID0,r3 + blr + +.global ICacheEnable +ICacheEnable: + isync + mfspr r3,rHID0 + ori r3,r3,HID0_ICE #HID0[ICE] + mtspr rHID0,r3 + blr + +ICacheDisable: + isync + mfspr r3,rHID0 + rlwinm r3,r3,0,17,15 #HID0[ICE] + mtspr rHID0,r3 + blr + +ISync: + isync + blr + +.global L2_Init +L2_Init: + mflr r0 + stw r0, 0x04(r1) + stwu r1,-0x10(r1) + stw r31,0x0C(r1) + mfmsr r3 + mr r31,r3 + sync + li r3,MSR_IR|MSR_DR #MSR[IR|DR] + mtmsr r3 + sync + bl L2_Disable + bl L2_Invalidate + mr r3,r31 + mtmsr r3 + lwz r0, 0x14(r1) + lwz r31,0x0C(r1) + mtlr r0 + blr + +.global L2_Enable +L2_Enable: + mfl2cr r3 + oris r0,r3,0x8000 #L2CR[L2E] + rlwinm r3,r0,0,11,9 #L2CR[L2I] + mtl2cr r3 + blr + +L2_Disable: + sync + mfl2cr r3 + clrlwi r3,r3,1 #L2CR[L2E] + mtl2cr r3 + sync + blr + +L2_Invalidate: + mflr r0 + stw r0, 0x04(r1) + stwu r1,-0x08(r1) + bl L2_Disable + mfl2cr r3 + oris r3,r3,0x200 #L2CR[L2I] + mtl2cr r3 +0: + mfl2cr r3 + clrlwi r0,r3,31 #L2CR[L2IP] + cmplwi r0,0 + bne+ 0b + mfl2cr r3 + rlwinm r3,r3,0,11,9 #L2CR[L2I] + mtl2cr r3 +1: + mfl2cr r3 + clrlwi r0,r3,31 #L2CR[L2IP] + cmplwi r0,0 + bne+ 1b + lwz r0,0x0C(r1) + addi r1,r1,0x08 + mtlr r0 + blr diff --git a/resources/extldr/memory.h b/resources/extldr/memory.h new file mode 100644 index 00000000..03c514da --- /dev/null +++ b/resources/extldr/memory.h @@ -0,0 +1,9 @@ +#ifndef __MEMORY_H__ +#define __MEMORY_H__ + +void __temp_abe(void); +void ICInvalidateRange(void *, int); +void DCFlashInvalidate(void *, int); + +#endif +