Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- / ************************************************************** /
- void gw_entry2 (void)
- {
- // GW started using 0x080f7250 area 0x0420 length for data area
- memset (0x080f7250, 0, 0x0420);
- // Set system mode, disable interrupts, the stack is set to 0x080f0000
- set_cpsr (0xdf);
- sp = 0x080f0000;
- // Enable memory area 3, 0x10000000-0x18000000, corresponding IO space
- mcr (c6, c3, 0, 0x10000035);
- // The following code to enable the region 4, and open the cache and so on.
- r0 = mrc (c2, c0, 0); // data cacheable bit
- r12 = mrc (c2, c0, 1); // inst cacheable bit
- r1 = mrc (c3, c0, 0); // data writeable
- r2 = mrc (c5, c0, 2); // data access permission
- r3 = mrc (c5, c0, 3); // inst access permission
- r2 & = 0xfff0ffff; // area 4
- r3 & = 0xfff0ffff; // area 4
- r2 | = 0x00030000; // all rw
- r3 | = 0x00030000; // all rw
- r0 | = 0x00000010; // area 4
- r12 | = 0x00000010; // area 4
- r1 | = 0x00000010; // area 4
- mcr (c2, c0, 0, r0);
- mcr (c2, c0, 1, r12);
- mcr (c3, c0, 0, r1);
- mcr (c5, c0, 2, r2);
- mcr (c5, c0, 3, r3);
- // Enable memory area 3, 0x18000000-0x20000000, corresponding AXI space for the kernel arm11
- mcr (c6, c4, 0, 0x18000035); // 0x18000000-0x20000000
- // Open area of cache and buffer 5
- r0 = mrc (c2, c0, 0);
- r1 = mrc (c2, c0, 1);
- r2 = mrc (c3, c0, 0);
- r0 | = 0x20;
- r1 | = 0x20;
- r2 | = 0x20;
- mcr (c2, c0, 0, r0);
- mcr (c2, c0, 1, r1);
- mcr (c3, c0, 0, r2);
- // The exception service arm9 set to loop
- * (U32 *) (0x08000004) = 0x080f03f8; // 08007b1c IRQ
- * (U32 *) (0x08000014) = 0x080f03f8; // 08007cdc SVC
- * (U32 *) (0x0800001c) = 0x080f03f8; // 08007fbc
- * (U32 *) (0x08000024) = 0x080f03f8; // 08007b18
- * (U32 *) (0x0800002c) = 0x080f03f8; // 08007b14
- // Skip to main
- sub_80F0B04 (var_80F0004);
- }
- // The code running on arm11
- //
- / Void sub_80F04B8 (void)
- {
- CLREX (); // Exclusive cleared
- CPS (0x13); // enter SVC mode
- r0 = mrc (c0, c0, 5);
- // Cpu0: fff3fb00
- // Cpu1: fff3fb80
- // R0 pointing this cpu
- // R2 point to another cpu
- r0 = (r0 & 3) 0xfff3fb80: 0xfff3fb00;?
- r2 = r0 ^ 0x80;
- // Write the address in r0 r0 own place, to synchronize another cpu
- [R0] = r0;
- [R0 + 4] + = 1;
- r1 = 0;
- mcr (c7, c14, 0); // clear and invalid data cache
- mcr (c7, c10, 4); // data sync
- r3 = [r2];
- // If another cpu finished running
- if (r3 == r2 || r3 == 0xaabbccdd){
- [R0] = 0xaabbccdd; // this cpu run to completion flag
- while (1) {
- // Fffeff00 is irq controller
- [0xfffeff00] = 0x000f0008;
- mcr (c7, c14, 0); // clear and invalid data cache
- mcr (c7, c10, 4); // data sync
- // Wait arm9 write r0. If the address is on the implementation, and then continue to wait
- r3 = [r0];
- if (r3! = 0xaabbccdd){
- (* R3) ();
- }
- }
- }
- // If another CPU irq has not occurred
- // Switch to the irq mode, proceed irq
- CPS (0x12);
- _exc_irq_fff6263c ();
- }
- void sub_80F0B04 (u8 * param)
- {
- var_10c = param;
- memset (var_5c, 0, 16);
- var_18 = 0;
- _try_again:
- // Copy function sub_80F0498 to 0x1FFF4B40 at length 0xd0
- // 1fff4b40 corresponding virtual address ffff4b40 arm11
- sub_80F6EE0 ();
- _flush_dcache_80F6ED0 ();
- // 1FFF4018 = EA0002CE
- // For 1FFF4018 patch, jump to 1FFF4B40 Office
- // Arm11 virtual address: ffff0018 irq vector
- sub_80F6F04 ();
- _flush_dcache_80F6ED0 ();
- // Wait arm11 code to run
- while (1) {
- // 1ffdfb00 -> fff3fb00
- // Fff3fb80
- _flush_dcache_single (0x1ffdfb00, 0x100);
- var_1c = * (u32 *) (0x1ffdfb00);
- var_20 = * (u32 *) (0x1ffdfb80);
- if (var_1c == 0xaabbccdd && var_20 == 0xaabbccdd)
- break;
- }
- // At this point arm11 already under control
- // Unknown PDN register
- * (U8 *) (0x10141230) = 0x02;
- delay_80F0AB8 (10);
- * (U8 *) (0x10141230) = 0x03;
- delay_80F0AB8 (10);
- // Disable NDMA?
- var_14 = 0;
- while (var_14 <8) {
- r2 = var_14;
- r3 = r2;
- r3 << = 3; // r2 * 8
- r3 - = r2; // r2 * 7
- r3 << = 2; // r3 = var_14 * 28
- r3 = 0x1000201c + var_14 * 28; // NDMA?
- r2 = r3;
- r3 = 0x1000201c + var_14 * 28;
- r3 = [r3];
- r3 & = 0x7fffffff;
- [R3] = r3;
- var_14 + = 1;
- }
- // XDMA
- * (U32 *) (0x1000c020) = 0;
- * (U32 *) (0x1000c02c) = 0xffffffff;
- // Make the code run fff82840 at arm11
- * (U32 *) (0x1ffdfb00) = 0xfff82840;
- * (U32 *) (0x1ffdfb80) = 0xfff82840;
- _flush_dcache_80F6ED0 ();
- // Initialize the sd card and file system
- var_18 = disable_irq_80F6EC8 ();
- _sdmmc_hw_init_80F24F4 ();
- _sdmmc_card_init_80F2644 ();
- r3 = _fatfs_init (& var_104);
- if (r3)
- goto _try_again;
- // Resume interrupted
- set_cpsr (var_18);
- // Set of unknown pxi communication
- while (1) {
- r0 = _pxi_recv_80F6B58 ();
- if (r0 == 0x00044836)
- break;
- r0 = _pxi_recv_80F6B58 ();
- if (r0 == 0x00348e43)
- while (1);
- }
- _pxi_send_80F6B68 (0x00964536);
- while (1) {
- r0 = _pxi_recv_80F6B58 ();
- if (r0 == 0x00044837)
- break;
- }
- _pxi_recv_80F6B58 ();
- _pxi_recv_80F6B58 ();
- while (1) {
- r0 = _pxi_recv_80F6B58 ();
- if (r0 == 0x00044846)
- break;
- }
- // Open Launcher.dat file
- var_24 = _fat_open_80F189C ("LAUNCHER.DAT");
- r3 = var_10c;
- r3 = [r3]; // data offset
- var_28 = _fat_seek_80F1B34 (r3);
- Loop // read the file
- // Start from Launcher.dat of 0xE680 total of three pieces of data:
- // Load Address 1: 0x1ff00000 length 0x00037a00
- // Load Address 2: 0x1ff80000 length 0x0002f000
- // Load Address 3: 0x08006800 length 0x00087a00
- // Aes decrypt each piece of data first, and then ras_sha256 check.
- var_c = 0;
- while (var_c <3) {
- r3 = var_C * 264 + 0x14;
- r3 + = var_10c;
- var_2c = r3;
- var_60 = 0;
- var_10 = 0;
- while ([var_2c + 4]> var_10) {
- r2 = [var_2c + 0]; // dest
- r1 = var_10 + r2;
- r2 = [var_2c + 4]; // size
- r3 = r2-var_10;
- if (r3> 0x4000)
- r3 = 0x4000;
- r2 = r3 & 0xffff;
- // Fat_read (u8 * buf, int size, int * read_size);
- _fat_read_80F1970 (r1, r2, & var_60);
- var_10 + = var_60;
- }
- if ([var_2c + 4]! = var_10)
- while (1);
- // Calculate sha256 signature
- _sha256_init_80F29B4 (& var_c8);
- r2 = [var_2c + 0]; // dest
- r3 = [var_2c + 4]; // size
- _sha256_update (& var_c8, r2, r3);
- _sha256_final (& var_c8, & var_4c);
- // Sha256 signature verification
- r0 = sub_80F2174 (var_2c + 8, 0x100, & var_4c);
- if (r0 == 0)
- while (1);
- _memset_80F6E1C (var_D8, 0, 0x10);
- _memset_80F6E1C (var_5C, 0, 0x10);
- _aes_decrypt_80F0AD4 (var_10c + 4, & var_5c, [var_2c + 0], [var_2c + 0], [var_2c + 4]);
- var_c + = 1;
- }
- // Arm11 firm entry
- [0x1ffffffc] = 0x1ffab034;
- _flush_dcache_80F6ED0 ();
- _flush_icache_80F6EFC ();
- sub_80F6EB8 ();
- // IRQ
- [0x10001000] = 0;
- [0x10001004] = 0xffffffff;
- // CONFIG
- [0x10000010] .b = 0x0c;
- // NTRCARD
- [0x10164000] .h = 0;
- [0x10164004] = 0;
- // CTRCARD
- [0x10004000] = 0;
- [0x10005000] = 0;
- // IRQ
- [0x10001004] = 0xffffffff;
- // Unknown PDN register
- [0x10141200] = 0x0001007e;
- _delay_80F0AB8 (10);
- [0x10141200] = 0x0001007f;
- _delay_80F0AB8 (10);
- // Final gw jump to your code:
- // Arm9 firm entry
- (* 0x0801b01c) ();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement