Index: embios/trunk/init.c |
— | — | @@ -44,6 +44,9 @@ |
45 | 45 | #include "disk.h"
|
46 | 46 | #include "file.h"
|
47 | 47 | #endif
|
| 48 | +#ifdef HAVE_BOOTFLASH
|
| 49 | +#include "bootflash.h"
|
| 50 | +#endif
|
48 | 51 |
|
49 | 52 |
|
50 | 53 | struct bootinfo_t
|
— | — | @@ -58,7 +61,7 @@ |
59 | 62 | bool bootflashflags;
|
60 | 63 | bool trymemmapped;
|
61 | 64 | void* memmappedaddr;
|
62 | | - uint32_t memmappedsize;
|
| 65 | + int memmappedsize;
|
63 | 66 | bool memmappedflags;
|
64 | 67 | };
|
65 | 68 |
|
— | — | @@ -86,12 +89,13 @@ |
87 | 90 | {
|
88 | 91 | int fd = file_open(bootinfo.dataflashpath, O_RDONLY);
|
89 | 92 | if (fd < 0) goto dataflashfailed;
|
90 | | - uint32_t size = filesize(fd);
|
| 93 | + int size = filesize(fd);
|
| 94 | + if (size < 0) goto dataflashfailed;
|
91 | 95 | if (bootinfo.dataflashflags & 1)
|
92 | 96 | {
|
93 | 97 | void* addr = (void*)((((uint32_t)&_loadspaceend) - size) & ~(CACHEALIGN_SIZE - 1));
|
94 | 98 | if (read(fd, addr, size) != size) goto dataflashfailed;
|
95 | | - if (ucl_decompress(addr, size, &_initstart, &size)) goto dataflashfailed;
|
| 99 | + if (ucl_decompress(addr, size, &_initstart, (uint32_t*)&size)) goto dataflashfailed;
|
96 | 100 | }
|
97 | 101 | else if (read(fd, &_initstart, size) != size) goto dataflashfailed;
|
98 | 102 | if (execimage(&_initstart) < 0) return;
|
— | — | @@ -101,13 +105,14 @@ |
102 | 106 | #ifdef HAVE_BOOTFLASH
|
103 | 107 | if (bootinfo.trybootflash)
|
104 | 108 | {
|
105 | | - uint32_t size = bootflash_filesize(bootinfo.bootimagename);
|
| 109 | + int size = bootflash_filesize(bootinfo.bootimagename);
|
106 | 110 | if (size < 0) goto bootflashfailed;
|
107 | 111 | #ifdef BOOTFLASH_IS_MEMMAPPED
|
108 | 112 | void* addr = bootflash_getaddr(bootinfo.bootimagename);
|
| 113 | + if (!addr) goto bootflashfailed;
|
109 | 114 | if (bootinfo.bootflashflags & 1)
|
110 | 115 | {
|
111 | | - if (ucl_decompress(addr, size, &_initstart, &size)) goto bootflashfailed;
|
| 116 | + if (ucl_decompress(addr, size, &_initstart, (uint32_t*)&size)) goto bootflashfailed;
|
112 | 117 | if (execimage(&_initstart) < 0) return;
|
113 | 118 | }
|
114 | 119 | else if (bootinfo.bootflashflags & 2)
|
— | — | @@ -120,10 +125,12 @@ |
121 | 126 | if (bootinfo.bootflashflags & 1)
|
122 | 127 | {
|
123 | 128 | void* addr = (void*)((((uint32_t)&_loadspaceend) - size) & ~(CACHEALIGN_SIZE - 1));
|
124 | | - bootflash_read(bootinfo.bootimagename, addr, 0, size);
|
125 | | - if (ucl_decompress(addr, size, &_initstart, &size)) goto bootflashfailed;
|
| 129 | + if (bootflash_read(bootinfo.bootimagename, addr, 0, size) != size)
|
| 130 | + goto bootflashfailed;
|
| 131 | + if (ucl_decompress(addr, size, &_initstart, (uint32_t*)&size)) goto bootflashfailed;
|
126 | 132 | }
|
127 | | - else bootflash_read(bootinfo.bootimagename, &_initstart, 0, size);
|
| 133 | + else if (bootflash_read(bootinfo.bootimagename, &_initstart, 0, size) != size)
|
| 134 | + goto bootflashfailed;
|
128 | 135 | if (execimage(&_initstart) < 0) return;
|
129 | 136 | #endif
|
130 | 137 | }
|
— | — | @@ -131,10 +138,10 @@ |
132 | 139 | #endif
|
133 | 140 | if (bootinfo.trymemmapped)
|
134 | 141 | {
|
135 | | - uint32_t size = bootinfo.memmappedsize;
|
| 142 | + int size = bootinfo.memmappedsize;
|
136 | 143 | if (bootinfo.bootflashflags & 1)
|
137 | 144 | {
|
138 | | - if (ucl_decompress(bootinfo.memmappedaddr, size, &_initstart, &size))
|
| 145 | + if (ucl_decompress(bootinfo.memmappedaddr, size, &_initstart, (uint32_t*)&size))
|
139 | 146 | goto memmappedfailed;
|
140 | 147 | if (execimage(&_initstart) < 0) return;
|
141 | 148 | }
|
Index: embios/trunk/SOURCES |
— | — | @@ -12,6 +12,7 @@ |
13 | 13 | target/ipodnano2g/ftl.c
|
14 | 14 | target/ipodnano2g/storage_nand.c
|
15 | 15 | target/ipodnano2g/clockgates.c
|
| 16 | +target/ipodnano2g/bootflash.c
|
16 | 17 | usb/synopsysotg.c
|
17 | 18 | #endif
|
18 | 19 |
|
Index: embios/trunk/target/ipodnano2g/bootflash.c |
— | — | @@ -0,0 +1,129 @@ |
| 2 | +//
|
| 3 | +//
|
| 4 | +// Copyright 2010 TheSeven
|
| 5 | +//
|
| 6 | +//
|
| 7 | +// This file is part of emBIOS.
|
| 8 | +//
|
| 9 | +// emBIOS is free software: you can redistribute it and/or
|
| 10 | +// modify it under the terms of the GNU General Public License as
|
| 11 | +// published by the Free Software Foundation, either version 2 of the
|
| 12 | +// License, or (at your option) any later version.
|
| 13 | +//
|
| 14 | +// emBIOS is distributed in the hope that it will be useful,
|
| 15 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 16 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
| 17 | +// See the GNU General Public License for more details.
|
| 18 | +//
|
| 19 | +// You should have received a copy of the GNU General Public License along
|
| 20 | +// with emBIOS. If not, see <http://www.gnu.org/licenses/>.
|
| 21 | +//
|
| 22 | +//
|
| 23 | +
|
| 24 | +
|
| 25 | +#include "global.h"
|
| 26 | +#include "bootflash.h"
|
| 27 | +#include "contextswitch.h"
|
| 28 | +#include "util.h"
|
| 29 | +
|
| 30 | +
|
| 31 | +#define nor ((uint8_t*)0x24000000)
|
| 32 | +#define norword ((uint32_t*)0x24000000)
|
| 33 | +#define norflsh ((volatile uint16_t*)0x24000000)
|
| 34 | +
|
| 35 | +
|
| 36 | +extern void control_nor_cache(bool enable);
|
| 37 | +
|
| 38 | +
|
| 39 | +static void* findflashfile(const char* filename, uint32_t* size)
|
| 40 | +{
|
| 41 | + uint32_t i;
|
| 42 | + for (i = 0; i < 0x1000; i += 0x10)
|
| 43 | + if (memcmp(&nor[i], filename, 8) == 0)
|
| 44 | + {
|
| 45 | + *size = norword[(i + 0xc) >> 2];
|
| 46 | + return &nor[norword[(i + 0x8) >> 2]];
|
| 47 | + }
|
| 48 | + return 0;
|
| 49 | +}
|
| 50 | +
|
| 51 | +int bootflash_filesize(const char* filename)
|
| 52 | +{
|
| 53 | + uint32_t size;
|
| 54 | + if (findflashfile(filename, &size)) return size & 0xfffff;
|
| 55 | + else return -1;
|
| 56 | +}
|
| 57 | +
|
| 58 | +int bootflash_attributes(const char* filename)
|
| 59 | +{
|
| 60 | + uint32_t size;
|
| 61 | + if (findflashfile(filename, &size)) return size >> 20;
|
| 62 | + else return -1;
|
| 63 | +}
|
| 64 | +
|
| 65 | +void* bootflash_getaddr(const char* filename)
|
| 66 | +{
|
| 67 | + uint32_t size;
|
| 68 | + return findflashfile(filename, &size);
|
| 69 | +}
|
| 70 | +
|
| 71 | +int bootflash_read(const char* filename, void* addr, int offset, int size)
|
| 72 | +{
|
| 73 | + uint32_t fsize;
|
| 74 | + uint8_t* file = (uint8_t*)findflashfile(filename, &fsize);
|
| 75 | + if (!file) return -1;
|
| 76 | + fsize &= 0xfffff;
|
| 77 | + if (offset + size > fsize) size = fsize - offset;
|
| 78 | + if (size > 0) memcpy(addr, &file[offset], size);
|
| 79 | + return size;
|
| 80 | +}
|
| 81 | +
|
| 82 | +void bootflash_readraw(void* addr, int offset, int size)
|
| 83 | +{
|
| 84 | + memcpy(addr, &nor[offset], size);
|
| 85 | +}
|
| 86 | +
|
| 87 | +void bootflash_writeraw(void* addr, int offset, int size)
|
| 88 | +{
|
| 89 | + uint32_t mode = enter_critical_section();
|
| 90 | + control_nor_cache(false);
|
| 91 | +
|
| 92 | + while (size > 0)
|
| 93 | + {
|
| 94 | + int remainder = MIN(0x1000 - (offset & 0xfff), size);
|
| 95 | + if (memcmp(&nor[offset], addr, remainder))
|
| 96 | + {
|
| 97 | + bool needserase = false;
|
| 98 | + int i;
|
| 99 | + for (i = 0; i < remainder; i += 2)
|
| 100 | + if (norflsh[(offset + i) >> 1] != 0xffff)
|
| 101 | + needserase = true;
|
| 102 | + if (needserase)
|
| 103 | + {
|
| 104 | + norflsh[0x5555] = 0xaa;
|
| 105 | + norflsh[0x2aaa] = 0x55;
|
| 106 | + norflsh[0x5555] = 0x80;
|
| 107 | + norflsh[0x5555] = 0xaa;
|
| 108 | + norflsh[0x2aaa] = 0x55;
|
| 109 | + norflsh[(offset & ~0xfff) >> 1] = 0x30;
|
| 110 | + while (norflsh[(offset & ~0xfff) >> 1] != 0xffff);
|
| 111 | + }
|
| 112 | + norflsh[0x5555] = 0xaa;
|
| 113 | + norflsh[0x2aaa] = 0x55;
|
| 114 | + norflsh[0x5555] = 0xa0;
|
| 115 | + norflsh[offset >> 1] = ((uint16_t*)addr)[offset >> 1];
|
| 116 | + while (norflsh[offset >> 1] != ((uint16_t*)addr)[offset >> 1]);
|
| 117 | + }
|
| 118 | + addr = (void*)(((uint32_t)addr) + remainder);
|
| 119 | + offset += remainder;
|
| 120 | + size -= remainder;
|
| 121 | + }
|
| 122 | +
|
| 123 | + control_nor_cache(true);
|
| 124 | + leave_critical_section(mode);
|
| 125 | +}
|
| 126 | +
|
| 127 | +void* bootflash_getrawaddr(int offset)
|
| 128 | +{
|
| 129 | + return &nor[offset];
|
| 130 | +}
|
Index: embios/trunk/target/ipodnano2g/bootflash.h |
— | — | @@ -0,0 +1,40 @@ |
| 2 | +//
|
| 3 | +//
|
| 4 | +// Copyright 2010 TheSeven
|
| 5 | +//
|
| 6 | +//
|
| 7 | +// This file is part of emBIOS.
|
| 8 | +//
|
| 9 | +// emBIOS is free software: you can redistribute it and/or
|
| 10 | +// modify it under the terms of the GNU General Public License as
|
| 11 | +// published by the Free Software Foundation, either version 2 of the
|
| 12 | +// License, or (at your option) any later version.
|
| 13 | +//
|
| 14 | +// emBIOS is distributed in the hope that it will be useful,
|
| 15 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 16 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
| 17 | +// See the GNU General Public License for more details.
|
| 18 | +//
|
| 19 | +// You should have received a copy of the GNU General Public License along
|
| 20 | +// with emBIOS. If not, see <http://www.gnu.org/licenses/>.
|
| 21 | +//
|
| 22 | +//
|
| 23 | +
|
| 24 | +
|
| 25 | +#ifndef __BOOTFLASH_H__
|
| 26 | +#define __BOOTFLASH_H__
|
| 27 | +
|
| 28 | +
|
| 29 | +#include "global.h"
|
| 30 | +
|
| 31 | +
|
| 32 | +int bootflash_filesize(const char* filename);
|
| 33 | +int bootflash_attributes(const char* filename);
|
| 34 | +void* bootflash_getaddr(const char* filename);
|
| 35 | +int bootflash_read(const char* filename, void* addr, int offset, int size);
|
| 36 | +void bootflash_readraw(void* addr, int offset, int size);
|
| 37 | +void bootflash_writeraw(void* addr, int offset, int size);
|
| 38 | +void* bootflash_getrawaddr(int offset);
|
| 39 | +
|
| 40 | +
|
| 41 | +#endif
|
Index: embios/trunk/target/ipodnano2g/crt0.S |
— | — | @@ -216,3 +216,42 @@ |
217 | 217 |
|
218 | 218 | val_3c700000:
|
219 | 219 | .word 0x3c700000
|
| 220 | +
|
| 221 | +
|
| 222 | +.section .text.control_nor_cache, "ax", %progbits
|
| 223 | +.align 2
|
| 224 | +.global control_nor_cache
|
| 225 | +.type control_nor_cache, %function
|
| 226 | +control_nor_cache:
|
| 227 | + mrc p15, 0, r3,c1,c0
|
| 228 | + bic r1, r3, #1
|
| 229 | + mcr p15, 0, r1,c1,c0
|
| 230 | + mov r1, #0
|
| 231 | + mcr p15, 0, r1,c7,c5
|
| 232 | +cnc_flushcache_loop:
|
| 233 | + mcr p15, 0, r1,c7,c14,2
|
| 234 | + add r2, r1, #0x10
|
| 235 | + mcr p15, 0, r2,c7,c14,2
|
| 236 | + add r2, r2, #0x10
|
| 237 | + mcr p15, 0, r2,c7,c14,2
|
| 238 | + add r2, r2, #0x10
|
| 239 | + mcr p15, 0, r2,c7,c14,2
|
| 240 | + adds r1, r1, #0x04000000
|
| 241 | + bne cnc_flushcache_loop
|
| 242 | + mcr p15, 0, r1,c7,c10,4
|
| 243 | + ands r0, r0, r0
|
| 244 | + mrc p15, 0, r1,c2,c0, 1
|
| 245 | + biceq r1, r1, #0x10
|
| 246 | + orrne r1, r1, #0x10
|
| 247 | + mcr p15, 0, r1,c2,c0, 1
|
| 248 | + mrc p15, 0, r1,c2,c0, 0
|
| 249 | + biceq r1, r1, #0x10
|
| 250 | + orrne r1, r1, #0x10
|
| 251 | + mcr p15, 0, r1,c2,c0, 0
|
| 252 | + mrc p15, 0, r1,c3,c0, 0
|
| 253 | + biceq r1, r1, #0x10
|
| 254 | + orrne r1, r1, #0x10
|
| 255 | + mcr p15, 0, r1,c3,c0, 0
|
| 256 | + mcr p15, 0, r3,c1,c0
|
| 257 | + mov pc, lr
|
| 258 | +.size control_nor_cache, .-control_nor_cache
|
Index: embios/trunk/target/ipodnano2g/target.h |
— | — | @@ -44,6 +44,9 @@ |
45 | 45 |
|
46 | 46 | #define HAVE_I2C
|
47 | 47 |
|
| 48 | +#define HAVE_BOOTFLASH
|
| 49 | +#define BOOTFLASH_IS_MEMMAPPED
|
| 50 | +
|
48 | 51 | #define HAVE_STORAGE
|
49 | 52 | #define HAVE_FLASH_STORAGE
|
50 | 53 | #define HAVE_STORAGE_FLUSH
|
Index: embios/trunk/usb/usb.c |
— | — | @@ -37,6 +37,9 @@ |
38 | 38 | #ifdef HAVE_I2C
|
39 | 39 | #include "i2c.h"
|
40 | 40 | #endif
|
| 41 | +#ifdef HAVE_BOOTFLASH
|
| 42 | +#include "bootflash.h"
|
| 43 | +#endif
|
41 | 44 |
|
42 | 45 |
|
43 | 46 | static uint8_t ctrlresp[2] CACHEALIGN_ATTR;
|
— | — | @@ -55,7 +58,9 @@ |
56 | 59 | DBGACTION_CWRITE,
|
57 | 60 | DBGACTION_CREAD,
|
58 | 61 | DBGACTION_CFLUSH,
|
59 | | - DBGACTION_EXECIMAGE
|
| 62 | + DBGACTION_EXECIMAGE,
|
| 63 | + DBGACTION_READBOOTFLASH,
|
| 64 | + DBGACTION_WRITEBOOTFLASH
|
60 | 65 | };
|
61 | 66 |
|
62 | 67 | static uint32_t dbgstack[0x100] STACK_ATTR;
|
— | — | @@ -65,6 +70,7 @@ |
66 | 71 | static int dbgi2cbus;
|
67 | 72 | static int dbgi2cslave;
|
68 | 73 | static int dbgactionaddr;
|
| 74 | +static int dbgactionoffset;
|
69 | 75 | static int dbgactionlength;
|
70 | 76 | static int dbgactionconsoles;
|
71 | 77 | static int dbgactiontype;
|
— | — | @@ -513,6 +519,20 @@ |
514 | 520 | if (set_dbgaction(DBGACTION_EXECIMAGE, 0)) break;
|
515 | 521 | dbgactionaddr = dbgrecvbuf[1];
|
516 | 522 | break;
|
| 523 | +#ifdef HAVE_BOOTFLASH
|
| 524 | + case 22: // READ BOOT FLASH
|
| 525 | + if (set_dbgaction(DBGACTION_READBOOTFLASH, 0)) break;
|
| 526 | + dbgactionaddr = dbgrecvbuf[1];
|
| 527 | + dbgactionoffset = dbgrecvbuf[2];
|
| 528 | + dbgactionlength = dbgrecvbuf[3];
|
| 529 | + break;
|
| 530 | + case 23: // WRITE BOOT FLASH
|
| 531 | + if (set_dbgaction(DBGACTION_WRITEBOOTFLASH, 0)) break;
|
| 532 | + dbgactionaddr = dbgrecvbuf[1];
|
| 533 | + dbgactionoffset = dbgrecvbuf[2];
|
| 534 | + dbgactionlength = dbgrecvbuf[3];
|
| 535 | + break;
|
| 536 | +#endif
|
517 | 537 | default:
|
518 | 538 | dbgsendbuf[0] = 2;
|
519 | 539 | size = 16;
|
— | — | @@ -601,6 +621,18 @@ |
602 | 622 | dbgasyncsendbuf[1] = execimage((void*)dbgactionaddr);
|
603 | 623 | usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
|
604 | 624 | break;
|
| 625 | +#ifdef HAVE_BOOTFLASH
|
| 626 | + case DBGACTION_READBOOTFLASH:
|
| 627 | + bootflash_readraw((void*)dbgactionaddr, dbgactionoffset, dbgactionlength);
|
| 628 | + dbgasyncsendbuf[0] = 1;
|
| 629 | + usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
|
| 630 | + break;
|
| 631 | + case DBGACTION_WRITEBOOTFLASH:
|
| 632 | + bootflash_writeraw((void*)dbgactionaddr, dbgactionoffset, dbgactionlength);
|
| 633 | + dbgasyncsendbuf[0] = 1;
|
| 634 | + usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
|
| 635 | + break;
|
| 636 | +#endif
|
605 | 637 | }
|
606 | 638 | dbgaction = DBGACTION_IDLE;
|
607 | 639 | }
|