1 // Copyright 2008-2009 Segher Boessenkool <segher@kernel.crashing.org>
2 // This code is licensed to you under the terms of the GNU GPL, version 2;
3 // see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
8 typedef unsigned int u32;
9 typedef unsigned char u8;
11 int nand_open_E0(const char *path, void *buf, u32 mode);
12 int nand_open_E2(const char *path, void *buf, u32 mode);
13 int nand_open_J0(const char *path, void *buf, u32 mode);
14 int nand_open_P0(const char *path, void *buf, u32 mode);
16 int nand_read_E0(void *buf, void *dest, u32 len);
17 int nand_read_E2(void *buf, void *dest, u32 len);
18 int nand_read_J0(void *buf, void *dest, u32 len);
19 int nand_read_P0(void *buf, void *dest, u32 len);
21 void audio_stop_E0(void);
22 void audio_stop_E2(void);
23 void audio_stop_J0(void);
24 void audio_stop_P0(void);
26 void graphics_stop_E0(void);
27 void graphics_stop_E2(void);
28 void graphics_stop_J0(void);
29 void graphics_stop_P0(void);
31 static u8 nand_buf[0x100] __attribute__ ((aligned(0x40)));
34 void gecko_print(void *, const char *);
36 #define PRINT(x) gecko_print(0, x)
39 static void hex(u32 x)
45 for (i = 0; i < 8; i++) {
48 s[i] = digit + '0' + (digit < 10 ? 0 : 'a' - 10 - '0');
55 #define PRINT(x) do { } while (0)
56 #define HEX(x) do { } while (0)
59 static void sync_cache(void *p, u32 n)
64 end = ((u32)p + n + 31) & ~31;
65 n = (end - start) >> 5;
68 asm("dcbst 0,%0 ; icbi 0,%0" : : "b"(p));
74 static void sync_before_read(void *p, u32 n)
79 end = ((u32)p + n + 31) & ~31;
80 n = (end - start) >> 5;
83 asm("dcbf 0,%0" : : "b"(p));
89 static void jump(void *p, u32 arg)
91 PRINT("taking the plunge...\n");
93 asm("mr 3,%1 ; mtctr %0 ; bctrl" : : "r"(p), "r"(arg) : "r3");
95 PRINT("whoops, payload returned to us\n");
99 static u32 read32(u32 addr)
103 asm volatile("lwz %0,0(%1) ; sync" : "=r"(x) : "b"(0xc0000000 | addr));
108 static void write32(u32 addr, u32 x)
110 asm("stw %0,0(%1) ; eieio" : : "r"(x), "b"(0xc0000000 | addr));
113 static void blink(u32 colour)
115 u32 *fb = (u32 *)0xC0F00000;
119 write32(0x0d8000c0, read32(0x0d8000c0) ^ 0x20);
121 for (i = 0; i < 640*576/2; i++)
125 #define blink(x) do { } while(0)
128 void __attribute__ ((noreturn)) main(u32 baddr)
132 char *gameid = (char *)0x80000000;
133 int (*nand_open)(const char *path, void *buf, u32 mode);
134 int (*nand_read)(void *buf, void *dest, u32 len);
135 void (*audio_stop)(void);
136 void (*graphics_stop)(void);
138 PRINT("Hello, Brave New World!\n");
144 if ((baddr>>16) == 0x8045) {
145 nand_open = nand_open_E2;
146 nand_read = nand_read_E2;
147 audio_stop = audio_stop_E2;
148 graphics_stop = graphics_stop_E2;
150 nand_open = nand_open_E0;
151 nand_read = nand_read_E0;
152 audio_stop = audio_stop_E0;
153 graphics_stop = graphics_stop_E0;
157 nand_open = nand_open_P0;
158 nand_read = nand_read_P0;
159 audio_stop = audio_stop_P0;
160 graphics_stop = graphics_stop_P0;
163 nand_open = nand_open_J0;
164 nand_read = nand_read_J0;
165 audio_stop = audio_stop_J0;
166 graphics_stop = graphics_stop_J0;
169 PRINT("unsupported game region\n");
177 blink(0x266a26c0); // maroon
179 ret = nand_open("zeldaTp.dat", nand_buf, 1);
181 blink(0x7140718a); // olive
183 PRINT("nand open --> ");
186 area = (void *)0x90000020;
188 // Skip past save game, to loader.bin
189 ret = nand_read(nand_buf, area, 0x4000);
192 for (i = 0; i < 0x40; i++) {
193 PRINT("reading bootloader page: ");
196 blink(0x40804080 + i*0x02000200); // grey
198 sync_before_read(area + 0x1000*i, 0x1000);
199 ret = nand_read(nand_buf, area + 0x1000*i, 0x1000);
202 blink(0x552b5515 + i*0x02000200); // lime
209 for (i = 0; i < 0x100; i++)
210 HEX(((u32 *)area)[i]);
212 blink(0xc399c36a); // sky blue
214 sync_cache(area, len);
217 blink(0x4c544cff); // red
219 PRINT("(shouldn't happen)\n");