aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHao Wu <wuhaotsh@google.com>2025-07-07 11:09:25 -0700
committerGitHub <noreply@github.com>2025-07-07 11:09:25 -0700
commitc076c6bc0b74bff38f43bf28d9df2ff9bde55ca8 (patch)
treea44fdfa838ed794fb004d7b9505771d11af0e2cb
parentd6e3386709b3e49322a94ffadc2aaab9944ab77b (diff)
parent80768e454d548a7f7f53374a3a0ff8ec4bbae778 (diff)
downloadvbootrom-master.zip
vbootrom-master.tar.gz
vbootrom-master.tar.bz2
Merge pull request #8 from jamin-aspeed/coprocessorHEADmaster
ast27x0: Initialize and enable SSP/TSP using SCU
-rw-r--r--ast27x0/Makefile4
-rw-r--r--ast27x0/image.c131
-rw-r--r--ast27x0/include/image.h58
-rw-r--r--ast27x0/include/io.h8
-rw-r--r--ast27x0/include/ssp_tsp.h97
-rw-r--r--ast27x0/include/uart.h2
-rw-r--r--ast27x0/ssp_tsp.c195
-rw-r--r--ast27x0/uart_aspeed.c6
8 files changed, 487 insertions, 14 deletions
diff --git a/ast27x0/Makefile b/ast27x0/Makefile
index 3096884..5d13ba1 100644
--- a/ast27x0/Makefile
+++ b/ast27x0/Makefile
@@ -41,13 +41,13 @@ GIT_VERSION := git-$(shell git rev-parse --short HEAD)
CFLAGS = -Os -Wall -Wextra -g -mcpu=cortex-a35 -fno-stack-protector \
-no-pie -fno-pic \
-I ./include -I ../lib/libfdt -I ../lib/libc/minimal/include
-CFLAGS += -DGIT_VERSION=\"$(GIT_VERSION)\"
+CFLAGS += -DGIT_VERSION=\"$(GIT_VERSION)\"
ASFLAGS = $(CFLAGS) -Wa,-mcpu=cortex-a35
LDSCRIPT = bootrom.ld
MAPFILE = bootrom.map
LDFLAGS = -Wl,--build-id=none -static -nostdlib -T $(LDSCRIPT) -Wl,-Map=$(MAPFILE)
-OBJS := start.o image.o uart_aspeed.o uart_console.o \
+OBJS := start.o image.o uart_aspeed.o uart_console.o ssp_tsp.o \
../lib/libc/minimal/source/string/string.o \
../lib/libfdt/fdt.o ../lib/libfdt/fdt_ro.o
diff --git a/ast27x0/image.c b/ast27x0/image.c
index ab88ee7..d00e792 100644
--- a/ast27x0/image.c
+++ b/ast27x0/image.c
@@ -21,11 +21,11 @@
#include <libfdt.h>
#include <uart.h>
#include <uart_console.h>
+#include <io.h>
+#include <image.h>
+#include <ssp_tsp.h>
#define DEBUG 0
-#define DRAM_ADDR 0x400000000ULL
-#define FMCCS0 0x100000000ULL
-#define UART12 0x14C33B00
#define FIT_SEARCH_START (FMCCS0)
#define FIT_SEARCH_END (FMCCS0 + 0x400000)
@@ -33,6 +33,9 @@
extern void panic(const char *);
+static bool has_sspfw;
+static bool has_tspfw;
+
/*
* This global struct is explicitly initialized, so it is placed in the .data
* section. The function pointer (uputc) is set to uart_aspeed_poll_out at
@@ -274,7 +277,8 @@ static uint64_t load_uboot_image(const void *fit_blob)
* if some images do not define explicit load addresses in the FIT.
*/
static void load_other_fit_images(const void *fit_blob, uint64_t uboot_end,
- uint64_t *dest_addr)
+ uint64_t *dest_addr,
+ const struct reserved_mem_info *info)
{
uintptr_t data_offset;
uint64_t load_addr;
@@ -316,6 +320,17 @@ static void load_other_fit_images(const void *fit_blob, uint64_t uboot_end,
if (strcmp(name, "atf") == 0) {
*dest_addr = dram_addr;
}
+
+ /* Init co-processor */
+ if (strcmp(name, "sspfw") == 0) {
+ ssp_init(dram_addr, info);
+ has_sspfw = true;
+ }
+
+ if (strcmp(name, "tspfw") == 0) {
+ tsp_init(dram_addr, info);
+ has_tspfw = true;
+ }
} else if (strcmp(name, "fdt") == 0 && uboot_end) {
/* fdt has no load address, fallback to uboot_end */
load_addr = uboot_end;
@@ -366,17 +381,111 @@ static const void *find_fit_image(uint64_t start_addr, uint64_t end_addr,
return NULL;
}
+static int find_fmc_image(uint64_t start_addr, uint64_t end_addr,
+ uint64_t search_step, struct fmc_img_info *info)
+{
+ struct ast_fmc_header *hdr;
+ uint32_t fmc_header_size;
+ uint32_t payload_size;
+ uint32_t total_size;
+ uint64_t addr;
+
+ if (info == NULL) {
+ return 0;
+ }
+
+ fmc_header_size = sizeof(struct ast_fmc_header);
+
+ for (addr = start_addr;
+ addr + fmc_header_size <= end_addr;
+ addr += search_step) {
+ hdr = (struct ast_fmc_header *)addr;
+
+ if (hdr->preamble.magic == FMC_HDR_MAGIC) {
+ payload_size = hdr->body.size;
+ total_size = fmc_header_size + payload_size;
+
+ if (payload_size > 0 && (addr + total_size) <= end_addr) {
+ info->payload_start = addr + fmc_header_size;
+ info->payload_end = ALIGN_UP(addr + total_size, search_step);
+ uprintf("Found valid FMC v%d image at 0x%lx (size: 0x%x)",
+ hdr->preamble.version, addr, total_size);
+ uprintf(", next FIT search @ 0x%lx\n", info->payload_end);
+ return 1;
+ }
+ }
+ }
+
+ uprintf("No valid FMC image found in range 0x%lx - 0x%lx (step: 0x%lx)\n",
+ start_addr, end_addr, search_step);
+
+ return 0;
+}
+
+static void *load_dtb_after_fmc(uint64_t fmc_end, uint64_t end_addr)
+{
+ void *dram_dtb_addr = (void *)(uintptr_t)DRAM_ADDR;
+ const uint32_t *magic_ptr;
+ size_t copy_size;
+ uint64_t addr;
+
+ for (addr = ALIGN_UP(fmc_end, 4); addr + 4 < end_addr; addr += 4) {
+ /* Check for DTB magic number (aligned on 4-byte boundary) */
+ magic_ptr = (const uint32_t *)(uintptr_t)addr;
+ if (*magic_ptr != cpu_to_fdt32(FDT_MAGIC)) {
+ continue;
+ }
+
+ /* Copy from flash to DRAM for validation */
+ copy_size = end_addr - addr;
+ memcpy(dram_dtb_addr, (const void *)(uintptr_t)addr, copy_size);
+
+ /* Verify if the copied region is a valid DTB */
+ if (fdt_check_header(dram_dtb_addr) == 0) {
+ uprintf("Valid DTB found at 0x%lx, copied to 0x%lx\n",
+ addr, (uint64_t)dram_dtb_addr);
+ return dram_dtb_addr;
+ } else {
+ uprintf("FDT_MAGIC at 0x%lx but invalid DTB header\n", addr);
+ }
+ }
+
+ uprintf("No valid DTB found between 0x%lx and 0x%lx\n", fmc_end, end_addr);
+ return NULL;
+}
+
uint64_t load_boot_image(void)
{
+ struct reserved_mem_info reservedinfo = {0};
+ struct fmc_img_info fmcinfo = {0};
+ uint64_t search_next_addr;
uint64_t bl31_addr = 0;
const void *fit_blob;
+ void *dtb_ptr = NULL;
uint64_t uboot_end;
uart_aspeed_init(UART12);
uart_console_register(&ucons);
print_build_info();
- fit_blob = find_fit_image(FIT_SEARCH_START,
+
+ search_next_addr = FIT_SEARCH_START;
+
+ /* Find FMC image */
+ if (find_fmc_image(search_next_addr, FIT_SEARCH_END, FIT_SEARCH_STEP,
+ &fmcinfo)) {
+ search_next_addr = fmcinfo.payload_end;
+
+ /* Try to find and load a valid SPL DTB between FMC and U-Boot FIT */
+ dtb_ptr = load_dtb_after_fmc(fmcinfo.payload_start,
+ fmcinfo.payload_end);
+ if (dtb_ptr) {
+ get_reserved_memory(dtb_ptr, &reservedinfo);
+ }
+ }
+
+ /* Find U-Boot FIT imag */
+ fit_blob = find_fit_image(search_next_addr,
FIT_SEARCH_END,
FIT_SEARCH_STEP);
if (!fit_blob) {
@@ -393,13 +502,23 @@ uint64_t load_boot_image(void)
panic("");
}
- load_other_fit_images(fit_blob, uboot_end, &bl31_addr);
+ load_other_fit_images(fit_blob, uboot_end, &bl31_addr, &reservedinfo);
if (!bl31_addr) {
uprintf("Error: BL31 (Trusted Firmware-A) not found, halting.\n");
panic("");
}
+
+ if (has_sspfw) {
+ ssp_enable();
+ }
+
+ if (has_tspfw) {
+ tsp_enable();
+ }
+
uprintf("\nJumping to BL31 (Trusted Firmware-A) at 0x%lx\n\n",
bl31_addr);
return bl31_addr;
}
+
diff --git a/ast27x0/include/image.h b/ast27x0/include/image.h
new file mode 100644
index 0000000..4fe3316
--- /dev/null
+++ b/ast27x0/include/image.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2025 ASPEED Technology Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __AST27X0_INCLUDE_IMAGE_H__
+#define __AST27X0_INCLUDE_IMAGE_H__
+
+#define DRAM_ADDR 0x400000000ULL
+#define FMCCS0 0x100000000ULL
+
+/* FMC v2 */
+/* ASTH */
+#define FMC_HDR_MAGIC 0x48545341
+#define ECC_SIGN_LEN 96
+#define LMS_SIGN_LEN 1620
+#define SHA_DGST_LEN 48
+
+struct hdr_preamble {
+ uint32_t magic;
+ uint32_t version;
+ uint32_t ecc_key_idx;
+ uint32_t lms_key_idx;
+ uint8_t ecc_sig[ECC_SIGN_LEN];
+ uint8_t lms_sig[LMS_SIGN_LEN];
+ uint32_t raz[15];
+};
+
+struct hdr_body {
+ uint32_t svn;
+ uint32_t size;
+ uint8_t dgst[SHA_DGST_LEN];
+ /* 712 bytes */
+ uint8_t reserved[178 * 4];
+};
+
+struct ast_fmc_header {
+ struct hdr_preamble preamble;
+ struct hdr_body body;
+} __attribute__((packed));
+
+struct fmc_img_info {
+ uint64_t payload_start;
+ uint64_t payload_end;
+};
+
+#endif /* __AST27X0_INCLUDE_IMAGE_H__ */
diff --git a/ast27x0/include/io.h b/ast27x0/include/io.h
index fab6546..6813940 100644
--- a/ast27x0/include/io.h
+++ b/ast27x0/include/io.h
@@ -27,4 +27,12 @@
#define writel(value, addr) (*(volatile unsigned int *)(addr) = (unsigned int)(value))
#define writeq(value, addr) (*(volatile unsigned long long *)(addr) = (unsigned long long)(value))
+#define BITS_PER_LONG (sizeof(unsigned long) * 8)
+#define GENMASK(h, l) \
+ (((~0UL) >> (BITS_PER_LONG - ((h) - (l) + 1))) << (l))
+
+#define BIT(x) (1UL << (x))
+
+#define ALIGN_UP(x, align) (((x) + ((align) - 1)) & ~((align) - 1))
+
#endif /* __AST27X0_INCLUDE_IO_H__ */
diff --git a/ast27x0/include/ssp_tsp.h b/ast27x0/include/ssp_tsp.h
new file mode 100644
index 0000000..b93b26f
--- /dev/null
+++ b/ast27x0/include/ssp_tsp.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2025 ASPEED Technology Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __AST27X0_INCLUDE_SSP_TSP_H__
+#define __AST27X0_INCLUDE_SSP_TSP_H__
+
+#include <stdint.h>
+
+/* MAX visible range is 512M for SSP and TSP */
+#define MAX_I_D_ADDRESS (512 * 1024 * 1024)
+#define TCM_SIZE (8 * 1024) /* 8KB */
+
+#define SSP_MEMORY_NODE "/reserved-memory/ssp-memory"
+#define TSP_MEMORY_NODE "/reserved-memory/tsp-memory"
+#define ATF_MEMORY_NODE "/reserved-memory/trusted-firmware-a"
+#define OPTEE_MEMORY_NODE "/reserved-memory/optee-core"
+#define IPC_SSP_MEMORY_NODE "/reserved-memory/ipc-ssp-share"
+
+/* SCU */
+#define ASPEED_CPU_SCU_BASE 0x12C02000
+
+struct ast2700_scu0 {
+ uint32_t rsv_0x11c[72]; /* 0x000 ~ 0x11C */
+ uint32_t ssp_ctrl_0; /* 0x120 */
+ uint32_t ssp_ctrl_1; /* 0x124 */
+ uint32_t ssp_ctrl_2; /* 0x128 */
+ uint32_t ssp_ctrl_3; /* 0x12C */
+ uint32_t ssp_ctrl_4; /* 0x130 */
+ uint32_t ssp_ctrl_5; /* 0x134 */
+ uint32_t ssp_ctrl_6; /* 0x138 */
+ uint32_t rsv_0x13c[1]; /* 0x13C */
+ uint32_t ssp_tcm_base; /* 0x140 */
+ uint32_t ssp_tcm_size; /* 0x144 */
+ uint32_t ssp_ahb_base; /* 0x148 */
+ uint32_t ssp_ahb_size; /* 0x14c */
+ uint32_t ssp_memory_base; /* 0x150 */
+ uint32_t ssp_memory_size; /* 0x154 */
+ uint32_t rsv_0x158[2]; /* 0x158 ~ 0x15C */
+ uint32_t tsp_ctrl_0; /* 0x160 */
+ uint32_t rsv_0x164[1]; /* 0x164 */
+ uint32_t tsp_ctrl_1; /* 0x168 */
+ uint32_t tsp_ctrl_2; /* 0x16C */
+ uint32_t tsp_ctrl_3; /* 0x170 */
+ uint32_t tsp_ctrl_4; /* 0x174 */
+ uint32_t tsp_ctrl_5; /* 0x178 */
+ uint32_t rsv_0x17c[6]; /* 0x17C ~ 0x190 */
+ uint32_t tsp_remap_size; /* 0x194 */
+};
+
+/* SSP control register 0 */
+#define SCU_CPU_SSP_TSP_RESET_STS BIT(8)
+#define SCU_CPU_SSP_TSP_SRAM_SD BIT(7)
+#define SCU_CPU_SSP_TSP_SRAM_DSLP BIT(6)
+#define SCU_CPU_SSP_TSP_SRAM_SLP BIT(5)
+#define SCU_CPU_SSP_TSP_NIDEN BIT(4)
+#define SCU_CPU_SSP_TSP_DBGEN BIT(3)
+#define SCU_CPU_SSP_TSP_DBG_ENABLE BIT(2)
+#define SCU_CPU_SSP_TSP_RESET BIT(1)
+#define SCU_CPU_SSP_TSP_ENABLE BIT(0)
+
+/* SSP control register 6 */
+#define SCU_CPU_SSP_TSP_CTRL_ICACHE_EN BIT(1)
+#define SCU_CPU_SSP_TSP_CTRL_DCACHE_EN BIT(0)
+
+struct mem_region {
+ uint64_t addr;
+ uint32_t size;
+};
+
+struct reserved_mem_info {
+ struct mem_region ssp;
+ struct mem_region tsp;
+ struct mem_region atf;
+ struct mem_region tee;
+ struct mem_region ipc_ssp;
+};
+
+void get_reserved_memory(const void *fdt_blob, struct reserved_mem_info *info);
+int ssp_init(uint64_t load_addr, const struct reserved_mem_info *info);
+int ssp_enable(void);
+int tsp_init(uint64_t load_addr, const struct reserved_mem_info *info);
+int tsp_enable(void);
+
+#endif /* __AST27X0_INCLUDE_SSP_TSP_H__ */
diff --git a/ast27x0/include/uart.h b/ast27x0/include/uart.h
index df16be7..567faf4 100644
--- a/ast27x0/include/uart.h
+++ b/ast27x0/include/uart.h
@@ -14,6 +14,8 @@
#ifndef __AST27X0_INCLUDE_UART_H__
#define __AST27X0_INCLUDE_UART_H__
+#define UART12 0x14C33B00
+
/**
* @brief UART Interface
* @defgroup uart_interface UART Interface
diff --git a/ast27x0/ssp_tsp.c b/ast27x0/ssp_tsp.c
new file mode 100644
index 0000000..260858b
--- /dev/null
+++ b/ast27x0/ssp_tsp.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2025 ASPEED Technology Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <io.h>
+#include <libfdt.h>
+#include <uart_console.h>
+#include <image.h>
+#include <ssp_tsp.h>
+
+void get_reserved_memory(const void *fdt_blob, struct reserved_mem_info *info)
+{
+ struct {
+ const char *path;
+ struct mem_region *region;
+ } nodes[] = {
+ { SSP_MEMORY_NODE, &info->ssp },
+ { TSP_MEMORY_NODE, &info->tsp },
+ { ATF_MEMORY_NODE, &info->atf },
+ { OPTEE_MEMORY_NODE, &info->tee },
+ { IPC_SSP_MEMORY_NODE, &info->ipc_ssp },
+ };
+
+ const fdt32_t *reg;
+ const char *path;
+ int offset;
+ size_t i;
+
+ for (i = 0; i < sizeof(nodes) / sizeof(nodes[0]); i++) {
+ path = nodes[i].path;
+
+ offset = fdt_path_offset(fdt_blob, path);
+ if (offset < 0) {
+ uprintf("Cannot find node %s in the device tree.\n", path);
+ nodes[i].region->addr = 0;
+ nodes[i].region->size = 0;
+ continue;
+ }
+
+ reg = fdt_getprop(fdt_blob, offset, "reg", NULL);
+ if (!reg) {
+ uprintf("No reg property found in %s\n", path);
+ nodes[i].region->addr = 0;
+ nodes[i].region->size = 0;
+ continue;
+ }
+
+ nodes[i].region->addr = fdt32_to_cpu(reg[0]);
+ nodes[i].region->size = fdt32_to_cpu(reg[1]);
+
+ uprintf("[reserved] %s base: 0x%lx size: 0x%lx\n", path,
+ nodes[i].region->addr, nodes[i].region->size);
+ }
+}
+
+int ssp_init(uint64_t load_addr, const struct reserved_mem_info *info)
+{
+ struct ast2700_scu0 *scu;
+ uint32_t reg_val;
+
+ scu = (struct ast2700_scu0 *)ASPEED_CPU_SCU_BASE;
+
+ reg_val = readl((void *)&scu->ssp_ctrl_0);
+ if (!(reg_val & SCU_CPU_SSP_TSP_RESET_STS)) {
+ return 0;
+ }
+
+ reg_val = SCU_CPU_SSP_TSP_NIDEN | SCU_CPU_SSP_TSP_DBGEN |
+ SCU_CPU_SSP_TSP_DBG_ENABLE | SCU_CPU_SSP_TSP_RESET;
+ writel(reg_val, (void *)&scu->ssp_ctrl_0);
+
+ /*
+ * SSP Memory Map:
+ * - 0x0000_0000 - 0x0587_FFFF: ssp_remap2 -> DRAM[load_addr]
+ * - 0x0588_0000 - 0x1FFF_DFFF: ssp_remap1 -> AHB -> DRAM[0]
+ * - 0x1FFF_E000 - 0x2000_0000: ssp_remap0 -> TCM (SSP stack)
+ *
+ * The SSP serves as the secure loader for TSP, ATF, OP-TEE, and U-Boot.
+ * Therefore, their load buffers must be visible to the SSP.
+ *
+ * - SSP remap entry #2 (ssp_remap2_base/size) maps the load buffers
+ * for SSP, TSP, ATF, OP-TEE and IPC share memory. Ensure these buffers
+ * are contiguous.
+ * - SSP remap entry #1 (ssp_remap1_base/size) maps the load buffer
+ * for U-Boot at DRAM offset 0x0.
+ * - SSP remap entry #0 (ssp_remap0_base/size) maps TCM, which is used for
+ * stack.
+ */
+ writel(0, (void *)&scu->ssp_memory_base);
+ reg_val = info->ssp.size + info->tsp.size + info->atf.size +
+ info->tee.size + info->ipc_ssp.size;
+ writel(reg_val, (void *)&scu->ssp_memory_size);
+
+ writel(reg_val, (void *)&scu->ssp_ahb_base);
+ writel(MAX_I_D_ADDRESS - reg_val - TCM_SIZE, (void *)&scu->ssp_ahb_size);
+
+ writel(MAX_I_D_ADDRESS - TCM_SIZE, (void *)&scu->ssp_tcm_base);
+ writel(TCM_SIZE, (void *)&scu->ssp_tcm_size);
+
+ /* Configure physical AHB remap: through H2M, mapped to SYS_DRAM_BASE */
+ writel((uint32_t)(DRAM_ADDR >> 4), (void *)&scu->ssp_ctrl_1);
+
+ /* Configure physical DRAM remap */
+ reg_val = (uint32_t)(load_addr >> 4);
+ writel(reg_val, (void *)&scu->ssp_ctrl_2);
+
+ /*
+ * For A1, the Cache region can only be enabled entirely;
+ * partial enabling is not supported.
+ */
+ writel(GENMASK(31, 0), (void *)&scu->ssp_ctrl_3);
+ writel(GENMASK(31, 0), (void *)&scu->ssp_ctrl_4);
+
+ /* Enable I and D cache as default */
+ writel(SCU_CPU_SSP_TSP_CTRL_ICACHE_EN | SCU_CPU_SSP_TSP_CTRL_DCACHE_EN,
+ (void *)&scu->ssp_ctrl_6);
+
+ return 0;
+}
+
+int ssp_enable(void)
+{
+ struct ast2700_scu0 *scu;
+ uint32_t reg_val;
+
+ scu = (struct ast2700_scu0 *)ASPEED_CPU_SCU_BASE;
+ reg_val = readl((void *)&scu->ssp_ctrl_0);
+ reg_val |= SCU_CPU_SSP_TSP_ENABLE | SCU_CPU_SSP_TSP_RESET;
+ writel(reg_val, (void *)&scu->ssp_ctrl_0);
+
+ return 0;
+}
+
+int tsp_init(uint64_t load_addr, const struct reserved_mem_info *info)
+{
+ struct ast2700_scu0 *scu;
+ uint32_t reg_val;
+
+ scu = (struct ast2700_scu0 *)ASPEED_CPU_SCU_BASE;
+
+ reg_val = readl((void *)&scu->tsp_ctrl_0);
+ if (!(reg_val & SCU_CPU_SSP_TSP_RESET_STS)) {
+ return 0;
+ }
+
+ reg_val = SCU_CPU_SSP_TSP_NIDEN | SCU_CPU_SSP_TSP_DBGEN |
+ SCU_CPU_SSP_TSP_DBG_ENABLE | SCU_CPU_SSP_TSP_RESET;
+ writel(reg_val, (void *)&scu->tsp_ctrl_0);
+
+ /* TSP 0x0000_0000 - 0x0200_0000 -> DRAM */
+ writel(info->tsp.size, (void *)&scu->tsp_remap_size);
+
+ /* Configure physical DRAM remap */
+ reg_val = (uint32_t)(load_addr >> 4);
+ writel(reg_val, (void *)&scu->tsp_ctrl_1);
+
+ /*
+ * For A1, the Cache region can only be enabled entirely;
+ * partial enabling is not supported.
+ */
+ writel(GENMASK(31, 0), (void *)&scu->tsp_ctrl_2);
+ writel(GENMASK(31, 0), (void *)&scu->tsp_ctrl_3);
+
+ /* Enable I and D cache as default */
+ writel(SCU_CPU_SSP_TSP_CTRL_ICACHE_EN | SCU_CPU_SSP_TSP_CTRL_DCACHE_EN,
+ (void *)&scu->tsp_ctrl_5);
+
+ return 0;
+}
+
+int tsp_enable(void)
+{
+ struct ast2700_scu0 *scu;
+ uint32_t reg_val;
+
+ scu = (struct ast2700_scu0 *)ASPEED_CPU_SCU_BASE;
+ reg_val = readl((void *)&scu->tsp_ctrl_0);
+ reg_val |= SCU_CPU_SSP_TSP_ENABLE | SCU_CPU_SSP_TSP_RESET;
+ writel(reg_val, (void *)&scu->tsp_ctrl_0);
+
+ return 0;
+}
+
diff --git a/ast27x0/uart_aspeed.c b/ast27x0/uart_aspeed.c
index 1ec4d7e..2a4990a 100644
--- a/ast27x0/uart_aspeed.c
+++ b/ast27x0/uart_aspeed.c
@@ -18,12 +18,6 @@
#include <uart.h>
#include <io.h>
-#define BITS_PER_LONG (sizeof(unsigned long) * 8)
-#define GENMASK(h, l) \
- (((~0UL) >> (BITS_PER_LONG - ((h) - (l) + 1))) << (l))
-
-#define BIT(x) (1UL << (x))
-
/* UART registers */
#define UART_THR 0x00
#define UART_DLL 0x00