aboutsummaryrefslogtreecommitdiffstats
path: root/roms/u-boot/arch/powerpc/lib
diff options
context:
space:
mode:
authorAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
committerAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
commitaf1a266670d040d2f4083ff309d732d648afba2a (patch)
tree2fc46203448ddcc6f81546d379abfaeb323575e9 /roms/u-boot/arch/powerpc/lib
parente02cda008591317b1625707ff8e115a4841aa889 (diff)
Add submodule dependency filesHEADmaster
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'roms/u-boot/arch/powerpc/lib')
-rw-r--r--roms/u-boot/arch/powerpc/lib/Kconfig9
-rw-r--r--roms/u-boot/arch/powerpc/lib/Makefile48
-rw-r--r--roms/u-boot/arch/powerpc/lib/_ashldi3.S41
-rw-r--r--roms/u-boot/arch/powerpc/lib/_ashrdi3.S43
-rw-r--r--roms/u-boot/arch/powerpc/lib/_lshrdi3.S41
-rw-r--r--roms/u-boot/arch/powerpc/lib/bat_rw.c244
-rw-r--r--roms/u-boot/arch/powerpc/lib/bdinfo.c68
-rw-r--r--roms/u-boot/arch/powerpc/lib/bootm.c345
-rw-r--r--roms/u-boot/arch/powerpc/lib/cache.c46
-rw-r--r--roms/u-boot/arch/powerpc/lib/extable.c62
-rw-r--r--roms/u-boot/arch/powerpc/lib/interrupts.c96
-rw-r--r--roms/u-boot/arch/powerpc/lib/kgdb.c261
-rw-r--r--roms/u-boot/arch/powerpc/lib/ppccache.S107
-rw-r--r--roms/u-boot/arch/powerpc/lib/ppcstring.S205
-rw-r--r--roms/u-boot/arch/powerpc/lib/reloc.S32
-rw-r--r--roms/u-boot/arch/powerpc/lib/spl.c29
-rw-r--r--roms/u-boot/arch/powerpc/lib/stack.c32
-rw-r--r--roms/u-boot/arch/powerpc/lib/ticks.S56
-rw-r--r--roms/u-boot/arch/powerpc/lib/time.c76
-rw-r--r--roms/u-boot/arch/powerpc/lib/traps.c19
20 files changed, 1860 insertions, 0 deletions
diff --git a/roms/u-boot/arch/powerpc/lib/Kconfig b/roms/u-boot/arch/powerpc/lib/Kconfig
new file mode 100644
index 000000000..b30b5edf7
--- /dev/null
+++ b/roms/u-boot/arch/powerpc/lib/Kconfig
@@ -0,0 +1,9 @@
+config CACHE_FLUSH_WATCHDOG_THRESHOLD
+ int "Bytes to flush between WATCHDOG_RESET calls"
+ default 0
+ help
+ The flush_cache() function periodically, and by default for
+ every cache line, calls WATCHDOG_RESET(). When flushing a
+ large area, that may add a significant amount of
+ overhead. This option allows you to set a threshold for how
+ many bytes to flush between each WATCHDOG_RESET call.
diff --git a/roms/u-boot/arch/powerpc/lib/Makefile b/roms/u-boot/arch/powerpc/lib/Makefile
new file mode 100644
index 000000000..2782740bf
--- /dev/null
+++ b/roms/u-boot/arch/powerpc/lib/Makefile
@@ -0,0 +1,48 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+
+## Build a couple of necessary functions into a private libgcc
+## if the user asked for it
+lib-$(CONFIG_USE_PRIVATE_LIBGCC) += _ashldi3.o _ashrdi3.o _lshrdi3.o
+
+MINIMAL=
+
+ifdef CONFIG_SPL_BUILD
+ifdef CONFIG_SPL_INIT_MINIMAL
+MINIMAL=y
+endif
+endif
+
+obj-y += bdinfo.o
+
+ifdef MINIMAL
+obj-y += cache.o time.o
+ifndef CONFIG_TIMER
+obj-y += ticks.o
+endif
+else
+
+obj-y += ppcstring.o
+
+obj-y += ppccache.o
+ifndef CONFIG_TIMER
+obj-y += ticks.o
+endif
+obj-y += reloc.o
+
+obj-$(CONFIG_BAT_RW) += bat_rw.o
+obj-$(CONFIG_CMD_BOOTM) += bootm.o
+obj-y += cache.o
+obj-y += extable.o
+obj-y += interrupts.o
+obj-$(CONFIG_CMD_KGDB) += kgdb.o
+obj-y += stack.o
+obj-y += time.o
+obj-y += traps.o
+endif # not minimal
+
+ifdef CONFIG_SPL_BUILD
+obj-$(CONFIG_$(SPL_TPL)_FRAMEWORK) += spl.o
+endif
diff --git a/roms/u-boot/arch/powerpc/lib/_ashldi3.S b/roms/u-boot/arch/powerpc/lib/_ashldi3.S
new file mode 100644
index 000000000..0a635a80c
--- /dev/null
+++ b/roms/u-boot/arch/powerpc/lib/_ashldi3.S
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * This code was copied from arch/powerpc/kernel/misc_32.S in the Linux
+ * kernel sources (commit 85e2efbb1db9a18d218006706d6e4fbeb0216213, also
+ * known as 2.6.38-rc5). The source file copyrights are as follows:
+ *
+ * (C) Copyright 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
+ * and Paul Mackerras.
+ */
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+#include <config.h>
+
+/*
+ * Extended precision shifts.
+ *
+ * Updated to be valid for shift counts from 0 to 63 inclusive.
+ * -- Gabriel
+ *
+ * R3/R4 has 64 bit value
+ * R5 has shift count
+ * result in R3/R4
+ *
+ * ashrdi3: arithmetic right shift (sign propagation)
+ * lshrdi3: logical right shift
+ * ashldi3: left shift
+ */
+ .globl __ashldi3
+__ashldi3:
+ subfic r6,r5,32
+ slw r3,r3,r5 # MSW = count > 31 ? 0 : MSW << count
+ addi r7,r5,32 # could be xori, or addi with -32
+ srw r6,r4,r6 # t1 = count > 31 ? 0 : LSW >> (32-count)
+ slw r7,r4,r7 # t2 = count < 32 ? 0 : LSW << (count-32)
+ or r3,r3,r6 # MSW |= t1
+ slw r4,r4,r5 # LSW = LSW << count
+ or r3,r3,r7 # MSW |= t2
+ blr
diff --git a/roms/u-boot/arch/powerpc/lib/_ashrdi3.S b/roms/u-boot/arch/powerpc/lib/_ashrdi3.S
new file mode 100644
index 000000000..728001696
--- /dev/null
+++ b/roms/u-boot/arch/powerpc/lib/_ashrdi3.S
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * This code was copied from arch/powerpc/kernel/misc_32.S in the Linux
+ * kernel sources (commit 85e2efbb1db9a18d218006706d6e4fbeb0216213, also
+ * known as 2.6.38-rc5). The source file copyrights are as follows:
+ *
+ * (C) Copyright 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
+ * and Paul Mackerras.
+ */
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+#include <config.h>
+
+/*
+ * Extended precision shifts.
+ *
+ * Updated to be valid for shift counts from 0 to 63 inclusive.
+ * -- Gabriel
+ *
+ * R3/R4 has 64 bit value
+ * R5 has shift count
+ * result in R3/R4
+ *
+ * ashrdi3: arithmetic right shift (sign propagation)
+ * lshrdi3: logical right shift
+ * ashldi3: left shift
+ */
+ .globl __ashrdi3
+__ashrdi3:
+ subfic r6,r5,32
+ srw r4,r4,r5 # LSW = count > 31 ? 0 : LSW >> count
+ addi r7,r5,32 # could be xori, or addi with -32
+ slw r6,r3,r6 # t1 = count > 31 ? 0 : MSW << (32-count)
+ rlwinm r8,r7,0,32 # t3 = (count < 32) ? 32 : 0
+ sraw r7,r3,r7 # t2 = MSW >> (count-32)
+ or r4,r4,r6 # LSW |= t1
+ slw r7,r7,r8 # t2 = (count < 32) ? 0 : t2
+ sraw r3,r3,r5 # MSW = MSW >> count
+ or r4,r4,r7 # LSW |= t2
+ blr
diff --git a/roms/u-boot/arch/powerpc/lib/_lshrdi3.S b/roms/u-boot/arch/powerpc/lib/_lshrdi3.S
new file mode 100644
index 000000000..55ebc7e23
--- /dev/null
+++ b/roms/u-boot/arch/powerpc/lib/_lshrdi3.S
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * This code was copied from arch/powerpc/kernel/misc_32.S in the Linux
+ * kernel sources (commit 85e2efbb1db9a18d218006706d6e4fbeb0216213, also
+ * known as 2.6.38-rc5). The source file copyrights are as follows:
+ *
+ * (C) Copyright 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
+ * and Paul Mackerras.
+ */
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+#include <config.h>
+
+/*
+ * Extended precision shifts.
+ *
+ * Updated to be valid for shift counts from 0 to 63 inclusive.
+ * -- Gabriel
+ *
+ * R3/R4 has 64 bit value
+ * R5 has shift count
+ * result in R3/R4
+ *
+ * ashrdi3: arithmetic right shift (sign propagation)
+ * lshrdi3: logical right shift
+ * ashldi3: left shift
+ */
+ .globl __lshrdi3
+__lshrdi3:
+ subfic r6,r5,32
+ srw r4,r4,r5 # LSW = count > 31 ? 0 : LSW >> count
+ addi r7,r5,32 # could be xori, or addi with -32
+ slw r6,r3,r6 # t1 = count > 31 ? 0 : MSW << (32-count)
+ srw r7,r3,r7 # t2 = count < 32 ? 0 : MSW >> (count-32)
+ or r4,r4,r6 # LSW |= t1
+ srw r3,r3,r5 # MSW = MSW >> count
+ or r4,r4,r7 # LSW |= t2
+ blr
diff --git a/roms/u-boot/arch/powerpc/lib/bat_rw.c b/roms/u-boot/arch/powerpc/lib/bat_rw.c
new file mode 100644
index 000000000..24dd30615
--- /dev/null
+++ b/roms/u-boot/arch/powerpc/lib/bat_rw.c
@@ -0,0 +1,244 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2002
+ * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
+ */
+
+#include <common.h>
+#include <asm/global_data.h>
+#include <asm/processor.h>
+#include <asm/mmu.h>
+#include <asm/io.h>
+#include <linux/compiler.h>
+
+#ifdef CONFIG_ADDR_MAP
+#include <addr_map.h>
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int write_bat (ppc_bat_t bat, unsigned long upper, unsigned long lower)
+{
+ __maybe_unused int batn = -1;
+
+ sync();
+
+ switch (bat) {
+ case DBAT0:
+ mtspr (DBAT0L, lower);
+ mtspr (DBAT0U, upper);
+ batn = 0;
+ break;
+ case IBAT0:
+ mtspr (IBAT0L, lower);
+ mtspr (IBAT0U, upper);
+ break;
+ case DBAT1:
+ mtspr (DBAT1L, lower);
+ mtspr (DBAT1U, upper);
+ batn = 1;
+ break;
+ case IBAT1:
+ mtspr (IBAT1L, lower);
+ mtspr (IBAT1U, upper);
+ break;
+ case DBAT2:
+ mtspr (DBAT2L, lower);
+ mtspr (DBAT2U, upper);
+ batn = 2;
+ break;
+ case IBAT2:
+ mtspr (IBAT2L, lower);
+ mtspr (IBAT2U, upper);
+ break;
+ case DBAT3:
+ mtspr (DBAT3L, lower);
+ mtspr (DBAT3U, upper);
+ batn = 3;
+ break;
+ case IBAT3:
+ mtspr (IBAT3L, lower);
+ mtspr (IBAT3U, upper);
+ break;
+#ifdef CONFIG_HIGH_BATS
+ case DBAT4:
+ mtspr (DBAT4L, lower);
+ mtspr (DBAT4U, upper);
+ batn = 4;
+ break;
+ case IBAT4:
+ mtspr (IBAT4L, lower);
+ mtspr (IBAT4U, upper);
+ break;
+ case DBAT5:
+ mtspr (DBAT5L, lower);
+ mtspr (DBAT5U, upper);
+ batn = 5;
+ break;
+ case IBAT5:
+ mtspr (IBAT5L, lower);
+ mtspr (IBAT5U, upper);
+ break;
+ case DBAT6:
+ mtspr (DBAT6L, lower);
+ mtspr (DBAT6U, upper);
+ batn = 6;
+ break;
+ case IBAT6:
+ mtspr (IBAT6L, lower);
+ mtspr (IBAT6U, upper);
+ break;
+ case DBAT7:
+ mtspr (DBAT7L, lower);
+ mtspr (DBAT7U, upper);
+ batn = 7;
+ break;
+ case IBAT7:
+ mtspr (IBAT7L, lower);
+ mtspr (IBAT7U, upper);
+ break;
+#endif
+ default:
+ return (-1);
+ }
+
+#ifdef CONFIG_ADDR_MAP
+ if ((gd->flags & GD_FLG_RELOC) && (batn >= 0)) {
+ phys_size_t size;
+ if (!BATU_VALID(upper))
+ size = 0;
+ else
+ size = BATU_SIZE(upper);
+ addrmap_set_entry(BATU_VADDR(upper), BATL_PADDR(lower),
+ size, batn);
+ }
+#endif
+
+ sync();
+ isync();
+
+ return (0);
+}
+
+int read_bat (ppc_bat_t bat, unsigned long *upper, unsigned long *lower)
+{
+ unsigned long register u;
+ unsigned long register l;
+
+ switch (bat) {
+ case DBAT0:
+ l = mfspr (DBAT0L);
+ u = mfspr (DBAT0U);
+ break;
+ case IBAT0:
+ l = mfspr (IBAT0L);
+ u = mfspr (IBAT0U);
+ break;
+ case DBAT1:
+ l = mfspr (DBAT1L);
+ u = mfspr (DBAT1U);
+ break;
+ case IBAT1:
+ l = mfspr (IBAT1L);
+ u = mfspr (IBAT1U);
+ break;
+ case DBAT2:
+ l = mfspr (DBAT2L);
+ u = mfspr (DBAT2U);
+ break;
+ case IBAT2:
+ l = mfspr (IBAT2L);
+ u = mfspr (IBAT2U);
+ break;
+ case DBAT3:
+ l = mfspr (DBAT3L);
+ u = mfspr (DBAT3U);
+ break;
+ case IBAT3:
+ l = mfspr (IBAT3L);
+ u = mfspr (IBAT3U);
+ break;
+#ifdef CONFIG_HIGH_BATS
+ case DBAT4:
+ l = mfspr (DBAT4L);
+ u = mfspr (DBAT4U);
+ break;
+ case IBAT4:
+ l = mfspr (IBAT4L);
+ u = mfspr (IBAT4U);
+ break;
+ case DBAT5:
+ l = mfspr (DBAT5L);
+ u = mfspr (DBAT5U);
+ break;
+ case IBAT5:
+ l = mfspr (IBAT5L);
+ u = mfspr (IBAT5U);
+ break;
+ case DBAT6:
+ l = mfspr (DBAT6L);
+ u = mfspr (DBAT6U);
+ break;
+ case IBAT6:
+ l = mfspr (IBAT6L);
+ u = mfspr (IBAT6U);
+ break;
+ case DBAT7:
+ l = mfspr (DBAT7L);
+ u = mfspr (DBAT7U);
+ break;
+ case IBAT7:
+ l = mfspr (IBAT7L);
+ u = mfspr (IBAT7U);
+ break;
+#endif
+ default:
+ return (-1);
+ }
+
+ *upper = u;
+ *lower = l;
+
+ return (0);
+}
+
+void print_bats(void)
+{
+ printf("BAT registers:\n");
+
+ printf ("\tIBAT0L = 0x%08X ", mfspr (IBAT0L));
+ printf ("\tIBAT0U = 0x%08X\n", mfspr (IBAT0U));
+ printf ("\tDBAT0L = 0x%08X ", mfspr (DBAT0L));
+ printf ("\tDBAT0U = 0x%08X\n", mfspr (DBAT0U));
+ printf ("\tIBAT1L = 0x%08X ", mfspr (IBAT1L));
+ printf ("\tIBAT1U = 0x%08X\n", mfspr (IBAT1U));
+ printf ("\tDBAT1L = 0x%08X ", mfspr (DBAT1L));
+ printf ("\tDBAT1U = 0x%08X\n", mfspr (DBAT1U));
+ printf ("\tIBAT2L = 0x%08X ", mfspr (IBAT2L));
+ printf ("\tIBAT2U = 0x%08X\n", mfspr (IBAT2U));
+ printf ("\tDBAT2L = 0x%08X ", mfspr (DBAT2L));
+ printf ("\tDBAT2U = 0x%08X\n", mfspr (DBAT2U));
+ printf ("\tIBAT3L = 0x%08X ", mfspr (IBAT3L));
+ printf ("\tIBAT3U = 0x%08X\n", mfspr (IBAT3U));
+ printf ("\tDBAT3L = 0x%08X ", mfspr (DBAT3L));
+ printf ("\tDBAT3U = 0x%08X\n", mfspr (DBAT3U));
+
+#ifdef CONFIG_HIGH_BATS
+ printf ("\tIBAT4L = 0x%08X ", mfspr (IBAT4L));
+ printf ("\tIBAT4U = 0x%08X\n", mfspr (IBAT4U));
+ printf ("\tDBAT4L = 0x%08X ", mfspr (DBAT4L));
+ printf ("\tDBAT4U = 0x%08X\n", mfspr (DBAT4U));
+ printf ("\tIBAT5L = 0x%08X ", mfspr (IBAT5L));
+ printf ("\tIBAT5U = 0x%08X\n", mfspr (IBAT5U));
+ printf ("\tDBAT5L = 0x%08X ", mfspr (DBAT5L));
+ printf ("\tDBAT5U = 0x%08X\n", mfspr (DBAT5U));
+ printf ("\tIBAT6L = 0x%08X ", mfspr (IBAT6L));
+ printf ("\tIBAT6U = 0x%08X\n", mfspr (IBAT6U));
+ printf ("\tDBAT6L = 0x%08X ", mfspr (DBAT6L));
+ printf ("\tDBAT6U = 0x%08X\n", mfspr (DBAT6U));
+ printf ("\tIBAT7L = 0x%08X ", mfspr (IBAT7L));
+ printf ("\tIBAT7U = 0x%08X\n", mfspr (IBAT7U));
+ printf ("\tDBAT7L = 0x%08X ", mfspr (DBAT7L));
+ printf ("\tDBAT7U = 0x%08X\n", mfspr (DBAT7U));
+#endif
+}
diff --git a/roms/u-boot/arch/powerpc/lib/bdinfo.c b/roms/u-boot/arch/powerpc/lib/bdinfo.c
new file mode 100644
index 000000000..d2e5e6057
--- /dev/null
+++ b/roms/u-boot/arch/powerpc/lib/bdinfo.c
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * PPC-specific information for the 'bd' command
+ *
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <asm/global_data.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int arch_setup_bdinfo(void)
+{
+ struct bd_info *bd = gd->bd;
+
+#if defined(CONFIG_E500) || defined(CONFIG_MPC86xx)
+ bd->bi_immr_base = CONFIG_SYS_IMMR; /* base of IMMR register */
+#endif
+
+#if defined(CONFIG_MPC83xx)
+ bd->bi_immrbar = CONFIG_SYS_IMMR;
+#endif
+
+ bd->bi_intfreq = gd->cpu_clk; /* Internal Freq, in Hz */
+ bd->bi_busfreq = gd->bus_clk; /* Bus Freq, in Hz */
+
+#if defined(CONFIG_CPM2)
+ bd->bi_cpmfreq = gd->arch.cpm_clk;
+ bd->bi_brgfreq = gd->arch.brg_clk;
+ bd->bi_sccfreq = gd->arch.scc_clk;
+ bd->bi_vco = gd->arch.vco_out;
+#endif /* CONFIG_CPM2 */
+
+ return 0;
+}
+
+void __weak board_detail(void)
+{
+ /* Please define board_detail() for your PPC platform */
+}
+
+void arch_print_bdinfo(void)
+{
+ struct bd_info *bd = gd->bd;
+
+ bdinfo_print_mhz("busfreq", bd->bi_busfreq);
+#if defined(CONFIG_MPC8xx) || defined(CONFIG_E500)
+ bdinfo_print_num_l("immr_base", bd->bi_immr_base);
+#endif
+ bdinfo_print_num_l("bootflags", bd->bi_bootflags);
+ bdinfo_print_mhz("intfreq", bd->bi_intfreq);
+#ifdef CONFIG_ENABLE_36BIT_PHYS
+ if (IS_ENABLED(CONFIG_PHYS_64BIT))
+ puts("addressing = 36-bit\n");
+ else
+ puts("addressing = 32-bit\n");
+#endif
+ board_detail();
+#if defined(CONFIG_CPM2)
+ bdinfo_print_mhz("cpmfreq", bd->bi_cpmfreq);
+ bdinfo_print_mhz("vco", bd->bi_vco);
+ bdinfo_print_mhz("sccfreq", bd->bi_sccfreq);
+ bdinfo_print_mhz("brgfreq", bd->bi_brgfreq);
+#endif
+}
diff --git a/roms/u-boot/arch/powerpc/lib/bootm.c b/roms/u-boot/arch/powerpc/lib/bootm.c
new file mode 100644
index 000000000..31c17b5bb
--- /dev/null
+++ b/roms/u-boot/arch/powerpc/lib/bootm.c
@@ -0,0 +1,345 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2008 Semihalf
+ *
+ * (C) Copyright 2000-2006
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ */
+
+
+#include <common.h>
+#include <bootstage.h>
+#include <cpu_func.h>
+#include <env.h>
+#include <init.h>
+#include <lmb.h>
+#include <log.h>
+#include <watchdog.h>
+#include <command.h>
+#include <image.h>
+#include <malloc.h>
+#include <asm/global_data.h>
+#include <u-boot/zlib.h>
+#include <bzlib.h>
+#include <asm/byteorder.h>
+#include <asm/mp.h>
+#include <bootm.h>
+#include <vxworks.h>
+
+#if defined(CONFIG_OF_LIBFDT)
+#include <linux/libfdt.h>
+#include <fdt_support.h>
+#endif
+
+#ifdef CONFIG_SYS_INIT_RAM_LOCK
+#include <asm/cache.h>
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static ulong get_sp (void);
+extern void ft_fixup_num_cores(void *blob);
+static void set_clocks_in_mhz (struct bd_info *kbd);
+
+#ifndef CONFIG_SYS_LINUX_LOWMEM_MAX_SIZE
+#define CONFIG_SYS_LINUX_LOWMEM_MAX_SIZE (768*1024*1024)
+#endif
+
+static void boot_jump_linux(bootm_headers_t *images)
+{
+ void (*kernel)(struct bd_info *, ulong r4, ulong r5, ulong r6,
+ ulong r7, ulong r8, ulong r9);
+#ifdef CONFIG_OF_LIBFDT
+ char *of_flat_tree = images->ft_addr;
+#endif
+
+ kernel = (void (*)(struct bd_info *, ulong, ulong, ulong,
+ ulong, ulong, ulong))images->ep;
+ debug("## Transferring control to Linux (at address %08lx) ...\n",
+ (ulong)kernel);
+
+ bootstage_mark(BOOTSTAGE_ID_RUN_OS);
+
+#ifdef CONFIG_BOOTSTAGE_FDT
+ bootstage_fdt_add_report();
+#endif
+#ifdef CONFIG_BOOTSTAGE_REPORT
+ bootstage_report();
+#endif
+
+#if defined(CONFIG_SYS_INIT_RAM_LOCK) && !defined(CONFIG_E500)
+ unlock_ram_in_cache();
+#endif
+
+#if defined(CONFIG_OF_LIBFDT)
+ if (of_flat_tree) { /* device tree; boot new style */
+ /*
+ * Linux Kernel Parameters (passing device tree):
+ * r3: pointer to the fdt
+ * r4: 0
+ * r5: 0
+ * r6: epapr magic
+ * r7: size of IMA in bytes
+ * r8: 0
+ * r9: 0
+ */
+ debug(" Booting using OF flat tree...\n");
+ WATCHDOG_RESET ();
+ (*kernel) ((struct bd_info *)of_flat_tree, 0, 0, EPAPR_MAGIC,
+ env_get_bootm_mapsize(), 0, 0);
+ /* does not return */
+ } else
+#endif
+ {
+ /*
+ * Linux Kernel Parameters (passing board info data):
+ * r3: ptr to board info data
+ * r4: initrd_start or 0 if no initrd
+ * r5: initrd_end - unused if r4 is 0
+ * r6: Start of command line string
+ * r7: End of command line string
+ * r8: 0
+ * r9: 0
+ */
+ ulong cmd_start = images->cmdline_start;
+ ulong cmd_end = images->cmdline_end;
+ ulong initrd_start = images->initrd_start;
+ ulong initrd_end = images->initrd_end;
+ struct bd_info *kbd = images->kbd;
+
+ debug(" Booting using board info...\n");
+ WATCHDOG_RESET ();
+ (*kernel) (kbd, initrd_start, initrd_end,
+ cmd_start, cmd_end, 0, 0);
+ /* does not return */
+ }
+ return ;
+}
+
+void arch_lmb_reserve(struct lmb *lmb)
+{
+ phys_size_t bootm_size;
+ ulong size, sp, bootmap_base;
+
+ bootmap_base = env_get_bootm_low();
+ bootm_size = env_get_bootm_size();
+
+#ifdef DEBUG
+ if (((u64)bootmap_base + bootm_size) >
+ (CONFIG_SYS_SDRAM_BASE + (u64)gd->ram_size))
+ puts("WARNING: bootm_low + bootm_size exceed total memory\n");
+ if ((bootmap_base + bootm_size) > get_effective_memsize())
+ puts("WARNING: bootm_low + bootm_size exceed eff. memory\n");
+#endif
+
+ size = min(bootm_size, get_effective_memsize());
+ size = min(size, (ulong)CONFIG_SYS_LINUX_LOWMEM_MAX_SIZE);
+
+ if (size < bootm_size) {
+ ulong base = bootmap_base + size;
+ printf("WARNING: adjusting available memory to %lx\n", size);
+ lmb_reserve(lmb, base, bootm_size - size);
+ }
+
+ /*
+ * Booting a (Linux) kernel image
+ *
+ * Allocate space for command line and board info - the
+ * address should be as high as possible within the reach of
+ * the kernel (see CONFIG_SYS_BOOTMAPSZ settings), but in unused
+ * memory, which means far enough below the current stack
+ * pointer.
+ */
+ sp = get_sp();
+ debug("## Current stack ends at 0x%08lx\n", sp);
+
+ /* adjust sp by 4K to be safe */
+ sp -= 4096;
+ lmb_reserve(lmb, sp, (CONFIG_SYS_SDRAM_BASE + get_effective_memsize() - sp));
+
+#ifdef CONFIG_MP
+ cpu_mp_lmb_reserve(lmb);
+#endif
+
+ return ;
+}
+
+static void boot_prep_linux(bootm_headers_t *images)
+{
+#ifdef CONFIG_MP
+ /*
+ * if we are MP make sure to flush the device tree so any changes are
+ * made visibile to all other cores. In AMP boot scenarios the cores
+ * might not be HW cache coherent with each other.
+ */
+ flush_cache((unsigned long)images->ft_addr, images->ft_len);
+#endif
+}
+
+static int boot_cmdline_linux(bootm_headers_t *images)
+{
+ ulong of_size = images->ft_len;
+ struct lmb *lmb = &images->lmb;
+ ulong *cmd_start = &images->cmdline_start;
+ ulong *cmd_end = &images->cmdline_end;
+
+ int ret = 0;
+
+ if (!of_size) {
+ /* allocate space and init command line */
+ ret = boot_get_cmdline (lmb, cmd_start, cmd_end);
+ if (ret) {
+ puts("ERROR with allocation of cmdline\n");
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
+static int boot_bd_t_linux(bootm_headers_t *images)
+{
+ ulong of_size = images->ft_len;
+ struct lmb *lmb = &images->lmb;
+ struct bd_info **kbd = &images->kbd;
+
+ int ret = 0;
+
+ if (!of_size) {
+ /* allocate space for kernel copy of board info */
+ ret = boot_get_kbd (lmb, kbd);
+ if (ret) {
+ puts("ERROR with allocation of kernel bd\n");
+ return ret;
+ }
+ set_clocks_in_mhz(*kbd);
+ }
+
+ return ret;
+}
+
+static int boot_body_linux(bootm_headers_t *images)
+{
+ int ret;
+
+ /* allocate space for kernel copy of board info */
+ ret = boot_bd_t_linux(images);
+ if (ret)
+ return ret;
+
+ ret = image_setup_linux(images);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+noinline int do_bootm_linux(int flag, int argc, char *const argv[],
+ bootm_headers_t *images)
+{
+ int ret;
+
+ if (flag & BOOTM_STATE_OS_CMDLINE) {
+ boot_cmdline_linux(images);
+ return 0;
+ }
+
+ if (flag & BOOTM_STATE_OS_BD_T) {
+ boot_bd_t_linux(images);
+ return 0;
+ }
+
+ if (flag & BOOTM_STATE_OS_PREP) {
+ boot_prep_linux(images);
+ return 0;
+ }
+
+ boot_prep_linux(images);
+ ret = boot_body_linux(images);
+ if (ret)
+ return ret;
+ boot_jump_linux(images);
+
+ return 0;
+}
+
+static ulong get_sp (void)
+{
+ ulong sp;
+
+ asm( "mr %0,1": "=r"(sp) : );
+ return sp;
+}
+
+static void set_clocks_in_mhz (struct bd_info *kbd)
+{
+ char *s;
+
+ s = env_get("clocks_in_mhz");
+ if (s) {
+ /* convert all clock information to MHz */
+ kbd->bi_intfreq /= 1000000L;
+ kbd->bi_busfreq /= 1000000L;
+#if defined(CONFIG_CPM2)
+ kbd->bi_cpmfreq /= 1000000L;
+ kbd->bi_brgfreq /= 1000000L;
+ kbd->bi_sccfreq /= 1000000L;
+ kbd->bi_vco /= 1000000L;
+#endif
+ }
+}
+
+#if defined(CONFIG_BOOTM_VXWORKS)
+void boot_prep_vxworks(bootm_headers_t *images)
+{
+#if defined(CONFIG_OF_LIBFDT)
+ int off;
+ u64 base, size;
+
+ if (!images->ft_addr)
+ return;
+
+ base = (u64)gd->ram_base;
+ size = (u64)gd->ram_size;
+
+ off = fdt_path_offset(images->ft_addr, "/memory");
+ if (off < 0)
+ fdt_fixup_memory(images->ft_addr, base, size);
+
+#if defined(CONFIG_MP)
+#if defined(CONFIG_MPC85xx)
+ ft_fixup_cpu(images->ft_addr, base + size);
+ ft_fixup_num_cores(images->ft_addr);
+#elif defined(CONFIG_MPC86xx)
+ off = fdt_add_mem_rsv(images->ft_addr,
+ determine_mp_bootpg(NULL), (u64)4096);
+ if (off < 0)
+ printf("## WARNING %s: %s\n", __func__, fdt_strerror(off));
+ ft_fixup_num_cores(images->ft_addr);
+#endif
+ flush_cache((unsigned long)images->ft_addr, images->ft_len);
+#endif
+#endif
+}
+
+void boot_jump_vxworks(bootm_headers_t *images)
+{
+ /* PowerPC VxWorks boot interface conforms to the ePAPR standard
+ * general purpuse registers:
+ *
+ * r3: Effective address of the device tree image
+ * r4: 0
+ * r5: 0
+ * r6: ePAPR magic value
+ * r7: shall be the size of the boot IMA in bytes
+ * r8: 0
+ * r9: 0
+ * TCR: WRC = 0, no watchdog timer reset will occur
+ */
+ WATCHDOG_RESET();
+
+ ((void (*)(void *, ulong, ulong, ulong,
+ ulong, ulong, ulong))images->ep)(images->ft_addr,
+ 0, 0, EPAPR_MAGIC, env_get_bootm_mapsize(), 0, 0);
+}
+#endif
diff --git a/roms/u-boot/arch/powerpc/lib/cache.c b/roms/u-boot/arch/powerpc/lib/cache.c
new file mode 100644
index 000000000..19162511c
--- /dev/null
+++ b/roms/u-boot/arch/powerpc/lib/cache.c
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <asm/cache.h>
+#include <watchdog.h>
+
+static ulong maybe_watchdog_reset(ulong flushed)
+{
+ flushed += CONFIG_SYS_CACHELINE_SIZE;
+ if (flushed >= CONFIG_CACHE_FLUSH_WATCHDOG_THRESHOLD) {
+ WATCHDOG_RESET();
+ flushed = 0;
+ }
+ return flushed;
+}
+
+void flush_cache(ulong start_addr, ulong size)
+{
+ ulong addr, start, end;
+ ulong flushed = 0;
+
+ start = start_addr & ~(CONFIG_SYS_CACHELINE_SIZE - 1);
+ end = start_addr + size - 1;
+
+ for (addr = start; (addr <= end) && (addr >= start);
+ addr += CONFIG_SYS_CACHELINE_SIZE) {
+ asm volatile("dcbst 0,%0" : : "r" (addr) : "memory");
+ flushed = maybe_watchdog_reset(flushed);
+ }
+ /* wait for all dcbst to complete on bus */
+ asm volatile("sync" : : : "memory");
+
+ for (addr = start; (addr <= end) && (addr >= start);
+ addr += CONFIG_SYS_CACHELINE_SIZE) {
+ asm volatile("icbi 0,%0" : : "r" (addr) : "memory");
+ flushed = maybe_watchdog_reset(flushed);
+ }
+ asm volatile("sync" : : : "memory");
+ /* flush prefetch queue */
+ asm volatile("isync" : : : "memory");
+}
diff --git a/roms/u-boot/arch/powerpc/lib/extable.c b/roms/u-boot/arch/powerpc/lib/extable.c
new file mode 100644
index 000000000..7e9d4f22f
--- /dev/null
+++ b/roms/u-boot/arch/powerpc/lib/extable.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
+ *
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ */
+#include <common.h>
+#include <log.h>
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue. No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path. This means when everything is well,
+ * we don't even have to jump over them. Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+
+struct exception_table_entry
+{
+ unsigned long insn, fixup;
+};
+
+extern const struct exception_table_entry __start___ex_table[];
+extern const struct exception_table_entry __stop___ex_table[];
+
+static inline unsigned long
+search_one_table(const struct exception_table_entry *first,
+ const struct exception_table_entry *last,
+ unsigned long value)
+{
+ long diff;
+ while (first <= last) {
+ diff = first->insn - value;
+ if (diff == 0)
+ return first->fixup;
+ first++;
+ }
+
+ return 0;
+}
+
+unsigned long
+search_exception_table(unsigned long addr)
+{
+ unsigned long ret;
+
+ /* There is only the kernel to search. */
+ ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
+ /* if the serial port does not hang in exception, printf can be used */
+#if !defined(CONFIG_SYS_SERIAL_HANG_IN_EXCEPTION)
+ debug("Bus Fault @ 0x%08lx, fixup 0x%08lx\n", addr, ret);
+#endif
+ if (ret) return ret;
+
+ return 0;
+}
diff --git a/roms/u-boot/arch/powerpc/lib/interrupts.c b/roms/u-boot/arch/powerpc/lib/interrupts.c
new file mode 100644
index 000000000..5ba4cd0c1
--- /dev/null
+++ b/roms/u-boot/arch/powerpc/lib/interrupts.c
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2000-2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2003
+ * Gleb Natapov <gnatapov@mrv.com>
+ */
+
+#include <common.h>
+#include <irq_func.h>
+#include <asm/processor.h>
+#include <watchdog.h>
+#ifdef CONFIG_LED_STATUS
+#include <status_led.h>
+#endif
+#include <asm/ptrace.h>
+
+#ifndef CONFIG_MPC83XX_TIMER
+#ifndef CONFIG_SYS_WATCHDOG_FREQ
+#define CONFIG_SYS_WATCHDOG_FREQ (CONFIG_SYS_HZ / 2)
+#endif
+
+static unsigned decrementer_count; /* count value for 1e6/HZ microseconds */
+
+static __inline__ unsigned long get_dec (void)
+{
+ unsigned long val;
+
+ asm volatile ("mfdec %0":"=r" (val):);
+
+ return val;
+}
+
+
+static __inline__ void set_dec (unsigned long val)
+{
+ if (val)
+ asm volatile ("mtdec %0"::"r" (val));
+}
+#endif /* !CONFIG_MPC83XX_TIMER */
+
+void enable_interrupts(void)
+{
+ set_msr (get_msr () | MSR_EE);
+}
+
+/* returns flag if MSR_EE was set before */
+int disable_interrupts(void)
+{
+ ulong msr = get_msr ();
+
+ set_msr (msr & ~MSR_EE);
+ return ((msr & MSR_EE) != 0);
+}
+
+#ifndef CONFIG_MPC83XX_TIMER
+int interrupt_init(void)
+{
+ /* call cpu specific function from $(CPU)/interrupts.c */
+ interrupt_init_cpu (&decrementer_count);
+
+ set_dec (decrementer_count);
+
+ set_msr (get_msr () | MSR_EE);
+
+ return (0);
+}
+
+static volatile ulong timestamp = 0;
+
+void timer_interrupt(struct pt_regs *regs)
+{
+ /* call cpu specific function from $(CPU)/interrupts.c */
+ timer_interrupt_cpu (regs);
+
+ /* Restore Decrementer Count */
+ set_dec (decrementer_count);
+
+ timestamp++;
+
+#if defined(CONFIG_WATCHDOG) || defined (CONFIG_HW_WATCHDOG)
+ if (CONFIG_SYS_WATCHDOG_FREQ && (timestamp % (CONFIG_SYS_WATCHDOG_FREQ)) == 0)
+ WATCHDOG_RESET ();
+#endif /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */
+
+#ifdef CONFIG_LED_STATUS
+ status_led_tick(timestamp);
+#endif /* CONFIG_LED_STATUS */
+}
+
+ulong get_timer (ulong base)
+{
+ return (timestamp - base);
+}
+#endif /* !CONFIG_MPC83XX_TIMER */
diff --git a/roms/u-boot/arch/powerpc/lib/kgdb.c b/roms/u-boot/arch/powerpc/lib/kgdb.c
new file mode 100644
index 000000000..8727d1888
--- /dev/null
+++ b/roms/u-boot/arch/powerpc/lib/kgdb.c
@@ -0,0 +1,261 @@
+#include <common.h>
+#include <command.h>
+#include <kgdb.h>
+#include <asm/ptrace.h>
+#include <asm/signal.h>
+#include <asm/processor.h>
+
+#define PC_REGNUM 64
+#define SP_REGNUM 1
+
+void breakinst(void);
+
+int
+kgdb_setjmp(long *buf)
+{
+ unsigned long temp;
+
+ asm volatile("mflr %0; stw %0,0(%1);"
+ "stw %%r1,4(%1); stw %%r2,8(%1);"
+ "mfcr %0; stw %0,12(%1);"
+ "stmw %%r13,16(%1)"
+ : "=&r"(temp) : "r" (buf));
+ /* XXX should save fp regs as well */
+ return 0;
+}
+
+void
+kgdb_longjmp(long *buf, int val)
+{
+ unsigned long temp;
+
+ if (val == 0)
+ val = 1;
+
+ asm volatile("lmw %%r13,16(%1);"
+ "lwz %0,12(%1); mtcrf 0x38,%0;"
+ "lwz %0,0(%1); lwz %%r1,4(%1); lwz %%r2,8(%1);"
+ "mtlr %0; mr %%r3,%2"
+ : "=&r"(temp) : "r" (buf), "r" (val));
+}
+
+/* Convert the SPARC hardware trap type code to a unix signal number. */
+/*
+ * This table contains the mapping between PowerPC hardware trap types, and
+ * signals, which are primarily what GDB understands.
+ */
+static struct hard_trap_info
+{
+ unsigned int tt; /* Trap type code for powerpc */
+ unsigned char signo; /* Signal that we map this trap into */
+} hard_trap_info[] = {
+ { 0x200, SIGSEGV }, /* machine check */
+ { 0x300, SIGSEGV }, /* address error (store) */
+ { 0x400, SIGBUS }, /* instruction bus error */
+ { 0x500, SIGINT }, /* interrupt */
+ { 0x600, SIGBUS }, /* alignment */
+ { 0x700, SIGTRAP }, /* breakpoint trap */
+ { 0x800, SIGFPE }, /* fpu unavail */
+ { 0x900, SIGALRM }, /* decrementer */
+ { 0xa00, SIGILL }, /* reserved */
+ { 0xb00, SIGILL }, /* reserved */
+ { 0xc00, SIGCHLD }, /* syscall */
+ { 0xd00, SIGTRAP }, /* single-step/watch */
+ { 0xe00, SIGFPE }, /* fp assist */
+ { 0, 0} /* Must be last */
+};
+
+static int
+computeSignal(unsigned int tt)
+{
+ struct hard_trap_info *ht;
+
+ for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
+ if (ht->tt == tt)
+ return ht->signo;
+
+ return SIGHUP; /* default for things we don't know about */
+}
+
+void
+kgdb_enter(struct pt_regs *regs, kgdb_data *kdp)
+{
+ unsigned long msr;
+
+ kdp->private[0] = msr = get_msr();
+ set_msr(msr & ~MSR_EE); /* disable interrupts */
+
+ if (regs->nip == (unsigned long)breakinst) {
+ /* Skip over breakpoint trap insn */
+ regs->nip += 4;
+ }
+ regs->msr &= ~MSR_SE;
+
+ /* reply to host that an exception has occurred */
+ kdp->sigval = computeSignal(regs->trap);
+
+ kdp->nregs = 2;
+
+ kdp->regs[0].num = PC_REGNUM;
+ kdp->regs[0].val = regs->nip;
+
+ kdp->regs[1].num = SP_REGNUM;
+ kdp->regs[1].val = regs->gpr[SP_REGNUM];
+}
+
+void
+kgdb_exit(struct pt_regs *regs, kgdb_data *kdp)
+{
+ unsigned long msr = kdp->private[0];
+
+ if (kdp->extype & KGDBEXIT_WITHADDR)
+ regs->nip = kdp->exaddr;
+
+ switch (kdp->extype & KGDBEXIT_TYPEMASK) {
+
+ case KGDBEXIT_KILL:
+ case KGDBEXIT_CONTINUE:
+ set_msr(msr);
+ break;
+
+ case KGDBEXIT_SINGLE:
+ regs->msr |= MSR_SE;
+#if 0
+ set_msr(msr | MSR_SE);
+#endif
+ break;
+ }
+}
+
+int
+kgdb_trap(struct pt_regs *regs)
+{
+ return (regs->trap);
+}
+
+/* return the value of the CPU registers.
+ * some of them are non-PowerPC names :(
+ * they are stored in gdb like:
+ * struct {
+ * u32 gpr[32];
+ * f64 fpr[32];
+ * u32 pc, ps, cnd, lr; (ps=msr)
+ * u32 cnt, xer, mq;
+ * }
+ */
+
+#define SPACE_REQUIRED ((32*4)+(32*8)+(6*4))
+
+int
+kgdb_getregs(struct pt_regs *regs, char *buf, int max)
+{
+ int i;
+ unsigned long *ptr = (unsigned long *)buf;
+
+ if (max < SPACE_REQUIRED)
+ kgdb_error(KGDBERR_NOSPACE);
+
+ if ((unsigned long)ptr & 3)
+ kgdb_error(KGDBERR_ALIGNFAULT);
+
+ /* General Purpose Regs */
+ for (i = 0; i < 32; i++)
+ *ptr++ = regs->gpr[i];
+
+ /* Floating Point Regs */
+ for (i = 0; i < 32; i++) {
+ *ptr++ = 0;
+ *ptr++ = 0;
+ }
+
+ /* pc, msr, cr, lr, ctr, xer, (mq is unused) */
+ *ptr++ = regs->nip;
+ *ptr++ = regs->msr;
+ *ptr++ = regs->ccr;
+ *ptr++ = regs->link;
+ *ptr++ = regs->ctr;
+ *ptr++ = regs->xer;
+
+ return (SPACE_REQUIRED);
+}
+
+/* set the value of the CPU registers */
+void
+kgdb_putreg(struct pt_regs *regs, int regno, char *buf, int length)
+{
+ unsigned long *ptr = (unsigned long *)buf;
+
+ if (regno < 0 || regno >= 70)
+ kgdb_error(KGDBERR_BADPARAMS);
+ else if (regno >= 32 && regno < 64) {
+ if (length < 8)
+ kgdb_error(KGDBERR_NOSPACE);
+ }
+ else {
+ if (length < 4)
+ kgdb_error(KGDBERR_NOSPACE);
+ }
+
+ if ((unsigned long)ptr & 3)
+ kgdb_error(KGDBERR_ALIGNFAULT);
+
+ if (regno >= 0 && regno < 32)
+ regs->gpr[regno] = *ptr;
+ else switch (regno) {
+ case 64: regs->nip = *ptr; break;
+ case 65: regs->msr = *ptr; break;
+ case 66: regs->ccr = *ptr; break;
+ case 67: regs->link = *ptr; break;
+ case 68: regs->ctr = *ptr; break;
+ case 69: regs->ctr = *ptr; break;
+
+ default:
+ kgdb_error(KGDBERR_BADPARAMS);
+ }
+}
+
+void
+kgdb_putregs(struct pt_regs *regs, char *buf, int length)
+{
+ int i;
+ unsigned long *ptr = (unsigned long *)buf;
+
+ if (length < SPACE_REQUIRED)
+ kgdb_error(KGDBERR_NOSPACE);
+
+ if ((unsigned long)ptr & 3)
+ kgdb_error(KGDBERR_ALIGNFAULT);
+
+ /*
+ * If the stack pointer has moved, you should pray.
+ * (cause only god can help you).
+ */
+
+ /* General Purpose Regs */
+ for (i = 0; i < 32; i++)
+ regs->gpr[i] = *ptr++;
+
+ /* Floating Point Regs */
+ ptr += 32*2;
+
+ /* pc, msr, cr, lr, ctr, xer, (mq is unused) */
+ regs->nip = *ptr++;
+ regs->msr = *ptr++;
+ regs->ccr = *ptr++;
+ regs->link = *ptr++;
+ regs->ctr = *ptr++;
+ regs->xer = *ptr++;
+}
+
+/* This function will generate a breakpoint exception. It is used at the
+ beginning of a program to sync up with a debugger and can be used
+ otherwise as a quick means to stop program execution and "break" into
+ the debugger. */
+
+void
+kgdb_breakpoint(int argc, char *const argv[])
+{
+ asm(" .globl breakinst\n\
+ breakinst: .long 0x7d821008\n\
+ ");
+}
diff --git a/roms/u-boot/arch/powerpc/lib/ppccache.S b/roms/u-boot/arch/powerpc/lib/ppccache.S
new file mode 100644
index 000000000..dcef1ffca
--- /dev/null
+++ b/roms/u-boot/arch/powerpc/lib/ppccache.S
@@ -0,0 +1,107 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
+ * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
+ * Copyright (C) 2000, 2001,2002 Wolfgang Denk <wd@denx.de>
+ * Copyright Freescale Semiconductor, Inc. 2004, 2006.
+ */
+
+#include <config.h>
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+
+/*------------------------------------------------------------------------------- */
+/* Function: ppcDcbf */
+/* Description: Data Cache block flush */
+/* Input: r3 = effective address */
+/* Output: none. */
+/*------------------------------------------------------------------------------- */
+ .globl ppcDcbf
+ppcDcbf:
+ dcbf r0,r3
+ blr
+
+/*------------------------------------------------------------------------------- */
+/* Function: ppcDcbi */
+/* Description: Data Cache block Invalidate */
+/* Input: r3 = effective address */
+/* Output: none. */
+/*------------------------------------------------------------------------------- */
+ .globl ppcDcbi
+ppcDcbi:
+ dcbi r0,r3
+ blr
+
+/*--------------------------------------------------------------------------
+ * Function: ppcDcbz
+ * Description: Data Cache block zero.
+ * Input: r3 = effective address
+ * Output: none.
+ *-------------------------------------------------------------------------- */
+
+ .globl ppcDcbz
+ppcDcbz:
+ dcbz r0,r3
+ blr
+
+/*------------------------------------------------------------------------------- */
+/* Function: ppcSync */
+/* Description: Processor Synchronize */
+/* Input: none. */
+/* Output: none. */
+/*------------------------------------------------------------------------------- */
+ .globl ppcSync
+ppcSync:
+ sync
+ blr
+
+/*
+ * Write any modified data cache blocks out to memory and invalidate them.
+ * Does not invalidate the corresponding instruction cache blocks.
+ *
+ * flush_dcache_range(unsigned long start, unsigned long stop)
+ */
+_GLOBAL(flush_dcache_range)
+#if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)
+ li r5,L1_CACHE_BYTES-1
+ andc r3,r3,r5
+ subf r4,r3,r4
+ add r4,r4,r5
+ srwi. r4,r4,L1_CACHE_SHIFT
+ beqlr
+ mtctr r4
+
+1: dcbf 0,r3
+ addi r3,r3,L1_CACHE_BYTES
+ bdnz 1b
+ sync /* wait for dcbst's to get to ram */
+#endif
+ blr
+
+/*
+ * Like above, but invalidate the D-cache. This is used by the 8xx
+ * to invalidate the cache so the PPC core doesn't get stale data
+ * from the CPM (no cache snooping here :-).
+ *
+ * invalidate_dcache_range(unsigned long start, unsigned long stop)
+ */
+_GLOBAL(invalidate_dcache_range)
+#if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)
+ li r5,L1_CACHE_BYTES-1
+ andc r3,r3,r5
+ subf r4,r3,r4
+ add r4,r4,r5
+ srwi. r4,r4,L1_CACHE_SHIFT
+ beqlr
+ mtctr r4
+
+ sync
+1: dcbi 0,r3
+ addi r3,r3,L1_CACHE_BYTES
+ bdnz 1b
+ sync /* wait for dcbi's to get to ram */
+#endif
+ blr
+
diff --git a/roms/u-boot/arch/powerpc/lib/ppcstring.S b/roms/u-boot/arch/powerpc/lib/ppcstring.S
new file mode 100644
index 000000000..f88d79fa4
--- /dev/null
+++ b/roms/u-boot/arch/powerpc/lib/ppcstring.S
@@ -0,0 +1,205 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * String handling functions for PowerPC.
+ *
+ * Copyright (C) 1996 Paul Mackerras.
+ */
+#include <ppc_asm.tmpl>
+#include <linux/errno.h>
+
+ .globl strcpy
+strcpy:
+ addi r5,r3,-1
+ addi r4,r4,-1
+1: lbzu r0,1(r4)
+ cmpwi 0,r0,0
+ stbu r0,1(r5)
+ bne 1b
+ blr
+
+ .globl strncpy
+strncpy:
+ cmpwi 0,r5,0
+ beqlr
+ mtctr r5
+ addi r6,r3,-1
+ addi r4,r4,-1
+1: lbzu r0,1(r4)
+ cmpwi 0,r0,0
+ stbu r0,1(r6)
+ bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */
+ blr
+
+ .globl strcat
+strcat:
+ addi r5,r3,-1
+ addi r4,r4,-1
+1: lbzu r0,1(r5)
+ cmpwi 0,r0,0
+ bne 1b
+ addi r5,r5,-1
+1: lbzu r0,1(r4)
+ cmpwi 0,r0,0
+ stbu r0,1(r5)
+ bne 1b
+ blr
+
+ .globl strcmp
+strcmp:
+ addi r5,r3,-1
+ addi r4,r4,-1
+1: lbzu r3,1(r5)
+ cmpwi 1,r3,0
+ lbzu r0,1(r4)
+ subf. r3,r0,r3
+ beqlr 1
+ beq 1b
+ blr
+
+ .globl strlen
+strlen:
+ addi r4,r3,-1
+1: lbzu r0,1(r4)
+ cmpwi 0,r0,0
+ bne 1b
+ subf r3,r3,r4
+ blr
+
+ .globl memset
+memset:
+ rlwimi r4,r4,8,16,23
+ rlwimi r4,r4,16,0,15
+ addi r6,r3,-4
+ cmplwi 0,r5,4
+ blt 7f
+ stwu r4,4(r6)
+ beqlr
+ andi. r0,r6,3
+ add r5,r0,r5
+ subf r6,r0,r6
+ rlwinm r0,r5,32-2,2,31
+ mtctr r0
+ bdz 6f
+1: stwu r4,4(r6)
+ bdnz 1b
+6: andi. r5,r5,3
+7: cmpwi 0,r5,0
+ beqlr
+ mtctr r5
+ addi r6,r6,3
+8: stbu r4,1(r6)
+ bdnz 8b
+ blr
+
+ .globl memmove
+memmove:
+ cmplw 0,r3,r4
+ bgt backwards_memcpy
+ /* fall through */
+
+ .globl memcpy
+memcpy:
+ rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */
+ addi r6,r3,-4
+ addi r4,r4,-4
+ beq 2f /* if less than 8 bytes to do */
+ andi. r0,r6,3 /* get dest word aligned */
+ mtctr r7
+ bne 5f
+1: lwz r7,4(r4)
+ lwzu r8,8(r4)
+ stw r7,4(r6)
+ stwu r8,8(r6)
+ bdnz 1b
+ andi. r5,r5,7
+2: cmplwi 0,r5,4
+ blt 3f
+ lwzu r0,4(r4)
+ addi r5,r5,-4
+ stwu r0,4(r6)
+3: cmpwi 0,r5,0
+ beqlr
+ mtctr r5
+ addi r4,r4,3
+ addi r6,r6,3
+4: lbzu r0,1(r4)
+ stbu r0,1(r6)
+ bdnz 4b
+ blr
+5: subfic r0,r0,4
+ mtctr r0
+6: lbz r7,4(r4)
+ addi r4,r4,1
+ stb r7,4(r6)
+ addi r6,r6,1
+ bdnz 6b
+ subf r5,r0,r5
+ rlwinm. r7,r5,32-3,3,31
+ beq 2b
+ mtctr r7
+ b 1b
+
+ .globl backwards_memcpy
+backwards_memcpy:
+ rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */
+ add r6,r3,r5
+ add r4,r4,r5
+ beq 2f
+ andi. r0,r6,3
+ mtctr r7
+ bne 5f
+1: lwz r7,-4(r4)
+ lwzu r8,-8(r4)
+ stw r7,-4(r6)
+ stwu r8,-8(r6)
+ bdnz 1b
+ andi. r5,r5,7
+2: cmplwi 0,r5,4
+ blt 3f
+ lwzu r0,-4(r4)
+ subi r5,r5,4
+ stwu r0,-4(r6)
+3: cmpwi 0,r5,0
+ beqlr
+ mtctr r5
+4: lbzu r0,-1(r4)
+ stbu r0,-1(r6)
+ bdnz 4b
+ blr
+5: mtctr r0
+6: lbzu r7,-1(r4)
+ stbu r7,-1(r6)
+ bdnz 6b
+ subf r5,r0,r5
+ rlwinm. r7,r5,32-3,3,31
+ beq 2b
+ mtctr r7
+ b 1b
+
+ .globl memcmp
+memcmp:
+ cmpwi 0,r5,0
+ ble- 2f
+ mtctr r5
+ addi r6,r3,-1
+ addi r4,r4,-1
+1: lbzu r3,1(r6)
+ lbzu r0,1(r4)
+ subf. r3,r0,r3
+ bdnzt 2,1b
+ blr
+2: li r3,0
+ blr
+
+ .global memchr
+memchr:
+ cmpwi 0,r5,0
+ ble- 2f
+ mtctr r5
+ addi r3,r3,-1
+1: lbzu r0,1(r3)
+ cmpw 0,r0,r4
+ bdnzf 2,1b
+ beqlr
+2: li r3,0
+ blr
diff --git a/roms/u-boot/arch/powerpc/lib/reloc.S b/roms/u-boot/arch/powerpc/lib/reloc.S
new file mode 100644
index 000000000..eb51fe888
--- /dev/null
+++ b/roms/u-boot/arch/powerpc/lib/reloc.S
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2009 Wolfgang Denk <wd@denx.de>
+ */
+
+#include <ppc_asm.tmpl>
+
+ .file "reloc.S"
+
+ .text
+#ifndef CONFIG_NAND_SPL
+ /*
+ * Function: relocate entries for one exception vector
+ */
+ .globl trap_reloc
+ .type trap_reloc, @function
+trap_reloc:
+ lwz r0, 0(r7) /* hdlr ... */
+ add r0, r0, r3 /* ... += dest_addr */
+ stw r0, 0(r7)
+
+ lwz r0, 4(r7) /* int_return ... */
+ add r0, r0, r3 /* ... += dest_addr */
+ stw r0, 4(r7)
+
+ lwz r0, 8(r7) /* transfer_to_handler ...*/
+ add r0, r0, r3 /* ... += dest_addr */
+ stw r0, 8(r7)
+
+ blr
+ .size trap_reloc, .-trap_reloc
+#endif
diff --git a/roms/u-boot/arch/powerpc/lib/spl.c b/roms/u-boot/arch/powerpc/lib/spl.c
new file mode 100644
index 000000000..d4a605752
--- /dev/null
+++ b/roms/u-boot/arch/powerpc/lib/spl.c
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2012 Stefan Roese <sr@denx.de>
+ */
+#include <common.h>
+#include <config.h>
+#include <log.h>
+#include <spl.h>
+#include <image.h>
+#include <linux/compiler.h>
+
+/*
+ * This function jumps to an image with argument. Normally an FDT or ATAGS
+ * image.
+ */
+#ifdef CONFIG_SPL_OS_BOOT
+void __noreturn jump_to_image_linux(struct spl_image_info *spl_image)
+{
+ debug("Entering kernel arg pointer: 0x%p\n", spl_image->arg);
+ typedef void (*image_entry_arg_t)(void *, ulong r4, ulong r5, ulong r6,
+ ulong r7, ulong r8, ulong r9)
+ __attribute__ ((noreturn));
+ image_entry_arg_t image_entry =
+ (image_entry_arg_t)spl_image->entry_point;
+
+ image_entry(spl_image->arg, 0, 0, EPAPR_MAGIC, CONFIG_SYS_BOOTMAPSZ,
+ 0, 0);
+}
+#endif /* CONFIG_SPL_OS_BOOT */
diff --git a/roms/u-boot/arch/powerpc/lib/stack.c b/roms/u-boot/arch/powerpc/lib/stack.c
new file mode 100644
index 000000000..f2a4652e0
--- /dev/null
+++ b/roms/u-boot/arch/powerpc/lib/stack.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2015 Andreas Bießmann <andreas@biessmann.org>
+ *
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * (C) Copyright 2002-2006
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ */
+#include <common.h>
+#include <init.h>
+#include <asm/global_data.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int arch_reserve_stacks(void)
+{
+ ulong *s;
+
+ /* setup stack pointer for exceptions */
+ gd->irq_sp = gd->start_addr_sp;
+
+ /* Clear initial stack frame */
+ s = (ulong *)gd->start_addr_sp;
+ *s = 0; /* Terminate back chain */
+ *++s = 0; /* NULL return address */
+
+ return 0;
+}
diff --git a/roms/u-boot/arch/powerpc/lib/ticks.S b/roms/u-boot/arch/powerpc/lib/ticks.S
new file mode 100644
index 000000000..c487f938f
--- /dev/null
+++ b/roms/u-boot/arch/powerpc/lib/ticks.S
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2000, 2001
+ * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com.
+ * base on code by
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ */
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+#include <config.h>
+#include <watchdog.h>
+
+/*
+ * unsigned long long get_ticks(void);
+ *
+ * read timebase as "long long"
+ */
+ .globl get_ticks
+get_ticks:
+1: mftbu r3
+ mftb r4
+ mftbu r5
+ cmp 0,r3,r5
+ bne 1b
+ blr
+
+/*
+ * Delay for a number of ticks
+ */
+ .globl wait_ticks
+wait_ticks:
+ stwu r1, -16(r1)
+ mflr r0 /* save link register */
+ stw r0, 20(r1) /* Use r0 or GDB will be unhappy */
+ stw r14, 12(r1) /* save used registers */
+ stw r15, 8(r1)
+ mr r14, r3 /* save tick count */
+ bl get_ticks /* Get start time */
+
+ /* Calculate end time */
+ addc r14, r4, r14 /* Compute end time lower */
+ addze r15, r3 /* and end time upper */
+
+ WATCHDOG_RESET /* Trigger watchdog, if needed */
+1: bl get_ticks /* Get current time */
+ subfc r4, r4, r14 /* Subtract current time from end time */
+ subfe. r3, r3, r15
+ bge 1b /* Loop until time expired */
+
+ lwz r15, 8(r1) /* restore saved registers */
+ lwz r14, 12(r1)
+ lwz r0, 20(r1)
+ addi r1,r1,16
+ mtlr r0
+ blr
diff --git a/roms/u-boot/arch/powerpc/lib/time.c b/roms/u-boot/arch/powerpc/lib/time.c
new file mode 100644
index 000000000..8d6babfb8
--- /dev/null
+++ b/roms/u-boot/arch/powerpc/lib/time.c
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2000, 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <time.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * This function is intended for SHORT delays only.
+ * It will overflow at around 10 seconds @ 400MHz,
+ * or 20 seconds @ 200MHz.
+ */
+unsigned long usec2ticks(unsigned long usec)
+{
+ ulong ticks;
+
+ if (usec < 1000) {
+ ticks = ((usec * (get_tbclk()/1000)) + 500) / 1000;
+ } else {
+ ticks = ((usec / 10) * (get_tbclk() / 100000));
+ }
+
+ return (ticks);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * We implement the delay by converting the delay (the number of
+ * microseconds to wait) into a number of time base ticks; then we
+ * watch the time base until it has incremented by that amount.
+ */
+void __udelay(unsigned long usec)
+{
+ ulong ticks = usec2ticks (usec);
+ wait_ticks (ticks);
+}
+
+/* ------------------------------------------------------------------------- */
+#ifndef CONFIG_NAND_SPL
+unsigned long ticks2usec(unsigned long ticks)
+{
+ ulong tbclk = get_tbclk();
+
+ /* usec = ticks * 1000000 / tbclk
+ * Multiplication would overflow at ~4.2e3 ticks,
+ * so we break it up into
+ * usec = ( ( ticks * 1000) / tbclk ) * 1000;
+ */
+ ticks *= 1000L;
+ ticks /= tbclk;
+ ticks *= 1000L;
+
+ return ((ulong)ticks);
+}
+#endif
+/* ------------------------------------------------------------------------- */
+
+int timer_init(void)
+{
+ unsigned long temp;
+
+ /* reset */
+ asm volatile("li %0,0 ; mttbl %0 ; mttbu %0;"
+ : "=&r"(temp) );
+
+ return (0);
+}
+/* ------------------------------------------------------------------------- */
diff --git a/roms/u-boot/arch/powerpc/lib/traps.c b/roms/u-boot/arch/powerpc/lib/traps.c
new file mode 100644
index 000000000..c7bce82a4
--- /dev/null
+++ b/roms/u-boot/arch/powerpc/lib/traps.c
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ */
+
+#include <init.h>
+#include <asm/global_data.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void trap_init(unsigned long reloc_addr);
+
+int arch_initr_trap(void)
+{
+ trap_init(gd->relocaddr);
+
+ return 0;
+}