void firmware() { display_init(); gfx_init_ctxt(&gfx_ctxt, display_init_framebuffer(), 720, 1280, 768); gfx_clear_color(&gfx_ctxt, 0xFF000000); gfx_con_init(&gfx_con, &gfx_ctxt); gfx_con_setcol(&gfx_con, DEFAULT_TEXT_COL, 0, 0); while (!sdMount()) { error("Failed to init SD card!\n"); print("Press POWER to power off, any other key to retry\n"); if (btn_wait() & BTN_POWER) i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_ONOFFCNFG1, MAX77620_ONOFFCNFG1_PWR_OFF); btn_wait(); } if(PMC(APBDEV_PMC_SCRATCH49) != 69 && fopen("/ReiNX.bin", "rb")) { fread((void*)PAYLOAD_ADDR, fsize(), 1); fclose(); sdUnmount(); display_end(); CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= 0x400; // Enable AHUB clock. CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= 0x40; // Enable APE clock. PMC(APBDEV_PMC_SCRATCH49) = 69; ((void (*)())PAYLOAD_ADDR)(); } SYSREG(AHB_AHB_SPARE_REG) = (volatile vu32)0xFFFFFF9F; PMC(APBDEV_PMC_SCRATCH49) = 0; print("Welcome to ReiNX %s!\n", VERSION); loadFirm(); drawSplash(); launch(); }
int _cluster_pmc_enable_partition(u32 part, u32 toggle) { //Check if the partition has already been turned on. if (PMC(APBDEV_PMC_PWRGATE_STATUS) & part) return 0; u32 i = 5001; while (PMC(APBDEV_PMC_PWRGATE_TOGGLE) & 0x100) { sleep(1); i--; if (i < 1) return 0; } PMC(APBDEV_PMC_PWRGATE_TOGGLE) = toggle | 0x100; i = 5001; while (i > 0) { if (PMC(APBDEV_PMC_PWRGATE_STATUS) & part) break; sleep(1); i--; } return 1; }
void pin_function(PinName pin, int function) { if (pin == (PinName)NC) return; int n = pin >> 4; int bitmask = 1<<(pin & 0xf); if (gpio_multi_guard != pin) { if (function == 0) { // means GPIO mode *PMC(n) &= ~bitmask; } else { // alt-function mode *PMC(n) |= bitmask; --function; if (function & (1 << 2)) { *PFCAE(n) |= bitmask;}else { *PFCAE(n) &= ~bitmask;} if (function & (1 << 1)) { *PFCE(n) |= bitmask;}else { *PFCE(n) &= ~bitmask;} if (function & (1 << 0)) { *PFC(n) |= bitmask;}else { *PFC(n) &= ~bitmask;} *PIPC(n) |= bitmask; if (P1_0 <= pin && pin <= P1_7 && function == 0) { *PBDC(n) |= bitmask; } } } else { gpio_multi_guard = (PinName)NC; } }
void pin_function(PinName pin, int function) { if (pin == (PinName)NC) return; int n = pin >> 4; int bitmask = 1<<(pin & 0xf); const PinFunc * Pipc_0_func = PIPC_0_tbl; int pipc_data = 1; if (gpio_multi_guard != pin) { if (function == 0) { // means GPIO mode *PMC(n) &= ~bitmask; } else { // alt-function mode --function; if (function & (1 << 2)) { *PFCAE(n) |= bitmask;}else { *PFCAE(n) &= ~bitmask;} if (function & (1 << 1)) { *PFCE(n) |= bitmask;}else { *PFCE(n) &= ~bitmask;} if (function & (1 << 0)) { *PFC(n) |= bitmask;}else { *PFC(n) &= ~bitmask;} while (Pipc_0_func->pin != NC) { if ((Pipc_0_func->pin == pin) && ((Pipc_0_func->function - 1) == function)) { pipc_data = 0; if (Pipc_0_func->pm == 0) { *PMSR(n) = (bitmask << 16) | 0; } else if (Pipc_0_func->pm == 1) { *PMSR(n) = (bitmask << 16) | bitmask; } else { // Do Nothing } break; } Pipc_0_func++; } if (pipc_data == 1) { *PIPC(n) |= bitmask; } else { *PIPC(n) &= ~bitmask; } if (P1_0 <= pin && pin <= P1_7 && function == 0) { *PBDC(n) |= bitmask; } *PMC(n) |= bitmask; } } else { gpio_multi_guard = (PinName)NC; } }
void config_oscillators() { CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) = CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) & 0xFFFFFFF3 | 4; SYSCTR0(SYSCTR0_CNTFID0) = 19200000; TMR(0x14) = 0x45F; CLOCK(CLK_RST_CONTROLLER_OSC_CTRL) = 0x50000071; PMC(APBDEV_PMC_OSC_EDPD_OVER) = PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFFFFF81 | 0xE; PMC(APBDEV_PMC_OSC_EDPD_OVER) = PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFBFFFFF | 0x400000; PMC(APBDEV_PMC_CNTRL2) = PMC(APBDEV_PMC_CNTRL2) & 0xFFFFEFFF | 0x1000; PMC(APBDEV_PMC_SCRATCH188) = PMC(APBDEV_PMC_SCRATCH188) & 0xFCFFFFFF | 0x2000000; CLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) &= 0xBFFFFFFF; PMC(APBDEV_PMC_TSC_MULT) = PMC(APBDEV_PMC_TSC_MULT) & 0xFFFF0000 | 0x249F; //0x249F = 19200000 * (16 / 32.768 kHz) CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20004444; CLOCK(CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER) = 0x80000000; CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; }
void launch() { u8 pre4x = pk11Offs->kb < KB_FIRMWARE_VERSION_400; se_aes_key_clear(0x8); se_aes_key_clear(0xB); if (pre4x) { if (pk11Offs->kb == KB_FIRMWARE_VERSION_300) PMC(APBDEV_PMC_SECURE_SCRATCH32) = 0xE3; else if (pk11Offs->kb == KB_FIRMWARE_VERSION_301) PMC(APBDEV_PMC_SECURE_SCRATCH32) = 0x104; se_key_acc_ctrl(12, 0xFF); se_key_acc_ctrl(13, 0xFF); } else { se_key_acc_ctrl(12, 0xFF); se_key_acc_ctrl(15, 0xFF); } // TODO: Don't Clear 'BootConfig' for retail >1.0.0. //memset((void *)0x4003D000, 0, 0x3000); SE_lock(); // Start boot process now that pk21 is loaded. *BOOT_STATE_ADDR = (pre4x ? BOOT_PKG2_LOADED : BOOT_PKG2_LOADED_4X); // Boot secmon and Wait for it get ready. cluster_boot_cpu0(pk11Offs->secmon_base); while (!*SECMON_STATE_ADDR) usleep(1); // Disable display. if (pre4x) display_end(); // Signal to finish boot process. *BOOT_STATE_ADDR = (pre4x ? BOOT_DONE : BOOT_DONE_4X);; // Halt ourselves in waitevent state. while (1) FLOW_CTLR(0x4) = 0x50000000; }
u8 loadFirm() { sdmmc_storage_t storage; sdmmc_t sdmmc; //Init nand sdmmc_storage_init_mmc(&storage, &sdmmc, SDMMC_4, SDMMC_BUS_WIDTH_8, 4); sdmmc_storage_set_mmc_partition(&storage, 1); // Read package1. u8 *package1 = ReadPackage1(&storage); // Setup firmware specific data. pk11Offs = pkg11_offsentify(package1); u8 *keyblob = (u8 *)malloc(NX_EMMC_BLOCKSIZE); sdmmc_storage_read(&storage, 0x180000 / NX_EMMC_BLOCKSIZE + pk11Offs->kb, 1, keyblob); keygen(keyblob, pk11Offs->kb, package1 + pk11Offs->tsec_off); free(keyblob); // Decrypt package1 and setup warmboot. print("Decrypting Package1...\n"); u8 *pkg11 = package1 + pk11Offs->pkg11_off; u32 pkg11_size = *(u32 *)pkg11; se_aes_crypt_ctr(11, pkg11 + 0x20, pkg11_size, pkg11 + 0x20, pkg11_size, pkg11 + 0x10); pkg1_unpack(pk11Offs, package1); PMC(APBDEV_PMC_SCRATCH1) = pk11Offs->warmboot_base; free(package1); //Read package2 u8 *pkg2 = ReadPackage2(&storage); // Unpack Package2. print("Unpacking package2...\n"); pkg2_hdr_t *dec_pkg2 = unpackFirmwarePackage(pkg2); LIST_INIT(kip1_info); pkg2_parse_kips(&kip1_info, dec_pkg2); // Patch firmware. print("Patching OS...\n"); patch(pk11Offs, dec_pkg2, &kip1_info); // Load all KIPs. char **sysmods = NULL; size_t cnt = enumerateDir(&sysmods, "/ReiNX/sysmodules", "*.kip"); for (u32 i = 0; i < cnt ; i++) { print("%kLoading %s\n%k", YELLOW, sysmods[i], DEFAULT_TEXT_COL); loadKip(&kip1_info, sysmods[i]); free(sysmods[i]); } free(sysmods); // Build Package2. buildFirmwarePackage(dec_pkg2->data, dec_pkg2->sec_size[PKG2_SEC_KERNEL], &kip1_info); }
void config_pmc_scratch() { PMC(APBDEV_PMC_SCRATCH20) &= 0xFFF3FFFF; PMC(APBDEV_PMC_SCRATCH190) &= 0xFFFFFFFE; PMC(APBDEV_PMC_SECURE_SCRATCH21) |= 0x10; }