Subversion Repositories freemyipod

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 theseven 1
//
2
//
3
//    Copyright 2010 TheSeven
4
//
5
//
6
//    This file is part of emBIOS.
7
//
8
//    emBIOS is free software: you can redistribute it and/or
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
//
13
//    emBIOS is distributed in the hope that it will be useful,
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
19
//    with emBIOS.  If not, see <http://www.gnu.org/licenses/>.
20
//
21
//
22
 
23
 
24
#include "global.h"
14 theseven 25
#include "thread.h"
26
#include "console.h"
85 theseven 27
#include "power.h"
28
#include "interrupt.h"
89 theseven 29
#include "ucl.h"
30
#include "util.h"
31
#include "execimage.h"
85 theseven 32
#ifdef HAVE_LCD
15 theseven 33
#include "lcd.h"
2 theseven 34
#include "lcdconsole.h"
85 theseven 35
#endif
36
#ifdef HAVE_I2C
15 theseven 37
#include "i2c.h"
85 theseven 38
#endif
39
#ifdef HAVE_USB
40
#include "usb/usb.h"
41
#endif
42
#ifdef HAVE_STORAGE
58 theseven 43
#include "storage.h"
44
#include "disk.h"
89 theseven 45
#include "file.h"
85 theseven 46
#endif
2 theseven 47
 
87 theseven 48
 
89 theseven 49
struct bootinfo_t
50
{
51
    char signature[8];
52
    int version;
53
    bool trydataflash;
54
    char dataflashpath[256];
55
    bool dataflashflags;
56
    bool trybootflash;
57
    char bootimagename[8];
58
    bool bootflashflags;
59
    bool trymemmapped;
60
    void* memmappedaddr;
61
    uint32_t memmappedsize;
62
    bool memmappedflags;
63
};
64
 
65
 
32 theseven 66
static const char welcomestring[] INITCONST_ATTR = "emBIOS v" VERSION " r" VERSION_SVN "\n\n";
66 theseven 67
static const char initthreadname[] INITCONST_ATTR = "Initialisation thread";
89 theseven 68
static uint32_t initstack[0x400] INITSTACK_ATTR;
69
extern int _loadspaceend;
70
extern int _initstart;
71
const struct bootinfo_t bootinfo_src INITCONST_ATTR =
72
{
73
    .signature = "emBIboot",
74
    .version = 0,
75
    .trydataflash = false,
76
    .trybootflash = false,
77
    .trymemmapped = false
78
};
15 theseven 79
 
87 theseven 80
 
89 theseven 81
void boot()
82
{
83
    struct bootinfo_t bootinfo = bootinfo_src;
84
#ifdef HAVE_STORAGE
85
    if (bootinfo.trydataflash)
86
    {
87
        int fd = file_open(bootinfo.dataflashpath, O_RDONLY);
88
        if (fd < 0) goto dataflashfailed;
89
        uint32_t size = filesize(fd);
90
        if (bootinfo.dataflashflags & 1)
91
        {
92
            void* addr = (void*)((((uint32_t)&_loadspaceend) - size) & ~(CACHEALIGN_SIZE - 1));
93
            if (read(fd, addr, size) != size) goto dataflashfailed;
94
            if (ucl_decompress(addr, size, &_initstart, &size)) goto dataflashfailed;
95
        }
96
        else if (read(fd, &_initstart, size) != size) goto dataflashfailed;
97
        if (execimage(&_initstart) < 0) return;
98
    }
99
dataflashfailed:
100
#endif
101
#ifdef HAVE_BOOTFLASH
102
    if (bootinfo.trybootflash)
103
    {
104
        uint32_t size = bootflash_filesize(bootinfo.bootimagename);
105
        if (size < 0) goto bootflashfailed;
106
#ifdef BOOTFLASH_IS_MEMMAPPED
107
        void* addr = bootflash_getaddr(bootinfo.bootimagename);
108
        if (bootinfo.bootflashflags & 1)
109
        {
110
            if (ucl_decompress(addr, size, &_initstart, &size)) goto bootflashfailed;
111
            if (execimage(&_initstart) < 0) return;
112
        }
113
        else if (bootinfo.bootflashflags & 2)
114
        {
115
            memcpy(&_initstart, addr, size);
116
            if (execimage(&_initstart) < 0) return;
117
        }
118
        else execimage(addr);
119
#else
120
        if (bootinfo.bootflashflags & 1)
121
        {
122
            void* addr = (void*)((((uint32_t)&_loadspaceend) - size) & ~(CACHEALIGN_SIZE - 1));
123
            bootflash_read(bootinfo.bootimagename, addr, 0, size);
124
            if (ucl_decompress(addr, size, &_initstart, &size)) goto bootflashfailed;
125
        }
126
        else bootflash_read(bootinfo.bootimagename, &_initstart, 0, size);
127
        if (execimage(&_initstart) < 0) return;
128
#endif
129
    }
130
bootflashfailed:
131
#endif
132
    if (bootinfo.trymemmapped)
133
    {
134
        uint32_t size = bootinfo.memmappedsize;
135
        if (bootinfo.bootflashflags & 1)
136
        {
137
            if (ucl_decompress(bootinfo.memmappedaddr, size, &_initstart, &size))
138
                goto memmappedfailed;
139
            if (execimage(&_initstart) < 0) return;
140
        }
141
        else if (bootinfo.bootflashflags & 2)
142
        {
143
            memcpy(&_initstart, bootinfo.memmappedaddr, size);
144
            if (execimage(&_initstart) < 0) return;
145
        }
146
        else if (execimage(bootinfo.memmappedaddr) < 0) return;
147
    }
148
memmappedfailed:
149
    if (bootinfo.trydataflash || bootinfo.trybootflash || bootinfo.trymemmapped)
150
        cputs(CONSOLE_BOOT, "Could not find a usable boot image!\n");
151
    cputs(CONSOLE_BOOT, "Waiting for USB commands\n\n");
152
}
153
 
66 theseven 154
void initthread() INITCODE_ATTR;
155
void initthread()
2 theseven 156
{
85 theseven 157
    cputs(CONSOLE_BOOT, welcomestring);
158
	#ifdef HAVE_I2C
15 theseven 159
    i2c_init();
85 theseven 160
	#endif
54 theseven 161
    power_init();
85 theseven 162
	#ifdef HAVE_USB
15 theseven 163
    usb_init();
85 theseven 164
	#endif
165
	#ifdef HAVE_STORAGE
66 theseven 166
    DEBUGF("Initializing storage drivers...");
58 theseven 167
    storage_init();
66 theseven 168
    DEBUGF("Initializing storage subsystem...");
58 theseven 169
    disk_init_subsystem();
66 theseven 170
    DEBUGF("Reading partition tables...");
58 theseven 171
    disk_init();
66 theseven 172
    DEBUGF("Mounting partitions...");
58 theseven 173
    disk_mount_all();
85 theseven 174
	#endif
66 theseven 175
    DEBUGF("Finished initialisation sequence");
89 theseven 176
    boot();
66 theseven 177
}
178
 
179
void init() INITCODE_ATTR;
180
void init()
181
{
182
    scheduler_init();
183
    console_init();
85 theseven 184
	#ifdef HAVE_LCD
66 theseven 185
    lcd_init();
186
    lcdconsole_init();
85 theseven 187
	#endif
66 theseven 188
    interrupt_init();
189
    thread_create(initthreadname, initthread, initstack,
190
                  sizeof(initstack), USER_THREAD, 127, true);
191
}