summaryrefslogtreecommitdiff
path: root/arch/nds32/lib
diff options
context:
space:
mode:
Diffstat (limited to 'arch/nds32/lib')
-rw-r--r--arch/nds32/lib/Makefile1
-rw-r--r--arch/nds32/lib/boot.c20
-rw-r--r--arch/nds32/lib/bootm.c23
-rw-r--r--arch/nds32/lib/cache.c197
4 files changed, 196 insertions, 45 deletions
diff --git a/arch/nds32/lib/Makefile b/arch/nds32/lib/Makefile
index 1a0d26f2e1..c88ad726bc 100644
--- a/arch/nds32/lib/Makefile
+++ b/arch/nds32/lib/Makefile
@@ -11,4 +11,5 @@
obj-y += cache.o
obj-$(CONFIG_CMD_BOOTM) += bootm.o
+obj-$(CONFIG_CMD_GO) += boot.o
obj-y += interrupts.o
diff --git a/arch/nds32/lib/boot.c b/arch/nds32/lib/boot.c
new file mode 100644
index 0000000000..f9c1c6b3ff
--- /dev/null
+++ b/arch/nds32/lib/boot.c
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2011 Andes Technology Corporation
+ * Rick Chen, Andes Technology Corporation <rick@andestech.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+
+#include <common.h>
+#include <command.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+unsigned long do_go_exec(ulong (*entry)(int, char * const []),
+ int argc, char * const argv[])
+{
+ cleanup_before_linux();
+
+ return entry(argc, argv);
+}
diff --git a/arch/nds32/lib/bootm.c b/arch/nds32/lib/bootm.c
index 7999167f4c..4c95a418a8 100644
--- a/arch/nds32/lib/bootm.c
+++ b/arch/nds32/lib/bootm.c
@@ -11,6 +11,7 @@
#include <image.h>
#include <u-boot/zlib.h>
#include <asm/byteorder.h>
+#include <asm/bootm.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -73,6 +74,15 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
debug("## Transferring control to Linux (at address %08lx) ...\n",
(ulong)theKernel);
+ if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) {
+#ifdef CONFIG_OF_LIBFDT
+ debug("using: FDT\n");
+ if (image_setup_linux(images)) {
+ printf("FDT creation failed! hanging...");
+ hang();
+ }
+#endif
+ } else if (BOOTM_ENABLE_TAGS) {
#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
defined(CONFIG_CMDLINE_TAG) || \
defined(CONFIG_INITRD_TAG) || \
@@ -107,16 +117,17 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
udc_disconnect();
}
#endif
-
+ }
cleanup_before_linux();
-
- theKernel(0, machid, bd->bi_boot_params);
+ if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len)
+ theKernel(0, machid, (unsigned long)images->ft_addr);
+ else
+ theKernel(0, machid, bd->bi_boot_params);
/* does not return */
return 1;
}
-
#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
defined(CONFIG_CMDLINE_TAG) || \
defined(CONFIG_INITRD_TAG) || \
@@ -136,7 +147,6 @@ static void setup_start_tag(bd_t *bd)
params = tag_next(params);
}
-
#ifdef CONFIG_SETUP_MEMORY_TAGS
static void setup_memory_tags(bd_t *bd)
{
@@ -154,7 +164,6 @@ static void setup_memory_tags(bd_t *bd)
}
#endif /* CONFIG_SETUP_MEMORY_TAGS */
-
static void setup_commandline_tag(bd_t *bd, char *commandline)
{
char *p;
@@ -182,7 +191,6 @@ static void setup_commandline_tag(bd_t *bd, char *commandline)
params = tag_next(params);
}
-
#ifdef CONFIG_INITRD_TAG
static void setup_initrd_tag(bd_t *bd, ulong initrd_start, ulong initrd_end)
{
@@ -230,7 +238,6 @@ void setup_revision_tag(struct tag **in_params)
}
#endif /* CONFIG_REVISION_TAG */
-
static void setup_end_tag(bd_t *bd)
{
params->hdr.tag = ATAG_NONE;
diff --git a/arch/nds32/lib/cache.c b/arch/nds32/lib/cache.c
index 866dc1a98a..846948167f 100644
--- a/arch/nds32/lib/cache.c
+++ b/arch/nds32/lib/cache.c
@@ -7,32 +7,56 @@
*/
#include <common.h>
+#if (!defined(CONFIG_SYS_ICACHE_OFF) || !defined(CONFIG_SYS_DCACHE_OFF))
+static inline unsigned long CACHE_SET(unsigned char cache)
+{
+ if (cache == ICACHE)
+ return 64 << ((GET_ICM_CFG() & ICM_CFG_MSK_ISET) \
+ >> ICM_CFG_OFF_ISET);
+ else
+ return 64 << ((GET_DCM_CFG() & DCM_CFG_MSK_DSET) \
+ >> DCM_CFG_OFF_DSET);
+}
+
+static inline unsigned long CACHE_WAY(unsigned char cache)
+{
+ if (cache == ICACHE)
+ return 1 + ((GET_ICM_CFG() & ICM_CFG_MSK_IWAY) \
+ >> ICM_CFG_OFF_IWAY);
+ else
+ return 1 + ((GET_DCM_CFG() & DCM_CFG_MSK_DWAY) \
+ >> DCM_CFG_OFF_DWAY);
+}
static inline unsigned long CACHE_LINE_SIZE(enum cache_t cache)
{
if (cache == ICACHE)
return 8 << (((GET_ICM_CFG() & ICM_CFG_MSK_ISZ) \
- >> ICM_CFG_OFF_ISZ) - 1);
+ >> ICM_CFG_OFF_ISZ) - 1);
else
return 8 << (((GET_DCM_CFG() & DCM_CFG_MSK_DSZ) \
- >> DCM_CFG_OFF_DSZ) - 1);
+ >> DCM_CFG_OFF_DSZ) - 1);
}
+#endif
-void flush_dcache_range(unsigned long start, unsigned long end)
+#ifndef CONFIG_SYS_ICACHE_OFF
+void invalidate_icache_all(void)
{
- unsigned long line_size;
+ unsigned long end, line_size;
+ line_size = CACHE_LINE_SIZE(ICACHE);
+ end = line_size * CACHE_WAY(ICACHE) * CACHE_SET(ICACHE);
+ do {
+ end -= line_size;
+ __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL" : : "r" (end));
- line_size = CACHE_LINE_SIZE(DCACHE);
+ end -= line_size;
+ __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL" : : "r" (end));
- while (end > start) {
- asm volatile (
- "\n\tcctl %0, L1D_VA_WB"
- "\n\tcctl %0, L1D_VA_INVAL"
- :
- : "r" (start)
- );
- start += line_size;
- }
+ end -= line_size;
+ __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL" : : "r" (end));
+ end -= line_size;
+ __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL" : : "r" (end));
+ } while (end > 0);
}
void invalidate_icache_range(unsigned long start, unsigned long end)
@@ -50,27 +74,6 @@ void invalidate_icache_range(unsigned long start, unsigned long end)
}
}
-void invalidate_dcache_range(unsigned long start, unsigned long end)
-{
- unsigned long line_size;
-
- line_size = CACHE_LINE_SIZE(DCACHE);
- while (end > start) {
- asm volatile (
- "\n\tcctl %0, L1D_VA_INVAL"
- :
- : "r"(start)
- );
- start += line_size;
- }
-}
-
-void flush_cache(unsigned long addr, unsigned long size)
-{
- flush_dcache_range(addr, addr + size);
- invalidate_icache_range(addr, addr + size);
-}
-
void icache_enable(void)
{
asm volatile (
@@ -107,6 +110,81 @@ int icache_status(void)
return ret;
}
+#else
+void invalidate_icache_all(void)
+{
+}
+
+void invalidate_icache_range(unsigned long start, unsigned long end)
+{
+}
+
+void icache_enable(void)
+{
+}
+
+void icache_disable(void)
+{
+}
+
+int icache_status(void)
+{
+ return 0;
+}
+
+#endif
+
+#ifndef CONFIG_SYS_DCACHE_OFF
+void dcache_wbinval_all(void)
+{
+ unsigned long end, line_size;
+ line_size = CACHE_LINE_SIZE(DCACHE);
+ end = line_size * CACHE_WAY(DCACHE) * CACHE_SET(DCACHE);
+ do {
+ end -= line_size;
+ __asm__ volatile ("\n\tcctl %0, L1D_IX_WB" : : "r" (end));
+ __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL" : : "r" (end));
+ end -= line_size;
+ __asm__ volatile ("\n\tcctl %0, L1D_IX_WB" : : "r" (end));
+ __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL" : : "r" (end));
+ end -= line_size;
+ __asm__ volatile ("\n\tcctl %0, L1D_IX_WB" : : "r" (end));
+ __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL" : : "r" (end));
+ end -= line_size;
+ __asm__ volatile ("\n\tcctl %0, L1D_IX_WB" : : "r" (end));
+ __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL" : : "r" (end));
+
+ } while (end > 0);
+}
+
+void flush_dcache_range(unsigned long start, unsigned long end)
+{
+ unsigned long line_size;
+
+ line_size = CACHE_LINE_SIZE(DCACHE);
+
+ while (end > start) {
+ asm volatile (
+ "\n\tcctl %0, L1D_VA_WB"
+ "\n\tcctl %0, L1D_VA_INVAL" : : "r" (start)
+ );
+ start += line_size;
+ }
+}
+
+void invalidate_dcache_range(unsigned long start, unsigned long end)
+{
+ unsigned long line_size;
+
+ line_size = CACHE_LINE_SIZE(DCACHE);
+ while (end > start) {
+ asm volatile (
+ "\n\tcctl %0, L1D_VA_INVAL" : : "r"(start)
+ );
+ start += line_size;
+ }
+}
+
void dcache_enable(void)
{
asm volatile (
@@ -131,7 +209,6 @@ void dcache_disable(void)
int dcache_status(void)
{
int ret;
-
asm volatile (
"mfsr $p0, $mr8\n\t"
"andi %0, $p0, 0x02\n\t"
@@ -139,6 +216,52 @@ int dcache_status(void)
:
: "memory"
);
-
return ret;
}
+
+#else
+void dcache_wbinval_all(void)
+{
+}
+
+void flush_dcache_range(unsigned long start, unsigned long end)
+{
+}
+
+void invalidate_dcache_range(unsigned long start, unsigned long end)
+{
+}
+
+void dcache_enable(void)
+{
+}
+
+void dcache_disable(void)
+{
+}
+
+int dcache_status(void)
+{
+ return 0;
+}
+
+#endif
+
+
+void flush_dcache_all(void)
+{
+ dcache_wbinval_all();
+}
+
+void cache_flush(void)
+{
+ flush_dcache_all();
+ invalidate_icache_all();
+}
+
+
+void flush_cache(unsigned long addr, unsigned long size)
+{
+ flush_dcache_range(addr, addr + size);
+ invalidate_icache_range(addr, addr + size);
+}