Merge commit 'origin/upstream' into juha-devel
[qemu] / hw / omap3_boot.c
1 /*
2  * TI OMAP3 boot ROM emulation. Based on information in the OMAP34xx 3.1
3  * Technical Reference Manual from Texas Instruments.
4  *
5  * Copyright (C) 2009 Nokia Corporation
6  *
7  * The OMAP3 boot ROM service routines accessed via ARM SMC instruction
8  * are not available in this emulation due to the limited availability
9  * of public documentation on the ARM TrustZone functionality. However
10  * it seems executing the SMC instruction as a NOP causes no harm.
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License as
14  * published by the Free Software Foundation; either version 2 or
15  * (at your option) version 3 of the License.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License along
23  * with this program; if not, write to the Free Software Foundation, Inc.,
24  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25  */
26 #include "hw.h"
27 #include "arm-misc.h"
28 #include "omap.h"
29 #include "sysemu.h"
30 #include "qemu-char.h"
31 #include "flash.h"
32 #include "block.h"
33
34 /* list of supported NAND devices according to the OMAP34xx TRM */
35 static const struct {
36     uint8_t id;
37     uint32_t pagesize;
38     uint32_t capacity_Mb;
39 } omap3_boot_nand_devices[] = {
40     {0xe6,  512,    64}, {0x33,  512,   128}, {0x73,  512,   128},
41     {0x43,  512,   128}, {0x53,  512,   128}, {0x35,  512,   256},
42     {0x75,  512,   256}, {0x45,  512,   256}, {0x55,  512,   256},
43     {0x36,  512,   512}, {0x76,  512,   512}, {0x46,  512,   512},
44     {0x56,  512,   512}, {0xa2, 2048,   512}, {0xf2, 2048,   512},
45     {0xb2, 2048,   512}, {0xc2, 2048,   512}, {0x39,  512,  1024},
46     {0x79,  512,  1024}, {0x49,  512,  1024}, {0x59,  512,  1024},
47     {0x78,  512,  1024}, {0x72,  512,  1024}, {0x74,  512,  1024},
48     {0xa1, 2048,  1024}, {0xf1, 2048,  1024}, {0xb1, 2048,  1024},
49     {0xc1, 2048,  1024}, {0xaa, 2048,  2048}, {0xda, 2048,  2048},
50     {0xba, 2048,  2048}, {0xca, 2048,  2048}, {0x71,  512,  2048},
51     {0x51,  512,  2048}, {0x31,  512,  2048}, {0x41,  512,  2048},
52     {0xac, 2048,  4096}, {0xdc, 2048,  4096}, {0xbc, 2048,  4096},
53     {0xcc, 2048,  4096}, {0xa3, 2048,  8192}, {0xd3, 2048,  8192},
54     {0xb3, 2048,  8192}, {0xc3, 2048,  8192}, {0xa5, 2048, 16384},
55     {0xd5, 2048, 16384}, {0xb5, 2048, 16384}, {0xc5, 2048, 16384},
56     {0xa7, 2048, 32768}, {0xb7, 2048, 32768}, {0xae, 2048, 65536},
57     {0xbe, 2048, 65536},
58     {0, 0, 0}
59 };
60
61 struct omap3_nand_boot_desc_s {
62     uint32_t pagesize;
63     uint32_t capacity_Mb;
64     uint8_t bus16;
65 };
66
67 static const uint8_t omap3_boot_rom[] = { /* 0x40014000-0x4001bfff */
68     /* 0x40014000: ROM Exception vectors */
69     0x3e, 0x00, 0x00, 0xea, /* b 0x40014100 */
70     0x18, 0xf0, 0x9f, 0xe5, /* ldr pc, [pc, #0x18] */
71     0x18, 0xf0, 0x9f, 0xe5, /* ldr pc, [pc, #0x18] */
72     0x18, 0xf0, 0x9f, 0xe5, /* ldr pc, [pc, #0x18] */
73     0x18, 0xf0, 0x9f, 0xe5, /* ldr pc, [pc, #0x18] */
74     0x18, 0xf0, 0x9f, 0xe5, /* ldr pc, [pc, #0x18] */
75     0x18, 0xf0, 0x9f, 0xe5, /* ldr pc, [pc, #0x18] */
76     0x18, 0xf0, 0x9f, 0xe5, /* ldr pc, [pc, #0x18] */
77     /* 0x40014020: ROM CRC */
78     0xff, 0xff, 0xff, 0xff, 
79     /* 0x40014024: unused(?), we use it for some data */
80     0xc8, 0xff, 0x20, 0x40, /* 0x40014024: undef sram vector address */
81     0xcc, 0xff, 0x20, 0x40, /* 0x40014028: swi sram vector address */
82     0xd0, 0xff, 0x20, 0x40, /* 0x4001402c: pabt sram vector address */
83     0xd4, 0xff, 0x20, 0x40, /* 0x40014030: dabt sram vector address */
84     0xd8, 0xff, 0x20, 0x40, /* 0x40014034: unused sram vector address */
85     0xdc, 0xff, 0x20, 0x40, /* 0x40014038: irq sram vector address */
86     0xe0, 0xff, 0x20, 0x40, /* 0x4001403c: fiq sram vector address */
87     0xff, 0xff, 0xff, 0xff, /* 0x40014040: boot loader image start address */
88     0xff, 0xff, 0xff, 0xff, /* 0x40014044: booting parameter structure 0-3 */
89     0xff, 0xff, 0xff, 0xff, /* 0x40014048: booting parameter structure 4-7 */
90     0xff, 0xff, 0xff, 0xff, /* 0x4001404c: booting parameter structure 8-11 */
91     0x0e, 0xf0, 0xb0, 0xe1, /* 0x40014050: "movs pc, lr" */
92     0xff, 0xff, 0xff, 0xff,
93     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
94     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
95     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
96     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
97     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
98     /* 0x40014080: Dead loops */
99     0xfe, 0xff, 0xff, 0xea, /* b 0x40014080 @ undefined exception */
100     0xfe, 0xff, 0xff, 0xea, /* b 0x40014084 @ swi exception */
101     0xfe, 0xff, 0xff, 0xea, /* b 0x40014088 @ prefetch abort exception */
102     0xfe, 0xff, 0xff, 0xea, /* b 0x4001408c @ data abort exception */
103     0xfe, 0xff, 0xff, 0xea, /* b 0x40014090 @ unused exception */
104     0xfe, 0xff, 0xff, 0xea, /* b 0x40014094 @ irq exception */
105     0xfe, 0xff, 0xff, 0xea, /* b 0x40014098 @ fiq exception */
106     0xfe, 0xff, 0xff, 0xea, /* b 0x4001409c @ validation tests pass */
107     0xfe, 0xff, 0xff, 0xea, /* b 0x400140a0 @ validation tests fail */
108     0xfe, 0xff, 0xff, 0xea, /* b 0x400140a4 @ boot failed: no more devices */
109     0xfe, 0xff, 0xff, 0xea, /* b 0x400140a8 @ image not executed or returned */
110     0xfe, 0xff, 0xff, 0xea, /* b 0x400140ac @ reserved */
111     0xfe, 0xff, 0xff, 0xea, /* b 0x400140b0 @ reserved */
112     0xfe, 0xff, 0xff, 0xea, /* b 0x400140b4 @ reserved */
113     0xfe, 0xff, 0xff, 0xea, /* b 0x400140b8 @ reserved */
114     0xfe, 0xff, 0xff, 0xea, /* b 0x400140bc @ reserved */
115     /* 0x400140c0: should perform a software reset & jump to r0 */
116     0x00, 0xf0, 0xa0, 0xe1, /* mov pc, r0 */
117     0xff, 0xff, 0xff, 0xff,
118     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
119     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
120     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
121     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
122     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
123     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
124     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
125     /* 0x40014100: code, ROM emulation uses this to launch the
126      * boot loader after it has been read into memory */
127     0xc8, 0x10, 0x1f, 0xe5, /* ldr r1, [#0x40014040] @ boot loader start */
128     0xb0, 0x0c, 0x0f, 0xe3, /* movw r0, #0xfcb0 */
129     0x20, 0x00, 0x44, 0xe3, /* movt r0, #0x4020   @ stack top at 0x4020fcb0 */
130     0xdf, 0xf0, 0x21, 0xe3, /* msr cpsr_c, #0xdf  @ enter SYS mode */
131     0x00, 0xd0, 0xa0, 0xe1, /* mov sp, r0 */
132     0x80, 0x0c, 0x40, 0xe2, /* sub r0, r0, #32768 @ 32kB SYS/USR stack */
133     0xd1, 0xf0, 0x21, 0xe3, /* msr cpsr_c, #0xd1  @ enter FIQ mode */
134     0x00, 0xd0, 0xa0, 0xe1, /* mov sp, r0 */
135     0x08, 0x0c, 0x40, 0xe2, /* sub r0, r0, #2048  @ 2kB FIQ stack */
136     0xd2, 0xf0, 0x21, 0xe3, /* msr cpsr_c, #0xd2  @ enter IRQ mode */
137     0x00, 0xd0, 0xa0, 0xe1, /* mov sp, r0 */
138     0x08, 0x0c, 0x40, 0xe2, /* sub r0, r0, #2048  @ 2kB IRQ stack */
139     0xd7, 0xf0, 0x21, 0xe3, /* msr cpsr_c, #0xd7  @ enter ABT mode */
140     0x00, 0xd0, 0xa0, 0xe1, /* mov sp, r0 */
141     0x08, 0x0c, 0x40, 0xe2, /* sub r0, r0, #2048  @ 2kB ABT stack */
142     0xdb, 0xf0, 0x21, 0xe3, /* msr cpsr_c, #0xdb  @ enter UND mode */
143     0x00, 0xd0, 0xa0, 0xe1, /* mov sp, r0 */
144     0x08, 0x0c, 0x40, 0xe2, /* sub r0, r0, #2048  @ 2kB UND stack */
145     0xd3, 0xf0, 0x21, 0xe3, /* msr cpsr_c, #0xd3  @ enter SVC mode */
146     0x00, 0xd0, 0xa0, 0xe1, /* mov sp, r0         @ 23kB left for SVC stack */
147     0x44, 0x00, 0x04, 0xe3, /* movw r0, #0x4044 */
148     0x01, 0x00, 0x44, 0xe3, /* movt r0, #0x4001   @ r0 -> booting parameter struct */
149     0x01, 0xf0, 0xa0, 0xe1, /* mov pc, r1 */
150 };
151
152 /* SRAM exception vectors, to be placed at 0x4020ffc8 */
153 static const uint8_t omap3_sram_vectors[] = {
154     0x14, 0xf0, 0x9f, 0xe5, /* ldr pc, [#0x4020ffe4] @ undefined */
155     0x14, 0xf0, 0x9f, 0xe5, /* ldr pc, [#0x4020ffe8] @ swi */
156     0x14, 0xf0, 0x9f, 0xe5, /* ldr pc, [#0x4020ffec] @ prefetch abort */
157     0x14, 0xf0, 0x9f, 0xe5, /* ldr pc, [#0x4020fff0] @ data abort */
158     0x14, 0xf0, 0x9f, 0xe5, /* ldr pc, [#0x4020fff4] @ unused */
159     0x14, 0xf0, 0x9f, 0xe5, /* ldr pc, [#0x4020fff8] @ irq */
160     0x14, 0xf0, 0x9f, 0xe5, /* ldr pc, [#0x4020fffc] @ fiq */
161     0x80, 0x40, 0x01, 0x00, /* 0x14080 */
162     0x50, 0x40, 0x01, 0x40, /* 0x40014050 (default is 0x14084) */
163     0x88, 0x40, 0x01, 0x00, /* 0x14088 */
164     0x8c, 0x40, 0x01, 0x00, /* 0x1408c */
165     0x90, 0x40, 0x01, 0x00, /* 0x14090 */
166     0x94, 0x40, 0x01, 0x00, /* 0x14094 */
167     0x98, 0x40, 0x01, 0x00, /* 0x14098 */
168 };
169
170 static inline uint32_t omap3_get_le32(const void *p)
171 {
172     const uint8_t *q = (const uint8_t *)p;
173     uint32_t v;
174     v = q[3]; v <<= 8;
175     v |= q[2]; v <<= 8;
176     v |= q[1]; v <<= 8;
177     v |= q[0];
178     return v;
179 }
180
181 static inline uint32_t omap3_get_le16(const void *p)
182 {
183     const uint8_t *q = (const uint8_t *)p;
184     uint32_t v;
185     v = q[1]; v <<= 8;
186     v |= q[0];
187     return v;
188 }
189
190 static inline void omap3_boot_setlsb(target_phys_addr_t addr, uint16_t lsb)
191 {
192     uint8_t x[4];
193     
194     cpu_physical_memory_read(addr, x, 4);
195     x[0] = lsb & 0xff;
196     x[1] = (lsb >> 8) & 0xff;
197     cpu_physical_memory_write(addr, x, 4);
198 }
199
200 typedef enum {
201     xip = 1,
202     nand,
203     onenand,
204     doc,
205     mmc2,
206     mmc1,
207     xipwait,
208     uart = 0x10,
209     hsusb,
210 }  omap3_boot_device_t;
211
212 struct omap3_boot_s {
213     struct omap_mpu_state_s *mpu;
214     omap3_boot_device_t devicetype;
215     enum {
216         undefined = 0,
217         confighdr,
218         chdone,
219         imagehdr,
220         copy,
221         done
222     } state;
223     uint8_t chflags;
224     target_phys_addr_t addr;
225     uint32_t count;
226 };
227
228 static struct omap3_boot_s *omap3_boot_init(struct omap_mpu_state_s *mpu,
229                                             omap3_boot_device_t dtype,
230                                             const uint8_t *data,
231                                             uint32_t data_len)
232 {
233     struct omap3_boot_s *s = qemu_mallocz(sizeof(struct omap3_boot_s));
234     s->mpu = mpu;
235     s->devicetype = dtype;
236     s->state = chdone;
237     if (data_len >= 512) {
238         if (!strncasecmp((char *)(data + 0x14), "chsettings", 10)
239             || !strncasecmp((char *)(data + 0x14), "chram", 5)
240             || !strncasecmp((char *)(data + 0x14), "chflash", 7)
241             || !strncasecmp((char *)(data + 0x14), "chmmcsd", 7))
242             s->state = confighdr;
243     }
244     return s;
245 }
246
247 static void omap3_boot_chsettings(struct omap3_boot_s *boot,
248                                   const uint8_t *chtoc)
249 {
250     uint32_t flags, x;
251     
252     if (omap3_get_le32(chtoc) != 0xc0c0c0c1) {
253         fprintf(stderr, "%s: invalid section verification key\n", __FUNCTION__);
254         return;
255     }
256     if (!chtoc[4]) { /* section disabled? */
257         return;
258     }
259     if (omap3_get_le16(chtoc + 5) != 0x0001) {
260         fprintf(stderr, "%s: unsupported CH version (0x%04x)\n", __FUNCTION__,
261                 omap3_get_le16(chtoc));
262         return;
263     }
264     boot->chflags |= 0x01;
265     flags = omap3_get_le32(chtoc + 8);
266     chtoc += 12;
267     if (flags & 1) {
268         cpu_physical_memory_write(0x48307270, chtoc + 0x00, 4); /* PRM_CLKSRC_CTRL */
269         cpu_physical_memory_write(0x48306d40, chtoc + 0x04, 4); /* PRM_CLKSEL */
270         cpu_physical_memory_write(0x48005140, chtoc + 0x08, 4); /* CM_CLKSEL1_EMU */
271         if (flags & (1 << 2)) { /* clock configuration */
272             cpu_physical_memory_write(0x48004a40, chtoc + 0x0c, 4); /* CM_CLKSEL_CORE */
273             cpu_physical_memory_write(0x48004c40, chtoc + 0x10, 4); /* CM_CLKSEL_WKUP */
274         }
275         if (flags & (1 << 5)) { /* DPLL3 CORE */
276             if (flags & (1 << 8)) { /* enable DPLL3 bypass */
277                 cpu_physical_memory_read(0x48004d00, (uint8_t *)&x, 4);
278                 x &= ~7; x |= 5; /* set DPLL3 bypass */
279                 cpu_physical_memory_write(0x48004d00, (uint8_t *)&x, 4);
280             }
281             cpu_physical_memory_write(0x48004d00, chtoc + 0x14, 4); /* CM_CLKEN_PLL */
282             cpu_physical_memory_write(0x48004d30, chtoc + 0x18, 4); /* CM_AUTOIDLE_PLL */
283             cpu_physical_memory_write(0x48004d40, chtoc + 0x1c, 4); /* CM_CLKSEL1_PLL */
284         }
285         if (flags & (1 << 3)) { /* DPLL4 PER */
286             if (flags & (1 << 6)) { /* enable DPLL4 bypass */
287                 cpu_physical_memory_read(0x48004d00, (uint8_t *)&x, 4);
288                 x &= ~0x70000; x |= 0x10000; /* set DPLL4 in stop mode */
289                 cpu_physical_memory_write(0x48004d00, (uint8_t *)&x, 4);
290             }
291             cpu_physical_memory_write(0x48004d00, chtoc + 0x20, 4); /* CM_CLKEN_PLL */
292             cpu_physical_memory_write(0x48004d30, chtoc + 0x24, 4); /* CM_AUTOIDLE_PLL */
293             cpu_physical_memory_write(0x48004d44, chtoc + 0x28, 4); /* CM_CLKSEL2_PLL */
294             cpu_physical_memory_write(0x48004d48, chtoc + 0x2c, 4); /* CM_CLKSEL3_PLL */
295         }
296         if (flags & (1 << 3)) { /* DPLL1 MPU */
297             if (flags & (1 << 7)) { /* enable DPLL1 bypass */
298                 cpu_physical_memory_read(0x48004904, (uint8_t *)&x, 4);
299                 x &= ~7; x |= 5; /* set DPLL1 bypass */
300                 cpu_physical_memory_write(0x48004904, (uint8_t *)&x, 4);
301             }
302             cpu_physical_memory_write(0x48004904, chtoc + 0x30, 4); /* CM_CLKEN_PLL_MPU */
303             cpu_physical_memory_write(0x48004934, chtoc + 0x34, 4); /* CM_AUTOIDLE_PLL_MPU */
304             cpu_physical_memory_write(0x48004940, chtoc + 0x38, 4); /* CM_CLKSEL1_PLL_MPU */
305             cpu_physical_memory_write(0x48004944, chtoc + 0x3c, 4); /* CM_CLKSEL2_PLL_MPU */
306             cpu_physical_memory_write(0x48004948, chtoc + 0x40, 4); /* CM_CLKSTCTRL_MPU */
307         }
308         switch ((flags >> 24) & 0xff) {
309             case 0x01: x = 0; break; /* 12MHz */
310             case 0x02: x = 1; break; /* 13MHz */
311             case 0x03: x = 5; break; /* 16.8MHz */
312             case 0x04: x = 2; break; /* 19.2MHz */
313             case 0x05: x = 3; break; /* 26MHz */
314             case 0x06: x = 4; break; /* 38.4MHz */
315             default:
316                 fprintf(stderr, "%s: unsupported SYS.CLK setting\n", __FUNCTION__);
317                 x = 1;
318                 break;
319         }
320         if (x != omap3_get_le32(chtoc + 0x04)) {
321             fprintf(stderr, "%s: mismatch in SYS.CLK id and PRM_CLKSEL value\n", __FUNCTION__);
322         }
323     }
324 }
325
326 static void omap3_boot_chram(struct omap3_boot_s *boot,
327                              const uint8_t *chtoc)
328 {
329     if (omap3_get_le32(chtoc) != 0xc0c0c0c2) {
330         fprintf(stderr, "%s: invalid section verification key\n", __FUNCTION__);
331         return;
332     }
333     if (!chtoc[4]) { /* section disabled? */
334         return;
335     }
336     boot->chflags |= 0x02;
337     omap3_boot_setlsb(0x6d000040, omap3_get_le16(chtoc + 0x0a)); /* SDRC_CS_CFG */
338     omap3_boot_setlsb(0x6d000044, omap3_get_le16(chtoc + 0x0c)); /* SDRC_SHARING */
339     cpu_physical_memory_write(0x6d000060, chtoc + 0x10, 4);      /* SDRC_DLLA_CTRL */
340     
341     cpu_physical_memory_write(0x6d000080, chtoc + 0x20, 4);      /* SDRC_MCFG_0 */
342     omap3_boot_setlsb(0x6d000084, omap3_get_le16(chtoc + 0x24)); /* SDRC_MR_0 */
343     omap3_boot_setlsb(0x6d000088, omap3_get_le16(chtoc + 0x26)); /* SDRC_EMR1_0? */
344     omap3_boot_setlsb(0x6d00008c, omap3_get_le16(chtoc + 0x28)); /* SDRC_EMR2_0 */
345     omap3_boot_setlsb(0x6d000090, omap3_get_le16(chtoc + 0x2a)); /* SDRC_EMR3_0? */
346     cpu_physical_memory_write(0x6d00009c, chtoc + 0x2c, 4);      /* SDRC_ACTIM_CTRLA_0 */
347     cpu_physical_memory_write(0x6d0000a0, chtoc + 0x30, 4);      /* SDRC_ACTIM_CTRLB_0 */
348     cpu_physical_memory_write(0x6d0000a4, chtoc + 0x34, 4);      /* SDRC_RFR_CTRL_0 */
349     
350     cpu_physical_memory_write(0x6d0000b0, chtoc + 0x20, 4);      /* SDRC_MCFG_1 */
351     omap3_boot_setlsb(0x6d0000b4, omap3_get_le16(chtoc + 0x24)); /* SDRC_MR_1 */
352     omap3_boot_setlsb(0x6d0000b8, omap3_get_le16(chtoc + 0x26)); /* SDRC_EMR1_1? */
353     omap3_boot_setlsb(0x6d0000bc, omap3_get_le16(chtoc + 0x28)); /* SDRC_EMR2_1 */
354     omap3_boot_setlsb(0x6d0000c0, omap3_get_le16(chtoc + 0x2a)); /* SDRC_EMR3_1? */
355     cpu_physical_memory_write(0x6d0000cc, chtoc + 0x2c, 4);      /* SDRC_ACTIM_CTRLA_1 */
356     cpu_physical_memory_write(0x6d0000d0, chtoc + 0x30, 4);      /* SDRC_ACTIM_CTRLB_1 */
357     cpu_physical_memory_write(0x6d0000d4, chtoc + 0x34, 4);      /* SDRC_RFR_CTRL_1 */
358 }
359
360 static void omap3_boot_chflash(struct omap3_boot_s *boot,
361                                const uint8_t *chtoc)
362 {
363     if (omap3_get_le32(chtoc) != 0xc0c0c0c3) {
364         fprintf(stderr, "%s: invalid section verification key\n", __FUNCTION__);
365         return;
366     }
367     if (!chtoc[4]) { /* section disabled? */
368         return;
369     }
370     boot->chflags |= 0x04;
371     omap3_boot_setlsb(0x6e000010, omap3_get_le16(chtoc + 0x08)); /* GPMC_SYSCONFIG */
372     omap3_boot_setlsb(0x6e00001c, omap3_get_le16(chtoc + 0x0a)); /* GPMC_IRQENABLE */
373     omap3_boot_setlsb(0x6e000040, omap3_get_le16(chtoc + 0x0c)); /* GPMC_TIMEOUT_CONTROL */
374     omap3_boot_setlsb(0x6e000050, omap3_get_le16(chtoc + 0x0e)); /* GPMC_CONFIG */
375     cpu_physical_memory_write(0x6e000060, chtoc + 0x10, 4);      /* GPMC_CONFIG1_0 */
376     cpu_physical_memory_write(0x6e000064, chtoc + 0x14, 4);      /* GPMC_CONFIG2_0 */
377     cpu_physical_memory_write(0x6e000068, chtoc + 0x18, 4);      /* GPMC_CONFIG3_0 */
378     cpu_physical_memory_write(0x6e00006c, chtoc + 0x1c, 4);      /* GPMC_CONFIG4_0 */
379     cpu_physical_memory_write(0x6e000070, chtoc + 0x20, 4);      /* GPMC_CONFIG5_0 */
380     cpu_physical_memory_write(0x6e000074, chtoc + 0x24, 4);      /* GPMC_CONFIG6_0 */
381     cpu_physical_memory_write(0x6e000078, chtoc + 0x28, 4);      /* GPMC_CONFIG7_0 */
382     cpu_physical_memory_write(0x6e0001e0, chtoc + 0x2c, 4);      /* GPMC_PREFETCH_CONFIG1 */
383     omap3_boot_setlsb(0x6e0001e4, omap3_get_le16(chtoc + 0x30)); /* GPMC_PREFETCH_CONFIG2 */
384     omap3_boot_setlsb(0x6e0001ec, omap3_get_le16(chtoc + 0x32)); /* GPMC_PREFETCH_CONTROL */
385     /* TODO: ECC config registers. The TRM spec is not clear on these */
386 }
387
388 static void omap3_boot_chmmcsd(struct omap3_boot_s *boot,
389                                const uint8_t *chtoc)
390 {
391     if (omap3_get_le32(chtoc) != 0xc0c0c0c4) {
392         fprintf(stderr, "%s: invalid section verification key\n", __FUNCTION__);
393         return;
394     }
395     if (!chtoc[4]) { /* section disabled? */
396         return;
397     }
398     boot->chflags |= 0x08;
399     /* TODO: MMCHS registers */
400 }
401
402 /* returns non-zero if more blocks are needed */
403 static uint32_t omap3_boot_block(const uint8_t *data,
404                                  uint32_t data_len,
405                                  struct omap3_boot_s *s)
406 {
407     const uint8_t *p = 0;
408     uint32_t i = 0;
409     
410     switch (s->state) {
411         case confighdr:
412             i = data_len;
413             for (p = data; i >= 32 && omap3_get_le32(p) != 0xffffffff; p += 32, i -= 32) {
414                 if (!strcasecmp((char *)(p + 0x14), "chsettings"))
415                     omap3_boot_chsettings(s, p + omap3_get_le32(p));
416                 else if (!strcasecmp((char *)(p + 0x14), "chram"))
417                     omap3_boot_chram(s, p + omap3_get_le32(p));
418                 else if (!strcasecmp((char *)(p + 0x14), "chflash"))
419                     omap3_boot_chflash(s, p + omap3_get_le32(p));
420                 else if (!strcasecmp((char *)(p + 0x14), "chmmcsd"))
421                     omap3_boot_chmmcsd(s, p + omap3_get_le32(p));
422                 else
423                     fprintf(stderr, "%s: unknown CHTOC item \"%s\"\n",
424                             __FUNCTION__, (char *)(p + 0x14));
425             }
426             data += 512;
427             data_len -= 512;
428             s->state = chdone;
429             /* fallthrough */
430         case chdone:
431             s->state = imagehdr;
432             /* fallthrough */
433         case imagehdr:
434             if (!data_len)
435                 return 1;
436             if (data_len < 8)
437                 break;
438             s->count = omap3_get_le32(data);
439             s->addr = omap3_get_le32(data + 4);
440             if (!s->count || (s->count >> 24) || !s->addr || s->addr == 0xffffffff)
441                 break;
442             /* patch image start address in boot ROM */
443             cpu_physical_memory_write_rom(0x40014040, data + 4, 4);
444             /* start copying image */
445             data += 8;
446             data_len -= 8;
447             s->state = copy;
448             /* fallthrough */
449         case copy:
450             i = (s->count >= data_len) ? data_len : s->count;
451             cpu_physical_memory_write(s->addr, data, i);
452             s->addr += i;
453             s->count -= i;
454             if (!s->count)
455                 s->state = done;
456             return s->count;
457         default:
458             break;
459     }
460     return 0;
461 }
462
463 /* returns non-zero if boot has finished succesfully */
464 static int omap3_boot_finish(struct omap3_boot_s *s)
465 {
466     uint8_t x[12] = {
467         0, 0, 0, 0, /* last received booting message */
468         (uint8_t)s->devicetype,
469         0,
470         1, /* POR */
471         s->chflags,
472         0, 0, 0, 0 /* device descriptor */
473     };
474     int result = (s->state == done);
475
476     if (result) {
477         /* fill in the booting parameter structure */
478         cpu_physical_memory_write_rom(0x40014044, x, 12);
479     }
480     free(s);
481     return result;
482 }
483
484 /* returns ptr to matching dir entry / zero entry or 0 if unsuccessful */
485 static const uint8_t *omap3_scan_fat_dir_sector(const uint8_t *s)
486 {
487     int i;
488     
489     /* there are 0x10 items with 0x20 bytes per item */
490     for (i = 0x10; i--; s += 0x20) {
491         if (*s == 0xe5 || (s[0x0b] & 0x0f) == 0x0f) continue; /* erased/LFN */
492         if (!*s || !strncasecmp((void *)s, "mlo        ", 8+3)) return s;
493     }
494     return 0;
495 }
496
497 struct omap3_fat_drv_s {
498     BlockDriverState *bs;
499     uint8_t ptype; /* 12, 16, 32 */
500     uint64_t c0;   /* physical byte offset for data cluster 0 */
501     uint64_t fat;  /* physical byte offset for used FAT sector 0 */
502     uint32_t spc;  /* sectors per cluster */
503 };
504
505 /* returns cluster data in the buffer and next cluster chain number
506  or 0 if unsuccessful */
507 static uint32_t omap3_read_fat_cluster(uint8_t *data,
508                                        struct omap3_fat_drv_s *drv,
509                                        uint32_t cl)
510 {
511     uint8_t buf[ 4 ];
512     uint32_t len = drv->spc * 0x200; /* number of bytes to read */
513     
514     switch (drv->ptype) { /* check for EOF */
515         case 12: if (cl > 0xff0) return 0; break;
516         case 16: if (cl > 0xfff0) return 0; break;
517         case 32: if (cl > 0x0ffffff0) return 0; break;
518         default: return 0;
519     }
520     
521     if (bdrv_pread(drv->bs, 
522                    drv->c0 + ((drv->ptype == 32 ? cl - 2 : cl) * len),
523                    data, len) != len)
524         return 0;
525     
526     switch (drv->ptype) { /* determine next cluster # */
527         case 12:
528             fprintf(stderr, "%s: FAT12 parsing not implemented!\n",
529                     __FUNCTION__);
530             break;
531         case 16:
532             return (bdrv_pread(drv->bs, drv->fat + cl * 2, buf, 2) != 2)
533             ? 0 : omap3_get_le16(buf);
534         case 32:
535             return (bdrv_pread(drv->bs, drv->fat + cl * 4, buf, 4) != 4)
536             ? 0 : omap3_get_le32(buf) & 0x0fffffff;
537         default:
538             break;
539     }
540     return 0;
541 }
542
543 static int omap3_mmc_fat_boot(BlockDriverState *bs,
544                               uint8_t *sector,
545                               uint32_t pstart,
546                               struct omap_mpu_state_s *mpu)
547 {
548     struct omap3_fat_drv_s drv;
549     struct omap3_boot_s *boot;
550     uint32_t i, j, cluster0, fatsize, bootsize, rootsize;
551     const uint8_t *p, *q;
552     uint8_t *cluster;
553     int result = 0;
554     
555     /* determine FAT type */
556     
557     drv.bs = bs;
558     fatsize = omap3_get_le16(sector + 0x16);
559     if (!fatsize) 
560         fatsize = omap3_get_le32(sector + 0x24);
561     bootsize = omap3_get_le16(sector + 0x0e);
562     cluster0 = bootsize + fatsize * sector[0x10];
563     rootsize = omap3_get_le16(sector + 0x11);
564     if (rootsize & 0x0f)
565         rootsize += 0x10;
566     rootsize >>= 4;
567     drv.spc = sector[0x0d];
568     i = omap3_get_le16(sector + 0x13);
569     if (!i)
570         i = omap3_get_le32(sector + 0x20);
571     i = (i - (cluster0 + rootsize)) / drv.spc;
572     drv.ptype = (i < 4085) ? 12 : (i < 65525) ? 16 : 32;
573     
574     /* search for boot loader file */
575     
576     drv.fat = (bootsize + pstart) * 0x200;
577     drv.c0 = (cluster0 + pstart) * 0x200;
578     if (drv.ptype == 32) {
579         i = omap3_get_le32(sector + 0x2c); /* first root cluster # */
580         j = omap3_get_le16(sector + 0x28);
581         if (j & 0x80)
582             drv.fat += (j & 0x0f) * fatsize * 0x200;
583         cluster = qemu_mallocz(drv.spc * 0x200);
584         for (p = 0; !p && (i = omap3_read_fat_cluster(cluster, &drv, i)); ) {
585             for (j = drv.spc, q=cluster; j-- & !p; q += 0x200)
586                 p = omap3_scan_fat_dir_sector(q);
587             if (p) 
588                 memcpy(sector, q - 0x200, 0x200); /* save the sector */
589         }
590         free(cluster);
591     } else { /* FAT12/16 */
592         for (i = rootsize, j = 0, p = 0; i-- && !p; j++) {
593             if (bdrv_pread(drv.bs, drv.c0 + j * 0x200, sector, 0x200) != 0x200)
594                 break;
595             p = omap3_scan_fat_dir_sector(sector);
596         }
597     }
598     
599     if (p && *p) { /* did we indeed find the file? */
600         i = omap3_get_le16(p + 0x14);
601         i <<= 16;
602         i |= omap3_get_le16(p + 0x1a);
603         j = drv.spc * 0x200;
604         uint8 *data = qemu_mallocz(j);
605         if ((i = omap3_read_fat_cluster(data, &drv, i))) {
606             boot = omap3_boot_init(mpu, mmc1, data, j);
607             boot->state = imagehdr; /* override CH detection */
608             while (omap3_boot_block(data, j, boot))
609                 i = omap3_read_fat_cluster(data, &drv, i);
610             result = omap3_boot_finish(boot);
611         } else
612             fprintf(stderr, "%s: unable to read MLO file contents from SD card\n",
613                     __FUNCTION__);
614         free(data);
615     } else
616         fprintf(stderr, "%s: MLO file not found in the root directory\n",
617                 __FUNCTION__);
618     
619     return result;
620 }
621
622 static int omap3_mmc_raw_boot(BlockDriverState *bs,
623                               uint8_t *sector,
624                               struct omap_mpu_state_s *mpu)
625 {
626     struct omap3_boot_s *boot;
627     uint32_t i = 0;
628     int result = 0;
629     
630     if (bdrv_pread(bs, 0, sector, 0x200) == 0x200) {
631         boot = omap3_boot_init(mpu, mmc1, sector, 0x200);
632         if (boot->state == confighdr) { /* CH must be present for raw boot */
633             while (omap3_boot_block(sector, 0x200, boot)) {
634                 if (bdrv_pread(bs, ++i, sector, 0x200) != 0x200) {
635                     fprintf(stderr, "%s: error trying to read sector %u on boot device\n",
636                             __FUNCTION__, i);
637                     break;
638                 }
639             }
640         }
641         result = (boot->state == done);
642         free(boot);
643     }
644     return result;
645 }
646
647 /* returns non-zero if successful, zero if unsuccessful */
648 static int omap3_mmc_boot(struct omap_mpu_state_s *s)
649 {
650     BlockDriverState *bs;
651     int sdindex = drive_get_index(IF_SD, 0, 0);
652     uint8_t *sector, *p;
653     uint32_t pstart, i;
654     int result = 0;
655     
656     /* very simple implementation for GP device boot,
657      supports only two modes:
658      1. MBR partition table with an active FAT partition
659      and boot loader file (MLO) in its root directory, or
660      2. CH sector located on first sector, followed by boot loader image */
661     if (sdindex >= 0) {
662         bs = drives_table[sdindex].bdrv;
663         sector = qemu_mallocz(0x200);
664         if (bdrv_pread(bs, 0, sector, 0x200) == 0x200) {
665             for (i = 0, p = sector + 0x1be; i < 4; i++, p += 0x10) 
666                 if (p[0] == 0x80) break;
667             if (sector[0x1fe] == 0x55 && sector[0x1ff] == 0xaa /* signature */
668                 && i < 4 /* active partition exists */
669                 && (p[4] == 1 || p[4] == 4 || p[4] == 6 || p[4] == 11
670                     || p[4] == 12 || p[4] == 14 || p[4] == 15) /* FAT */
671                 && bdrv_pread(bs, (pstart = omap3_get_le32(p + 8)) * 0x200,
672                               sector, 0x200) == 0x200
673                 && sector[0x1fe] == 0x55 && sector[0x1ff] == 0xaa)
674                 result = omap3_mmc_fat_boot(bs, sector, pstart, s);
675             else
676                 result = omap3_mmc_raw_boot(bs, sector, s);
677         }
678         free(sector);
679     }
680     return result;
681 }
682
683 static inline void omap3_nand_sendcmd(struct omap3_nand_boot_desc_s *nd,
684                                       uint8_t cmd)
685 {
686     uint8_t x[2] = { cmd, 0 };
687     
688     cpu_physical_memory_write(0x6e00007c, x, nd->bus16 ? 2 : 1);
689 }
690
691 static inline void omap3_nand_sendaddr_byte(struct omap3_nand_boot_desc_s *nd,
692                                             uint8_t a)
693 {
694     uint8_t x[2] = { a, 0 };
695     
696     cpu_physical_memory_write(0x6e000080, x, nd->bus16 ? 2 : 1);
697 }
698
699 static inline uint8_t omap3_nand_readbyte(struct omap3_nand_boot_desc_s *nd)
700 {
701     uint8_t x[2];
702     
703     cpu_physical_memory_read(0x6e000084, x, nd->bus16 ? 2 : 1);
704     return x[0];
705 }
706
707 static inline void omap3_nand_readpage(struct omap3_nand_boot_desc_s *nd,
708                                        uint32_t pageaddr,
709                                        uint8_t *data)
710 {
711     uint32_t i;
712     
713     omap3_nand_sendcmd(nd, 0x00); /* read page */
714     omap3_nand_sendaddr_byte(nd, 0x00);
715     if (nd->pagesize >= 2048) {
716         omap3_nand_sendaddr_byte(nd, 0x00);
717         omap3_nand_sendaddr_byte(nd, (uint8_t)(pageaddr & 0xff));
718         omap3_nand_sendaddr_byte(nd, (uint8_t)((pageaddr >> 8) & 0xff));
719         if (nd->capacity_Mb >= 2048)
720             omap3_nand_sendaddr_byte(nd, (uint8_t)((pageaddr >> 16) & 0xff));
721         omap3_nand_sendcmd(nd, 0x30); /* confirm read */
722     } else {
723         omap3_nand_sendaddr_byte(nd, (uint8_t)(pageaddr & 0xff));
724         omap3_nand_sendaddr_byte(nd, (uint8_t)((pageaddr >> 8) & 0xff));
725     }
726     if (nd->bus16) {
727         for (i = nd->pagesize / 2; i--; data += 2)
728             cpu_physical_memory_read(0x6e000084, data, 2);
729     } else {
730         for (i = nd->pagesize; i--; data++)
731             cpu_physical_memory_read(0x6e000084, data, 1);
732     }
733 }
734
735 /* returns non-zero if successful, zero if unsuccessful */
736 static int omap3_nand_boot(struct omap_mpu_state_s *mpu, int bus16)
737 {
738     struct omap3_nand_boot_desc_s *nd;
739     struct omap3_boot_s *boot;
740     uint8_t *data;
741     uint32_t page = 0;
742     int result = 0, i;
743     uint8_t id[4];
744     
745     /* TODO: support bad block marks */
746     nd = qemu_mallocz(sizeof(struct omap3_nand_boot_desc_s));
747     nd->bus16 = bus16;
748     omap3_nand_sendcmd(nd, 0xff); /* reset */
749     omap3_nand_sendcmd(nd, 0x90); /* read id */
750     omap3_nand_sendaddr_byte(nd, 0);
751     id[0] = omap3_nand_readbyte(nd); /* manufacturer id */
752     id[1] = omap3_nand_readbyte(nd); /* device id */
753     id[2] = omap3_nand_readbyte(nd); /* don't care */
754     id[3] = omap3_nand_readbyte(nd); /* attributes */
755     for (i = 0; omap3_boot_nand_devices[i].id; i++) {
756         if (omap3_boot_nand_devices[i].id == id[1]) {
757             nd->capacity_Mb = omap3_boot_nand_devices[i].capacity_Mb;
758             if (nd->capacity_Mb > 1024)
759                 nd->pagesize = 1024 * (1 << (id[3] & 3));
760             else
761                 nd->pagesize = omap3_boot_nand_devices[i].pagesize;
762             break;
763         }
764     }
765     /* TODO: if device is not recognized at this state, we should
766      * issue READ ID2 command to the device and get device parameters
767      * from there */
768     if (nd->pagesize) {
769         data = qemu_mallocz(nd->pagesize);
770         /* TODO: scan through 4 first blocks for image */
771         omap3_nand_readpage(nd, 0, data);
772         boot = omap3_boot_init(mpu, nand, data, nd->pagesize);
773         while (omap3_boot_block(data, nd->pagesize, boot))
774             omap3_nand_readpage(nd, ++page, data);
775         result = omap3_boot_finish(boot);
776         free(data);
777     }
778     free(nd);
779     return result;
780 }
781
782 static inline void omap3_onenand_writereg(uint16_t reg, uint16_t value)
783 {
784     cpu_to_le16s(&value);
785     cpu_physical_memory_write(0x08000000 + (reg << 1), (void *)&value, 2);
786 }
787
788 static inline uint16_t omap3_onenand_readreg(uint16_t reg)
789 {
790     uint16_t value;
791     cpu_physical_memory_read(0x08000000 + (reg << 1), (void *)&value, 2);
792     return le16_to_cpu(value);
793 }
794
795 static int omap3_onenand_readpage(uint16_t pagesize,
796                                   uint16_t b,
797                                   uint16_t p,
798                                   uint8_t *d)
799 {
800     omap3_onenand_writereg(0xf100, b);
801     omap3_onenand_writereg(0xf107, (p & 0x3f) << 2);
802     omap3_onenand_writereg(0xf200, 0x0800);
803     omap3_onenand_writereg(0xf101, 0);
804     omap3_onenand_writereg(0xf241, 0);
805     omap3_onenand_writereg(0xf220, 0);
806     if (!(omap3_onenand_readreg(0xf241) & 0x8000) ||
807         (omap3_onenand_readreg(0xf240) & 0x0400))
808         return 0;
809     cpu_physical_memory_read(0x08000400, (void *)d, pagesize);
810     return 1;
811 }
812
813 static int omap3_onenand_boot(struct omap_mpu_state_s *s)
814 {
815     uint32_t x;
816     uint16_t i, j, pagesize;
817     uint8_t *page;
818     struct omap3_boot_s *boot;
819     int result = 0;
820     
821     /* reset device type at cs0: 16bit NOR, no wait monitoring */
822     cpu_to_le32wu(&x, 0x79001000);
823     cpu_physical_memory_write(0x6e000060, (void *)&x, 4); /* GPMC_CONFIG1_0 */
824     /* map cs0 at 0x08000000 */
825     cpu_to_le32wu(&x, 0x00000848);
826     cpu_physical_memory_write(0x6e000078, (void *)&x, 4); /* GPMC_CONFIG7_0 */
827     /* try to read onenand registers */
828     if (omap3_onenand_readreg(0xf000) != 0x00ec) /* manufacturer id */
829         return 0;
830     pagesize = omap3_onenand_readreg(0xf003);
831     if (pagesize != 2048 && pagesize != 1024) {
832         fprintf(stderr, "%s: OneNAND page size %d not supported\n",
833                 __FUNCTION__, pagesize);
834         return 0;
835     }
836     /* search for boot loader */
837     page = qemu_mallocz(pagesize);
838     for (i = 0; i < 4; i++) { /* search 4 blocks */
839         if (omap3_onenand_readpage(pagesize, i, 0, page)) {
840             boot = omap3_boot_init(s, onenand, page, pagesize);
841             for (j = 1; omap3_boot_block(page, pagesize, boot); j++)
842                 if (!omap3_onenand_readpage(pagesize, i, j, page))
843                     break;
844             result = omap3_boot_finish(boot);
845             if (result)
846                 break;
847         }
848     }
849     free(page);
850     return result;
851 }
852
853
854 void omap3_boot_rom_emu(struct omap_mpu_state_s *s)
855 {
856     const uint8_t rom_version[4] = { 0x00, 0x14, 0x00, 0x00 }; /* v. 14.00 */
857     uint8_t x[4] = {0, 0, 0, 0};
858     int result = 0;
859     ram_addr_t bootrom_base;
860     
861     bootrom_base = qemu_ram_alloc(OMAP3XXX_BOOTROM_SIZE);
862     cpu_register_physical_memory(OMAP3_Q1_BASE + 0x14000,
863                                  OMAP3XXX_BOOTROM_SIZE,
864                                  bootrom_base | IO_MEM_ROM);
865     cpu_physical_memory_write_rom(OMAP3_Q1_BASE + 0x14000,
866                                   omap3_boot_rom,
867                                   sizeof(omap3_boot_rom));
868     cpu_physical_memory_write_rom(OMAP3_Q1_BASE + 0x1bffc,
869                                   rom_version,
870                                   sizeof(rom_version));
871     cpu_physical_memory_write(OMAP3_SRAM_BASE + 0xffc8,
872                               omap3_sram_vectors,
873                               sizeof(omap3_sram_vectors));
874
875     /* here we are relying on all memories to be attached and gpmc_attach
876      * to fill in DEVICETYPE field correctly for CS0 for us */
877     cpu_physical_memory_read(0x6e000060, x, 4); /* GPMC_CONFIG1_0 */
878     switch (((x[1] >> 2) & 3)) {
879         case 0: /* NOR */
880             result = omap3_onenand_boot(s);
881             break;
882         case 2: /* NAND */
883             result = omap3_nand_boot(s, ((x[1] >> 4) & 3) == 1);
884             break;
885         default:
886             break;
887     }
888
889     /* if no boot loader found yet, try the MMC/SD card... */
890     if (!result)
891         result = omap3_mmc_boot(s);
892     
893     /* ensure boot ROM is mapped at zero address */
894     cpu_register_physical_memory(0, OMAP3XXX_BOOTROM_SIZE,
895                                  bootrom_base | IO_MEM_ROM);
896     
897     if (!result) { /* no boot device found */
898         /* move PC to the appropriate ROM dead loop address */
899         s->env->regs[15] = 0x400140a4;
900         /* ...on second thought, let's just call it a day and quit */
901         cpu_abort(s->env, "no boot device found");
902     }
903 }