branch for testing malloc/free fails on aes engine
[ppcskel.git] / main.c
1 /*
2         BootMii - a Free Software replacement for the Nintendo/BroadOn bootloader.
3         Requires mini.
4
5 Copyright (C) 2008, 2009        Haxx Enterprises <bushing@gmail.com>
6 Copyright (C) 2009              Andre Heider "dhewg" <dhewg@wiibrew.org>
7 Copyright (C) 2008, 2009        Hector Martin "marcan" <marcan@marcansoft.com>
8 Copyright (C) 2008, 2009        Sven Peter <svenpeter@gmail.com>
9 Copyright (C) 2009              John Kelley <wiidev@kelley.ca>
10
11 # This code is licensed to you under the terms of the GNU GPL, version 2;
12 # see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
13 */
14
15 #include "bootmii_ppc.h"
16 #include "string.h"
17 #include "ipc.h"
18 #include "mini_ipc.h"
19 #include "nandfs.h"
20 #include "fat.h"
21 #include "malloc.h"
22 #include "diskio.h"
23 #include "printf.h"
24 #include "video_low.h"
25 #include "input.h"
26 #include "console.h"
27
28 #define MINIMUM_MINI_VERSION 0x00010001
29
30 /* AES registers for our example */
31 #define         AES_REG_BASE            0xd020000
32 #define         AES_CMD                 (AES_REG_BASE + 0x000)
33 #define         AES_SRC                 (AES_REG_BASE + 0x004)
34 #define         AES_DEST                (AES_REG_BASE + 0x008)
35 #define         AES_KEY                 (AES_REG_BASE + 0x00c)
36 #define         AES_IV                  (AES_REG_BASE + 0x010)
37
38 otp_t otp;
39 seeprom_t seeprom;
40
41 static void dsp_reset(void)
42 {
43         write16(0x0c00500a, read16(0x0c00500a) & ~0x01f8);
44         write16(0x0c00500a, read16(0x0c00500a) | 0x0010);
45         write16(0x0c005036, 0);
46 }
47
48 static char ascii(char s) {
49   if(s < 0x20) return '.';
50   if(s > 0x7E) return '.';
51   return s;
52 }
53
54 void hexdump(void *d, int len) {
55   u8 *data;
56   int i, off;
57   data = (u8*)d;
58   for (off=0; off<len; off += 16) {
59     printf("%08x  ",off);
60     for(i=0; i<16; i++)
61       if((i+off)>=len) printf("   ");
62       else printf("%02x ",data[off+i]);
63
64     printf(" ");
65     for(i=0; i<16; i++)
66       if((i+off)>=len) printf(" ");
67       else printf("%c",ascii(data[off+i]));
68     printf("\n");
69   }
70 }
71         
72 void testOTP(void)
73 {
74         printf("reading OTP...\n");
75         getotp(&otp);
76         printf("read OTP!\n");
77         printf("OTP:\n");
78         hexdump(&otp, sizeof(otp));
79
80         printf("reading SEEPROM...\n");
81         getseeprom(&seeprom);
82         printf("read SEEPROM!\n");
83         printf("SEEPROM:\n");
84         hexdump(&seeprom, sizeof(seeprom));
85 }
86
87 /* idea of this simple AES engine test:
88  * show how the malloc/free pair fails concerning dma access from i/o devices -
89  * we don't use real encryption mode here but just copy the data from source to
90  * destination - this is achieved by setting the ENA flag in AES_CMD to zero. */
91 void simple_aes_copy(void)
92 {
93         /* first, allocate memory for source and destination */
94         u8* source = memalign(16, 16); // 16 byte aligned, 16 byte length
95         u8* destination = memalign(16, 16); // 16 byte aligned, 16 byte length
96
97         /* fill source with some evil data, and set destination to all the same bytes ('?')
98          * to see quickly see whether the copying has worked or not */
99         memset(source, '\0', 16);
100         strlcpy(source, "please copy me", 16);
101         memset(destination, '?', 16);
102
103         printf("----- source addr: %08X, dest addr: %08X -----\n", source, destination);
104         hexdump(source, 16);
105         hexdump(destination, 16);
106
107         /* reset aes controller */
108         write32(AES_CMD, 0);
109         while(read32(AES_CMD) != 0);
110
111         /* flush buffers and tell the controller their addresses */
112         sync_after_write(source, 16);
113         sync_after_write(destination, 16);
114         write32(AES_SRC, virt_to_phys(source));
115         write32(AES_DEST, virt_to_phys(destination));
116
117         /* fire up copying! */
118         write32(AES_CMD, 0x80000000);
119         while(read32(AES_CMD) & 0x80000000);
120
121         /* show result */
122         printf("result is there:\n");
123         sync_before_read(source, 16); // should not be needed, but just to get sure...
124         sync_before_read(destination, 16);
125         hexdump(source, 16);
126         hexdump(destination, 16);
127
128         /* now THIS should show that something is wrong with memory (MMU stuff etc.?) */
129         free(source);
130         free(destination);
131 }
132
133 int main(void)
134 {
135         int vmode = -1;
136         exception_init();
137         dsp_reset();
138
139         // clear interrupt mask
140         write32(0x0c003004, 0);
141
142         ipc_initialize();
143         ipc_slowping();
144
145         gecko_init();
146         input_init();
147         init_fb(vmode);
148
149         VIDEO_Init(vmode);
150         VIDEO_SetFrameBuffer(get_xfb());
151         VISetupEncoder();
152
153         u32 version = ipc_getvers();
154         u16 mini_version_major = version >> 16 & 0xFFFF;
155         u16 mini_version_minor = version & 0xFFFF;
156         printf("Mini version: %d.%0d\n", mini_version_major, mini_version_minor);
157
158         if (version < MINIMUM_MINI_VERSION) {
159                 printf("Sorry, this version of MINI (armboot.bin)\n"
160                         "is too old, please update to at least %d.%0d.\n", 
161                         (MINIMUM_MINI_VERSION >> 16), (MINIMUM_MINI_VERSION & 0xFFFF));
162                 for (;;) 
163                         ; // better ideas welcome!
164         }
165
166         /* perform 3 tests... */
167         u8 i;
168         for (i=0; i<3; i++) {
169                 printf("======== aes copy test (%d) ========\n", i+1);
170                 simple_aes_copy();
171                 printf("====================================\n\n");
172         }
173
174         return 0;
175 }
176