OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2011 The Chromium OS Authors. All rights reserved. | 2 * Copyright (c) 2011 The Chromium OS Authors. All rights reserved. |
3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
5 * | 5 * |
6 * Alternatively, this software may be distributed under the terms of the | 6 * Alternatively, this software may be distributed under the terms of the |
7 * GNU General Public License ("GPL") version 2 as published by the Free | 7 * GNU General Public License ("GPL") version 2 as published by the Free |
8 * Software Foundation. | 8 * Software Foundation. |
9 */ | 9 */ |
10 | 10 |
11 #include <common.h> | 11 #include <common.h> |
12 #include <malloc.h> | 12 #include <malloc.h> |
13 #include <part.h> | 13 #include <part.h> |
14 #include <chromeos/os_storage.h> | 14 #include <chromeos/os_storage.h> |
15 | 15 |
| 16 /* TODO For load fmap; remove when not used */ |
| 17 #include <chromeos/firmware_storage.h> |
| 18 |
| 19 /* TODO For strcpy; remove when not used */ |
| 20 #include <linux/string.h> |
| 21 |
| 22 /* TODO remove when not used */ |
| 23 extern uint64_t get_nvcxt_lba(void); |
| 24 |
16 #include <boot_device.h> | 25 #include <boot_device.h> |
17 #include <load_kernel_fw.h> | 26 #include <load_kernel_fw.h> |
18 #include <vboot_nvstorage.h> | 27 #include <vboot_nvstorage.h> |
19 #include <vboot_struct.h> | 28 #include <vboot_struct.h> |
20 | 29 |
21 #define PREFIX "boot_device: " | 30 #define PREFIX "boot_device: " |
22 | 31 |
23 #define BACKUP_LBA_OFFSET 0x20 | 32 #define BACKUP_LBA_OFFSET 0x20 |
24 | 33 |
25 static struct { | 34 static struct { |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 return 0; | 162 return 0; |
154 } | 163 } |
155 | 164 |
156 #undef PREFIX | 165 #undef PREFIX |
157 #define PREFIX "load_kernel_wrapper: " | 166 #define PREFIX "load_kernel_wrapper: " |
158 | 167 |
159 int load_kernel_wrapper(LoadKernelParams *params, | 168 int load_kernel_wrapper(LoadKernelParams *params, |
160 void *gbb_data, uint64_t gbb_size, uint64_t boot_flags, | 169 void *gbb_data, uint64_t gbb_size, uint64_t boot_flags, |
161 VbNvContext *nvcxt, uint8_t *shared_data_blob) | 170 VbNvContext *nvcxt, uint8_t *shared_data_blob) |
162 { | 171 { |
| 172 /* |
| 173 * TODO(clchiou): Hack for bringing up factory; preserve recovery |
| 174 * reason before LoadKernel destroys it. Remove when not needed. |
| 175 * |
| 176 * XXX: I found a potential bug that for example, VbNvGet() returns |
| 177 * reason == 0x81 |
| 178 * but if you access the raw data directly, it gives you |
| 179 * nvcxt->raw[RECOVERY_OFFSET] == 0x02. |
| 180 */ |
| 181 uint32_t reason = 0; |
| 182 VbNvGet(&nvcxt, VBNV_RECOVERY_REQUEST, &reason); |
| 183 |
163 int status = LOAD_KERNEL_NOT_FOUND; | 184 int status = LOAD_KERNEL_NOT_FOUND; |
164 block_dev_desc_t *dev_desc; | 185 block_dev_desc_t *dev_desc; |
165 | 186 |
166 memset(params, '\0', sizeof(*params)); | 187 memset(params, '\0', sizeof(*params)); |
167 | 188 |
168 dev_desc = get_bootdev(); | 189 dev_desc = get_bootdev(); |
169 if (!dev_desc) { | 190 if (!dev_desc) { |
170 debug(PREFIX "get_bootdev fail\n"); | 191 debug(PREFIX "get_bootdev fail\n"); |
171 goto EXIT; | 192 goto EXIT; |
172 } | 193 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 } else if (params->partition_number == 4) { | 240 } else if (params->partition_number == 4) { |
220 setenv("kernelpart", "4"); | 241 setenv("kernelpart", "4"); |
221 setenv("rootpart", "5"); | 242 setenv("rootpart", "5"); |
222 } else { | 243 } else { |
223 debug(PREFIX "unknown kernel partition: %d\n", | 244 debug(PREFIX "unknown kernel partition: %d\n", |
224 (int) params->partition_number); | 245 (int) params->partition_number); |
225 status = LOAD_KERNEL_NOT_FOUND; | 246 status = LOAD_KERNEL_NOT_FOUND; |
226 } | 247 } |
227 } | 248 } |
228 | 249 |
| 250 /* |
| 251 * TODO(clchiou): This is an urgent hack for bringing up factory. We |
| 252 * fill in data that will be used by kernel at last 1MB space. |
| 253 * |
| 254 * Rewrite this part after the protocol specification between |
| 255 * Chrome OS firmware and kernel is finalized. |
| 256 */ |
| 257 if (status == LOAD_KERNEL_SUCCESS) { |
| 258 DECLARE_GLOBAL_DATA_PTR; |
| 259 |
| 260 void *kernel_shared_data = (void*) |
| 261 gd->bd->bi_dram[CONFIG_NR_DRAM_BANKS-1].start + |
| 262 gd->bd->bi_dram[CONFIG_NR_DRAM_BANKS-1].size - SZ_1M; |
| 263 |
| 264 struct { |
| 265 uint8_t signature[16]; |
| 266 uint32_t chsw; |
| 267 uint8_t hwid[256]; |
| 268 uint8_t fwid[256]; |
| 269 uint8_t frid[256]; |
| 270 uint32_t binf[5]; |
| 271 uint32_t gpio[11]; |
| 272 uint32_t vbnv[2]; |
| 273 uint64_t fmap_start_address; |
| 274 uint64_t nvcxt_lba; |
| 275 uint8_t nvcxt_cache[VBNV_BLOCK_SIZE]; |
| 276 } __attribute__((packed)) *sd = kernel_shared_data; |
| 277 |
| 278 void *kernel_shared_data_body = |
| 279 kernel_shared_data + sizeof(*sd); |
| 280 |
| 281 int i; |
| 282 |
| 283 debug(PREFIX "kernel shared data at %p\n", kernel_shared_data); |
| 284 |
| 285 memset(sd, '\0', sizeof(*sd)); |
| 286 |
| 287 strcpy((char*) sd->signature, "CHROMEOS"); |
| 288 |
| 289 /* |
| 290 * chsw bit value |
| 291 * bit 0x00000002 : recovery button pressed |
| 292 * bit 0x00000020 : developer mode enabled |
| 293 * bit 0x00000200 : firmware write protect disabled |
| 294 */ |
| 295 if (params->boot_flags & BOOT_FLAG_RECOVERY) |
| 296 sd->chsw |= 0x002; |
| 297 if (params->boot_flags & BOOT_FLAG_DEVELOPER) |
| 298 sd->chsw |= 0x020; |
| 299 sd->chsw |= 0x200; /* so far write protect is disabled */ |
| 300 |
| 301 strcpy((char*) sd->hwid, CONFIG_CHROMEOS_HWID); |
| 302 strcpy((char*) sd->fwid, "ARM Firmware ID"); |
| 303 strcpy((char*) sd->frid, "ARM Read-Only Firmware ID"); |
| 304 |
| 305 sd->binf[0] = 0; /* boot reason; always 0 */ |
| 306 if (params->boot_flags & BOOT_FLAG_RECOVERY) { |
| 307 sd->binf[1] = 0; /* active main firmware */ |
| 308 sd->binf[3] = 0; /* active firmware type */ |
| 309 } else { |
| 310 sd->binf[1] = 1; /* active main firmware */ |
| 311 sd->binf[3] = 1; /* active firmware type */ |
| 312 } |
| 313 sd->binf[2] = 0; /* active EC firmware */ |
| 314 sd->binf[4] = reason; |
| 315 |
| 316 /* sd->gpio[i] == 1 if it is active-high */ |
| 317 sd->gpio[1] = 1; /* only developer mode gpio is active high */ |
| 318 |
| 319 sd->vbnv[0] = 0; |
| 320 sd->vbnv[1] = VBNV_BLOCK_SIZE; |
| 321 |
| 322 firmware_storage_t file; |
| 323 firmware_storage_init(&file); |
| 324 firmware_storage_read(&file, |
| 325 CONFIG_OFFSET_FMAP, CONFIG_LENGTH_FMAP, |
| 326 kernel_shared_data_body); |
| 327 file.close(file.context); |
| 328 sd->fmap_start_address = (uint64_t) kernel_shared_data_body; |
| 329 kernel_shared_data_body += CONFIG_LENGTH_FMAP; |
| 330 |
| 331 sd->nvcxt_lba = get_nvcxt_lba(); |
| 332 |
| 333 memcpy(sd->nvcxt_cache, |
| 334 params->nv_context->raw, VBNV_BLOCK_SIZE); |
| 335 |
| 336 debug(PREFIX "chsw %08x\n", sd->chsw); |
| 337 for (i = 0; i < 5; i++) |
| 338 debug(PREFIX "binf[%2d] %08x\n", i, sd->binf[i]); |
| 339 for (i = 0; i < 11; i++) |
| 340 debug(PREFIX "gpio[%2d] %08x\n", i, sd->gpio[i]); |
| 341 debug(PREFIX "vbnv[ 0] %08x\n", sd->vbnv[0]); |
| 342 debug(PREFIX "vbnv[ 1] %08x\n", sd->vbnv[1]); |
| 343 debug(PREFIX "fmap %08llx\n", sd->fmap_start_address); |
| 344 debug(PREFIX "nvcxt %08llx\n", sd->nvcxt_lba); |
| 345 debug(PREFIX "nvcxt_c "); |
| 346 for (i = 0; i < VBNV_BLOCK_SIZE; i++) |
| 347 debug("%02x", sd->nvcxt_cache[i]); |
| 348 putc('\n'); |
| 349 } |
| 350 |
229 return status; | 351 return status; |
230 } | 352 } |
OLD | NEW |