Merge pull request #746 from antonio-nino-diaz-arm/an/fix-checkpatch
Fix format of patches passed to checkpatch
diff --git a/.checkpatch.conf b/.checkpatch.conf
index c8a6084..0c84fcd 100644
--- a/.checkpatch.conf
+++ b/.checkpatch.conf
@@ -36,9 +36,6 @@
# This is not Linux so don't expect a Linux tree!
--no-tree
-# 'Signed-off-by' lines in commit messages are not mandated for TF.
---no-signoff
-
# This clarifes the lines indications in the report.
#
# E.g.:
diff --git a/.gitignore b/.gitignore
index d2cff7c..c0d5183 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@
cscope.*
*.swp
*.patch
+*~
.project
.cproject
diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S
index 743e65c..9a05e6c 100644
--- a/bl31/bl31.ld.S
+++ b/bl31/bl31.ld.S
@@ -39,6 +39,9 @@
RAM (rwx): ORIGIN = BL31_BASE, LENGTH = BL31_LIMIT - BL31_BASE
}
+#ifdef PLAT_EXTRA_LD_SCRIPT
+#include <plat.ld.S>
+#endif
SECTIONS
{
diff --git a/docs/porting-guide.md b/docs/porting-guide.md
index 8e913b9..aa014f1 100644
--- a/docs/porting-guide.md
+++ b/docs/porting-guide.md
@@ -501,6 +501,17 @@
PLAT_PL061_MAX_GPIOS := 160
$(eval $(call add_define,PLAT_PL061_MAX_GPIOS))
+If the platform port uses the partition driver, the following constant may
+optionally be defined:
+
+* **PLAT_PARTITION_MAX_ENTRIES**
+ Maximum number of partition entries required by the platform. This allows
+ control how much memory is allocated for partition entries. The default
+ value is 128.
+ [For example, define the build flag in platform.mk]:
+ PLAT_PARTITION_MAX_ENTRIES := 12
+ $(eval $(call add_define,PLAT_PARTITION_MAX_ENTRIES))
+
### File : plat_macros.S [mandatory]
@@ -547,7 +558,7 @@
Argument : void
Return : uintptr_t
-This function is called with the called with the MMU and caches disabled
+This function is called with the MMU and caches disabled
(`SCTLR_EL3.M` = 0 and `SCTLR_EL3.C` = 0). The function is responsible for
distinguishing between a warm and cold reset for the current CPU using
platform-specific means. If it's a warm reset, then it returns the warm
diff --git a/drivers/partition/gpt.c b/drivers/partition/gpt.c
new file mode 100644
index 0000000..9240d5a
--- /dev/null
+++ b/drivers/partition/gpt.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. 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 ARM 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 HOLDER 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 <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <gpt.h>
+#include <string.h>
+
+static int unicode_to_ascii(unsigned short *str_in, unsigned char *str_out)
+{
+ uint8_t *name = (uint8_t *)str_in;
+ int i;
+
+ assert((str_in != NULL) && (str_out != NULL) && (name[0] != '\0'));
+
+ /* check whether the unicode string is valid */
+ for (i = 1; i < (EFI_NAMELEN << 1); i += 2) {
+ if (name[i] != '\0')
+ return -EINVAL;
+ }
+ /* convert the unicode string to ascii string */
+ for (i = 0; i < (EFI_NAMELEN << 1); i += 2) {
+ str_out[i >> 1] = name[i];
+ if (name[i] == '\0')
+ break;
+ }
+ return 0;
+}
+
+int parse_gpt_entry(gpt_entry_t *gpt_entry, partition_entry_t *entry)
+{
+ int result;
+
+ assert((gpt_entry != 0) && (entry != 0));
+
+ if ((gpt_entry->first_lba == 0) && (gpt_entry->last_lba == 0)) {
+ return -EINVAL;
+ }
+
+ memset(entry, 0, sizeof(partition_entry_t));
+ result = unicode_to_ascii(gpt_entry->name, (uint8_t *)entry->name);
+ if (result != 0) {
+ return result;
+ }
+ entry->start = (uint64_t)gpt_entry->first_lba * PARTITION_BLOCK_SIZE;
+ entry->length = (uint64_t)(gpt_entry->last_lba -
+ gpt_entry->first_lba + 1) *
+ PARTITION_BLOCK_SIZE;
+ return 0;
+}
diff --git a/drivers/partition/partition.c b/drivers/partition/partition.c
new file mode 100644
index 0000000..8bf6848
--- /dev/null
+++ b/drivers/partition/partition.c
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. 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 ARM 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 HOLDER 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 <assert.h>
+#include <debug.h>
+#include <io_storage.h>
+#include <gpt.h>
+#include <mbr.h>
+#include <partition.h>
+#include <platform.h>
+#include <string.h>
+
+static uint8_t mbr_sector[PARTITION_BLOCK_SIZE];
+partition_entry_list_t list;
+
+#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
+static void dump_entries(int num)
+{
+ char name[EFI_NAMELEN];
+ int i, j, len;
+
+ VERBOSE("Partition table with %d entries:\n", num);
+ for (i = 0; i < num; i++) {
+ len = snprintf(name, EFI_NAMELEN, "%s", list.list[i].name);
+ for (j = 0; j < EFI_NAMELEN - len - 1; j++) {
+ name[len + j] = ' ';
+ }
+ name[EFI_NAMELEN - 1] = '\0';
+ VERBOSE("%d: %s %lx-%lx\n", i + 1, name, list.list[i].start,
+ list.list[i].start + list.list[i].length - 4);
+ }
+}
+#else
+#define dump_entries(num) ((void)num)
+#endif
+
+/*
+ * Load the first sector that carries MBR header.
+ * The MBR boot signature should be always valid whether it's MBR or GPT.
+ */
+static int load_mbr_header(uintptr_t image_handle, mbr_entry_t *mbr_entry)
+{
+ size_t bytes_read;
+ uintptr_t offset;
+ int result;
+
+ assert(mbr_entry != NULL);
+ /* MBR partition table is in LBA0. */
+ result = io_seek(image_handle, IO_SEEK_SET, MBR_OFFSET);
+ if (result != 0) {
+ WARN("Failed to seek (%i)\n", result);
+ return result;
+ }
+ result = io_read(image_handle, (uintptr_t)&mbr_sector,
+ PARTITION_BLOCK_SIZE, &bytes_read);
+ if (result != 0) {
+ WARN("Failed to read data (%i)\n", result);
+ return result;
+ }
+
+ /* Check MBR boot signature. */
+ if ((mbr_sector[PARTITION_BLOCK_SIZE - 2] != MBR_SIGNATURE_FIRST) ||
+ (mbr_sector[PARTITION_BLOCK_SIZE - 1] != MBR_SIGNATURE_SECOND)) {
+ return -ENOENT;
+ }
+ offset = (uintptr_t)&mbr_sector + MBR_PRIMARY_ENTRY_OFFSET;
+ memcpy(mbr_entry, (void *)offset, sizeof(mbr_entry_t));
+ return 0;
+}
+
+/*
+ * Load GPT header and check the GPT signature.
+ * If partiton numbers could be found, check & update it.
+ */
+static int load_gpt_header(uintptr_t image_handle)
+{
+ gpt_header_t header;
+ size_t bytes_read;
+ int result;
+
+ result = io_seek(image_handle, IO_SEEK_SET, GPT_HEADER_OFFSET);
+ if (result != 0) {
+ return result;
+ }
+ result = io_read(image_handle, (uintptr_t)&header,
+ sizeof(gpt_header_t), &bytes_read);
+ if ((result != 0) || (sizeof(gpt_header_t) != bytes_read)) {
+ return result;
+ }
+ if (memcmp(header.signature, GPT_SIGNATURE,
+ sizeof(header.signature)) != 0) {
+ return -EINVAL;
+ }
+
+ /* partition numbers can't exceed PLAT_PARTITION_MAX_ENTRIES */
+ list.entry_count = header.list_num;
+ if (list.entry_count > PLAT_PARTITION_MAX_ENTRIES) {
+ list.entry_count = PLAT_PARTITION_MAX_ENTRIES;
+ }
+ return 0;
+}
+
+static int load_gpt_entry(uintptr_t image_handle, gpt_entry_t *entry)
+{
+ size_t bytes_read;
+ int result;
+
+ assert(entry != NULL);
+ result = io_read(image_handle, (uintptr_t)entry, sizeof(gpt_entry_t),
+ &bytes_read);
+ if (sizeof(gpt_entry_t) != bytes_read)
+ return -EINVAL;
+ return result;
+}
+
+static int verify_partition_gpt(uintptr_t image_handle)
+{
+ gpt_entry_t entry;
+ int result, i;
+
+ for (i = 0; i < list.entry_count; i++) {
+ result = load_gpt_entry(image_handle, &entry);
+ assert(result == 0);
+ result = parse_gpt_entry(&entry, &list.list[i]);
+ if (result != 0) {
+ break;
+ }
+ }
+ if (i == 0) {
+ return -EINVAL;
+ }
+ /*
+ * Only records the valid partition number that is loaded from
+ * partition table.
+ */
+ list.entry_count = i;
+ dump_entries(list.entry_count);
+
+ return 0;
+}
+
+int load_partition_table(unsigned int image_id)
+{
+ uintptr_t dev_handle, image_handle, image_spec = 0;
+ mbr_entry_t mbr_entry;
+ int result;
+
+ result = plat_get_image_source(image_id, &dev_handle, &image_spec);
+ if (result != 0) {
+ WARN("Failed to obtain reference to image id=%u (%i)\n",
+ image_id, result);
+ return result;
+ }
+
+ result = io_open(dev_handle, image_spec, &image_handle);
+ if (result != 0) {
+ WARN("Failed to access image id=%u (%i)\n", image_id, result);
+ return result;
+ }
+
+ result = load_mbr_header(image_handle, &mbr_entry);
+ if (result != 0) {
+ WARN("Failed to access image id=%u (%i)\n", image_id, result);
+ return result;
+ }
+ if (mbr_entry.type == PARTITION_TYPE_GPT) {
+ result = load_gpt_header(image_handle);
+ assert(result == 0);
+ result = io_seek(image_handle, IO_SEEK_SET, GPT_ENTRY_OFFSET);
+ assert(result == 0);
+ result = verify_partition_gpt(image_handle);
+ } else {
+ /* MBR type isn't supported yet. */
+ result = -EINVAL;
+ goto exit;
+ }
+exit:
+ io_close(image_handle);
+ return result;
+}
+
+const partition_entry_t *get_partition_entry(const char *name)
+{
+ int i;
+
+ for (i = 0; i < list.entry_count; i++) {
+ if (strcmp(name, list.list[i].name) == 0) {
+ return &list.list[i];
+ }
+ }
+ return NULL;
+}
+
+const partition_entry_list_t *get_partition_entry_list(void)
+{
+ return &list;
+}
+
+void partition_init(unsigned int image_id)
+{
+ load_partition_table(image_id);
+}
diff --git a/include/drivers/partition/gpt.h b/include/drivers/partition/gpt.h
new file mode 100644
index 0000000..bd0a7f0
--- /dev/null
+++ b/include/drivers/partition/gpt.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. 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 ARM 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 HOLDER 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 __GPT_H__
+#define __GPT_H__
+
+#include <partition.h>
+
+#define PARTITION_TYPE_GPT 0xee
+#define GPT_HEADER_OFFSET PARTITION_BLOCK_SIZE
+#define GPT_ENTRY_OFFSET (GPT_HEADER_OFFSET + \
+ PARTITION_BLOCK_SIZE)
+#define GUID_LEN 16
+
+#define GPT_SIGNATURE "EFI PART"
+
+typedef struct gpt_entry {
+ unsigned char type_uuid[GUID_LEN];
+ unsigned char unique_uuid[GUID_LEN];
+ unsigned long long first_lba;
+ unsigned long long last_lba;
+ unsigned long long attr;
+ unsigned short name[EFI_NAMELEN];
+} gpt_entry_t;
+
+typedef struct gpt_header {
+ unsigned char signature[8];
+ unsigned int revision;
+ unsigned int size;
+ unsigned int header_crc;
+ unsigned int reserved;
+ unsigned long long current_lba;
+ unsigned long long backup_lba;
+ unsigned long long first_lba;
+ unsigned long long last_lba;
+ unsigned char disk_uuid[16];
+ /* starting LBA of array of partition entries */
+ unsigned long long part_lba;
+ /* number of partition entries in array */
+ unsigned int list_num;
+ /* size of a single partition entry (usually 128) */
+ unsigned int part_size;
+ unsigned int part_crc;
+} gpt_header_t;
+
+int parse_gpt_entry(gpt_entry_t *gpt_entry, partition_entry_t *entry);
+
+#endif /* __GPT_H__ */
diff --git a/include/drivers/partition/mbr.h b/include/drivers/partition/mbr.h
new file mode 100644
index 0000000..5287e28
--- /dev/null
+++ b/include/drivers/partition/mbr.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. 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 ARM 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 HOLDER 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 __MBR_H__
+#define __MBR_H__
+
+#define MBR_OFFSET 0
+
+#define MBR_PRIMARY_ENTRY_OFFSET 0x1be
+#define MBR_PRIMARY_ENTRY_SIZE 0x10
+#define MBR_PRIMARY_ENTRY_NUMBER 4
+#define MBR_CHS_ADDRESS_LEN 3
+
+#define MBR_SIGNATURE_FIRST 0x55
+#define MBR_SIGNATURE_SECOND 0xAA
+
+typedef struct mbr_entry {
+ unsigned char status;
+ unsigned char first_sector[MBR_CHS_ADDRESS_LEN];
+ unsigned char type;
+ unsigned char last_sector[MBR_CHS_ADDRESS_LEN];
+ unsigned int first_lba;
+ unsigned int sector_nums;
+} mbr_entry_t;
+
+#endif /* __MBR_H__ */
diff --git a/include/drivers/partition/partition.h b/include/drivers/partition/partition.h
new file mode 100644
index 0000000..9d7221d
--- /dev/null
+++ b/include/drivers/partition/partition.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. 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 ARM 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 HOLDER 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 __PARTITION_H__
+#define __PARTITION_H__
+
+#include <cassert.h>
+#include <types.h>
+
+#if !PLAT_PARTITION_MAX_ENTRIES
+# define PLAT_PARTITION_MAX_ENTRIES 128
+#endif /* PLAT_PARTITION_MAX_ENTRIES */
+
+CASSERT(PLAT_PARTITION_MAX_ENTRIES <= 128, assert_plat_partition_max_entries);
+
+#define PARTITION_BLOCK_SIZE 512
+
+#define EFI_NAMELEN 36
+
+typedef struct partition_entry {
+ uint64_t start;
+ uint64_t length;
+ char name[EFI_NAMELEN];
+} partition_entry_t;
+
+typedef struct partition_entry_list {
+ partition_entry_t list[PLAT_PARTITION_MAX_ENTRIES];
+ int entry_count;
+} partition_entry_list_t;
+
+int load_partition_table(unsigned int image_id);
+const partition_entry_t *get_partition_entry(const char *name);
+const partition_entry_list_t *get_partition_entry_list(void);
+void partition_init(unsigned int image_id);
+
+#endif /* __PARTITION_H__ */
diff --git a/plat/common/aarch64/platform_helpers.S b/plat/common/aarch64/platform_helpers.S
index a134ded..68bda22 100644
--- a/plat/common/aarch64/platform_helpers.S
+++ b/plat/common/aarch64/platform_helpers.S
@@ -98,7 +98,7 @@
/* -----------------------------------------------------
* Placeholder function which should be redefined by
- * each platform. This function should preserve x10.
+ * each platform. This function should preserve x19 - x29.
* -----------------------------------------------------
*/
func plat_reset_handler
diff --git a/plat/rockchip/common/aarch64/plat_helpers.S b/plat/rockchip/common/aarch64/plat_helpers.S
index d06d4cb..a93b526 100644
--- a/plat/rockchip/common/aarch64/plat_helpers.S
+++ b/plat/rockchip/common/aarch64/plat_helpers.S
@@ -67,7 +67,7 @@
* Set the L2 Data RAM latency for Cortex-A72.
* Set the L2 Tag RAM latency to for Cortex-A72.
*/
- mov x0, #((2 << L2CTLR_DATA_RAM_LATENCY_SHIFT) | \
+ mov x0, #((5 << L2CTLR_DATA_RAM_LATENCY_SHIFT) | \
(0x1 << 5))
msr L2CTLR_EL1, x0
isb
diff --git a/plat/rockchip/common/aarch64/platform_common.c b/plat/rockchip/common/aarch64/platform_common.c
index 40cd29e..ff47016 100644
--- a/plat/rockchip/common/aarch64/platform_common.c
+++ b/plat/rockchip/common/aarch64/platform_common.c
@@ -68,6 +68,7 @@
coh_limit - coh_start, \
MT_DEVICE | MT_RW | MT_SECURE); \
mmap_add(plat_rk_mmap); \
+ rockchip_plat_sram_mmu_el##_el(); \
init_xlat_tables(); \
\
enable_mmu_el ## _el(0); \
diff --git a/plat/rockchip/common/bl31_plat_setup.c b/plat/rockchip/common/bl31_plat_setup.c
index 47a245a..b073bde 100644
--- a/plat/rockchip/common/bl31_plat_setup.c
+++ b/plat/rockchip/common/bl31_plat_setup.c
@@ -115,10 +115,6 @@
bl32_ep_info = *from_bl2->bl32_ep_info;
bl33_ep_info = *from_bl2->bl33_ep_info;
- /*
- * The code for resuming cpu from suspend must be excuted in pmusram.
- * Copy the code into pmusram.
- */
plat_rockchip_pmusram_prepare();
/* there may have some board sepcific message need to initialize */
diff --git a/plat/rockchip/common/include/plat_private.h b/plat/rockchip/common/include/plat_private.h
index ad01266..a093e79 100644
--- a/plat/rockchip/common/include/plat_private.h
+++ b/plat/rockchip/common/include/plat_private.h
@@ -37,6 +37,14 @@
#include <xlat_tables.h>
#include <psci.h>
+#define __sramdata __attribute__((section(".sram.data")))
+#define __sramconst __attribute__((section(".sram.rodata")))
+#define __sramfunc __attribute__((section(".sram.text"))) \
+ __attribute__((noinline))
+
+extern uint32_t __bl31_sram_text_start, __bl31_sram_text_end;
+extern uint32_t __bl31_sram_data_start, __bl31_sram_data_end;
+
/******************************************************************************
* For rockchip socs pm ops
******************************************************************************/
@@ -135,6 +143,10 @@
extern uint32_t cpuson_flags[PLATFORM_CORE_COUNT];
extern const mmap_region_t plat_rk_mmap[];
+
+void rockchip_plat_sram_mmu_el3(void);
+void plat_rockchip_mem_prepare(void);
+
#endif /* __ASSEMBLY__ */
/******************************************************************************
diff --git a/plat/rockchip/common/plat_pm.c b/plat/rockchip/common/plat_pm.c
index d28100d..e926345 100644
--- a/plat/rockchip/common/plat_pm.c
+++ b/plat/rockchip/common/plat_pm.c
@@ -317,18 +317,6 @@
rockchip_ops->system_off();
}
-static void
-__dead2 rockchip_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state)
-{
- if ((RK_CORE_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) &&
- (rockchip_ops)) {
- if (RK_SYSTEM_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE &&
- rockchip_ops->sys_pwr_down_wfi)
- rockchip_ops->sys_pwr_down_wfi(target_state);
- }
- psci_power_down_wfi();
-}
-
/*******************************************************************************
* Export the platform handlers via plat_rockchip_psci_pm_ops. The rockchip
* standard
@@ -341,7 +329,6 @@
.pwr_domain_suspend = rockchip_pwr_domain_suspend,
.pwr_domain_on_finish = rockchip_pwr_domain_on_finish,
.pwr_domain_suspend_finish = rockchip_pwr_domain_suspend_finish,
- .pwr_domain_pwr_down_wfi = rockchip_pwr_domain_pwr_down_wfi,
.system_reset = rockchip_system_reset,
.system_off = rockchip_system_poweroff,
.validate_power_state = rockchip_validate_power_state,
diff --git a/plat/rockchip/common/pmusram/pmu_sram.c b/plat/rockchip/common/pmusram/pmu_sram.c
index bea4875..5c6a6e6 100644
--- a/plat/rockchip/common/pmusram/pmu_sram.c
+++ b/plat/rockchip/common/pmusram/pmu_sram.c
@@ -24,7 +24,10 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include <console.h>
+#include <debug.h>
#include <platform.h>
+#include <plat_private.h>
/*****************************************************************************
* sram only surpport 32-bits access
@@ -36,3 +39,33 @@
for (i = 0; i < bytes; i++)
dst[i] = src[i];
}
+
+void rockchip_plat_sram_mmu_el3(void)
+{
+#ifdef PLAT_EXTRA_LD_SCRIPT
+ size_t sram_size;
+
+ /* sram.text size */
+ sram_size = (char *)&__bl31_sram_text_end -
+ (char *)&__bl31_sram_text_start;
+ mmap_add_region((unsigned long)&__bl31_sram_text_start,
+ (unsigned long)&__bl31_sram_text_start,
+ sram_size, MT_MEMORY | MT_RO | MT_SECURE);
+
+ /* sram.data size */
+ sram_size = (char *)&__bl31_sram_data_end -
+ (char *)&__bl31_sram_data_start;
+ mmap_add_region((unsigned long)&__bl31_sram_data_start,
+ (unsigned long)&__bl31_sram_data_start,
+ sram_size, MT_MEMORY | MT_RW | MT_SECURE);
+#else
+ /* TODO: Support other SoCs, Just support RK3399 now */
+ return;
+#endif
+}
+
+void plat_rockchip_mem_prepare(void)
+{
+ /* The code for resuming cpu from suspend must be excuted in pmusram */
+ plat_rockchip_pmusram_prepare();
+}
diff --git a/plat/rockchip/common/pmusram/pmu_sram.h b/plat/rockchip/common/pmusram/pmu_sram.h
index f290461..ec2d341 100644
--- a/plat/rockchip/common/pmusram/pmu_sram.h
+++ b/plat/rockchip/common/pmusram/pmu_sram.h
@@ -45,16 +45,6 @@
#ifndef __ASSEMBLY__
-/*
- * The struct is used in pmu_cpus_on.S which
- * gets the data of the struct by the following index
- * #define PSRAM_DT_SP 0x0
- * #define PSRAM_DT_DDR_FUNC 0x8
- * #define PSRAM_DT_DDR_DATA 0x10
- * #define PSRAM_DT_DDRFLAG 0x18
- * #define PSRAM_DT_SYS_MODE 0x1c
- * #define PSRAM_DT_MPIDR 0x20
- */
struct psram_data_t {
uint64_t sp;
uint64_t ddr_func;
@@ -76,6 +66,7 @@
CASSERT(__builtin_offsetof(struct psram_data_t, boot_mpidr) == PSRAM_DT_MPIDR,
assert_psram_dt_mpidr_offset_mistmatch);
void u32_align_cpy(uint32_t *dst, const uint32_t *src, size_t bytes);
+
#endif /* __ASSEMBLY__ */
#endif
diff --git a/plat/rockchip/rk3399/drivers/m0/Makefile b/plat/rockchip/rk3399/drivers/m0/Makefile
new file mode 100644
index 0000000..8adc47e
--- /dev/null
+++ b/plat/rockchip/rk3399/drivers/m0/Makefile
@@ -0,0 +1,156 @@
+#
+# Copyright (c) 2016, ARM Limited and Contributors. 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 ARM 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 HOLDER 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.
+#
+
+# Cross Compile
+M0_CROSS_COMPILE ?= arm-none-eabi-
+
+# Build architecture
+ARCH := cortex-m0
+
+# Build platform
+PLAT_M0 ?= rk3399m0
+
+ifeq (${V},0)
+ Q=@
+ CHECKCODE_ARGS += --no-summary --terse
+else
+ Q=
+endif
+export Q
+
+# All PHONY definition
+.PHONY: all clean distclean ${ARCH}
+all: ${ARCH}
+
+.SUFFIXES:
+
+INCLUDES += -Iinclude/
+
+# NOTE: Add C source files here
+C_SOURCES := src/startup.c \
+ src/main.c
+
+# Flags definition
+CFLAGS := -g
+ASFLAGS := -g -Wa,--gdwarf-2
+
+ASFLAGS += -mcpu=$(ARCH) -mthumb -Wall -ffunction-sections -O3
+CFLAGS += -mcpu=$(ARCH) -mthumb -Wall -ffunction-sections -O3
+
+LDFLAGS := -mcpu=$(ARCH) -mthumb -g -nostartfiles -O3
+LDFLAGS += -Wl,--gc-sections -Wl,--build-id=none
+
+# Cross tool
+CC := ${M0_CROSS_COMPILE}gcc
+CPP := ${M0_CROSS_COMPILE}cpp
+AS := ${M0_CROSS_COMPILE}gcc
+AR := ${M0_CROSS_COMPILE}ar
+LD := ${M0_CROSS_COMPILE}ld
+OC := ${M0_CROSS_COMPILE}objcopy
+OD := ${M0_CROSS_COMPILE}objdump
+NM := ${M0_CROSS_COMPILE}nm
+PP := ${M0_CROSS_COMPILE}gcc -E ${CFLAGS}
+
+# NOTE: The line continuation '\' is required in the next define otherwise we
+# end up with a line-feed characer at the end of the last c filename.
+# Also bare this issue in mind if extending the list of supported filetypes.
+define SOURCES_TO_OBJS
+ $(notdir $(patsubst %.c,%.o,$(filter %.c,$(1)))) \
+ $(notdir $(patsubst %.S,%.o,$(filter %.S,$(1))))
+endef
+
+BUILD_DIR := ${BUILD_PLAT}/obj
+BIN_DIR := ${BUILD_PLAT}/bin
+SOURCES := $(C_SOURCES)
+OBJS := $(addprefix $(BUILD_DIR)/,$(call SOURCES_TO_OBJS,$(SOURCES)))
+LINKERFILE := src/rk3399m0.ld
+MAPFILE := $(BIN_DIR)/$(PLAT_M0).map
+ELF := $(BIN_DIR)/$(PLAT_M0).elf
+BIN := $(BIN_DIR)/$(PLAT_M0).bin
+
+# Function definition related compilation
+define MAKE_C
+$(eval OBJ := $(1)/$(patsubst %.c,%.o,$(notdir $(2))))
+
+$(OBJ) : $(2)
+ @echo " CC $$<"
+ $$(Q)$$(CC) $$(CFLAGS) $$(INCLUDES) -c $$< -o $$@
+endef
+
+define MAKE_S
+$(eval OBJ := $(1)/$(patsubst %.S,%.o,$(notdir $(2))))
+
+$(OBJ) : $(2)
+ @echo " AS $$<"
+ $$(Q)$$(AS) $$(ASFLAGS) -c $$< -o $$@
+endef
+
+define MAKE_OBJS
+ $(eval C_OBJS := $(filter %.c,$(2)))
+ $(eval REMAIN := $(filter-out %.c,$(2)))
+ $(eval $(foreach obj,$(C_OBJS),$(call MAKE_C,$(1),$(obj),$(3))))
+
+ $(eval S_OBJS := $(filter %.S,$(REMAIN)))
+ $(eval REMAIN := $(filter-out %.S,$(REMAIN)))
+ $(eval $(foreach obj,$(S_OBJS),$(call MAKE_S,$(1),$(obj),$(3))))
+
+ $(and $(REMAIN),$(error Unexpected source files present: $(REMAIN)))
+endef
+
+$(BIN_DIR) :
+ $(Q)mkdir -p "$@"
+
+$(BUILD_DIR) : $(BIN_DIR)
+ $(Q)mkdir -p "$@"
+
+$(ELF) : $(OBJS) $(LINKERFILE)
+ @echo " LD $@"
+ $(Q)$(CC) -o $@ $(LDFLAGS) -Wl,-Map=$(MAPFILE) -Wl,-T$(LINKERFILE) \
+ $(OBJS)
+
+$(BIN) : $(ELF)
+ @echo " BIN $@"
+ $(Q)$(OC) -O binary $< $@
+
+.PHONY : ${ARCH}
+${ARCH} : $(BUILD_DIR) $(BIN)
+
+$(eval $(call MAKE_OBJS,$(BUILD_DIR),$(SOURCES),$(1)))
+
+# Other common compilation entries
+clean:
+ @echo " CLEAN"
+ ${Q}rm -rf ${BUILD_BASE}/${PLAT_M0}
+ ${Q}rm -rf ${VER_BIN_DIR}/$(PLAT_M0)*
+
+distclean:
+ @echo " DISTCLEAN"
+ ${Q}rm -rf ${BUILD_BASE}/${PLAT_M0}
+ ${Q}rm -rf ${VER_BIN_DIR}/$(PLAT_M0)*
diff --git a/plat/rockchip/rk3399/drivers/m0/include/rk3399_mcu.h b/plat/rockchip/rk3399/drivers/m0/include/rk3399_mcu.h
new file mode 100644
index 0000000..7ea40fa
--- /dev/null
+++ b/plat/rockchip/rk3399/drivers/m0/include/rk3399_mcu.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. 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 ARM 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 HOLDER 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 __RK3399_MCU_H__
+#define __RK3399_MCU_H__
+
+#define readl(c) ({unsigned int __v = \
+ (*(volatile unsigned int *)(c)); __v; })
+#define writel(v, c) ((*(volatile unsigned int *) (c)) = (v))
+
+#define MCU_BASE 0x40000000
+#define PMU_BASE (MCU_BASE + 0x07310000)
+
+#endif /* __RK3399_MCU_H__ */
diff --git a/plat/rockchip/rk3399/drivers/m0/src/main.c b/plat/rockchip/rk3399/drivers/m0/src/main.c
new file mode 100644
index 0000000..2e583c7
--- /dev/null
+++ b/plat/rockchip/rk3399/drivers/m0/src/main.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. 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 ARM 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 HOLDER 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 "rk3399_mcu.h"
+
+#define PMU_PWRMODE_CON 0x20
+#define PMU_POWER_ST 0x78
+
+#define M0_SCR 0xe000ed10 /* System Control Register (SCR) */
+
+#define SCR_SLEEPDEEP_SHIFT (1 << 2)
+
+static void system_wakeup(void)
+{
+ unsigned int status_value;
+ unsigned int mode_con;
+
+ while (1) {
+ status_value = readl(PMU_BASE + PMU_POWER_ST);
+ if (status_value) {
+ mode_con = readl(PMU_BASE + PMU_PWRMODE_CON);
+ writel(mode_con & (~0x01),
+ PMU_BASE + PMU_PWRMODE_CON);
+ return;
+ }
+ }
+}
+
+int main(void)
+{
+ unsigned int reg_src;
+
+ system_wakeup();
+
+ reg_src = readl(M0_SCR);
+
+ /* m0 enter deep sleep mode */
+ writel(reg_src | SCR_SLEEPDEEP_SHIFT, M0_SCR);
+
+ for (;;)
+ __asm volatile("wfi");
+
+ return 0;
+}
diff --git a/plat/rockchip/rk3399/drivers/m0/src/rk3399m0.ld b/plat/rockchip/rk3399/drivers/m0/src/rk3399m0.ld
new file mode 100644
index 0000000..0b7b124
--- /dev/null
+++ b/plat/rockchip/rk3399/drivers/m0/src/rk3399m0.ld
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. 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 ARM 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 HOLDER 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.
+ */
+
+OUTPUT_FORMAT("elf32-littlearm")
+
+SECTIONS {
+ .m0_bin 0 : {
+ KEEP(*(.isr_vector))
+ ASSERT(. == 0xc0, "ISR vector has the wrong size.");
+ *(.text*)
+ *(.rodata*)
+ *(.data*)
+ *(.bss*)
+ . = ALIGN(8);
+ *(.co_stack*)
+ }
+
+ /DISCARD/ : { *(.comment) *(.note*) }
+}
diff --git a/plat/rockchip/rk3399/drivers/m0/src/startup.c b/plat/rockchip/rk3399/drivers/m0/src/startup.c
new file mode 100644
index 0000000..47561fd
--- /dev/null
+++ b/plat/rockchip/rk3399/drivers/m0/src/startup.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. 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 ARM 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 HOLDER 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 "rk3399_mcu.h"
+
+/* Stack configuration */
+#define STACK_SIZE 0x00000100
+__attribute__ ((section(".co_stack")))
+unsigned long pstack[STACK_SIZE];
+
+/* Macro definition */
+#define WEAK __attribute__ ((weak))
+
+/* System exception vector handler */
+__attribute__ ((used))
+void WEAK reset_handler(void);
+void WEAK nmi_handler(void);
+void WEAK hardware_fault_handler(void);
+void WEAK svc_handler(void);
+void WEAK pend_sv_handler(void);
+void WEAK systick_handler(void);
+
+extern int main(void);
+
+/* Function prototypes */
+static void default_reset_handler(void);
+static void default_handler(void);
+
+/*
+ * The minimal vector table for a Cortex M3. Note that the proper constructs
+ * must be placed on this to ensure that it ends up at physical address
+ * 0x00000000.
+ */
+__attribute__ ((used, section(".isr_vector")))
+void (* const g_pfnVectors[])(void) = {
+ /* core Exceptions */
+ (void *)&pstack[STACK_SIZE], /* the initial stack pointer */
+ reset_handler,
+ nmi_handler,
+ hardware_fault_handler,
+ 0, 0, 0, 0, 0, 0, 0,
+ svc_handler,
+ 0, 0,
+ pend_sv_handler,
+ systick_handler,
+
+ /* external exceptions */
+ 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0
+};
+
+/**
+ * This is the code that gets called when the processor first
+ * starts execution following a reset event. Only the absolutely
+ * necessary set is performed, after which the application
+ * supplied main() routine is called.
+ */
+static void default_reset_handler(void)
+{
+ /* call the application's entry point */
+ main();
+}
+
+/**
+ * Provide weak aliases for each Exception handler to the Default_Handler.
+ * As they are weak aliases, any function with the same name will override
+ * this definition.
+ */
+#pragma weak reset_handler = default_reset_handler
+#pragma weak nmi_handler = default_handler
+#pragma weak hardware_fault_handler = default_handler
+#pragma weak svc_handler = default_handler
+#pragma weak pend_sv_handler = default_handler
+#pragma weak systick_handler = default_handler
+
+/**
+ * This is the code that gets called when the processor receives
+ * an unexpected interrupt. This simply enters an infinite loop,
+ * preserving the system state for examination by a debugger.
+ */
+static void default_handler(void)
+{
+ /* go into an infinite loop. */
+ while (1)
+ ;
+}
diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu.c b/plat/rockchip/rk3399/drivers/pmu/pmu.c
index 07a5b1e..8d3f482 100644
--- a/plat/rockchip/rk3399/drivers/pmu/pmu.c
+++ b/plat/rockchip/rk3399/drivers/pmu/pmu.c
@@ -48,6 +48,7 @@
#include <pwm.h>
#include <soc.h>
#include <bl31.h>
+#include <rk3399m0.h>
DEFINE_BAKERY_LOCK(rockchip_pd_lock);
@@ -436,7 +437,7 @@
void plat_rockchip_pmusram_prepare(void)
{
uint32_t *sram_dst, *sram_src;
- size_t sram_size = 2;
+ size_t sram_size;
/*
* pmu sram code and data prepare
@@ -840,8 +841,6 @@
BIT(PMU_SCU_PD_EN) |
BIT(PMU_CCI_PD_EN) |
BIT(PMU_CLK_CORE_SRC_GATE_EN) |
- BIT(PMU_PERILP_PD_EN) |
- BIT(PMU_CLK_PERILP_SRC_GATE_EN) |
BIT(PMU_ALIVE_USE_LF) |
BIT(PMU_SREF0_ENTER_EN) |
BIT(PMU_SREF1_ENTER_EN) |
@@ -1058,6 +1057,38 @@
}
}
+static void m0_clock_init(void)
+{
+ /* enable clocks for M0 */
+ mmio_write_32(PMUCRU_BASE + PMUCRU_CLKGATE_CON2,
+ BITS_WITH_WMASK(0x0, 0x2f, 0));
+
+ /* switch the parent to xin24M and div == 1 */
+ mmio_write_32(PMUCRU_BASE + PMUCRU_CLKSEL_CON0,
+ BIT_WITH_WMSK(15) | BITS_WITH_WMASK(0x0, 0x1f, 8));
+
+ /* start M0 */
+ mmio_write_32(PMUCRU_BASE + PMUCRU_SOFTRST_CON0,
+ BITS_WITH_WMASK(0x0, 0x24, 0));
+
+ /* gating disable for M0 */
+ mmio_write_32(PMUCRU_BASE + PMUCRU_GATEDIS_CON0, BIT_WITH_WMSK(1));
+}
+
+static void m0_reset(void)
+{
+ /* stop M0 */
+ mmio_write_32(PMUCRU_BASE + PMUCRU_SOFTRST_CON0,
+ BITS_WITH_WMASK(0x24, 0x24, 0));
+
+ /* recover gating bit for M0 */
+ mmio_write_32(PMUCRU_BASE + PMUCRU_GATEDIS_CON0, WMSK_BIT(1));
+
+ /* disable clocks for M0 */
+ mmio_write_32(PMUCRU_BASE + PMUCRU_CLKGATE_CON2,
+ BITS_WITH_WMASK(0x2f, 0x2f, 0));
+}
+
static int sys_pwr_domain_suspend(void)
{
uint32_t wait_cnt = 0;
@@ -1071,12 +1102,12 @@
BIT(PMU_CLR_CCIM0) |
BIT(PMU_CLR_CCIM1) |
BIT(PMU_CLR_CENTER) |
- BIT(PMU_CLR_PERILP) |
- BIT(PMU_CLR_PMU) |
- BIT(PMU_CLR_PERILPM0) |
BIT(PMU_CLR_GIC));
sys_slp_config();
+
+ m0_clock_init();
+
pmu_sgrf_rst_hld();
mmio_write_32(SGRF_BASE + SGRF_SOC_CON0_1(1),
@@ -1111,6 +1142,7 @@
disable_dvfs_plls();
disable_pwms();
disable_nodvfs_plls();
+
suspend_apio();
suspend_gpio();
@@ -1186,12 +1218,12 @@
BIT(PMU_CLR_CCIM0) |
BIT(PMU_CLR_CCIM1) |
BIT(PMU_CLR_CENTER) |
- BIT(PMU_CLR_PERILP) |
- BIT(PMU_CLR_PMU) |
BIT(PMU_CLR_GIC));
plat_rockchip_gic_cpuif_enable();
+ m0_reset();
+
return 0;
}
@@ -1236,42 +1268,6 @@
while (1)
;
}
-static void __dead2 sys_pwr_down_wfi(const psci_power_state_t *target_state)
-{
- uint32_t wakeup_status;
-
- /*
- * Check wakeup status and abort suspend early if we see a wakeup
- * event.
- *
- * NOTE: technically I we're supposed to just execute a wfi here and
- * we'll either execute a normal suspend/resume or the wfi will be
- * treated as a no-op if a wake event was present and caused an abort
- * of the suspend/resume. For some reason that's not happening and if
- * we execute the wfi while a wake event is pending then the whole
- * system wedges.
- *
- * Until the above is solved this extra check prevents system wedges in
- * most cases but there is still a small race condition between checking
- * PMU_WAKEUP_STATUS and executing wfi. If a wake event happens in
- * there then we will die.
- */
- wakeup_status = mmio_read_32(PMU_BASE + PMU_WAKEUP_STATUS);
- if (wakeup_status) {
- WARN("early wake, will not enter power mode.\n");
-
- mmio_write_32(PMU_BASE + PMU_PWRMODE_CON, 0);
-
- disable_mmu_icache_el3();
- bl31_warm_entrypoint();
-
- while (1)
- ;
- } else {
- /* Enter WFI */
- psci_power_down_wfi();
- }
-}
static struct rockchip_pm_ops_cb pm_ops = {
.cores_pwr_dm_on = cores_pwr_domain_on,
@@ -1287,7 +1283,6 @@
.sys_pwr_dm_resume = sys_pwr_domain_resume,
.sys_gbl_soft_reset = soc_soft_reset,
.system_off = soc_system_off,
- .sys_pwr_down_wfi = sys_pwr_down_wfi,
};
void plat_rockchip_pmu_init(void)
diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c b/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c
new file mode 100644
index 0000000..01f08e6
--- /dev/null
+++ b/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. 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 ARM 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 HOLDER 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.
+ */
+
+/* convoluted way to make sure that the define is pasted just the right way */
+#define _INCBIN(file, sym) \
+ __asm__( \
+ ".section .sram.incbin\n" \
+ ".global " #sym "\n" \
+ ".type " #sym ", %object\n" \
+ ".align 4\n" \
+ #sym ":\n" \
+ ".incbin \"" #file "\"\n" \
+ ".size " #sym ", .-" #sym "\n" \
+ ".global " #sym "_end\n" \
+ #sym "_end:\n" \
+ )
+
+#define INCBIN(file, sym) _INCBIN(file, sym)
+
+INCBIN(RK3399M0FW, rk3399m0_bin);
diff --git a/plat/rockchip/rk3399/drivers/pmu/rk3399m0.h b/plat/rockchip/rk3399/drivers/pmu/rk3399m0.h
new file mode 100644
index 0000000..78b350a
--- /dev/null
+++ b/plat/rockchip/rk3399/drivers/pmu/rk3399m0.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. 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 ARM 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 HOLDER 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 __RK3399M0_H__
+#define __RK3399M0_H__
+
+/* pmu_fw.c */
+extern char rk3399m0_bin[];
+extern char rk3399m0_bin_end[];
+
+#define M0_BINCODE_BASE ((uintptr_t)rk3399m0_bin)
+
+#endif /* __RK3399M0_H__ */
diff --git a/plat/rockchip/rk3399/drivers/soc/soc.c b/plat/rockchip/rk3399/drivers/soc/soc.c
index 6af7a2e..e99db19 100644
--- a/plat/rockchip/rk3399/drivers/soc/soc.c
+++ b/plat/rockchip/rk3399/drivers/soc/soc.c
@@ -35,6 +35,7 @@
#include <platform_def.h>
#include <plat_private.h>
#include <rk3399_def.h>
+#include <rk3399m0.h>
#include <soc.h>
/* Table of regions to map using the MMU. */
@@ -387,6 +388,20 @@
;
}
+static void soc_m0_init(void)
+{
+ /* secure config for pmu M0 */
+ mmio_write_32(SGRF_BASE + SGRF_PMU_CON(0), WMSK_BIT(7));
+
+ /* set the execute address for M0 */
+ mmio_write_32(SGRF_BASE + SGRF_PMU_CON(3),
+ BITS_WITH_WMASK((M0_BINCODE_BASE >> 12) & 0xffff,
+ 0xffff, 0));
+ mmio_write_32(SGRF_BASE + SGRF_PMU_CON(7),
+ BITS_WITH_WMASK((M0_BINCODE_BASE >> 28) & 0xf,
+ 0xf, 0));
+}
+
void plat_rockchip_soc_init(void)
{
secure_timer_init();
@@ -394,4 +409,5 @@
sgrf_init();
soc_global_soft_reset_init();
plat_rockchip_gpio_init();
+ soc_m0_init();
}
diff --git a/plat/rockchip/rk3399/drivers/soc/soc.h b/plat/rockchip/rk3399/drivers/soc/soc.h
index d99b380..9693f57 100644
--- a/plat/rockchip/rk3399/drivers/soc/soc.h
+++ b/plat/rockchip/rk3399/drivers/soc/soc.h
@@ -64,7 +64,7 @@
#define PLL_NO_BYPASS_MODE WMSK_BIT(PLL_BYPASS_SHIFT)
#define PLL_CON_COUNT 0x06
-#define CRU_CLKSEL_COUNT 0x108
+#define CRU_CLKSEL_COUNT 108
#define CRU_CLKSEL_CON(n) (0x100 + (n) * 4)
#define PMUCRU_CLKSEL_CONUT 0x06
@@ -293,6 +293,18 @@
#define GRF_DDRC1_CON0 0xe388
#define GRF_DDRC1_CON1 0xe38c
+#define PMUCRU_CLKSEL_CON0 0x0080
+#define PMUCRU_CLKGATE_CON2 0x0108
+#define PMUCRU_SOFTRST_CON0 0x0110
+#define PMUCRU_GATEDIS_CON0 0x0130
+
+#define SGRF_SOC_CON6 0x0e018
+#define SGRF_PERILP_CON0 0x08100
+#define SGRF_PERILP_CON(n) (SGRF_PERILP_CON0 + (n) * 4)
+#define SGRF_PMU_CON0 0x0c100
+#define SGRF_PMU_CON(n) (SGRF_PMU_CON0 + (n) * 4)
+#define PMUCRU_SOFTRST_CON(n) (PMUCRU_SOFTRST_CON0 + (n) * 4)
+
/*
* When system reset in running state, we want the cpus to be reboot
* from maskrom (system reboot),
diff --git a/plat/rockchip/rk3399/include/plat.ld.S b/plat/rockchip/rk3399/include/plat.ld.S
new file mode 100644
index 0000000..1614fba
--- /dev/null
+++ b/plat/rockchip/rk3399/include/plat.ld.S
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. 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 ARM 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 HOLDER 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 __ROCKCHIP_PLAT_LD_S__
+#define __ROCKCHIP_PLAT_LD_S__
+
+MEMORY {
+ SRAM (rwx): ORIGIN = SRAM_BASE, LENGTH = SRAM_SIZE
+}
+
+SECTIONS
+{
+ . = SRAM_BASE;
+ ASSERT(. == ALIGN(4096),
+ "SRAM_BASE address is not aligned on a page boundary.")
+
+ /*
+ * The SRAM space allocation for RK3399
+ * ----------------
+ * | m0 code bin
+ * ----------------
+ * | sram text
+ * ----------------
+ * | sram data
+ * ----------------
+ */
+ .incbin_sram : ALIGN(4096) {
+ __sram_incbin_start = .;
+ *(.sram.incbin)
+ . = ALIGN(4096);
+ __sram_incbin_end = .;
+ } >SRAM
+
+ .text_sram : ALIGN(4096) {
+ __bl31_sram_text_start = .;
+ *(.sram.text)
+ *(.sram.rodata)
+ . = ALIGN(4096);
+ __bl31_sram_text_end = .;
+ } >SRAM
+
+ .data_sram : ALIGN(4096) {
+ __bl31_sram_data_start = .;
+ *(.sram.data)
+ . = ALIGN(4096);
+ __bl31_sram_data_end = .;
+ } >SRAM
+}
+
+#endif /* __ROCKCHIP_PLAT_LD_S__ */
diff --git a/plat/rockchip/rk3399/platform.mk b/plat/rockchip/rk3399/platform.mk
index 3627857..604de9c 100644
--- a/plat/rockchip/rk3399/platform.mk
+++ b/plat/rockchip/rk3399/platform.mk
@@ -76,9 +76,28 @@
${RK_PLAT_SOC}/plat_sip_calls.c \
${RK_PLAT_SOC}/drivers/gpio/rk3399_gpio.c \
${RK_PLAT_SOC}/drivers/pmu/pmu.c \
+ ${RK_PLAT_SOC}/drivers/pmu/pmu_fw.c \
${RK_PLAT_SOC}/drivers/pwm/pwm.c \
${RK_PLAT_SOC}/drivers/soc/soc.c \
${RK_PLAT_SOC}/drivers/dram/dram.c \
${RK_PLAT_SOC}/drivers/dram/dram_spec_timing.c
ENABLE_PLAT_COMPAT := 0
+
+$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
+
+# M0 source build
+PLAT_M0 := ${PLAT}m0
+
+RK3399M0FW=${BUILD_PLAT}/m0/bin/${PLAT_M0}.bin
+$(eval $(call add_define,RK3399M0FW))
+
+# CCACHE_EXTRAFILES is needed because ccache doesn't handle .incbin
+export CCACHE_EXTRAFILES
+${BUILD_PLAT}/bl31/pmu_fw.o: CCACHE_EXTRAFILES=$(RK3399M0FW)
+${RK_PLAT_SOC}/drivers/pmu/pmu_fw.c: $(RK3399M0FW)
+
+.PHONY: $(RK3399M0FW)
+$(RK3399M0FW):
+ $(MAKE) -C ${RK_PLAT_SOC}/drivers/m0 \
+ BUILD_PLAT=$(abspath ${BUILD_PLAT}/m0)
diff --git a/tools/fiptool/fiptool.c b/tools/fiptool/fiptool.c
index b3f02f6..0084edf 100644
--- a/tools/fiptool/fiptool.c
+++ b/tools/fiptool/fiptool.c
@@ -187,7 +187,7 @@
}
}
-static toc_entry_t *get_entry_lookup_from_uuid(const uuid_t *uuid)
+static toc_entry_t *lookup_entry_from_uuid(uuid_t *uuid)
{
toc_entry_t *toc_entry = toc_entries;
@@ -197,6 +197,19 @@
return NULL;
}
+static image_t *lookup_image_from_uuid(uuid_t *uuid)
+{
+ image_t *image;
+ int i;
+
+ for (i = 0; i < nr_images; i++) {
+ image = images[i];
+ if (memcmp(&image->uuid, uuid, sizeof(uuid_t)) == 0)
+ return image;
+ }
+ return NULL;
+}
+
static int parse_fip(char *filename, fip_toc_header_t *toc_header_out)
{
struct stat st;
@@ -268,16 +281,6 @@
toc_entry->size);
image->size = toc_entry->size;
- image->toc_entry = get_entry_lookup_from_uuid(&toc_entry->uuid);
- if (image->toc_entry == NULL) {
- add_image(image);
- toc_entry++;
- continue;
- }
-
- assert(image->toc_entry->image == NULL);
- /* Link backpointer from lookup entry. */
- image->toc_entry->image = image;
add_image(image);
toc_entry++;
@@ -290,12 +293,14 @@
return 0;
}
-static image_t *read_image_from_file(toc_entry_t *toc_entry, char *filename)
+static image_t *read_image_from_file(uuid_t *uuid, char *filename)
{
struct stat st;
image_t *image;
FILE *fp;
+ assert(uuid != NULL);
+
fp = fopen(filename, "r");
if (fp == NULL)
log_err("fopen %s", filename);
@@ -307,7 +312,7 @@
if (image == NULL)
log_err("malloc");
- memcpy(&image->uuid, &toc_entry->uuid, sizeof(uuid_t));
+ memcpy(&image->uuid, uuid, sizeof(uuid_t));
image->buffer = malloc(st.st_size);
if (image->buffer == NULL)
@@ -315,7 +320,6 @@
if (fread(image->buffer, 1, st.st_size, fp) != st.st_size)
log_errx("Failed to read %s", filename);
image->size = st.st_size;
- image->toc_entry = toc_entry;
fclose(fp);
return image;
@@ -391,18 +395,21 @@
(sizeof(fip_toc_entry_t) * (nr_images + 1));
for (i = 0; i < nr_images; i++) {
+ toc_entry_t *toc_entry;
+
image = images[i];
- if (image->toc_entry != NULL)
- printf("%s: ", image->toc_entry->name);
+ toc_entry = lookup_entry_from_uuid(&image->uuid);
+ if (toc_entry != NULL)
+ printf("%s: ", toc_entry->name);
else
printf("Unknown entry: ");
image_size = image->size;
printf("offset=0x%llX, size=0x%llX",
(unsigned long long)image_offset,
(unsigned long long)image_size);
- if (image->toc_entry != NULL)
+ if (toc_entry != NULL)
printf(", cmdline=\"--%s\"",
- image->toc_entry->cmdline_name);
+ toc_entry->cmdline_name);
if (verbose) {
unsigned char md[SHA256_DIGEST_LENGTH];
@@ -505,7 +512,7 @@
static void update_fip(void)
{
toc_entry_t *toc_entry;
- image_t *image;
+ image_t *new_image, *old_image;
/* Add or replace images in the FIP file. */
for (toc_entry = toc_entries;
@@ -514,21 +521,21 @@
if (toc_entry->action != DO_PACK)
continue;
- image = read_image_from_file(toc_entry, toc_entry->action_arg);
- if (toc_entry->image != NULL) {
+ new_image = read_image_from_file(&toc_entry->uuid,
+ toc_entry->action_arg);
+ old_image = lookup_image_from_uuid(&toc_entry->uuid);
+ if (old_image != NULL) {
if (verbose)
log_dbgx("Replacing image %s.bin with %s",
toc_entry->cmdline_name,
toc_entry->action_arg);
- replace_image(toc_entry->image, image);
+ replace_image(old_image, new_image);
} else {
if (verbose)
log_dbgx("Adding image %s",
toc_entry->action_arg);
- add_image(image);
+ add_image(new_image);
}
- /* Link backpointer from lookup entry. */
- toc_entry->image = image;
free(toc_entry->action_arg);
toc_entry->action_arg = NULL;
@@ -758,23 +765,13 @@
if (chdir(outdir) == -1)
log_err("chdir %s", outdir);
- /* Mark all images to be unpacked. */
- if (unpack_all) {
- for (toc_entry = toc_entries;
- toc_entry->cmdline_name != NULL;
- toc_entry++) {
- if (toc_entry->image != NULL) {
- toc_entry->action = DO_UNPACK;
- toc_entry->action_arg = NULL;
- }
- }
- }
-
/* Unpack all specified images. */
for (toc_entry = toc_entries;
toc_entry->cmdline_name != NULL;
toc_entry++) {
- if (toc_entry->action != DO_UNPACK)
+ image_t *image;
+
+ if (!unpack_all && toc_entry->action != DO_UNPACK)
continue;
/* Build filename. */
@@ -785,9 +782,11 @@
snprintf(file, sizeof(file), "%s",
toc_entry->action_arg);
- if (toc_entry->image == NULL) {
- log_warnx("Requested image %s is not in %s",
- file, argv[0]);
+ image = lookup_image_from_uuid(&toc_entry->uuid);
+ if (image == NULL) {
+ if (!unpack_all)
+ log_warnx("Requested image %s is not in %s",
+ file, argv[0]);
free(toc_entry->action_arg);
toc_entry->action_arg = NULL;
continue;
@@ -796,7 +795,7 @@
if (access(file, F_OK) != 0 || fflag) {
if (verbose)
log_dbgx("Unpacking %s", file);
- write_image_to_file(toc_entry->image, file);
+ write_image_to_file(image, file);
} else {
log_warnx("File %s already exists, use --force to overwrite it",
file);
@@ -885,13 +884,16 @@
for (toc_entry = toc_entries;
toc_entry->cmdline_name != NULL;
toc_entry++) {
+ image_t *image;
+
if (toc_entry->action != DO_REMOVE)
continue;
- if (toc_entry->image != NULL) {
+ image = lookup_image_from_uuid(&toc_entry->uuid);
+ if (image != NULL) {
if (verbose)
log_dbgx("Removing %s.bin",
toc_entry->cmdline_name);
- remove_image(toc_entry->image);
+ remove_image(image);
} else {
log_warnx("Requested image %s.bin is not in %s",
toc_entry->cmdline_name, argv[0]);
@@ -983,6 +985,8 @@
strcmp(argv[0], "--verbose") == 0) {
verbose = 1;
argc--, argv++;
+ if (argc < 1)
+ usage();
}
for (i = 0; i < NELEM(cmds); i++) {
diff --git a/tools/fiptool/fiptool.h b/tools/fiptool/fiptool.h
index 0fe64c0..7705107 100644
--- a/tools/fiptool/fiptool.h
+++ b/tools/fiptool/fiptool.h
@@ -57,7 +57,6 @@
uuid_t uuid;
size_t size;
void *buffer;
- struct toc_entry *toc_entry;
} image_t;
typedef struct cmd {
diff --git a/tools/fiptool/tbbr_config.c b/tools/fiptool/tbbr_config.c
index e8fbbba..b92e8da 100644
--- a/tools/fiptool/tbbr_config.c
+++ b/tools/fiptool/tbbr_config.c
@@ -35,49 +35,155 @@
/* The images used depends on the platform. */
toc_entry_t toc_entries[] = {
- { "SCP Firmware Updater Configuration FWU SCP_BL2U", UUID_TRUSTED_UPDATE_FIRMWARE_SCP_BL2U,
- "scp-fwu-cfg", NULL, 0, NULL },
- { "AP Firmware Updater Configuration BL2U", UUID_TRUSTED_UPDATE_FIRMWARE_BL2U,
- "ap-fwu-cfg", NULL, 0, NULL },
- { "Firmware Updater NS_BL2U", UUID_TRUSTED_UPDATE_FIRMWARE_NS_BL2U,
- "fwu", NULL, 0, NULL },
- { "Non-Trusted Firmware Updater certificate", UUID_TRUSTED_FWU_CERT,
- "fwu-cert", NULL, 0, NULL },
- { "Trusted Boot Firmware BL2", UUID_TRUSTED_BOOT_FIRMWARE_BL2,
- "tb-fw", NULL, 0, NULL },
- { "SCP Firmware SCP_BL2", UUID_SCP_FIRMWARE_SCP_BL2,
- "scp-fw", NULL, 0, NULL },
- { "EL3 Runtime Firmware BL31", UUID_EL3_RUNTIME_FIRMWARE_BL31,
- "soc-fw", NULL, 0, NULL },
- { "Secure Payload BL32 (Trusted OS)", UUID_SECURE_PAYLOAD_BL32,
- "tos-fw", NULL, 0, NULL },
- { "Non-Trusted Firmware BL33", UUID_NON_TRUSTED_FIRMWARE_BL33,
- "nt-fw", NULL, 0, NULL },
+ {
+ .name = "SCP Firmware Updater Configuration FWU SCP_BL2U",
+ .uuid = UUID_TRUSTED_UPDATE_FIRMWARE_SCP_BL2U,
+ .cmdline_name = "scp-fwu-cfg",
+ .action = 0,
+ .action_arg = NULL
+ },
+ {
+ .name = "AP Firmware Updater Configuration BL2U",
+ .uuid = UUID_TRUSTED_UPDATE_FIRMWARE_BL2U,
+ .cmdline_name = "ap-fwu-cfg",
+ .action = 0,
+ .action_arg = NULL
+ },
+ {
+ .name = "Firmware Updater NS_BL2U",
+ .uuid = UUID_TRUSTED_UPDATE_FIRMWARE_NS_BL2U,
+ .cmdline_name = "fwu",
+ .action = 0,
+ .action_arg = NULL
+ },
+ {
+ .name = "Non-Trusted Firmware Updater certificate",
+ .uuid = UUID_TRUSTED_FWU_CERT,
+ .cmdline_name = "fwu-cert",
+ .action = 0,
+ .action_arg = NULL
+ },
+ {
+ .name = "Trusted Boot Firmware BL2",
+ .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
+ .cmdline_name = "tb-fw",
+ .action = 0,
+ .action_arg = NULL
+ },
+ {
+ .name = "SCP Firmware SCP_BL2",
+ .uuid = UUID_SCP_FIRMWARE_SCP_BL2,
+ .cmdline_name = "scp-fw",
+ .action = 0,
+ .action_arg = NULL
+ },
+ {
+ .name = "EL3 Runtime Firmware BL31",
+ .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
+ .cmdline_name = "soc-fw",
+ .action = 0,
+ .action_arg = NULL
+ },
+ {
+ .name = "Secure Payload BL32 (Trusted OS)",
+ .uuid = UUID_SECURE_PAYLOAD_BL32,
+ .cmdline_name = "tos-fw",
+ .action = 0,
+ .action_arg = NULL
+ },
+ {
+ .name = "Non-Trusted Firmware BL33",
+ .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
+ .cmdline_name = "nt-fw",
+ .action = 0,
+ .action_arg = NULL
+ },
/* Key Certificates */
- { "Root Of Trust key certificate", UUID_ROT_KEY_CERT,
- "rot-cert", NULL, 0, NULL },
- { "Trusted key certificate", UUID_TRUSTED_KEY_CERT,
- "trusted-key-cert", NULL, 0, NULL },
- { "SCP Firmware key certificate", UUID_SCP_FW_KEY_CERT,
- "scp-fw-key-cert", NULL, 0, NULL },
- { "SoC Firmware key certificate", UUID_SOC_FW_KEY_CERT,
- "soc-fw-key-cert", NULL, 0, NULL },
- { "Trusted OS Firmware key certificate", UUID_TRUSTED_OS_FW_KEY_CERT,
- "tos-fw-key-cert", NULL, 0, NULL },
- { "Non-Trusted Firmware key certificate", UUID_NON_TRUSTED_FW_KEY_CERT,
- "nt-fw-key-cert", NULL, 0, NULL },
+ {
+ .name = "Root Of Trust key certificate",
+ .uuid = UUID_ROT_KEY_CERT,
+ .cmdline_name = "rot-cert",
+ .action = 0,
+ .action_arg = NULL
+ },
+ {
+ .name = "Trusted key certificate",
+ .uuid = UUID_TRUSTED_KEY_CERT,
+ .cmdline_name = "trusted-key-cert",
+ .action = 0,
+ .action_arg = NULL
+ },
+ {
+ .name = "SCP Firmware key certificate",
+ .uuid = UUID_SCP_FW_KEY_CERT,
+ .cmdline_name = "scp-fw-key-cert",
+ .action = 0,
+ .action_arg = NULL
+ },
+ {
+ .name = "SoC Firmware key certificate",
+ .uuid = UUID_SOC_FW_KEY_CERT,
+ .cmdline_name = "soc-fw-key-cert",
+ .action = 0,
+ .action_arg = NULL
+ },
+ {
+ .name = "Trusted OS Firmware key certificate",
+ .uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
+ .cmdline_name = "tos-fw-key-cert",
+ .action = 0,
+ .action_arg = NULL
+ },
+ {
+ .name = "Non-Trusted Firmware key certificate",
+ .uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
+ .cmdline_name = "nt-fw-key-cert",
+ .action = 0,
+ .action_arg = NULL
+ },
/* Content certificates */
- { "Trusted Boot Firmware BL2 certificate", UUID_TRUSTED_BOOT_FW_CERT,
- "tb-fw-cert", NULL, 0, NULL },
- { "SCP Firmware content certificate", UUID_SCP_FW_CONTENT_CERT,
- "scp-fw-cert", NULL, 0, NULL },
- { "SoC Firmware content certificate", UUID_SOC_FW_CONTENT_CERT,
- "soc-fw-cert", NULL, 0, NULL },
- { "Trusted OS Firmware content certificate", UUID_TRUSTED_OS_FW_CONTENT_CERT,
- "tos-fw-cert", NULL, 0, NULL },
- { "Non-Trusted Firmware content certificate", UUID_NON_TRUSTED_FW_CONTENT_CERT,
- "nt-fw-cert", NULL, 0, NULL },
- { NULL, { 0 }, NULL, NULL, 0, NULL }
+ {
+ .name = "Trusted Boot Firmware BL2 certificate",
+ .uuid = UUID_TRUSTED_BOOT_FW_CERT,
+ .cmdline_name = "tb-fw-cert",
+ .action = 0,
+ .action_arg = NULL
+ },
+ {
+ .name = "SCP Firmware content certificate",
+ .uuid = UUID_SCP_FW_CONTENT_CERT,
+ .cmdline_name = "scp-fw-cert",
+ .action = 0,
+ .action_arg = NULL
+ },
+ {
+ .name = "SoC Firmware content certificate",
+ .uuid = UUID_SOC_FW_CONTENT_CERT,
+ .cmdline_name = "soc-fw-cert",
+ .action = 0,
+ .action_arg = NULL
+ },
+ {
+ .name = "Trusted OS Firmware content certificate",
+ .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
+ .cmdline_name = "tos-fw-cert",
+ .action = 0,
+ .action_arg = NULL
+ },
+ {
+ .name = "Non-Trusted Firmware content certificate",
+ .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
+ .cmdline_name = "nt-fw-cert",
+ .action = 0,
+ .action_arg = NULL
+ },
+ {
+ .name = NULL,
+ .uuid = { 0 },
+ .cmdline_name = NULL,
+ .action = 0,
+ .action_arg = NULL
+ }
};
size_t toc_entries_len = sizeof(toc_entries) / sizeof(toc_entries[0]);
diff --git a/tools/fiptool/tbbr_config.h b/tools/fiptool/tbbr_config.h
index d771a9b..c459335 100644
--- a/tools/fiptool/tbbr_config.h
+++ b/tools/fiptool/tbbr_config.h
@@ -42,7 +42,6 @@
const char *name;
uuid_t uuid;
const char *cmdline_name;
- struct image *image;
int action;
char *action_arg;
} toc_entry_t;