[U-Boot] [PATCH v2 1/4] core support of arm64
fenghua at phytium.com.cn
fenghua at phytium.com.cn
Wed Aug 14 12:58:04 CEST 2013
From: David Feng <fenghua at phytium.com.cn>
This patch provide u-boot with arm64 support. Currently, it works on
Foundation Model for armv8 or Fast Model for armv8.
Signed-off-by: David Feng <fenghua at phytium.com.cn>
---
Changes for v2:
- fix EXPORT_FUNC macro to use register x9 according to "Scott Wood" mail
- redefine some copyright text
- add declaration of cache related functions, remove some compiler warnnings
common/cmd_bdinfo.c | 32 +++++++++++++++++++++
common/fdt_support.c | 66 ++++++++++++++++++++++---------------------
common/image.c | 5 ++--
doc/README.arm64 | 10 +++++++
examples/standalone/stubs.c | 13 +++++++++
include/image.h | 1 +
lib/asm-offsets.c | 4 ---
7 files changed, 93 insertions(+), 38 deletions(-)
create mode 100644 doc/README.arm64
diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c
index af884b8..4a7b61b 100644
--- a/common/cmd_bdinfo.c
+++ b/common/cmd_bdinfo.c
@@ -517,6 +517,38 @@ int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
return 0;
}
+#elif defined(CONFIG_ARM64)
+
+int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ int i;
+
+ for (i = 0; i < CONFIG_NR_DRAM_BANKS; ++i) {
+ print_num("DRAM bank", i);
+ print_num(" -> start", gd->bd->bi_dram[i].start);
+ print_num(" -> size", gd->bd->bi_dram[i].size);
+ }
+
+ printf("baudrate = %ld bps\n", gd->bd->bi_baudrate);
+
+ print_num("relocaddr", gd->relocaddr);
+ print_num("reloc off", gd->reloc_off);
+ print_num("sp start ", gd->start_addr_sp);
+#ifndef CONFIG_SYS_DCACHE_OFF
+ print_num("TLB addr", gd->arch.tlb_addr);
+#endif
+
+ printf("CPU frequency = %ld MHz\n", gd->cpu_clk);
+ printf("DDR frequency = %ld MHz\n", gd->mem_clk);
+
+#if defined(CONFIG_CMD_NET)
+ print_eth(0);
+ printf("ip_addr = %s\n", getenv("ipaddr"));
+#endif
+
+ return 0;
+}
+
#else
#error "a case for this architecture does not exist!"
#endif
diff --git a/common/fdt_support.c b/common/fdt_support.c
index b034c98..9bc5821 100644
--- a/common/fdt_support.c
+++ b/common/fdt_support.c
@@ -21,6 +21,34 @@
*/
DECLARE_GLOBAL_DATA_PTR;
+/*
+ * Get cells len in bytes
+ * if #NNNN-cells property is 2 then len is 8
+ * otherwise len is 4
+ */
+static int get_cells_len(void *blob, char *nr_cells_name)
+{
+ const fdt32_t *cell;
+
+ cell = fdt_getprop(blob, 0, nr_cells_name, NULL);
+ if (cell && fdt32_to_cpu(*cell) == 2)
+ return 8;
+
+ return 4;
+}
+
+/*
+ * Write a 4 or 8 byte big endian cell
+ */
+static void write_cell(u8 *addr, u64 val, int size)
+{
+ int shift = (size - 1) * 8;
+ while (size-- > 0) {
+ *addr++ = (val >> shift) & 0xff;
+ shift -= 8;
+ }
+}
+
/**
* fdt_getprop_u32_default - Find a node and return it's property or a default
*
@@ -131,9 +159,9 @@ static int fdt_fixup_stdout(void *fdt, int chosenoff)
int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end, int force)
{
- int nodeoffset;
+ int nodeoffset, addr_cell_len;
int err, j, total;
- fdt32_t tmp;
+ fdt64_t tmp;
const char *path;
uint64_t addr, size;
@@ -170,9 +198,11 @@ int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end, int force)
return err;
}
+ addr_cell_len = get_cells_len(fdt, "#address-cells");
+
path = fdt_getprop(fdt, nodeoffset, "linux,initrd-start", NULL);
if ((path == NULL) || force) {
- tmp = cpu_to_fdt32(initrd_start);
+ write_cell((u8 *)&tmp, initrd_start, addr_cell_len);
err = fdt_setprop(fdt, nodeoffset,
"linux,initrd-start", &tmp, sizeof(tmp));
if (err < 0) {
@@ -181,7 +211,7 @@ int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end, int force)
fdt_strerror(err));
return err;
}
- tmp = cpu_to_fdt32(initrd_end);
+ write_cell((u8 *)&tmp, initrd_end, addr_cell_len);
err = fdt_setprop(fdt, nodeoffset,
"linux,initrd-end", &tmp, sizeof(tmp));
if (err < 0) {
@@ -343,34 +373,6 @@ void do_fixup_by_compat_u32(void *fdt, const char *compat,
do_fixup_by_compat(fdt, compat, prop, &tmp, 4, create);
}
-/*
- * Get cells len in bytes
- * if #NNNN-cells property is 2 then len is 8
- * otherwise len is 4
- */
-static int get_cells_len(void *blob, char *nr_cells_name)
-{
- const fdt32_t *cell;
-
- cell = fdt_getprop(blob, 0, nr_cells_name, NULL);
- if (cell && fdt32_to_cpu(*cell) == 2)
- return 8;
-
- return 4;
-}
-
-/*
- * Write a 4 or 8 byte big endian cell
- */
-static void write_cell(u8 *addr, u64 val, int size)
-{
- int shift = (size - 1) * 8;
- while (size-- > 0) {
- *addr++ = (val >> shift) & 0xff;
- shift -= 8;
- }
-}
-
#ifdef CONFIG_NR_DRAM_BANKS
#define MEMORY_BANKS_MAX CONFIG_NR_DRAM_BANKS
#else
diff --git a/common/image.c b/common/image.c
index 56a5a62..7a24550 100644
--- a/common/image.c
+++ b/common/image.c
@@ -81,6 +81,7 @@ static const table_entry_t uimage_arch[] = {
{ IH_ARCH_NDS32, "nds32", "NDS32", },
{ IH_ARCH_OPENRISC, "or1k", "OpenRISC 1000",},
{ IH_ARCH_SANDBOX, "sandbox", "Sandbox", },
+ { IH_ARCH_ARM64, "arm64", "ARM64", },
{ -1, "", "", },
};
@@ -422,7 +423,7 @@ ulong getenv_bootm_low(void)
#if defined(CONFIG_SYS_SDRAM_BASE)
return CONFIG_SYS_SDRAM_BASE;
-#elif defined(CONFIG_ARM)
+#elif defined(CONFIG_ARM) || defined(CONFIG_ARM64)
return gd->bd->bi_dram[0].start;
#else
return 0;
@@ -444,7 +445,7 @@ phys_size_t getenv_bootm_size(void)
tmp = 0;
-#if defined(CONFIG_ARM)
+#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
return gd->bd->bi_dram[0].size - tmp;
#else
return gd->bd->bi_memsize - tmp;
diff --git a/doc/README.arm64 b/doc/README.arm64
new file mode 100644
index 0000000..8fef26d
--- /dev/null
+++ b/doc/README.arm64
@@ -0,0 +1,10 @@
+Notes:
+
+1. Currenly, u-boot running at EL2.
+
+2. Currently, gcc-aarch64 produce error when compiling with pie and rel_dyn.
+ So, GOT is used to relocate u-boot and CONFIG_NEEDS_MANUAL_RELOC is needed.
+
+3. Currently, fdt should be in the first 512MB of RAM, so, fdt_high should be handled specially.
+ I define fdt_high as 0xa0000000 when CONFIG_SYS_SDRAM_BASE is 0x80000000.
+
diff --git a/examples/standalone/stubs.c b/examples/standalone/stubs.c
index 8fb1765..578985a 100644
--- a/examples/standalone/stubs.c
+++ b/examples/standalone/stubs.c
@@ -195,6 +195,19 @@ gd_t *global_data;
" l.jr r13\n" \
" l.nop\n" \
: : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r13");
+#elif defined(CONFIG_ARM64)
+/*
+ * x18 holds the pointer to the global_data, x9 is a call-clobbered
+ * register
+ */
+#define EXPORT_FUNC(x) \
+ asm volatile ( \
+" .globl " #x "\n" \
+#x ":\n" \
+" ldr x9, [x18, %0]\n" \
+" ldr x9, [x9, %1]\n" \
+" br x9\n" \
+ : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "x19");
#else
/*" addi $sp, $sp, -24\n" \
" br $r16\n" \*/
diff --git a/include/image.h b/include/image.h
index f93a393..491e547 100644
--- a/include/image.h
+++ b/include/image.h
@@ -156,6 +156,7 @@ struct lmb;
#define IH_ARCH_SANDBOX 19 /* Sandbox architecture (test only) */
#define IH_ARCH_NDS32 20 /* ANDES Technology - NDS32 */
#define IH_ARCH_OPENRISC 21 /* OpenRISC 1000 */
+#define IH_ARCH_ARM64 22 /* ARM64 */
/*
* Image Types
diff --git a/lib/asm-offsets.c b/lib/asm-offsets.c
index 6ea7b03..450514d 100644
--- a/lib/asm-offsets.c
+++ b/lib/asm-offsets.c
@@ -29,15 +29,11 @@ int main(void)
DEFINE(GD_BD, offsetof(struct global_data, bd));
-#if defined(CONFIG_ARM)
-
DEFINE(GD_RELOCADDR, offsetof(struct global_data, relocaddr));
DEFINE(GD_RELOC_OFF, offsetof(struct global_data, reloc_off));
DEFINE(GD_START_ADDR_SP, offsetof(struct global_data, start_addr_sp));
-#endif
-
return 0;
}
--
1.7.9.5
More information about the U-Boot
mailing list