Skip to content

Instantly share code, notes, and snippets.

@pixel-stuck
Last active June 23, 2019 04:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pixel-stuck/006933116c384e68706b77ed2833aa72 to your computer and use it in GitHub Desktop.
Save pixel-stuck/006933116c384e68706b77ed2833aa72 to your computer and use it in GitHub Desktop.
#include <string.h>
#include <stdio.h>
#include <switch.h>
#define FUSE_PHYS_ADDR 0x7000F800
#define FUSE_ARRAY_SIZE 0x100
#define FUSE_CTRL ((*(volatile u32 *)fuse_virt_addr))
#define FUSE_REG_ADDR ((*(volatile u32 *)(fuse_virt_addr + 4)))
#define FUSE_REG_READ ((*(volatile u32 *)(fuse_virt_addr + 8)))
#define FUSE_CACHED ((*(volatile u32 *)(fuse_virt_addr + 0x100)))
#define CLK_RST_PHYS_ADDR 0x60006000
#define CLK_RST_CONTROLLER_MISC_CLK_ENB_0 ((*(volatile u32 *)(clk_rst_virt_addr + 0x48)))
u64 clk_rst_virt_addr = 0;
u64 fuse_virt_addr = 0;
Result get_io_regions(void)
{
Result clk_rst_res = svcQueryIoMapping(&clk_rst_virt_addr, CLK_RST_PHYS_ADDR, 0x400);
Result fuse_res = svcQueryIoMapping(&fuse_virt_addr, FUSE_PHYS_ADDR, 0x400);
return clk_rst_res | fuse_res;
}
void clk_rst_set_fuse_state(int fuse_state)
{
CLK_RST_CONTROLLER_MISC_CLK_ENB_0 = CLK_RST_CONTROLLER_MISC_CLK_ENB_0 & 0xEFFFFFFF | (fuse_state << 28) & 0x1FFFFFFF;
}
int main(int argc, char **argv)
{
gfxInitDefault();
consoleInit(NULL);
printf("Fuse dumper v1 by stuckpixel\n");
Result res = get_io_regions();
FILE *cached_f = fopen("sdmc:/fuses_cached.bin", "wb");
FILE *fuse_f = fopen("sdmc:/fuses.bin", "wb");
if(!cached_f | !fuse_f)
{
printf("Failed to open file!\n");
gfxExit();
return 0;
}
if(!res)
{
clk_rst_set_fuse_state(1); //enable fuse registers
FUSE_CTRL &= 0xFBFFFFFF; //clear the powerdown flag
for(int i = 0; i < FUSE_ARRAY_SIZE; i++)
{
FUSE_REG_ADDR = i; //set the fuse to be dumped
FUSE_CTRL = ((FUSE_CTRL >> 2) << 2) | 1; //start the operation
while(FUSE_CTRL << 11 >> 27 != 4); //wait for read to finish
fwrite(&FUSE_REG_READ, 1, 4, fuse_f); //write data to file
}
fwrite(&FUSE_CACHED, 1, 0x300, cached_f); //write cached fuses to a file
/* close files */
fclose(cached_f);
fclose(fuse_f);
clk_rst_set_fuse_state(0); //disables fuse registers
printf("Fuses successfully dumped!\nPress the + button to exit\n");
}
else
{
printf("Failed to map one or more I/O regions!\n");
}
while(appletMainLoop())
{
hidScanInput();
u32 kDown = hidKeysDown(CONTROLLER_P1_AUTO);
if (kDown & KEY_PLUS) break;
gfxFlushBuffers();
gfxSwapBuffers();
gfxWaitForVsync();
}
gfxExit();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment