copper: load device tree blob
Update LK to find the device tree from the device tree
table present in the boot.img.
Change-Id: I097908c20a6db954e92965df748b1061ccba17dd
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index f81a44b..44e212b 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -60,6 +60,7 @@
#include "sparse_format.h"
#include "mmc.h"
#include "devinfo.h"
+#include "board.h"
#include "scm.h"
@@ -77,6 +78,27 @@
#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
@@ -406,6 +428,7 @@
#define ROUND_TO_PAGE(x,y) (((x) + (y)) & (~(y)))
static unsigned char buf[4096]; //Equal to max-supported pagesize
+static unsigned char dt_buf[4096];
int boot_linux_from_mmc(void)
{
@@ -421,6 +444,14 @@
unsigned kernel_actual;
unsigned ramdisk_actual;
unsigned imagesize_actual;
+ unsigned second_actual = 0;
+ unsigned dt_actual = 0;
+
+#if DEVICE_TREE
+ struct dt_table *table;
+ struct dt_entry *dt_entry_ptr;
+ unsigned dt_table_offset;
+#endif
uhdr = (struct boot_img_hdr *)EMMC_BOOT_IMG_HEADER_ADDR;
if (!memcmp(uhdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
@@ -466,7 +497,10 @@
image_addr = (unsigned char *)target_get_scratch_address();
kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
- imagesize_actual = (page_size + kernel_actual + ramdisk_actual);
+ second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
+ dt_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
+ imagesize_actual = (page_size + kernel_actual + ramdisk_actual + second_actual +
+ dt_actual);
offset = 0;
@@ -500,10 +534,36 @@
}
}
- /* Move kernel and ramdisk to correct address */
+ /* Move kernel, ramdisk and device tree to correct address */
memmove((void*) hdr->kernel_addr, (char *)(image_addr + page_size), hdr->kernel_size);
memmove((void*) hdr->ramdisk_addr, (char *)(image_addr + page_size + kernel_actual), hdr->ramdisk_size);
+ #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);
+
+ memmove((void *) dt_buf, (char *)dt_table_offset, page_size);
+
+ /* 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;
+ }
+
+ /* Find index of device tree within device tree table */
+ if((dt_entry_ptr = get_device_tree_ptr(table)) == NULL){
+ dprintf(CRITICAL, "ERROR: Device Tree Blob cannot be found\n");
+ return -1;
+ }
+
+ /* Read device device tree in the "tags_add */
+ memmove((void *)hdr->tags_addr, (char *)dt_table_offset + dt_entry_ptr->offset, dt_entry_ptr->size);
+ }
+ #endif
/* Make sure everything from scratch address is read before next step!*/
if(device.is_tampered)
{
@@ -536,6 +596,46 @@
}
}
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(mmc_read(ptn + offset,(unsigned int *) 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 = get_device_tree_ptr(table)) == NULL){
+ dprintf(CRITICAL, "ERROR: Getting device tree address failed\n");
+ return -1;
+ }
+
+ /* Read device device tree in the "tags_add */
+ hdr->tags_addr = 0x8400000;
+ if(mmc_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
}
unified_boot:
@@ -1415,7 +1515,25 @@
APP_END
#if DEVICE_TREE
-/* Device Tree Stuff */
+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)
{
diff --git a/app/aboot/bootimg.h b/app/aboot/bootimg.h
index 44fde92..f9966a1 100644
--- a/app/aboot/bootimg.h
+++ b/app/aboot/bootimg.h
@@ -51,7 +51,8 @@
unsigned tags_addr; /* physical addr for kernel tags */
unsigned page_size; /* flash page size we assume */
- unsigned unused[2]; /* future expansion: should be 0 */
+ unsigned dt_size; /* device_tree in bytes */
+ unsigned unused; /* future expansion: should be 0 */
unsigned char name[BOOT_NAME_SIZE]; /* asciiz product name */
@@ -70,11 +71,13 @@
** +-----------------+
** | second stage | o pages
** +-----------------+
+** | device tree | p pages
+** +-----------------+
**
** n = (kernel_size + page_size - 1) / page_size
** m = (ramdisk_size + page_size - 1) / page_size
** o = (second_size + page_size - 1) / page_size
-**
+** p = (dt_size + page_size - 1) / page_size
** 0. all entities are page_size aligned in flash
** 1. kernel and ramdisk are required (size != 0)
** 2. second is optional (second_size == 0 -> no second)
diff --git a/platform/copper/platform.c b/platform/copper/platform.c
index b8c7279..397bb84 100644
--- a/platform/copper/platform.c
+++ b/platform/copper/platform.c
@@ -38,6 +38,7 @@
void platform_early_init(void)
{
+ board_init();
platform_clock_init();
qgic_init();
qtimer_init();
diff --git a/platform/msm_shared/board.c b/platform/msm_shared/board.c
index fdc5ed0..5bc9996 100644
--- a/platform/msm_shared/board.c
+++ b/platform/msm_shared/board.c
@@ -31,7 +31,6 @@
#include <board.h>
#include <smem.h>
#include <baseband.h>
-#include <board.h>
static struct board_data board = {UNKNOWN,
HW_PLATFORM_UNKNOWN,
@@ -109,3 +108,8 @@
{
return board.baseband;
}
+
+uint32_t board_hardware_id()
+{
+ return board.platform_hw;
+}
diff --git a/platform/msm_shared/include/board.h b/platform/msm_shared/include/board.h
index 40c0897..9aca934 100644
--- a/platform/msm_shared/include/board.h
+++ b/platform/msm_shared/include/board.h
@@ -30,7 +30,7 @@
#ifndef __BOARD_H
#define __BOARD_H
-#include <target/board.h>
+#define LINUX_MACHTYPE_UNKNOWN 0
struct board_data {
uint32_t platform;
@@ -46,5 +46,6 @@
uint32_t board_platform_id();
uint32_t board_target_id();
uint32_t board_baseband();
+uint32_t board_hardware_id();
#endif
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index a7f6c93..5df9e11 100644
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -66,6 +66,7 @@
$(LOCAL_DIR)/clock_pll.o \
$(LOCAL_DIR)/clock_lib2.o \
$(LOCAL_DIR)/uart_dm.o \
+ $(LOCAL_DIR)/board.o \
$(LOCAL_DIR)/spmi.o
endif
diff --git a/platform/msm_shared/smem.h b/platform/msm_shared/smem.h
index f36efe8..0d6069b 100644
--- a/platform/msm_shared/smem.h
+++ b/platform/msm_shared/smem.h
@@ -217,12 +217,14 @@
MSM8660A = 122,
MSM8260A = 123,
APQ8060A = 124,
+ MSM8974 = 126,
MSM8225 = 127,
MSM8625 = 129,
MPQ8064 = 130,
MSM7225AB = 131,
MSM7625AB = 132,
ESM7225AB = 133,
+ MDM9625 = 134,
MSM7125A = 135,
MSM7127A = 136,
MSM8930AA = 142,
@@ -242,7 +244,9 @@
HW_PLATFORM_DRAGON = 10,
HW_PLATFORM_HRD = 13,
HW_PLATFORM_DTV = 14,
- HW_PLATFORM_32BITS = 0x7FFFFFFF
+ HW_PLATFORM_RUMI = 15,
+ HW_PLATFORM_VIRTIO = 16,
+ HW_PLATFORM_32BITS = 0x7FFFFFFF,
};
enum platform_subtype {
diff --git a/project/copper.mk b/project/copper.mk
index f3af929..e6e7b40 100644
--- a/project/copper.mk
+++ b/project/copper.mk
@@ -11,4 +11,4 @@
#DEFINES += WITH_DEBUG_DCC=1
DEFINES += WITH_DEBUG_UART=1
#DEFINES += WITH_DEBUG_FBCON=1
-#DEFINES += DEVICE_TREE=1
+DEFINES += DEVICE_TREE=1
diff --git a/target/copper/init.c b/target/copper/init.c
index a2f3f14..2c812c7 100644
--- a/target/copper/init.c
+++ b/target/copper/init.c
@@ -36,13 +36,13 @@
#include <uart_dm.h>
#include <mmc.h>
#include <spmi.h>
+#include <board.h>
+#include <smem.h>
+#include <baseband.h>
static unsigned int target_id;
-static void target_detect(void);
-
-#define COPPER_TARGET_ID 0xffffffff
#define PMIC_ARB_CHANNEL_NUM 0
#define PMIC_ARB_OWNER_ID 0
@@ -63,7 +63,6 @@
dprintf(INFO, "target_init()\n");
- target_id = COPPER_TARGET_ID;
spmi_init(PMIC_ARB_CHANNEL_NUM, PMIC_ARB_OWNER_ID);
/* Trying Slot 1*/
@@ -92,3 +91,19 @@
{
}
+
+/* Detect the target type */
+void target_detect(struct board_data *board)
+{
+ board->target = LINUX_MACHTYPE_UNKNOWN;
+}
+
+/* Detect the modem type */
+void target_baseband_detect(struct board_data *board)
+{
+ /* Check for baseband variants. Default to MSM */
+ if (board->platform_subtype == HW_PLATFORM_SUBTYPE_MDM)
+ board->baseband = BASEBAND_MDM;
+ else
+ board->baseband = BASEBAND_MSM;
+}
diff --git a/target/mdm9625/include/target/board.h b/target/mdm9625/include/target/board.h
index f9aef47..81faa85 100644
--- a/target/mdm9625/include/target/board.h
+++ b/target/mdm9625/include/target/board.h
@@ -30,7 +30,6 @@
#ifndef __TARGET_BOARD_H
#define __TARGET_BOARD_H
-#define LINUX_MACHTYPE_UNKNOWN 0
#define LINUX_MACHTYPE_9625_CDP 0
#define LINUX_MACHTYPE_9625_MTP 0
diff --git a/target/msm8960/include/target/board.h b/target/msm8960/include/target/board.h
index d40a7a0..906eb8a 100644
--- a/target/msm8960/include/target/board.h
+++ b/target/msm8960/include/target/board.h
@@ -30,7 +30,6 @@
#ifndef __TARGET_BOARD_H
#define __TARGET_BOARD_H
-#define LINUX_MACHTYPE_UNKNOWN 0
/* 8960 */
#define LINUX_MACHTYPE_8960_SIM 3230
diff --git a/target/msm8960/init.c b/target/msm8960/init.c
index c87652a..403957d 100644
--- a/target/msm8960/init.c
+++ b/target/msm8960/init.c
@@ -48,6 +48,7 @@
#include <uart_dm.h>
#include <crypto_hash.h>
#include <board.h>
+#include <target/board.h>
extern void dmb(void);
extern void msm8960_keypad_init(void);
diff --git a/target/msm8960/target_display.c b/target/msm8960/target_display.c
index a25c3b8..81c8918 100644
--- a/target/msm8960/target_display.c
+++ b/target/msm8960/target_display.c
@@ -32,6 +32,7 @@
#include <board.h>
#include <mdp4.h>
#include <target/display.h>
+#include <target/board.h>
static struct msm_fb_panel_data panel;
static uint8_t display_enable;