OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright 2010, Google Inc. | |
Che-Liang Chiou
2011/03/09 02:37:53
2011. I would suggest we use the "Chromium OS Auth
Tom Wai-Hong Tam
2011/03/09 10:15:05
Done.
| |
3 * All rights reserved. | |
4 * | |
5 * Redistribution and use in source and binary forms, with or without | |
6 * modification, are permitted provided that the following conditions are | |
7 * met: | |
8 * | |
9 * * Redistributions of source code must retain the above copyright | |
10 * notice, this list of conditions and the following disclaimer. | |
11 * * Redistributions in binary form must reproduce the above | |
12 * copyright notice, this list of conditions and the following disclaimer | |
13 * in the documentation and/or other materials provided with the | |
14 * distribution. | |
15 * * Neither the name of Google Inc. nor the names of its | |
16 * contributors may be used to endorse or promote products derived from | |
17 * this software without specific prior written permission. | |
18 * | |
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
30 * | |
31 * Alternatively, this software may be distributed under the terms of the | |
32 * GNU General Public License ("GPL") version 2 as published by the Free | |
33 * Software Foundation. | |
34 */ | |
35 | |
36 /* Debug commands for Chrome OS recovery mode firmware */ | |
37 | |
38 #include <common.h> | |
39 #include <command.h> | |
40 #include <mmc.h> | |
41 #include <usb.h> | |
42 | |
43 #include <bmpblk_header.h> | |
44 #include <chromeos/gbb_bmpblk.h> | |
45 #include <chromeos/hardware_interface.h> | |
46 | |
47 #include <gbb_header.h> | |
48 #include <load_firmware_fw.h> | |
49 #include <load_kernel_fw.h> | |
50 #include <chromeos/boot_device_impl.h> | |
51 | |
52 #ifdef VBOOT_DEBUG | |
53 #define WARN_ON_FAILURE(action) do { \ | |
54 int return_code = (action); \ | |
55 if (return_code != 0) \ | |
56 debug("Boot Stub: %s failed, returning %d\n", \ | |
57 #action, return_code); \ | |
58 } while (0) | |
59 #else | |
60 #define WARN_ON_FAILURE(action) action | |
61 #endif | |
62 | |
63 int lcd_clear(); | |
Che-Liang Chiou
2011/03/09 02:37:53
Where is this function defined? Would you add a co
Tom Wai-Hong Tam
2011/03/09 10:15:05
Fixed it. Now it is included in lcd.h.
| |
64 | |
65 int g_is_dev = 0; | |
Che-Liang Chiou
2011/03/09 02:37:53
Why use a global variable, instead of polling the
Tom Wai-Hong Tam
2011/03/09 10:15:05
Checking it once can keep the logic simple and sec
| |
66 | |
67 static void sleep_ms(int msecond) | |
68 { | |
69 const ulong start = get_timer(0); | |
70 const ulong delay = msecond * CONFIG_SYS_HZ / 1000; | |
71 | |
72 while (!ctrlc() && get_timer(start) < delay) | |
73 udelay(100); | |
74 } | |
75 | |
76 static int is_mmc_storage_present(void) | |
77 { | |
78 return mmc_legacy_init(1) == 0; | |
Che-Liang Chiou
2011/03/09 06:55:26
Why pass 1? Is this value cross-platform? If not,
Tom Wai-Hong Tam
2011/03/09 10:15:05
There are 2 MMC devices in the system. 0 is the ma
| |
79 } | |
80 | |
81 static int is_usb_storage_present(void) | |
82 { | |
83 int i; | |
84 usb_stop(); | |
Che-Liang Chiou
2011/03/09 06:55:26
Do we have to restart usb here? Should add a FIXME
Tom Wai-Hong Tam
2011/03/09 10:15:05
OK. I added a TODO.
| |
85 i = usb_init(); | |
86 #ifdef CONFIG_USB_STORAGE | |
87 if (i >= 0) | |
88 return usb_stor_scan(1) == 0; | |
Che-Liang Chiou
2011/03/09 06:55:26
Same as above. (Why 1?)
Tom Wai-Hong Tam
2011/03/09 10:15:05
Now 1 is the mode that to probe storage device.
| |
89 #else | |
90 return i; | |
91 #endif | |
92 } | |
93 | |
94 static int write_log(void) | |
95 { | |
96 /* TODO Implement it when Chrome OS firmware logging is ready. */ | |
97 return 0; | |
98 } | |
99 | |
100 static int clear_ram_not_in_use(void) | |
101 { | |
102 /* TODO Implement it when the memory layout is defined. */ | |
103 return 0; | |
104 } | |
105 | |
106 int load_kernel(uint8_t *load_addr, size_t load_size) | |
Che-Liang Chiou
2011/03/09 06:55:26
Normal firmware also needs to call LoadKernel(). I
Tom Wai-Hong Tam
2011/03/09 10:15:05
Will change it when your CL is committed.
| |
107 { | |
108 LoadKernelParams par; | |
109 block_dev_desc_t *dev_desc; | |
110 VbNvContext vnc; | |
111 int i, status; | |
112 GoogleBinaryBlockHeader *gbbh = (void *)(TEXT_BASE + CONFIG_OFFSET_GBB); | |
Che-Liang Chiou
2011/03/09 02:37:53
This address might not be valid. Please use the in
Tom Wai-Hong Tam
2011/03/09 10:15:05
Done.
| |
113 char buffer[CONFIG_SYS_CBSIZE]; | |
114 | |
115 if ((dev_desc = get_bootdev()) == NULL) { | |
116 printf("No boot device set yet\n"); | |
117 return 1; | |
118 } | |
119 | |
120 par.header_sign_key_blob = (uint8_t*)gbbh + gbbh->recovery_key_offset; | |
121 par.bytes_per_lba = (uint64_t) dev_desc->blksz; | |
122 par.ending_lba = (uint64_t) get_limit() - 1; | |
123 par.kernel_buffer = load_addr; | |
124 par.kernel_buffer_size = load_size; | |
125 par.boot_flags = BOOT_FLAG_RECOVERY | BOOT_FLAG_SKIP_ADDR_CHECK; | |
126 /* TODO: load vnc.raw from NV storage */ | |
127 par.nv_context = &vnc; | |
128 | |
129 if (g_is_dev) { | |
130 par.boot_flags |= BOOT_FLAG_DEVELOPER; | |
131 } | |
132 | |
133 status = LoadKernel(&par); | |
134 | |
135 if (vnc.raw_changed) { | |
136 /* TODO: save vnc.raw to NV storage */ | |
137 } | |
138 | |
139 switch (status) { | |
140 case LOAD_KERNEL_SUCCESS: | |
141 puts("Success; good kernel found on device\n"); | |
142 printf("partition_number: %lld\n", | |
143 par.partition_number); | |
144 printf("bootloader_address: 0x%llx", | |
145 par.bootloader_address); | |
146 printf("bootloader_size: 0x%llx", par.bootloader_size); | |
147 puts("partition_guid:"); | |
148 for (i = 0; i < 16; i++) | |
149 printf(" %02x", par.partition_guid[i]); | |
150 putc('\n'); | |
151 | |
152 lcd_clear(); | |
153 | |
154 strcpy(buffer, "console=ttyS0,115200n8 "); | |
155 strcat(buffer, getenv("platform_extras")); | |
156 setenv("bootargs", buffer); | |
157 sprintf(buffer, "%lld", par.partition_number + 1); | |
158 setenv("rootpart", buffer); | |
159 | |
160 source(CONFIG_LOADADDR + par.bootloader_address - | |
161 0x100000, NULL); | |
162 run_command("bootm ${loadaddr}", 0); | |
163 break; | |
164 case LOAD_KERNEL_NOT_FOUND: | |
165 puts("No kernel found on device\n"); | |
166 break; | |
167 case LOAD_KERNEL_INVALID: | |
168 puts("Only invalid kernels found on device\n"); | |
169 break; | |
170 case LOAD_KERNEL_RECOVERY: | |
171 puts("Internal error; reboot to recovery mode\n"); | |
172 break; | |
173 case LOAD_KERNEL_REBOOT: | |
174 puts("Internal error; reboot to current mode\n"); | |
175 break; | |
176 default: | |
177 printf("Unexpected return status from LoadKernel: %d\n", | |
178 status); | |
179 return 1; | |
180 } | |
181 return 0; | |
182 } | |
183 | |
184 static int load_recovery_image_in_mmc(void) | |
185 { | |
186 setenv("devname", "mmcblk1p"); | |
187 set_bootdev("mmc", 1, 0); | |
188 return load_kernel((uint8_t *)CONFIG_LOADADDR, 0x01000000); | |
189 } | |
190 | |
191 static int load_recovery_image_in_usb(void) | |
192 { | |
193 setenv("devname", "sda"); | |
194 set_bootdev("usb", 0, 0); | |
195 return load_kernel((uint8_t *)CONFIG_LOADADDR, 0x01000000); | |
196 } | |
197 | |
198 static int show_screen(ScreenIndex scr) | |
199 { | |
200 static ScreenIndex cur_scr; | |
201 if (cur_scr == scr) { | |
202 return 0; | |
203 } else { | |
204 cur_scr = scr; | |
205 return display_screen_in_bmpblk( | |
206 (uint8_t *)(TEXT_BASE + CONFIG_OFFSET_GBB), scr); | |
Che-Liang Chiou
2011/03/09 02:37:53
This address of GBB might not be valid. Please use
Tom Wai-Hong Tam
2011/03/09 10:15:05
Done.
| |
207 } | |
208 } | |
209 | |
210 int do_cros_rec(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | |
211 { | |
212 ScreenIndex scr; | |
Che-Liang Chiou
2011/03/09 02:37:53
What's scr used for? I don't see any use of it exc
Tom Wai-Hong Tam
2011/03/09 10:15:05
My mistake. Fixed.
| |
213 WARN_ON_FAILURE(write_log()); | |
214 WARN_ON_FAILURE(clear_ram_not_in_use()); | |
215 | |
216 g_is_dev = is_developer_mode_gpio_asserted(); | |
217 | |
218 if (!g_is_dev) { | |
219 while (is_mmc_storage_present() || is_usb_storage_present()) { | |
220 scr = SCREEN_RECOVERY_MODE; | |
Che-Liang Chiou
2011/03/09 06:55:26
Never use this variable hereafter.
Tom Wai-Hong Tam
2011/03/09 10:15:05
Fixed.
| |
221 WARN_ON_FAILURE(show_screen(SCREEN_RECOVERY_MODE)); | |
222 sleep_ms(200); | |
223 } | |
224 } | |
225 | |
226 for (;;) { | |
227 while (!is_mmc_storage_present() && !is_usb_storage_present()) { | |
228 WARN_ON_FAILURE(show_screen(SCREEN_RECOVERY_NO_OS)); | |
229 sleep_ms(200); | |
230 } | |
231 if (is_mmc_storage_present()) { | |
232 WARN_ON_FAILURE(load_recovery_image_in_mmc()); | |
233 } | |
234 if (is_usb_storage_present()) { | |
235 WARN_ON_FAILURE(load_recovery_image_in_usb()); | |
236 } | |
237 WARN_ON_FAILURE(show_screen(SCREEN_RECOVERY_MISSING_OS)); | |
238 sleep_ms(100); | |
239 } | |
240 | |
241 /* This point is never reached */ | |
242 return 0; | |
243 } | |
244 | |
245 U_BOOT_CMD(cros_rec, 1, 1, do_cros_rec, "cros_rec", "long help"); | |
OLD | NEW |