freemyipod r95 - Code Review

Jump to: navigation, search
Repository:freemyipod
Revision:r94‎ | r95 | r96 >
Date:17:12, 11 August 2010
Author:theseven
Status:new
Tags:
Comment:
Add support for accessing the boot flash on Nano2G
Modified paths:
  • /embios/trunk/SOURCES (modified) (history)
  • /embios/trunk/init.c (modified) (history)
  • /embios/trunk/target/ipodnano2g/bootflash.c (added) (history)
  • /embios/trunk/target/ipodnano2g/bootflash.h (added) (history)
  • /embios/trunk/target/ipodnano2g/crt0.S (modified) (history)
  • /embios/trunk/target/ipodnano2g/target.h (modified) (history)
  • /embios/trunk/usb/usb.c (modified) (history)

Diff [purge]

Index: embios/trunk/init.c
@@ -44,6 +44,9 @@
4545 #include "disk.h"
4646 #include "file.h"
4747 #endif
 48+#ifdef HAVE_BOOTFLASH
 49+#include "bootflash.h"
 50+#endif
4851
4952
5053 struct bootinfo_t
@@ -58,7 +61,7 @@
5962 bool bootflashflags;
6063 bool trymemmapped;
6164 void* memmappedaddr;
62 - uint32_t memmappedsize;
 65+ int memmappedsize;
6366 bool memmappedflags;
6467 };
6568
@@ -86,12 +89,13 @@
8790 {
8891 int fd = file_open(bootinfo.dataflashpath, O_RDONLY);
8992 if (fd < 0) goto dataflashfailed;
90 - uint32_t size = filesize(fd);
 93+ int size = filesize(fd);
 94+ if (size < 0) goto dataflashfailed;
9195 if (bootinfo.dataflashflags & 1)
9296 {
9397 void* addr = (void*)((((uint32_t)&_loadspaceend) - size) & ~(CACHEALIGN_SIZE - 1));
9498 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;
96100 }
97101 else if (read(fd, &_initstart, size) != size) goto dataflashfailed;
98102 if (execimage(&_initstart) < 0) return;
@@ -101,13 +105,14 @@
102106 #ifdef HAVE_BOOTFLASH
103107 if (bootinfo.trybootflash)
104108 {
105 - uint32_t size = bootflash_filesize(bootinfo.bootimagename);
 109+ int size = bootflash_filesize(bootinfo.bootimagename);
106110 if (size < 0) goto bootflashfailed;
107111 #ifdef BOOTFLASH_IS_MEMMAPPED
108112 void* addr = bootflash_getaddr(bootinfo.bootimagename);
 113+ if (!addr) goto bootflashfailed;
109114 if (bootinfo.bootflashflags & 1)
110115 {
111 - if (ucl_decompress(addr, size, &_initstart, &size)) goto bootflashfailed;
 116+ if (ucl_decompress(addr, size, &_initstart, (uint32_t*)&size)) goto bootflashfailed;
112117 if (execimage(&_initstart) < 0) return;
113118 }
114119 else if (bootinfo.bootflashflags & 2)
@@ -120,10 +125,12 @@
121126 if (bootinfo.bootflashflags & 1)
122127 {
123128 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;
126132 }
127 - else bootflash_read(bootinfo.bootimagename, &_initstart, 0, size);
 133+ else if (bootflash_read(bootinfo.bootimagename, &_initstart, 0, size) != size)
 134+ goto bootflashfailed;
128135 if (execimage(&_initstart) < 0) return;
129136 #endif
130137 }
@@ -131,10 +138,10 @@
132139 #endif
133140 if (bootinfo.trymemmapped)
134141 {
135 - uint32_t size = bootinfo.memmappedsize;
 142+ int size = bootinfo.memmappedsize;
136143 if (bootinfo.bootflashflags & 1)
137144 {
138 - if (ucl_decompress(bootinfo.memmappedaddr, size, &_initstart, &size))
 145+ if (ucl_decompress(bootinfo.memmappedaddr, size, &_initstart, (uint32_t*)&size))
139146 goto memmappedfailed;
140147 if (execimage(&_initstart) < 0) return;
141148 }
Index: embios/trunk/SOURCES
@@ -12,6 +12,7 @@
1313 target/ipodnano2g/ftl.c
1414 target/ipodnano2g/storage_nand.c
1515 target/ipodnano2g/clockgates.c
 16+target/ipodnano2g/bootflash.c
1617 usb/synopsysotg.c
1718 #endif
1819
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 @@
217217
218218 val_3c700000:
219219 .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 @@
4545
4646 #define HAVE_I2C
4747
 48+#define HAVE_BOOTFLASH
 49+#define BOOTFLASH_IS_MEMMAPPED
 50+
4851 #define HAVE_STORAGE
4952 #define HAVE_FLASH_STORAGE
5053 #define HAVE_STORAGE_FLUSH
Index: embios/trunk/usb/usb.c
@@ -37,6 +37,9 @@
3838 #ifdef HAVE_I2C
3939 #include "i2c.h"
4040 #endif
 41+#ifdef HAVE_BOOTFLASH
 42+#include "bootflash.h"
 43+#endif
4144
4245
4346 static uint8_t ctrlresp[2] CACHEALIGN_ATTR;
@@ -55,7 +58,9 @@
5659 DBGACTION_CWRITE,
5760 DBGACTION_CREAD,
5861 DBGACTION_CFLUSH,
59 - DBGACTION_EXECIMAGE
 62+ DBGACTION_EXECIMAGE,
 63+ DBGACTION_READBOOTFLASH,
 64+ DBGACTION_WRITEBOOTFLASH
6065 };
6166
6267 static uint32_t dbgstack[0x100] STACK_ATTR;
@@ -65,6 +70,7 @@
6671 static int dbgi2cbus;
6772 static int dbgi2cslave;
6873 static int dbgactionaddr;
 74+static int dbgactionoffset;
6975 static int dbgactionlength;
7076 static int dbgactionconsoles;
7177 static int dbgactiontype;
@@ -513,6 +519,20 @@
514520 if (set_dbgaction(DBGACTION_EXECIMAGE, 0)) break;
515521 dbgactionaddr = dbgrecvbuf[1];
516522 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
517537 default:
518538 dbgsendbuf[0] = 2;
519539 size = 16;
@@ -601,6 +621,18 @@
602622 dbgasyncsendbuf[1] = execimage((void*)dbgactionaddr);
603623 usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
604624 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
605637 }
606638 dbgaction = DBGACTION_IDLE;
607639 }