Merge "aboot: Add dtree support for flash targets."
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
diff --git a/arch/arm/mmu.c b/arch/arm/mmu.c
index cc74534..bbc5451 100644
--- a/arch/arm/mmu.c
+++ b/arch/arm/mmu.c
@@ -93,7 +93,7 @@
void arch_disable_mmu(void)
{
arm_write_cr1(arm_read_cr1() & ~(1<<0));
+ arm_invalidate_tlb();
}
#endif // ARM_WITH_MMU
-
diff --git a/platform/mdm9x25/include/platform/iomap.h b/platform/mdm9x25/include/platform/iomap.h
index 154fa0e..8b30758 100644
--- a/platform/mdm9x25/include/platform/iomap.h
+++ b/platform/mdm9x25/include/platform/iomap.h
@@ -1,36 +1,37 @@
-/*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 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:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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 Google, Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this
- * software without specific prior written permission.
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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 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.
*
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _PLATFORM_MDM9625_IOMAP_H_
#define _PLATFORM_MDM9625_IOMAP_H_
+/*SDRAM start address */
+#define SDRAM_START_ADDR 0x0
+
/* TBD: shared base is not defined yet */
#define MSM_SHARED_BASE 0x00000000
@@ -52,8 +53,8 @@
#define QTMR_BASE APCS_F0_QTMR_V1_BASE
/* GPIO */
-#define GPIO_CONFIG_ADDR(x) (TLMM_BASE_ADDR + 0x1000 + (x)*0x10)
-#define GPIO_IN_OUT_ADDR(x) (TLMM_BASE_ADDR + 0x1004 + (x)*0x10)
+#define GPIO_CONFIG_ADDR(x) (TLMM_BASE_ADDR + 0x10000 + 0x1000 + (x)*0x10)
+#define GPIO_IN_OUT_ADDR(x) (TLMM_BASE_ADDR + 0x10000 + 0x1004 + (x)*0x10)
/* USB */
#define MSM_USB_BASE (PERIPH_SS_BASE + 0x00255000)
@@ -63,5 +64,4 @@
/* NAND BAM */
#define MSM_NAND_BAM_BASE 0xF9AC4000
-
#endif
diff --git a/platform/mdm9x25/platform.c b/platform/mdm9x25/platform.c
index 21d5705..7f61100 100644
--- a/platform/mdm9x25/platform.c
+++ b/platform/mdm9x25/platform.c
@@ -1,5 +1,4 @@
-/*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 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
@@ -10,7 +9,7 @@
* 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 Forum, Inc. nor the names of its
+ * * 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.
*
@@ -26,15 +25,17 @@
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
#include <debug.h>
#include <platform.h>
#include <qgic.h>
#include <qtimer.h>
+#include <board.h>
void platform_early_init(void)
{
/* Initialize board identifier data */
- //board_init();
+ board_init();
/* Initialize interrupt controller */
qgic_init();
diff --git a/platform/msm_shared/dev_tree.c b/platform/msm_shared/dev_tree.c
new file mode 100644
index 0000000..29cce69
--- /dev/null
+++ b/platform/msm_shared/dev_tree.c
@@ -0,0 +1,424 @@
+/* Copyright (c) 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:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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 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.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <libfdt.h>
+#include <dev_tree.h>
+#include <lib/ptable.h>
+#include <malloc.h>
+#include <qpic_nand.h>
+#include <stdlib.h>
+#include <string.h>
+#include <platform.h>
+#include <board.h>
+
+extern unsigned char *update_cmdline(const char * cmdline);
+extern int target_is_emmc_boot(void);
+extern uint32_t target_dev_tree_mem(void *fdt, uint32_t memory_node_offset);
+
+/* Function to return the pointer to the start of the correct device tree
+ * based on the platform data.
+ */
+struct dt_entry * dev_tree_get_entry_ptr(struct dt_table *table)
+{
+ uint32_t i;
+ struct dt_entry *dt_entry_ptr;
+
+ dt_entry_ptr = (struct dt_entry *)((char *)table + DEV_TREE_HEADER_SIZE);
+
+ for(i = 0; i < table->num_entries; i++)
+ {
+ /* TODO: Add support to pass soc rev correctly.
+ * Currently, the code does not support different soc revisions.
+ */
+ 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;
+}
+
+/* Function to return the offset of flash node - "/qcom,mtd-partitions".
+ * The function creates this node if it does not exist.
+ */
+static uint32_t dev_tree_get_flash_node_offset(void *fdt)
+{
+ uint32_t offset;
+ int ret = DT_OP_SUCCESS;
+
+ /* Find the mtd node. */
+ ret = fdt_path_offset(fdt, "/qcom,mtd-partitions");
+
+ if (ret & FDT_ERR_NOTFOUND)
+ {
+ /* Node not found.
+ * Add node as sub node of root.
+ */
+ ret = fdt_path_offset(fdt, "/");
+
+ if (ret < 0)
+ {
+ dprintf(CRITICAL, "Unable to calculate root offset\n");
+ ret = DT_OP_FAILURE;
+ goto dev_tree_get_flash_node_offset_err;
+ }
+
+ offset = ret;
+ /* Add flash partition node. */
+ ret = fdt_add_subnode(fdt, offset, "qcom,mtd-partitions");
+
+ if (ret < 0)
+ {
+ dprintf(CRITICAL, "Unable to add partition node. \n");
+ ret = DT_OP_FAILURE;
+ goto dev_tree_get_flash_node_offset_err;
+ }
+
+ /* Save the offset of the added node. */
+ offset = fdt_path_offset(fdt, "/qcom,mtd-partitions");
+ }
+ else if (ret != 0)
+ {
+ dprintf(CRITICAL, "Unable to calculate partition node offset\n");
+ ret = DT_OP_FAILURE;
+ goto dev_tree_get_flash_node_offset_err;
+ }
+
+dev_tree_get_flash_node_offset_err:
+
+ return offset;
+}
+
+/* Function to add the individual nand partition nodes to the device tree.
+ * Pre-condition: The function assumes the presence of
+ * "/qcom,mtd-partitions" device node.
+ */
+static int dev_tree_add_ptable_nodes(void *fdt, uint32_t parent_offset)
+{
+ struct ptable *ptable;
+ int n;
+ unsigned char array[100];
+ unsigned char *ptn_name_array;
+ int dt_ret = DT_OP_SUCCESS;
+ int ret;
+ int i;
+ uint32_t node_offset;
+ uint32_t blk_size;
+
+ n = sizeof("partition@");
+
+ /* Allocate bytes to save partition name:
+ * Since address is of uint uint32_t,
+ * allocate twice this size for string
+ * as 1 digit occupies 1 byte is ASCII.
+ */
+ ptn_name_array = (unsigned char*) malloc(sizeof(uint32_t) * 2 + n + 1);
+
+ if (ptn_name_array == NULL)
+ {
+ dprintf(CRITICAL, "Failed to allocate memory for flash partition name\n");
+ return -1;
+ }
+
+ strcpy((char*)ptn_name_array, (const char*)"partition@");
+
+ /* Add ptable nodes. */
+ ptable = flash_get_ptable();
+ /* Get block size. */
+ blk_size = flash_block_size();
+
+ /* Need to add partitions in reverse order since libfdt adds
+ * new nodes on the top.
+ * Kernel looks to mount the partitions in the order specified in
+ * the partition.xml in the meta build.
+ */
+ for (i = (ptable->count - 1); i >= 0; i--)
+ {
+ /* Add the partition node. */
+ if (itoa(ptable->parts[i].start * blk_size, ptn_name_array + n - 1, sizeof(uint32_t) * 2 + 1, 16) < 0)
+ {
+ dprintf(CRITICAL, "String len exceeded for itoa\n");
+ return -1;
+ }
+
+ strcpy((char *)array, (const char*)"/qcom,mtd-partitions/");
+ strcat((char*)array, (const char*)ptn_name_array);
+
+ ret = fdt_add_subnode(fdt, parent_offset, (const char*)ptn_name_array);
+
+ if (ret < 0)
+ {
+ dprintf(CRITICAL, "Unable to add partition node: %s.\n",
+ ptn_name_array);
+ dt_ret = DT_OP_FAILURE;
+ goto dev_tree_add_ptable_nodes_err;
+ }
+
+ dt_ret = fdt_path_offset(fdt, (const char*)array);
+
+ if (dt_ret < 0)
+ {
+ dprintf(CRITICAL, "Unable to calculate parition node offset: %s\n",
+ ptn_name_array);
+ dt_ret = DT_OP_FAILURE;
+ goto dev_tree_add_ptable_nodes_err;
+ }
+
+ node_offset = dt_ret;
+
+ /* Add the partition name as label. */
+ ret = fdt_setprop_string(fdt, node_offset, (const char*)"label", (const char*)ptable->parts[i].name);
+
+ if (ret != 0)
+ {
+ dprintf(CRITICAL, "Unable to add label property: %s.\n",
+ ptable->parts[i].name);
+ dt_ret = DT_OP_FAILURE;
+ goto dev_tree_add_ptable_nodes_err;
+ }
+
+ /* Add the reg values. */
+ ret = fdt_setprop_u32(fdt, node_offset, (const char*)"reg", ptable->parts[i].start * blk_size);
+
+ if (ret != 0)
+ {
+ dprintf(CRITICAL, "Unable to add reg property. %s\n",
+ ptable->parts[i].name);
+ dt_ret = DT_OP_FAILURE;
+ goto dev_tree_add_ptable_nodes_err;
+ }
+
+ ret = fdt_appendprop_u32(fdt, node_offset, (const char*)"reg", ptable->parts[i].length * blk_size);
+
+ if (ret != 0)
+ {
+ dprintf(CRITICAL, "Unable to add reg property. %s\n",
+ ptable->parts[i].name);
+ dt_ret = DT_OP_FAILURE;
+ goto dev_tree_add_ptable_nodes_err;
+ }
+
+ }
+
+dev_tree_add_ptable_nodes_err:
+ free(ptn_name_array);
+ return dt_ret;
+}
+
+/* Top level function to add flash ptable info to the device tree. */
+static int dev_tree_add_flash_ptable(void *fdt)
+{
+ uint32_t offset;
+ int ret;
+ int dt_ret = DT_OP_SUCCESS;
+
+ dt_ret = dev_tree_get_flash_node_offset(fdt);
+
+ if (dt_ret < 0)
+ {
+ dt_ret = DT_OP_FAILURE;
+ goto dev_tree_add_flash_ptable_err;
+ }
+
+ offset = dt_ret;
+
+ /* Add address and size cell properties. */
+ ret = fdt_setprop_u32(fdt, offset, (const char*)"#address-cells", 1);
+
+ if (ret != 0)
+ {
+ dprintf(CRITICAL, "Unable to add #address-cells property. \n");
+ dt_ret = DT_OP_FAILURE;
+ goto dev_tree_add_flash_ptable_err;
+ }
+
+ ret = fdt_setprop_u32(fdt, offset, (const char*)"#size-cells", 1);
+
+ if (ret != 0)
+ {
+ dprintf(CRITICAL, "Unable to add #size-cells property. \n");
+ dt_ret = DT_OP_FAILURE;
+ goto dev_tree_add_flash_ptable_err;
+ }
+
+ ret = dev_tree_add_ptable_nodes(fdt, offset);
+
+ if (ret < 0)
+ {
+ dprintf(CRITICAL, "Unable to add #size-cells property. \n");
+ dt_ret = DT_OP_FAILURE;
+ goto dev_tree_add_flash_ptable_err;
+ }
+
+dev_tree_add_flash_ptable_err:
+ return dt_ret;
+}
+
+/* Function to add the first RAM partition info to the device tree.
+ * Note: The function replaces the reg property in the "/memory" node
+ * with the addr and size provided.
+ */
+int dev_tree_add_first_mem_info(uint32_t *fdt, uint32_t offset, uint32_t addr, uint32_t size)
+{
+ int ret;
+
+ ret = fdt_setprop_u32(fdt, offset, "reg", addr);
+
+ if (ret)
+ {
+ dprintf(CRITICAL, "Failed to add the memory information addr: %d\n",
+ ret);
+ }
+
+
+ ret = fdt_appendprop_u32(fdt, offset, "reg", size);
+
+ if (ret)
+ {
+ dprintf(CRITICAL, "Failed to add the memory information size: %d\n",
+ ret);
+ }
+
+ return ret;
+}
+
+/* Function to add the subsequent RAM partition info to the device tree. */
+int dev_tree_add_mem_info(void *fdt, uint32_t offset, uint32_t addr, uint32_t size)
+{
+ static int mem_info_cnt = 0;
+ int ret;
+
+ if (!mem_info_cnt)
+ {
+ /* Replace any other reg prop in the memory node. */
+ ret = fdt_setprop_u32(fdt, offset, "reg", addr);
+ mem_info_cnt = 1;
+ }
+ else
+ {
+ /* Append the mem info to the reg prop for subsequent nodes. */
+ ret = fdt_appendprop_u32(fdt, offset, "reg", addr);
+ }
+
+ if (ret)
+ {
+ dprintf(CRITICAL, "Failed to add the memory information addr: %d\n",
+ ret);
+ }
+
+
+ ret = fdt_appendprop_u32(fdt, offset, "reg", size);
+
+ if (ret)
+ {
+ dprintf(CRITICAL, "Failed to add the memory information size: %d\n",
+ ret);
+ }
+
+ return ret;
+}
+
+/* Top level function that updates the device tree. */
+int update_device_tree(void *fdt, const char *cmdline,
+ void *ramdisk, uint32_t ramdisk_size)
+{
+ int ret = 0;
+ uint32_t offset;
+ unsigned char *final_cmdline;
+
+ /* 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 */
+ ret = fdt_path_offset(fdt, "/memory");
+ if (ret < 0)
+ {
+ dprintf(CRITICAL, "Could not find memory node.\n");
+ return ret;
+ }
+
+ offset = ret;
+
+ ret = target_dev_tree_mem(fdt, offset);
+ if(ret)
+ {
+ dprintf(CRITICAL, "ERROR: Cannot update memory node\n");
+ return ret;
+ }
+
+ /* Skip NAND partition nodes for eMMC boot */
+ if (!target_is_emmc_boot()){
+ dev_tree_add_flash_ptable(fdt);
+ }
+
+ /* Get offset of the chosen node */
+ ret = fdt_path_offset(fdt, "/chosen");
+ if (ret < 0)
+ {
+ dprintf(CRITICAL, "Could not find chosen node.\n");
+ return ret;
+ }
+
+ offset = ret;
+ /* Adding the cmdline to the chosen node */
+ final_cmdline = update_cmdline((const char*)cmdline);
+ ret = fdt_setprop_string(fdt, offset, (const char*)"bootargs", (const void*)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_u32(fdt, offset, "linux,initrd-start", (uint32_t)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_u32(fdt, offset, "linux,initrd-end", ((uint32_t)ramdisk + ramdisk_size));
+ if (ret)
+ {
+ dprintf(CRITICAL, "ERROR: Cannot update chosen node [linux,initrd-end]\n");
+ return ret;
+ }
+
+ fdt_pack(fdt);
+
+ return ret;
+}
diff --git a/platform/msm_shared/include/dev_tree.h b/platform/msm_shared/include/dev_tree.h
new file mode 100644
index 0000000..5c58b38
--- /dev/null
+++ b/platform/msm_shared/include/dev_tree.h
@@ -0,0 +1,66 @@
+/* Copyright (c) 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:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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 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.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <debug.h>
+
+#ifndef __DEVICE_TREE__
+#define __DEVICE_TREE__
+
+#define DEV_TREE_SUCCESS 0
+#define DEV_TREE_MAGIC 0x54444351 /* "QCDT" */
+#define DEV_TREE_MAGIC_LEN 4
+#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;
+ uint32_t num_entries;
+};
+
+enum dt_err_codes
+{
+ DT_OP_SUCCESS,
+ DT_OP_FAILURE = -1,
+};
+
+struct dt_entry * dev_tree_get_entry_ptr(struct dt_table *);
+int update_device_tree(void *, const char *, void *, unsigned);
+int dev_tree_add_mem_info(void *fdt, uint32_t offset, uint32_t size, uint32_t addr);
+
+#endif
diff --git a/platform/msm_shared/include/qpic_nand.h b/platform/msm_shared/include/qpic_nand.h
index 3431981..47224df 100644
--- a/platform/msm_shared/include/qpic_nand.h
+++ b/platform/msm_shared/include/qpic_nand.h
@@ -324,5 +324,8 @@
void
qpic_nand_init(struct qpic_nand_init_config *config);
+unsigned
+flash_block_size(void);
+
#endif
diff --git a/platform/msm_shared/qpic_nand.c b/platform/msm_shared/qpic_nand.c
index faef7cd..693ecf2 100644
--- a/platform/msm_shared/qpic_nand.c
+++ b/platform/msm_shared/qpic_nand.c
@@ -1215,17 +1215,27 @@
bbtbl[i] = NAND_BAD_BLK_VALUE_NOT_READ;
}
-unsigned flash_page_size(void)
+unsigned
+flash_page_size(void)
{
return flash.page_size;
}
-struct ptable *flash_get_ptable(void)
+unsigned
+flash_block_size(void)
+{
+ return flash.block_size;
+}
+
+
+struct ptable *
+flash_get_ptable(void)
{
return flash_ptable;
}
-void flash_set_ptable(struct ptable *new_ptable)
+void
+flash_set_ptable(struct ptable *new_ptable)
{
ASSERT(flash_ptable == NULL && new_ptable != NULL);
flash_ptable = new_ptable;
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index 53da1cc..6101a02 100644
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -71,7 +71,8 @@
$(LOCAL_DIR)/board.o \
$(LOCAL_DIR)/spmi.o \
$(LOCAL_DIR)/bam.o \
- $(LOCAL_DIR)/nand.o
+ $(LOCAL_DIR)/qpic_nand.o \
+ $(LOCAL_DIR)/dev_tree.o
endif
ifeq ($(PLATFORM),msm7x27a)
@@ -130,5 +131,6 @@
$(LOCAL_DIR)/qtimer_mmap.o \
$(LOCAL_DIR)/board.o \
$(LOCAL_DIR)/qpic_nand.o \
- $(LOCAL_DIR)/bam.o
+ $(LOCAL_DIR)/bam.o \
+ $(LOCAL_DIR)/dev_tree.o
endif
diff --git a/project/mdm9625.mk b/project/mdm9625.mk
index e450f6a..9f5f305 100644
--- a/project/mdm9625.mk
+++ b/project/mdm9625.mk
@@ -9,6 +9,7 @@
#DEFINES += WITH_DEBUG_DCC=1
#DEFINES += WITH_DEBUG_UART=1
#DEFINES += WITH_DEBUG_FBCON=1
+DEFINES += DEVICE_TREE=1
#disable Thumb mode for the codesourcery/arm-2011.03 toolchain
ENABLE_THUMB := false
diff --git a/target/copper/meminfo.c b/target/copper/meminfo.c
index fae3aea..e0feaa1 100644
--- a/target/copper/meminfo.c
+++ b/target/copper/meminfo.c
@@ -1,29 +1,29 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 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:
+ * modification, are permitted provided that the following conditions are
+ * met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
- * * 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
- * the names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
+ * * 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 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.
*
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if DEVICE_TREE /* If using device tree */
@@ -35,6 +35,7 @@
#include <stdint.h>
#include <libfdt.h>
#include <platform/iomap.h>
+#include <dev_tree.h>
#define SIZE_1M (1024 * 1024)
@@ -43,7 +44,6 @@
uint32_t start_addr;
}mem_info;
-
mem_info copper_default_fixed_memory[] = {
{ .size = (132 * SIZE_1M),
.start_addr = SDRAM_START_ADDR
@@ -60,19 +60,13 @@
},
};
-uint32_t *target_mem_dev_tree_create(uint32_t *ptr, uint32_t size, uint32_t addr)
-{
- *ptr++ = cpu_to_fdt32(addr);
- *ptr++ = cpu_to_fdt32(size);
-
- return ptr;
-}
-
-uint32_t *target_dev_tree_create(uint32_t *ptr,
- mem_info usable_mem_map[],
- uint32_t num_regions)
+int target_add_first_mem_bank(void *fdt,
+ uint32_t offset,
+ mem_info usable_mem_map[],
+ uint32_t num_regions)
{
uint32_t i;
+ int ret;
ASSERT(num_regions);
@@ -80,96 +74,91 @@
for (i = 0; i < num_regions; i++)
{
- ptr = target_mem_dev_tree_create(ptr,
- usable_mem_map[i].size,
- usable_mem_map[i].start_addr);
+ ret = dev_tree_add_mem_info(fdt,
+ offset,
+ usable_mem_map[i].start_addr,
+ usable_mem_map[i].size);
}
- return ptr;
+ return ret;
}
-uint32_t* target_dev_tree_mem(uint32_t *num_of_entries)
+/* Funtion to add the ram partition entries into device tree.
+ * The function assumes that all the entire fixed memory regions should
+ * be listed in the first bank of the passed in ddr regions.
+ */
+uint32_t target_dev_tree_mem(void *fdt, uint32_t memory_node_offset)
{
struct smem_ram_ptable ram_ptable;
- uint32_t *meminfo_ptr;
- uint32_t num_of_sections = 0;
- uint32_t *ptr;
- uint32_t last_fixed_add;
+ uint32_t last_fixed_addr;
int n;
- int i;
- int index = 0;
- int count = 0;
- int overflow = 0;
+ unsigned int i;
+ int ret;
/* Make sure RAM partition table is initialized */
ASSERT(smem_ram_ptable_init(&ram_ptable));
n = ARRAY_SIZE(copper_default_fixed_memory);
- last_fixed_add = copper_default_fixed_memory[n-1].start_addr +
- copper_default_fixed_memory[n-1].size;
- /* Find the number of parts in ram_ptable of category SDRAM and type SYS_MEMORY */
- for(i = 0; i < ram_ptable.len; i++)
- { if((ram_ptable.parts[i].category ==SDRAM) &&
- (ram_ptable.parts[i].type == SYS_MEMORY))
- count++;
- }
+ last_fixed_addr = copper_default_fixed_memory[n-1].start_addr +
+ copper_default_fixed_memory[n-1].size;
- /* Calculating the size of the mem_info_ptr */
+ /* Calculating the size of the mem_info_ptr */
for (i = 0 ; i < ram_ptable.len; i++)
{
- if((ram_ptable.parts[i].category ==SDRAM) &&
+ if((ram_ptable.parts[i].category == SDRAM) &&
(ram_ptable.parts[i].type == SYS_MEMORY))
{
- if((ram_ptable.parts[i].start <= last_fixed_add) &&
- ((ram_ptable.parts[i].start + ram_ptable.parts[i].size) >= last_fixed_add))
+ if((ram_ptable.parts[i].start <= last_fixed_addr) &&
+ ((ram_ptable.parts[i].start + ram_ptable.parts[i].size) >= last_fixed_addr))
{
- if((ram_ptable.parts[i].start + ram_ptable.parts[i].size) == last_fixed_add)
- {
- num_of_sections = n + (count - i - 1);
+
+ /* Pass along all fixed memory regions to Linux */
+ ret = target_add_first_mem_bank(fdt,
+ memory_node_offset,
+ copper_default_fixed_memory,
+ ARRAY_SIZE(copper_default_fixed_memory));
+
+ if (ret)
+ {
+ dprintf(CRITICAL, "Failed to add first bank fixed memory addresses\n");
+ goto target_dev_tree_mem_err;
+ }
+
+ if((ram_ptable.parts[i].start + ram_ptable.parts[i].size) != last_fixed_addr)
+ {
+ /* Pass the memory beyond the fixed memory present in the partition */
+ ret = dev_tree_add_mem_info(fdt,
+ memory_node_offset,
+ ram_ptable.parts[i].start + last_fixed_addr,
+ ram_ptable.parts[i].size - last_fixed_addr);
+
+ if (ret)
+ {
+ dprintf(CRITICAL, "Failed to add first bank memory addresses\n");
+ goto target_dev_tree_mem_err;
+ }
}
- else
- {
- num_of_sections = n + (count - i );
- overflow = 1;
- }
- index = i+1;
- break;
- }
- }
+ }
+ else
+ {
+ /* Pass along all other usable memory regions to Linux */
+ ret = dev_tree_add_mem_info(fdt,
+ memory_node_offset,
+ ram_ptable.parts[i].start,
+ ram_ptable.parts[i].size);
+
+ if (ret)
+ {
+ dprintf(CRITICAL, "Failed to add secondary banks memory addresses\n");
+ goto target_dev_tree_mem_err;
+ }
+ }
+ }
}
- *num_of_entries = num_of_sections;
- meminfo_ptr = (uint32_t*) malloc(sizeof(uint32_t) * num_of_sections * 2);
- ptr = meminfo_ptr;
+target_dev_tree_mem_err:
- /* Assumption that the fixed memory region always starts from the first ram_ptable part */
- ASSERT((ram_ptable.parts[0].category ==SDRAM) &&
- (ram_ptable.parts[0].type == SYS_MEMORY) &&
- (ram_ptable.parts[0].start == SDRAM_START_ADDR));
-
- /* Pass along all fixed memory regions to Linux */
- meminfo_ptr = target_dev_tree_create(meminfo_ptr, copper_default_fixed_memory,
- ARRAY_SIZE(copper_default_fixed_memory));
-
- if(overflow)
- {
- /* Pass the memory beyond the fixed memory present in the partition */
- meminfo_ptr = target_mem_dev_tree_create(meminfo_ptr,
- ram_ptable.parts[i].size - last_fixed_add,
- ram_ptable.parts[i].start + last_fixed_add);
- }
- for( i = index ; i < ram_ptable.len ; i ++)
- {
- if((ram_ptable.parts[i].category ==SDRAM) &&
- (ram_ptable.parts[i].type == SYS_MEMORY))
- {
- /* Pass along all other usable memory regions to Linux */
- meminfo_ptr = target_mem_dev_tree_create(meminfo_ptr,
- ram_ptable.parts[i].size,
- ram_ptable.parts[i].start);
- }
- }
- return ptr;
+ return ret;
}
void *target_get_scratch_address(void)
@@ -182,4 +171,3 @@
return (512 * 1024 * 1024);
}
#endif /* DEVICE_TREE */
-
diff --git a/target/mdm9625/init.c b/target/mdm9625/init.c
index 81a1c27..d9d7e9c 100644
--- a/target/mdm9625/init.c
+++ b/target/mdm9625/init.c
@@ -1,5 +1,4 @@
-/*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 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
@@ -10,7 +9,7 @@
* 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 Forum, Inc. nor the names of its
+ * * 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.
*
@@ -26,6 +25,7 @@
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
#include <debug.h>
#include <board.h>
#include <platform.h>
@@ -34,6 +34,11 @@
#include <baseband.h>
#include <lib/ptable.h>
#include <qpic_nand.h>
+#include <ctype.h>
+#include <string.h>
+
+extern void smem_ptable_init(void);
+extern void smem_add_modem_partitions(struct ptable *flash_ptable);
static struct ptable flash_ptable;
@@ -43,6 +48,34 @@
#define CMD_PIPE 2
struct qpic_nand_init_config config;
+
+void update_ptable_names(void)
+{
+ uint32_t ptn_index;
+ struct ptentry *ptentry_ptr = flash_ptable.parts;
+ struct ptentry *boot_ptn;
+ unsigned i;
+ uint32_t len;
+
+ /* Change all names to lower case. */
+ for (ptn_index = 0; ptn_index != (uint32_t)flash_ptable.count; ptn_index++)
+ {
+ len = strlen(ptentry_ptr[ptn_index].name);
+
+ for (i = 0; i < len; i++)
+ {
+ if (isupper(ptentry_ptr[ptn_index].name[i]))
+ {
+ ptentry_ptr[ptn_index].name[i] = tolower(ptentry_ptr[ptn_index].name[i]);
+ }
+ }
+ }
+
+ /* Rename apps ptn to boot. */
+ boot_ptn = ptable_find(&flash_ptable, "apps");
+ strcpy(boot_ptn->name, "boot");
+}
+
/* init */
void target_init(void)
{
@@ -57,14 +90,15 @@
qpic_nand_init(&config);
- /* Below lines are to be removed once the bootchain is available */
-
ptable_init(&flash_ptable);
- flash_set_ptable(&flash_ptable);
+ smem_ptable_init();
- /* Add boot ptn..until the bootchain adds it */
- ptable_add(&flash_ptable, "boot", 0x347, 0x52, 0, TYPE_APPS_PARTITION, PERM_WRITEABLE);
+ smem_add_modem_partitions(&flash_ptable);
+
+ update_ptable_names();
+
+ flash_set_ptable(&flash_ptable);
}
/* reboot */
@@ -80,25 +114,25 @@
return 0;
}
-/* Create ATAGs for this target */
-unsigned* target_atag_mem(unsigned* ptr)
-{
- return ptr;
-}
-
-/* mach type */
-unsigned board_machtype(void)
-{
- //return board_target_id();
-}
-
/* Identify the current target */
void target_detect(struct board_data *board)
{
}
+unsigned board_machtype(void)
+{
+ return board_target_id();
+}
+
/* Identify the baseband being used */
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
+ {
+ dprintf(CRITICAL, "Could not detect baseband id\n");
+ ASSERT(0);
+ }
}
diff --git a/target/mdm9625/meminfo.c b/target/mdm9625/meminfo.c
new file mode 100644
index 0000000..96b1b5b
--- /dev/null
+++ b/target/mdm9625/meminfo.c
@@ -0,0 +1,164 @@
+/* Copyright (c) 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:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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 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.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <reg.h>
+#include <debug.h>
+#include <malloc.h>
+#include <smem.h>
+#include <stdint.h>
+#include <libfdt.h>
+#include <platform/iomap.h>
+#include <dev_tree.h>
+
+#define SIZE_1M (1024 * 1024)
+
+typedef struct {
+ uint32_t size;
+ uint32_t start_addr;
+}mem_info;
+
+mem_info mdm9625_default_fixed_memory[] = {
+ { .size = (29 * SIZE_1M),
+ .start_addr = SDRAM_START_ADDR +
+ (2 * SIZE_1M)
+ },
+ { .size = (10 * SIZE_1M),
+ .start_addr = SDRAM_START_ADDR +
+ (118 * SIZE_1M)
+ },
+};
+
+int target_add_first_mem_bank(void *fdt,
+ uint32_t offset,
+ mem_info usable_mem_map[],
+ uint32_t num_regions)
+{
+ uint32_t i;
+ int ret;
+
+ ASSERT(num_regions);
+
+ dprintf(SPEW, "Number of HLOS regions in 1st bank = %u\n", num_regions);
+
+ for (i = 0; i < num_regions; i++)
+ {
+ ret = dev_tree_add_mem_info(fdt,
+ offset,
+ usable_mem_map[i].start_addr,
+ usable_mem_map[i].size);
+ }
+ return ret;
+}
+
+/* Funtion to add the ram partition entries into device tree.
+ * The function assumes that all the entire fixed memory regions should
+ * be listed in the first bank of the passed in ddr regions.
+ */
+uint32_t target_dev_tree_mem(void *fdt, uint32_t memory_node_offset)
+{
+ struct smem_ram_ptable ram_ptable;
+ uint32_t last_fixed_addr;
+ int n;
+ unsigned int i;
+ int ret;
+
+ /* Make sure RAM partition table is initialized */
+ ASSERT(smem_ram_ptable_init(&ram_ptable));
+
+ n = ARRAY_SIZE(mdm9625_default_fixed_memory);
+
+ last_fixed_addr = mdm9625_default_fixed_memory[n-1].start_addr +
+ mdm9625_default_fixed_memory[n-1].size;
+
+ for (i = 0; i < ram_ptable.len; i++)
+ {
+ if((ram_ptable.parts[i].category == SDRAM) &&
+ (ram_ptable.parts[i].type == SYS_MEMORY))
+ {
+ if((ram_ptable.parts[i].start <= last_fixed_addr) &&
+ ((ram_ptable.parts[i].start + ram_ptable.parts[i].size) >= last_fixed_addr))
+ {
+
+ /* Pass along all fixed memory regions to Linux */
+ ret = target_add_first_mem_bank(fdt,
+ memory_node_offset,
+ mdm9625_default_fixed_memory,
+ ARRAY_SIZE(mdm9625_default_fixed_memory));
+
+ if (ret)
+ {
+ dprintf(CRITICAL, "Failed to add first bank fixed memory addresses\n");
+ goto target_dev_tree_mem_err;
+ }
+
+ if((ram_ptable.parts[i].start + ram_ptable.parts[i].size) != last_fixed_addr)
+ {
+ /* Pass the memory beyond the fixed memory present in the partition */
+ ret = dev_tree_add_mem_info(fdt,
+ memory_node_offset,
+ ram_ptable.parts[i].start + last_fixed_addr,
+ ram_ptable.parts[i].size - last_fixed_addr);
+
+ if (ret)
+ {
+ dprintf(CRITICAL, "Failed to add first bank memory addresses\n");
+ goto target_dev_tree_mem_err;
+ }
+ }
+ }
+ else
+ {
+ /* Pass along all other usable memory regions to Linux */
+ ret = dev_tree_add_mem_info(fdt,
+ memory_node_offset,
+ ram_ptable.parts[i].start,
+ ram_ptable.parts[i].size);
+
+ if (ret)
+ {
+ dprintf(CRITICAL, "Failed to add secondary banks memory addresses\n");
+ goto target_dev_tree_mem_err;
+ }
+ }
+ }
+ }
+
+target_dev_tree_mem_err:
+
+ return ret;
+}
+
+void *target_get_scratch_address(void)
+{
+ return ((void *)SCRATCH_ADDR);
+}
+
+unsigned target_get_max_flash_size(void)
+{
+ return (28 * 1024 * 1024);
+}
diff --git a/target/mdm9625/rules.mk b/target/mdm9625/rules.mk
index d577380..9e54221 100755
--- a/target/mdm9625/rules.mk
+++ b/target/mdm9625/rules.mk
@@ -12,11 +12,13 @@
MODULES += \
dev/keys \
- lib/ptable
+ lib/ptable \
+ lib/libfdt
DEFINES += \
MEMBASE=$(MEMBASE) \
SCRATCH_ADDR=$(SCRATCH_ADDR)
OBJS += \
- $(LOCAL_DIR)/init.o
+ $(LOCAL_DIR)/init.o \
+ $(LOCAL_DIR)/meminfo.o