2 e07 bootloader suite - boot menu
3 Copyright (c) 2009 Christopher Hall <hsw@openmoko.com>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #define APPLICATION_TITLE "boot menu"
21 #include "application.h"
34 #define MAXIMUM_BLOCKS 8
35 #define HEADER_MAGIC 0x4f4d4153
42 static const char spinner
[4] = "-\\|/";
45 int process(int block
, int status
);
46 void print_cpu_type(void);
49 // this must be the first executable code as the loader executes from the first program address
50 ReturnType
menu(int block
, int status
)
53 APPLICATION_INITIALISE();
55 i
= process(block
, status
);
58 APPLICATION_FINALISE(i
, 0);
61 static void fill(u8 value
)
65 u8
*fb
= (u8
*)LCD_VRAM
;
67 for (y
= 0; y
< LCD_HEIGHT_LINES
; ++y
) {
68 for (x
= 0; x
< LCD_VRAM_WIDTH_BYTES
; ++x
) {
73 static void display_image(u8 background
, u8 toggle
)
75 int xOffset
= (LCD_WIDTH_PIXELS
- splash_image
.width
) / (2 * 8);
76 u8
*fb
= (u8
*)LCD_VRAM
;
79 unsigned int width
= (splash_image
.width
+ 7) / 8;
80 const u8
*src
= splash_image
.data
;
83 fb
+= (LCD_HEIGHT_LINES
- splash_image
.height
) / 2 * LCD_VRAM_WIDTH_BYTES
;
84 for (y
= 0; y
< splash_image
.height
; ++y
) {
85 for (x
= 0; x
< width
; ++x
) {
86 fb
[x
+ xOffset
] = toggle
^ *src
++;
88 fb
+= LCD_VRAM_WIDTH_BYTES
;
92 int process(int block
, int status
)
96 u8 valid
[MAXIMUM_BLOCKS
] = {0};
98 display_image(0x00, 0xff);
103 for (i
= 0; i
< 20; ++i
) {
104 for (k
= 0; k
< sizeof(spinner
); ++k
) {
106 print_char(spinner
[k
]);
109 if (serial_input_available()) {
118 print("\nBoot Menu\n\n");
120 // not zero since this program should be in block zero
121 for (i
= 1; i
< MAXIMUM_BLOCKS
; ++i
) {
122 eeprom_load((i
<< 13), (void *)&header
, sizeof(header
));
124 if (HEADER_MAGIC
== header
.magic
) {
125 print_char(('A' - 1) + i
);
127 for (k
= 0; k
< sizeof(header
.name
); ++k
) {
128 if ('\0' == header
.name
[k
] || '\xff' == header
.name
[k
]) {
131 print_char(header
.name
[k
]);
137 print("\nEnter selection: ");
139 k
= serial_input_char();
140 if ('A' <= k
&& 'Z' >= k
) {
144 if (0 < i
&& MAXIMUM_BLOCKS
> i
) {
158 void print_cpu_type(void)
162 case CORE_ID_STANDARD
:
163 print(CORE_ID_STANDARD_DESC
);
166 print(CORE_ID_MINI_DESC
);
168 case CORE_ID_ADVANCED
:
169 print(CORE_ID_ADVANCED_DESC
);
172 print(CORE_ID_PE_DESC
);
175 print(CORE_ID_PE_LE_DESC
);
178 print("CORE unknown");
182 switch (PRODUCT_ID
) {
184 print(PRODUCT_ID_3_DESC
);
187 print(PRODUCT_ID_4_DESC
);
190 print(PRODUCT_ID_3E_DESC
);
193 print(PRODUCT_ID_3L_DESC
);
196 print_byte(MODEL_ID
);
198 print_byte(VERSION_ID
);