// call this to erase pages // return true on success, else false bool FlashErase(uint32_t startOffset, uint32_t length) { uint32_t offset = startOffset; uint32_t endOffset = startOffset + length; int errors = 0; while (offset < endOffset) { uint32_t * ptr = (void*)FlashData; ptr += offset; void * physicalAddress = VirtualToPhysicalAddress(ptr); // Claim: Microchip has serious bug in their PIC32 peripheral lib - erase page depends on series // from http://www.microchip.com/forums/m772388.aspx // next solution: In "PIC32 Flash Programming Specification" DS61145L, Table 5.1: I finally found the details. // Flash page size 256 Word for PIC32MX1 and MX2. Flash page size 1024 Words for MX3 and higher, and 4096 Words for MZ devices. // shizzle f**k :) // needs PHYSICAL address, not virtual address if (NVMErasePage(physicalAddress) != 0) { // double try if (NVMErasePage(physicalAddress) != 0) { errors++; } } offset += BYTE_PAGE_SIZE/4; // note this size changes by PIC model } if (errors == 0) return true; return false; }
ResultCode SetBufferSwap(u32 screen_id, const FrameBufferInfo& info) { u32 base_address = 0x400000; PAddr phys_address_left = VirtualToPhysicalAddress(info.address_left); PAddr phys_address_right = VirtualToPhysicalAddress(info.address_right); if (info.active_fb == 0) { WriteSingleHWReg(base_address + 4 * static_cast<u32>(GPU_REG_INDEX( framebuffer_config[screen_id].address_left1)), phys_address_left); WriteSingleHWReg(base_address + 4 * static_cast<u32>(GPU_REG_INDEX( framebuffer_config[screen_id].address_right1)), phys_address_right); } else { WriteSingleHWReg(base_address + 4 * static_cast<u32>(GPU_REG_INDEX( framebuffer_config[screen_id].address_left2)), phys_address_left); WriteSingleHWReg(base_address + 4 * static_cast<u32>(GPU_REG_INDEX( framebuffer_config[screen_id].address_right2)), phys_address_right); } WriteSingleHWReg(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].stride)), info.stride); WriteSingleHWReg(base_address + 4 * static_cast<u32>(GPU_REG_INDEX( framebuffer_config[screen_id].color_format)), info.format); WriteSingleHWReg( base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].active_fb)), info.shown_fb); if (Pica::g_debug_context) Pica::g_debug_context->OnEvent(Pica::DebugContext::Event::BufferSwapped, nullptr); if (screen_id == 0) { MicroProfileFlip(); Core::System::GetInstance().perf_stats.EndGameFrame(); } return RESULT_SUCCESS; }
// return true on success, else false bool FlashWrite(uint32_t wordOffset, uint32_t value) { if (FLASH_BLOCK_SIZE_BYTES / 4 <= wordOffset) return false; // out of bounds uint32_t * ptr = (void*)FlashData; ptr += wordOffset; void * physicalAddress = VirtualToPhysicalAddress(ptr); // try writing twice, and check the value each try if (NVMWriteWord(physicalAddress, value) != 0 || *ptr != value) { if (NVMWriteWord(physicalAddress, value) != 0 || *ptr != value) { return false; } } return true; }