summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--platform/generic/Kconfig5
-rw-r--r--platform/generic/configs/defconfig1
-rw-r--r--platform/generic/eswin/Kconfig29
-rw-r--r--platform/generic/eswin/eic770x.c403
-rw-r--r--platform/generic/eswin/objects.mk10
-rw-r--r--platform/generic/include/eswin/eic770x.h79
6 files changed, 527 insertions, 0 deletions
diff --git a/platform/generic/Kconfig b/platform/generic/Kconfig
index b1808012..716fab42 100644
--- a/platform/generic/Kconfig
+++ b/platform/generic/Kconfig
@@ -48,6 +48,10 @@ config PLATFORM_ANDES_QILAI
select ANDES_SBI
default n
+config PLATFORM_ESWIN_EIC770X
+ bool "ESWIN EIC770X support"
+ default n
+
config PLATFORM_OPENHWGROUP_OPENPITON
bool "OpenHWGroup Openpiton support"
default n
@@ -98,6 +102,7 @@ config PLATFORM_SPACEMIT_K1
default n
source "$(OPENSBI_SRC_DIR)/platform/generic/andes/Kconfig"
+source "$(OPENSBI_SRC_DIR)/platform/generic/eswin/Kconfig"
source "$(OPENSBI_SRC_DIR)/platform/generic/thead/Kconfig"
endif
diff --git a/platform/generic/configs/defconfig b/platform/generic/configs/defconfig
index d0e2ec26..aab1560f 100644
--- a/platform/generic/configs/defconfig
+++ b/platform/generic/configs/defconfig
@@ -1,6 +1,7 @@
CONFIG_PLATFORM_ALLWINNER_D1=y
CONFIG_PLATFORM_ANDES_AE350=y
CONFIG_PLATFORM_ANDES_QILAI=y
+CONFIG_PLATFORM_ESWIN_EIC770X=y
CONFIG_PLATFORM_OPENHWGROUP_ARIANE=y
CONFIG_PLATFORM_OPENHWGROUP_OPENPITON=y
CONFIG_PLATFORM_RENESAS_RZFIVE=y
diff --git a/platform/generic/eswin/Kconfig b/platform/generic/eswin/Kconfig
new file mode 100644
index 00000000..7326686b
--- /dev/null
+++ b/platform/generic/eswin/Kconfig
@@ -0,0 +1,29 @@
+# SPDX-License-Identifier: BSD-2-Clause
+
+config ESWIN_EIC770X_FEAT0_CFG
+ hex "ESWIN EIC7700X Feature Disable 0 CSR Configuration"
+ default 0x4000
+ help
+ CSR Value to initialize EIC770X_FEAT0 (0x7c1) with.
+ Refer to EIC770X SoC TRM for recommendations.
+
+config ESWIN_EIC770X_FEAT1_CFG
+ hex "ESWIN EIC7700X Feature Disable 1 CSR Configuration"
+ default 0x80
+ help
+ CSR Value to initialize EIC770X_FEAT1 (0x7c2) with.
+ Refer to EIC770X SoC TRM for recommendations.
+
+config ESWIN_EIC770X_L1_HWPF_CFG
+ hex "ESWIN EIC7700X L1 HW Prefetcher CSR Configuration"
+ default 0x1005c1be649
+ help
+ CSR Value to initialize EIC770X_L1_HWPF (0x7c3) with.
+ Refer to EIC770X SoC TRM for recommendations.
+
+config ESWIN_EIC770X_L2_HWPF_CFG
+ hex "ESWIN EIC7700X L2 HW Prefetcher CSR Configuration"
+ default 0x929f
+ help
+ CSR Value to initialize EIC770X_L2_HWPF (0x7c4) with.
+ Refer to EIC770X SoC TRM for recommendations.
diff --git a/platform/generic/eswin/eic770x.c b/platform/generic/eswin/eic770x.c
new file mode 100644
index 00000000..bce53a19
--- /dev/null
+++ b/platform/generic/eswin/eic770x.c
@@ -0,0 +1,403 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2025 Bo Gan <[email protected]>
+ *
+ */
+
+#include <platform_override.h>
+#include <sbi/riscv_io.h>
+#include <sbi/sbi_console.h>
+#include <sbi/sbi_system.h>
+#include <sbi/sbi_math.h>
+#include <sbi/sbi_hart_pmp.h>
+#include <sbi/sbi_hart_protection.h>
+#include <eswin/eic770x.h>
+
+static struct sbi_hart_protection eswin_eic7700_pmp_protection;
+
+static int eic770x_system_reset_check(u32 type, u32 reason)
+{
+ switch (type) {
+ case SBI_SRST_RESET_TYPE_COLD_REBOOT:
+ case SBI_SRST_RESET_TYPE_WARM_REBOOT:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static void eic770x_system_reset(u32 type, u32 reason)
+{
+ switch (type) {
+ case SBI_SRST_RESET_TYPE_COLD_REBOOT:
+ case SBI_SRST_RESET_TYPE_WARM_REBOOT:
+ sbi_printf("%s: resetting...\n", __func__);
+ writel(EIC770X_SYSCRG_RST_VAL, (void *)EIC770X_SYSCRG_RST);
+ }
+
+ sbi_hart_hang();
+}
+
+static struct sbi_system_reset_device *board_reset = NULL;
+static struct sbi_system_reset_device eic770x_reset = {
+ .name = "eic770x_reset",
+ .system_reset_check = eic770x_system_reset_check,
+ .system_reset = eic770x_system_reset,
+};
+
+#define add_root_mem_chk(...) do { \
+ rc = sbi_domain_root_add_memrange(__VA_ARGS__); \
+ if (rc) \
+ return rc; \
+} while (0)
+
+/**
+ * EIC7700 special arrangement of PMP entries:
+ *
+ * We have to use extra PMPs to block data cacheable regions that
+ * that doesn't belong to the current hart's die in order to prevent
+ * speculative accesses or HW prefetcher from generating bus error:
+ *
+ * bus error of cause event: 9, accrued: 0x220,
+ * physical address: 0x24ffffffa0
+ *
+ * The data cacheable regions (per datasheet) include:
+ *
+ * - [0x1a000000, 0x1a400000) -- Die 0 L3 zero device
+ * - [0x3a000000, 0x3a400000) -- Die 1 L3 zero device
+ * - [0x80000000, 0x80_00000000) -- memory port
+ *
+ * To make the blocker effective for M mode too, the extra PMPs need
+ * LOCK bit to be set, and once set, we can't change them later.
+ * We also have to to use 1 extra PMP to protect OpenSBI in uncached
+ * memory. EIC770X maps main memory (DRAM) twice -- one in memory
+ * port (cached), the other in system port (uncached). P550 doesn't
+ * support Svpbmt, so EIC770X use the uncached window to handle DMA
+ * that are cache incoherent -- pretty much all peripherals
+ *
+ * Final PMP configuration:
+ *
+ * From die 0 point of view, block
+ * - [0x3a000000, 0x3a400000) -- Die 1 L3 zero device
+ * - [0x10_00000000, 0x80_00000000) -- Die 1 cached mem + holes
+ *
+ * Root domain Harts:
+ * PMP[0]: [ 0x80000000, 0x80080000) ____ Firmware in cached mem
+ * PMP[1]: [0xc0_00000000, 0xc0_00080000) ____ Firmware in uncached
+ * PMP[2]: [ 0x3a000000, 0x3a400000) L___ Die 1 L3 zero device
+ * PMP[3]: [ 0x2000000 0x2010000) ____ CLINT
+ * PMP[4]: [ 0x0, 0x10_00000000) _RWX P550/System/Die 0 cached mem
+ * PMP[5]: <Free>
+ * PMP[6]: [ 0x0, 0x80_00000000) L___ P550/System/Memory Port
+ * PMP[7]: [ 0x0, 0xffffffffffffffff] _RWX Everything
+ *
+ * From die 1 point of view, block
+ * - [0x1a000000, 0x1a400000) -- Die 0 L3 zero device
+ * - [0x80000000, 0x20_00000000) -- Die 0 cached mem + holes
+ * - [0x30_00000000, 0x80_00000000) -- other holes in Memory port
+ *
+ * Root domain Harts:
+ * PMP[0]: [0x20_00000000, 0x20_00080000) ____ Firmware in cached mem
+ * PMP[1]: [0xe0_00000000, 0xe0_00080000) ____ Firmware in uncached
+ * PMP[2]: [ 0x1a000000, 0x1a400000) L___ Die 0 L3 zero dev
+ * PMP[3]: [ 0x22000000 0x22010000) ____ CLINT
+ * PMP[4]: [ 0x0, 0x80000000) _RWX Die 0/1 P550 internal
+ * PMP[5]: [0x20_00000000, 0x30_00000000) _RWX Die 1 cached memory
+ * PMP[6]: [ 0x0, 0x80_00000000) L___ P550/System/Memory Port
+ * PMP[7]: [ 0x0, 0xffffffffffffffff] _RWX Everything
+ *
+ * EIC770X memory port map:
+ * P550 Internal
+ * ├─ 0x0000_0000 - 0x2000_0000 die 0 internal
+ * └─ 0x2000_0000 - 0x4000_0000 die 1 internal
+ * System Port 0
+ * ├─ 0x4000_0000 - 0x6000_0000 die 0 low MMIO
+ * └─ 0x6000_0000 - 0x8000_0000 die 1 low MMIO
+ * Memory Port
+ * ├─ 0x8000_0000 - 0x10_8000_0000 die 0 memory (cached)
+ * ├─ 0x20_0000_0000 - 0x30_0000_0000 die 1 memory (cached)
+ * └─ 0x40_0000_0000 - 0x60_0000_0000 interleaved memory (cached)
+ * System Port 1
+ * ├─ 0x80_0000_0000 - 0xa0_0000_0000 die 0 high MMIO
+ * ├─ 0xa0_0000_0000 - 0xc0_0000_0000 die 1 high MMIO
+ * ├─ 0xc0_0000_0000 - 0xd0_0000_0000 die 0 memory (uncached)
+ * ├─ 0xe0_0000_0000 - 0xf0_0000_0000 die 1 memory (uncached)
+ * ├─ 0x100_0000_0000 - 0x120_0000_0000 interleaved memory (uncached)
+ * └─ ...
+ *
+ * In early_init, add memory regions such that lib/ code has the knowledge
+ * of blocked ranges. When the driver code inserts new regions, lib/ code
+ * can optimize away unnecessary ones. Next, in final_init, we program the
+ * PMPs to a default state that'll keep ourselves functional (CLINT/...
+ * accessible). Later, in pmp_configure, do the actual configuration of
+ * PMP, using domain memory regions and permissions.
+ */
+
+static int eswin_eic7700_early_init(bool cold_boot)
+{
+ struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
+ int rc;
+
+ if (!cold_boot)
+ return generic_early_init(cold_boot);
+
+ if (board_reset)
+ sbi_system_reset_add_device(board_reset);
+ sbi_system_reset_add_device(&eic770x_reset);
+
+ /* Enable bus blocker */
+ writel(1, (void*)EIC770X_TL64D2D_OUT);
+ writel(1, (void*)EIC770X_TL256D2D_OUT);
+ writel(1, (void*)EIC770X_TL256D2D_IN);
+ asm volatile ("fence o, rw");
+
+ /* Block firmware in uncached memory */
+ add_root_mem_chk(EIC770X_TO_UNCACHED(
+ scratch->fw_start),
+ 1UL << log2roundup(scratch->fw_size),
+ 1UL << log2roundup(scratch->fw_size),
+ (SBI_DOMAIN_MEMREGION_M_READABLE |
+ SBI_DOMAIN_MEMREGION_M_WRITABLE |
+ SBI_DOMAIN_MEMREGION_M_EXECUTABLE |
+ SBI_DOMAIN_MEMREGION_MMIO |
+ SBI_DOMAIN_MEMREGION_FW));
+
+ /* Allow SURW of P550 + System Port */
+ add_root_mem_chk(0,
+ EIC770X_MEMPORT_BASE,
+ EIC770X_MEMPORT_BASE,
+ (SBI_DOMAIN_MEMREGION_MMIO |
+ SBI_DOMAIN_MEMREGION_SHARED_SURW_MRW));
+
+ if (current_hart_die()) {
+ /* Allow SURWX of die 1 cached memory */
+ add_root_mem_chk(EIC770X_D1_MEM_BASE,
+ EIC770X_D1_MEM_SIZE,
+ EIC770X_D1_MEM_SIZE,
+ (SBI_DOMAIN_MEMREGION_M_READABLE |
+ SBI_DOMAIN_MEMREGION_M_WRITABLE |
+ SBI_DOMAIN_MEMREGION_SU_RWX));
+ } else {
+ /* Allow SURWX of P550 + System Port + die 0 cached memory */
+ add_root_mem_chk(0,
+ EIC770X_D0_MEM_LIMIT,
+ EIC770X_D0_MEM_LIMIT,
+ (SBI_DOMAIN_MEMREGION_M_READABLE |
+ SBI_DOMAIN_MEMREGION_M_WRITABLE |
+ SBI_DOMAIN_MEMREGION_SU_RWX));
+ }
+
+ /* Block P550 + System Port 0 + Memory Port (enforced) */
+ add_root_mem_chk(0,
+ EIC770X_MEMPORT_LIMIT,
+ EIC770X_MEMPORT_LIMIT,
+ (SBI_DOMAIN_MEMREGION_MMIO |
+ SBI_DOMAIN_MEMREGION_ENF_PERMISSIONS));
+
+ rc = sbi_hart_protection_register(&eswin_eic7700_pmp_protection);
+ if (rc)
+ return rc;
+
+ return generic_early_init(cold_boot);
+}
+
+#define PMP_FW_START 0
+#define PMP_FW_COUNT 2
+#define PMP_RESERVED_A 2
+#define PMP_FREE_A_START 3
+#define PMP_FREE_A_COUNT 3
+#define PMP_RESERVED_B 6
+#define PMP_FREE_B_START 7
+#define PMP_FREE_B_COUNT 1
+
+static int eswin_eic7700_final_init(bool cold_boot)
+{
+ /**
+ * For both dies after final_init:
+ *
+ * PMP[0]: Protect OpenSBI in cached memory
+ * PMP[1]: Protect OpenSBI in uncached memory
+ * PMP[2]: Block remote die P550 L3 Zero Device
+ * PMP[3-5]: <Free ranges A>
+ * PMP[5]: Temporary enable P550 + System Port
+ * PMP[6]: Block all P550 + System + Memory Port
+ * PMP[7-7]: <Free ranges B>
+ */
+ struct sbi_domain_memregion *reg;
+ unsigned int pmp_idx = PMP_FW_START,
+ pmp_max = PMP_FW_START + PMP_FW_COUNT;
+ int rc;
+
+
+ /**
+ * Do generic_final_init stuff first, because it touchs FDT.
+ * After final_init, we'll block entire memory port with the
+ * LOCK bit set, which means we can't access memory outside
+ * of [fw_start, fw_start + fw_size). The FDT could very well
+ * reside outside of firmware region. Later, pmp_configure()
+ * may unblock it with some preceding entries for root domain
+ * harts. It may not unblock it, however, for non-root harts.
+ */
+ rc = generic_final_init(cold_boot);
+ if (rc)
+ return rc;
+
+ /* Process firmware regions */
+ sbi_domain_for_each_memregion(&root, reg) {
+ if (!SBI_DOMAIN_MEMREGION_IS_FIRMWARE(reg->flags))
+ continue;
+
+ if (pmp_idx >= pmp_max) {
+ sbi_printf("%s: insufficient FW PMP entries\n",
+ __func__);
+ return SBI_EFAIL;
+ }
+ pmp_set(pmp_idx++, sbi_domain_get_oldpmp_flags(reg),
+ reg->base, reg->order);
+ }
+
+ pmp_set(PMP_RESERVED_A, PMP_L, EIC770X_L3_ZERO_REMOTE,
+ log2roundup(EIC770X_L3_ZERO_SIZE));
+ /**
+ * Enable P550 internal + System Port, so OpenSBI can access
+ * CLINT/PLIC/UART. Might be overwritten in pmp_configure.
+ */
+ pmp_set(PMP_FREE_A_START + PMP_FREE_A_COUNT - 1, 0, 0,
+ log2roundup(EIC770X_MEMPORT_BASE));
+
+ pmp_set(PMP_RESERVED_B, PMP_L, 0,
+ log2roundup(EIC770X_MEMPORT_LIMIT));
+ /**
+ * These must come after the setup of PMP, as we are about to
+ * enable speculation and HW prefetcher bits
+ */
+ csr_write(EIC770X_CSR_FEAT0, CONFIG_ESWIN_EIC770X_FEAT0_CFG);
+ csr_write(EIC770X_CSR_FEAT1, CONFIG_ESWIN_EIC770X_FEAT1_CFG);
+ csr_write(EIC770X_CSR_L1_HWPF, CONFIG_ESWIN_EIC770X_L1_HWPF_CFG);
+ csr_write(EIC770X_CSR_L2_HWPF, CONFIG_ESWIN_EIC770X_L2_HWPF_CFG);
+
+ return 0;
+}
+
+static int eswin_eic7700_pmp_configure(struct sbi_scratch *scratch)
+{
+ struct sbi_domain *dom = sbi_domain_thishart_ptr();
+ struct sbi_domain_memregion *reg, *prev = NULL;
+ unsigned int pmp_idx, pmp_max;
+ unsigned int i, j;
+
+ /* Process the first free range A [3-5] */
+ pmp_idx = PMP_FREE_A_START,
+ pmp_max = PMP_FREE_A_START + PMP_FREE_A_COUNT;
+
+ sbi_domain_for_each_memregion_idx(dom, reg, i) {
+ if (SBI_DOMAIN_MEMREGION_IS_FIRMWARE(reg->flags))
+ continue;
+
+ /**
+ * This must be the one blocking P550 + System Port +
+ * Memory Port we setup in early_init, or a superset
+ * of it. If seen, break, and program the rest in
+ * free range B.
+ */
+ if (reg->base == 0 &&
+ reg->order >= log2roundup(EIC770X_MEMPORT_LIMIT))
+ break;
+
+ /**
+ * Relaxation:
+ * Treat a previous region with SURW as SURWX if the
+ * current has SURWX, and current region with MMIO
+ * if previous has MMIO, and see if it can be merged.
+ * This saves 1 PMP entry on die 0/
+ */
+ if (prev && sbi_domain_memregion_is_subset(prev, reg) &&
+ (reg->flags | SBI_DOMAIN_MEMREGION_MMIO) ==
+ (prev->flags | SBI_DOMAIN_MEMREGION_SU_EXECUTABLE))
+ pmp_idx--;
+
+ if (pmp_idx >= pmp_max)
+ goto no_more_pmp;
+
+ pmp_set(pmp_idx++, sbi_domain_get_oldpmp_flags(reg),
+ reg->base, reg->order);
+ prev = reg;
+ }
+ /* Disable the rest */
+ while (pmp_idx < pmp_max)
+ pmp_disable(pmp_idx++);
+
+ /* Process the second free range B [7-7] */
+ pmp_idx = PMP_FREE_B_START,
+ pmp_max = PMP_FREE_B_START + PMP_FREE_B_COUNT;
+
+ sbi_domain_for_each_memregion_idx(dom, reg, j) {
+ if (i >= j)
+ continue;
+
+ if (pmp_idx >= pmp_max)
+ goto no_more_pmp;
+
+ pmp_set(pmp_idx++, sbi_domain_get_oldpmp_flags(reg),
+ reg->base, reg->order);
+ }
+ /* Disable the rest */
+ while (pmp_idx < pmp_max)
+ pmp_disable(pmp_idx++);
+
+ sbi_hart_pmp_fence();
+ return 0;
+no_more_pmp:
+ sbi_printf("%s: insufficient PMP entries\n", __func__);
+ return SBI_EFAIL;
+}
+
+static void eswin_eic7700_pmp_unconfigure(struct sbi_scratch *scratch)
+{
+ /* Enable P550 internal + System Port */
+ pmp_set(PMP_FREE_A_START + PMP_FREE_A_COUNT - 1, 0, 0,
+ log2roundup(EIC770X_MEMPORT_BASE));
+
+ for (unsigned int i = 0; i < PMP_FREE_A_COUNT - 1; i++)
+ pmp_disable(i + PMP_FREE_A_START);
+
+ for (unsigned int i = 0; i < PMP_FREE_B_COUNT; i++)
+ pmp_disable(i + PMP_FREE_B_START);
+}
+
+static struct sbi_hart_protection eswin_eic7700_pmp_protection = {
+ .name = "eic7700_pmp",
+ .rating = -1UL,
+ .configure = eswin_eic7700_pmp_configure,
+ .unconfigure = eswin_eic7700_pmp_unconfigure,
+};
+
+static bool eswin_eic7700_single_fw_region(void)
+{
+ return true;
+}
+
+static int eswin_eic7700_platform_init(const void *fdt, int nodeoff,
+ const struct fdt_match *match)
+{
+ const struct eic770x_board_override *board_override = match->data;
+
+ generic_platform_ops.early_init = eswin_eic7700_early_init;
+ generic_platform_ops.final_init = eswin_eic7700_final_init;
+ generic_platform_ops.single_fw_region = eswin_eic7700_single_fw_region;
+
+ if (board_override)
+ board_reset = board_override->reset_dev;
+ return 0;
+}
+
+static const struct fdt_match eswin_eic7700_match[] = {
+ { .compatible = "eswin,eic7700" },
+ { },
+};
+
+const struct fdt_driver eswin_eic7700 = {
+ .match_table = eswin_eic7700_match,
+ .init = eswin_eic7700_platform_init,
+};
diff --git a/platform/generic/eswin/objects.mk b/platform/generic/eswin/objects.mk
new file mode 100644
index 00000000..be5420ce
--- /dev/null
+++ b/platform/generic/eswin/objects.mk
@@ -0,0 +1,10 @@
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (C) 2025 Bo Gan <[email protected]>
+#
+
+ifeq ($(PLATFORM_RISCV_XLEN), 64)
+carray-platform_override_modules-$(CONFIG_PLATFORM_ESWIN_EIC770X) += eswin_eic7700
+platform-objs-$(CONFIG_PLATFORM_ESWIN_EIC770X) += eswin/eic770x.o
+endif
diff --git a/platform/generic/include/eswin/eic770x.h b/platform/generic/include/eswin/eic770x.h
new file mode 100644
index 00000000..b1994669
--- /dev/null
+++ b/platform/generic/include/eswin/eic770x.h
@@ -0,0 +1,79 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2025 Bo Gan <[email protected]>
+ *
+ */
+
+#ifndef __EIC770X_H__
+#define __EIC770X_H__
+
+#include <sbi/riscv_asm.h>
+
+struct eic770x_board_override {
+ struct sbi_system_reset_device *reset_dev;
+};
+
+/* CSRs */
+#define EIC770X_CSR_BRPREDICT 0x7c0
+#define EIC770X_CSR_FEAT0 0x7c1
+#define EIC770X_CSR_FEAT1 0x7c2
+#define EIC770X_CSR_L1_HWPF 0x7c3
+#define EIC770X_CSR_L2_HWPF 0x7c4
+
+/* Hart ID to core/die conversion */
+#define CPU_CORE_BITS 2
+#define CPU_CORE_MASK ((1 << CPU_CORE_BITS) - 1)
+#define CPU_DIE_SHIFT CPU_CORE_BITS
+#define CPU_DIE_BITS 1
+#define CPU_DIE_MASK ((1 << CPU_DIE_BITS) - 1)
+
+#define hart_core(i) ((i) & CPU_CORE_MASK)
+#define hart_die(i) (((i) >> CPU_DIE_SHIFT) & CPU_DIE_MASK)
+#define current_hart_core() hart_core(current_hartid())
+#define current_hart_die() hart_die(current_hartid())
+
+/* P550 Internal and System Port 0 */
+#define EIC770X_P550INT_SIZE 0x20000000UL
+#define EIC770X_P550INT_BASE(d) (0UL + EIC770X_P550INT_SIZE * (d))
+#define EIC770X_P550INT_LOCAL EIC770X_P550INT_BASE(current_hart_die())
+#define EIC770X_TL64D2D_OUT (EIC770X_P550INT_LOCAL + 0x200000)
+#define EIC770X_TL256D2D_OUT (EIC770X_P550INT_LOCAL + 0x202000)
+#define EIC770X_TL256D2D_IN (EIC770X_P550INT_LOCAL + 0x204000)
+#define EIC770X_L3_ZERO_SIZE 0x400000UL
+#define EIC770X_L3_ZERO_BASE(d) (EIC770X_P550INT_BASE(d) + 0x1a000000)
+#define EIC770X_L3_ZERO_LOCAL EIC770X_L3_ZERO_BASE(current_hart_die())
+#define EIC770X_L3_ZERO_REMOTE EIC770X_L3_ZERO_BASE(1 - current_hart_die())
+
+#define EIC770X_SYSPORT_SIZE 0x20000000UL
+#define EIC770X_SYSPORT_BASE(d) (0x40000000UL + EIC770X_SYSPORT_SIZE * (d))
+#define EIC770X_SYSPORT_LOCAL EIC770X_SYSPORT_BASE(current_hart_die())
+#define EIC770X_SYSCRG (EIC770X_SYSPORT_LOCAL + 0x11828000UL)
+#define EIC770X_SYSCRG_RST (EIC770X_SYSCRG + 0x300UL)
+#define EIC770X_SYSCRG_RST_VAL 0x1AC0FFE6UL
+
+/* Memory Ports */
+#define EIC770X_MEMPORT_BASE 0x0080000000UL // 2G
+#define EIC770X_MEMPORT_SIZE 0x7f80000000UL // +510G
+#define EIC770X_MEMPORT_LIMIT (EIC770X_MEMPORT_BASE + EIC770X_MEMPORT_SIZE)
+#define EIC770X_D0_MEM_BASE 0x0080000000UL // 2G
+#define EIC770X_D0_MEM_SIZE 0x0f80000000UL // +62G
+#define EIC770X_D0_MEM_LIMIT (EIC770X_D0_MEM_BASE + EIC770X_D0_MEM_SIZE)
+#define EIC770X_D1_MEM_BASE 0x2000000000UL // 128G
+#define EIC770X_D1_MEM_SIZE 0x1000000000UL // +64G
+#define EIC770X_D1_MEM_LIMIT (EIC770X_D1_MEM_BASE + EIC770X_D1_MEM_SIZE)
+#define EIC770X_CACHED_BASE (current_hart_die() ? \
+ EIC770X_D1_MEM_BASE : \
+ EIC770X_D0_MEM_BASE)
+
+/* Uncached memory mapped in System Port 1 */
+#define EIC770X_D0_UC_BASE 0xc000000000UL
+#define EIC770X_D1_UC_BASE 0xe000000000UL
+#define EIC770X_UNCACHED_BASE (current_hart_die() ? \
+ EIC770X_D1_UC_BASE : \
+ EIC770X_D0_UC_BASE)
+
+#define EIC770X_TO_UNCACHED(x) ((x) - EIC770X_CACHED_BASE + \
+ EIC770X_UNCACHED_BASE)
+
+#endif