Subversion Repositories freemyipod

Rev

Rev 968 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
304 theseven 1
//
2
//
3
//    Copyright 2010 TheSeven
4
//
5
//
427 farthen 6
//    This file is part of emCORE.
304 theseven 7
//
427 farthen 8
//    emCORE is free software: you can redistribute it and/or
304 theseven 9
//    modify it under the terms of the GNU General Public License as
10
//    published by the Free Software Foundation, either version 2 of the
11
//    License, or (at your option) any later version.
12
//
427 farthen 13
//    emCORE is distributed in the hope that it will be useful,
304 theseven 14
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
//    See the GNU General Public License for more details.
17
//
18
//    You should have received a copy of the GNU General Public License along
427 farthen 19
//    with emCORE.  If not, see <http://www.gnu.org/licenses/>.
304 theseven 20
//
21
//
22
 
23
 
24
#include "global.h"
961 theseven 25
#include "bootflash.h"
304 theseven 26
#include "clickwheel.h"
961 theseven 27
#include "clockgates.h"
28
#include "s5l8702.h"
304 theseven 29
 
30
 
961 theseven 31
#define sysi ((uint8_t*)0x2203fdf8)
32
#define sysiword ((uint32_t*)0x2203fdf8)
33
 
34
 
304 theseven 35
void targetinit_late()
36
{
961 theseven 37
    int i;
38
 
304 theseven 39
    clickwheel_init();
968 theseven 40
    int buttons = clickwheel_get_state() & 0x1f;
41
    if (buttons == 0x11)
42
    {
43
        cputs(CONSOLE_BOOT, "MENU+SELECT is being pressed.\n"
44
                            "Continue pressing these buttons to enter DFU mode.\n");
45
        while (buttons == 0x11)
46
        {
47
            sleep(100000);
48
            buttons = clickwheel_get_state() & 0x1f;
49
        }
50
        cputs(CONSOLE_BOOT, "MENU+SELECT was released. Continuing normal boot.\n");
51
    }    
961 theseven 52
 
53
    uint8_t* nor = (uint8_t*)memalign(0x10, 0x1000);
54
    uint32_t* norword = (uint32_t*)nor;
55
    if (!nor) return;
56
    bootflash_readraw(nor, 0, 0x1000);
57
    uint32_t scfg_size = norword[1];
58
    uint32_t scfg_entrycount = norword[5];
59
    if (norword[0] == 0x53436667 && scfg_size <= 0x1000
60
     && scfg_entrycount * 0x14 + 0x18 == scfg_size)
61
    {
62
        memset(sysi, 0, 0x128);
63
        sysiword[0] = 0x53797349;
64
        sysiword[1] = 4;
65
        sysiword[0x22] = 0x414e;
66
        sysiword[0x38] = 0x4000000;
67
        sysiword[0x39] = 0x8000000;
68
        sysiword[0x3a] = 0x40000;
69
        sysiword[0x3b] = 0x22000000;
70
        sysiword[0x3c] = 0x100000;
71
        sysiword[0x3d] = 0x24000000;
72
        sysiword[0x46] = 0x7672736e;
73
        sysiword[0x47] = 0x1308004;
74
        sysiword[0x48] = 0x53797349;
75
        sysiword[0x49] = 0x2203fdf8;
76
        for (i = 0; i < scfg_entrycount; i++)
77
            switch (norword[6 + i * 5])
78
            {
79
                case 0x53724e6d: // SrNm
80
                    memcpy(&sysi[0x18], &norword[6 + i * 5 + 1], 16);
81
                    break;
82
                case 0x46774964: // FwId
83
                    memcpy(&sysi[0x38], &norword[6 + i * 5 + 2], 8);
84
                    break;
85
                case 0x48775672: // HwVr
86
                    sysiword[0x21] = norword[6 + i * 5 + 2];
87
                    break;
88
                case 0x5265676e: // Regn
89
                    if (nor[24 + i * 0x14 + 4] == 1 && nor[24 + i * 0x14 + 5] == 0)
90
                        memcpy(&sysi[0x92], &norword[6 + i * 5 + 2], 4);
91
                    break;
92
                case 0x4d6f6423: // Mod#
93
                    memcpy(&sysi[0x98], &norword[6 + i * 5 + 1], 16);
94
                    break;
95
                case 0x436f6463: // Codc
96
                    sysiword[0x45] = norword[6 + i * 5 + 1];
97
                    break;
98
                case 0x53775672: // SwVr
99
                    memcpy(&sysi[0x108], &norword[6 + i * 5 + 1], 16);
100
                    break;
101
            }
102
		switch (sysiword[0x21])
103
		{
104
			case 0x130100:
105
				sysiword[0x47] = 0x1308004;
106
				break;
107
			case 0x130200:
108
				sysiword[0x47] = 0x1708004;
109
				break;
110
		}
111
    }
112
    free(nor);
304 theseven 113
}
961 theseven 114
 
115
void targetinit_execfirmware() ICODE_ATTR;
116
void targetinit_execfirmware()
117
{
118
    clockgate_enable(CLOCKGATE_I2C_0, true);
119
    while (IIC10(0));
120
    IICCON(0) = 0x184;
121
}
122