aboot: Add dtree support for flash targets.
Change-Id: I320a66851dbdb9b842f2e15894082480a257b7ef
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index 910cd08..f6d6e50 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -2,7 +2,7 @@
* Copyright (c) 2009, Google Inc.
* All rights reserved.
*
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -11,7 +11,7 @@
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * * Neither the name of Code Aurora nor
+ * * Neither the name of The Linux Foundation nor
* the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
@@ -48,9 +48,11 @@
#include <partition_parser.h>
#include <platform.h>
#include <crypto_hash.h>
+#include <malloc.h>
#if DEVICE_TREE
#include <libfdt.h>
+#include <dev_tree.h>
#endif
#include "image_verify.h"
@@ -64,6 +66,14 @@
#include "scm.h"
+extern bool target_use_signed_kernel(void);
+extern void dsb();
+extern void isb();
+extern void platform_uninit(void);
+
+void write_device_info_mmc(device_info *dev);
+void write_device_info_flash(device_info *dev);
+
#define EXPAND(NAME) #NAME
#define TARGET(NAME) EXPAND(NAME)
#define DEFAULT_CMDLINE "mem=100M console=null";
@@ -77,31 +87,6 @@
#define RECOVERY_MODE 0x77665502
#define FASTBOOT_MODE 0x77665500
-#if DEVICE_TREE
-#define DEV_TREE_SUCCESS 0
-#define DEV_TREE_MAGIC "QCDT"
-#define DEV_TREE_VERSION 1
-#define DEV_TREE_HEADER_SIZE 12
-
-
-struct dt_entry{
- uint32_t platform_id;
- uint32_t variant_id;
- uint32_t soc_rev;
- uint32_t offset;
- uint32_t size;
-};
-
-struct dt_table{
- uint32_t magic;
- uint32_t version;
- unsigned num_entries;
-};
-
-struct dt_entry * get_device_tree_ptr(struct dt_table *);
-int update_device_tree(const void *, char *, void *, unsigned);
-#endif
-
static const char *emmc_cmdline = " androidboot.emmc=true";
static const char *usb_sn_cmdline = " androidboot.serialno=";
static const char *battchg_pause = " androidboot.mode=charger";
@@ -213,8 +198,8 @@
if (cmdline_len > 0) {
const char *src;
- char *dst = malloc((cmdline_len + 4) & (~3));
- assert(dst != NULL);
+ unsigned char *dst = (unsigned char*) malloc((cmdline_len + 4) & (~3));
+ ASSERT(dst != NULL);
/* Save start ptr for debug print */
cmdline_final = dst;
@@ -321,8 +306,8 @@
struct ptable *ptable;
if ((ptable = flash_get_ptable()) && (ptable->count != 0)) {
- *(*ptr_addr)++ = 2 + (ptable->count * (sizeof(struct atag_ptbl_entry) /
- sizeof(unsigned)));
+ *(*ptr_addr)++ = 2 + (ptable->count * (sizeof(struct atag_ptbl_entry) /
+ sizeof(unsigned)));
*(*ptr_addr)++ = 0x4d534d70;
for (i = 0; i < ptable->count; ++i)
ptentry_to_tag(ptr_addr, ptable_get(ptable, i));
@@ -343,13 +328,13 @@
dprintf(INFO, "cmdline: %s\n", cmdline_final);
}
- cmdline_length =strlen(cmdline_final);
+ cmdline_length =strlen((const char*)cmdline_final);
n = (cmdline_length + 4) & (~3);
*ptr++ = (n / 4) + 2;
*ptr++ = 0x54410009;
dest = (char *) ptr;
- while (*dest++ = *cmdline_final++);
+ while ((*dest++ = *cmdline_final++));
ptr += (n / 4);
return ptr;
@@ -390,7 +375,7 @@
#if DEVICE_TREE
/* Update the Device Tree */
- ret = update_device_tree(tags, cmdline, ramdisk, ramdisk_size);
+ ret = update_device_tree((void *)tags, cmdline, ramdisk, ramdisk_size);
if(ret)
{
dprintf(CRITICAL, "ERROR: Updating Device Tree Failed \n");
@@ -405,19 +390,12 @@
kernel, ramdisk, ramdisk_size);
enter_critical_section();
+
/* do any platform specific cleanup before kernel entry */
platform_uninit();
+
arch_disable_cache(UCACHE);
- /* NOTE:
- * The value of "entry" is getting corrupted at this point.
- * The value is in R4 and gets pushed to stack on entry into
- * disable_cache(), however, on return it is not the same.
- * Not entirely sure why this dsb() seems to take of this.
- * The stack pop operation on return from disable_cache()
- * should restore R4 properly, but that is not happening.
- * Will need to revisit to find the root cause.
- */
- dsb();
+
#if ARM_WITH_MMU
arch_disable_mmu();
#endif
@@ -540,7 +518,7 @@
#if DEVICE_TREE
if(hdr->dt_size) {
table = (struct dt_table*) dt_buf;
- dt_table_offset = (image_addr + page_size + kernel_actual + ramdisk_actual + second_actual);
+ dt_table_offset = ((uint32_t)image_addr + page_size + kernel_actual + ramdisk_actual + second_actual);
memmove((void *) dt_buf, (char *)dt_table_offset, page_size);
@@ -554,7 +532,7 @@
}
/* Find index of device tree within device tree table */
- if((dt_entry_ptr = get_device_tree_ptr(table)) == NULL){
+ if((dt_entry_ptr = dev_tree_get_entry_ptr(table)) == NULL){
dprintf(CRITICAL, "ERROR: Device Tree Blob cannot be found\n");
return -1;
}
@@ -621,7 +599,7 @@
}
/* Calculate the offset of device tree within device tree table */
- if((dt_entry_ptr = get_device_tree_ptr(table)) == NULL){
+ if((dt_entry_ptr = dev_tree_get_entry_ptr(table)) == NULL){
dprintf(CRITICAL, "ERROR: Getting device tree address failed\n");
return -1;
}
@@ -671,6 +649,12 @@
unsigned ramdisk_actual;
unsigned imagesize_actual;
+#if DEVICE_TREE
+ struct dt_table *table;
+ struct dt_entry *dt_entry_ptr;
+#endif
+
+
if (target_is_emmc_boot()) {
hdr = (struct boot_img_hdr *)EMMC_BOOT_IMG_HEADER_ADDR;
if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
@@ -689,6 +673,7 @@
if(!boot_into_recovery)
{
ptn = ptable_find(ptable, "boot");
+
if (ptn == NULL) {
dprintf(CRITICAL, "ERROR: No boot partition found\n");
return -1;
@@ -790,6 +775,47 @@
return -1;
}
offset += n;
+
+ if(hdr->second_size != 0) {
+ n = ROUND_TO_PAGE(hdr->second_size, page_mask);
+ offset += n;
+ }
+
+#if DEVICE_TREE
+ if(hdr->dt_size != 0) {
+
+ /* Read the device tree table into buffer */
+ if(flash_read(ptn, offset, (void *) dt_buf, page_size)) {
+ dprintf(CRITICAL, "ERROR: Cannot read the Device Tree Table\n");
+ return -1;
+ }
+
+ table = (struct dt_table*) dt_buf;
+
+ /* Restriction that the device tree entry table should be less than a page*/
+ ASSERT(((table->num_entries * sizeof(struct dt_entry))+ DEV_TREE_HEADER_SIZE) < hdr->page_size);
+
+ /* Validate the device tree table header */
+ if((table->magic != DEV_TREE_MAGIC) && (table->version != DEV_TREE_VERSION)) {
+ dprintf(CRITICAL, "ERROR: Cannot validate Device Tree Table \n");
+ return -1;
+ }
+
+ /* Calculate the offset of device tree within device tree table */
+ if((dt_entry_ptr = dev_tree_get_entry_ptr(table)) == NULL){
+ dprintf(CRITICAL, "ERROR: Getting device tree address failed\n");
+ return -1;
+ }
+
+ /* Read device device tree in the "tags_add */
+ if(flash_read(ptn, offset + dt_entry_ptr->offset,
+ (void *)hdr->tags_addr, dt_entry_ptr->size)) {
+ dprintf(CRITICAL, "ERROR: Cannot read device tree\n");
+ return -1;
+ }
+ }
+#endif
+
}
continue_boot:
dprintf(INFO, "\nkernel @ %x (%d bytes)\n", hdr->kernel_addr,
@@ -983,11 +1009,9 @@
uint32_t n;
struct dt_table *table;
struct dt_entry *dt_entry_ptr;
- unsigned dt_table_offset;
struct boot_img_hdr *hdr = (struct boot_img_hdr *) (boot_image_start);
-
if(hdr->dt_size != 0) {
/* add kernel offset */
@@ -1006,7 +1030,7 @@
}
/* offset now point to start of dt.img */
- table = boot_image_start + dt_image_offset;
+ table = (struct dt_table*)(boot_image_start + dt_image_offset);
/* Restriction that the device tree entry table should be less than a page*/
ASSERT(((table->num_entries * sizeof(struct dt_entry))+ DEV_TREE_HEADER_SIZE) < hdr->page_size);
@@ -1018,7 +1042,7 @@
}
/* Calculate the offset of device tree within device tree table */
- if((dt_entry_ptr = get_device_tree_ptr(table)) == NULL){
+ if((dt_entry_ptr = dev_tree_get_entry_ptr(table)) == NULL){
dprintf(CRITICAL, "ERROR: Getting device tree address failed\n");
return -1;
}
@@ -1075,8 +1099,8 @@
fastboot_okay("");
udc_stop();
- memmove((void*) hdr.kernel_addr, ptr + page_size, hdr.kernel_size);
memmove((void*) hdr.ramdisk_addr, ptr + page_size + kernel_actual, hdr.ramdisk_size);
+ memmove((void*) hdr.kernel_addr, ptr + page_size, hdr.kernel_size);
boot_linux((void*) hdr.kernel_addr, (void*) hdr.tags_addr,
(const char*) hdr.cmdline, board_machtype(),
@@ -1576,87 +1600,3 @@
APP_START(aboot)
.init = aboot_init,
APP_END
-
-#if DEVICE_TREE
-struct dt_entry * get_device_tree_ptr(struct dt_table *table)
-{
- unsigned i;
- struct dt_entry *dt_entry_ptr;
-
- dt_entry_ptr = (char *)table + DEV_TREE_HEADER_SIZE ;
-
- for(i = 0; i < table->num_entries; i++)
- {
- if((dt_entry_ptr->platform_id == board_platform_id()) &&
- (dt_entry_ptr->variant_id == board_hardware_id()) &&
- (dt_entry_ptr->soc_rev == 0)){
- return dt_entry_ptr;
- }
- dt_entry_ptr++;
- }
- return NULL;
-}
-
-int update_device_tree(const void * fdt, char *cmdline,
- void *ramdisk, unsigned ramdisk_size)
-{
- int ret = 0;
- int offset;
- uint32_t *memory_reg;
- unsigned char *final_cmdline;
- uint32_t len;
-
- /* Check the device tree header */
- ret = fdt_check_header(fdt);
- if(ret)
- {
- dprintf(CRITICAL, "Invalid device tree header \n");
- return ret;
- }
-
- /* Get offset of the memory node */
- offset = fdt_path_offset(fdt,"/memory");
-
- memory_reg = target_dev_tree_mem(&len);
-
- /* Adding the memory values to the reg property */
- ret = fdt_setprop(fdt, offset, "reg", memory_reg, sizeof(uint32_t) * len * 2);
- if(ret)
- {
- dprintf(CRITICAL, "ERROR: Cannot update memory node\n");
- return ret;
- }
-
- /* Get offset of the chosen node */
- offset = fdt_path_offset(fdt, "/chosen");
-
- /* Adding the cmdline to the chosen node */
- final_cmdline = update_cmdline(cmdline);
- ret = fdt_setprop_string(fdt, offset, "bootargs", final_cmdline);
- if(ret)
- {
- dprintf(CRITICAL, "ERROR: Cannot update chosen node [bootargs]\n");
- return ret;
- }
-
- /* Adding the initrd-start to the chosen node */
- ret = fdt_setprop_cell(fdt, offset, "linux,initrd-start", ramdisk);
- if(ret)
- {
- dprintf(CRITICAL, "ERROR: Cannot update chosen node [linux,initrd-start]\n");
- return ret;
- }
-
- /* Adding the initrd-end to the chosen node */
- ret = fdt_setprop_cell(fdt, offset, "linux,initrd-end", (ramdisk + ramdisk_size));
- if(ret)
- {
- dprintf(CRITICAL, "ERROR: Cannot update chosen node [linux,initrd-end]\n");
- return ret;
- }
-
- fdt_pack(fdt);
-
- return ret;
-}
-#endif