summaryrefslogtreecommitdiff
path: root/chip
diff options
context:
space:
mode:
authorYilun Lin <yllin@google.com>2018-12-20 17:05:24 +0800
committerchrome-bot <chrome-bot@chromium.org>2019-01-24 00:51:28 -0800
commitfa379e1983ec568e6ca475311af3f77dec9327ff (patch)
tree431922bd6b7625bf41b19eb55676f3bccbe8d83d /chip
parent579719f073c3b526d5801a3b0cc886cc8246821f (diff)
downloadchrome-ec-fa379e1983ec568e6ca475311af3f77dec9327ff.tar.gz
mt_scp/memmap: Enable memmap between AP and SCP.
SCP/AP can access the AP/SCP address via memory address translation. TEST=Run memmap (TEST-ONLY CL), see direct mapping makes sense: Direct mapping: 00001000 INVAL 0f002000 INVAL 10003000 INVAL 1f004000 INVAL 20005000 40005000 => 20005000 OK 2f006000 4f006000 => 2f006000 OK 30007000 50007000 => 30007000 OK 3f008000 5f008000 => 3f008000 OK 40009000 INVAL 4f00a000 INVAL 5000b000 INVAL 5f00c000 INVAL 6000d000 6000d000 => 6000d000 OK 6f00e000 6f00e000 => 6f00e000 OK 7000f000 7000f000 => 7000f000 OK 7f010000 7f010000 => 7f010000 OK 80011000 80011000 => 80011000 OK 8f012000 8f012000 => 8f012000 OK 90013000 00013000 => 90013000 OK 9f014000 0f014000 => 9f014000 OK a0015000 10015000 => a0015000 OK af016000 1f016000 => af016000 OK b0017000 20017000 => b0017000 OK bf018000 2f018000 => bf018000 OK c0019000 30019000 => c0019000 OK cf01a000 3f01a000 => cf01a000 OK d001b000 1001b000 => a001b000 BAD df01c000 1f01c000 => af01c000 BAD (these are ok as 0x1* is mapped from both 0xd* and 0xa*) e001d000 a001d000 => e001d000 OK ef01e000 af01e000 => ef01e000 OK f001f000 9001f000 => f001f000 OK ff020000 9f020000 => ff020000 OK BRANCH=None BUG=b:114326670 Change-Id: I29298c2e5a897d08d21390c751bdd881170adb59 Signed-off-by: Yilun Lin <yllin@google.com> Signed-off-by: Nicolas Boichat <drinkcat@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1385910 Reviewed-by: Erin Lo <erin.lo@mediatek.com> Reviewed-by: Rong Chang <rongchang@chromium.org>
Diffstat (limited to 'chip')
-rw-r--r--chip/mt_scp/build.mk2
-rw-r--r--chip/mt_scp/memmap.c145
-rw-r--r--chip/mt_scp/memmap.h49
-rw-r--r--chip/mt_scp/registers.h28
-rw-r--r--chip/mt_scp/system.c23
5 files changed, 224 insertions, 23 deletions
diff --git a/chip/mt_scp/build.mk b/chip/mt_scp/build.mk
index dac5e3dfcb..03937f8591 100644
--- a/chip/mt_scp/build.mk
+++ b/chip/mt_scp/build.mk
@@ -10,7 +10,7 @@ CORE:=cortex-m
CFLAGS_CPU+=-march=armv7e-m -mcpu=cortex-m4
# Required chip modules
-chip-y=clock.o gpio.o stepping_stone.o system.o uart.o
+chip-y=clock.o gpio.o memmap.o stepping_stone.o system.o uart.o
# Optional chip modules
chip-$(CONFIG_COMMON_TIMER)+=hrtimer.o
diff --git a/chip/mt_scp/memmap.c b/chip/mt_scp/memmap.c
new file mode 100644
index 0000000000..798969b63d
--- /dev/null
+++ b/chip/mt_scp/memmap.c
@@ -0,0 +1,145 @@
+/* Copyright 2018 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * SCP memory map
+ */
+
+#include "common.h"
+#include "compile_time_macros.h"
+#include "hooks.h"
+#include "memmap.h"
+#include "registers.h"
+
+/*
+ * Map SCP address (bits 31~28) to AP address
+ *
+ * SCP addr : AP addr
+ * 0x20000000 0x40000000
+ * 0x30000000 0x50000000
+ * 0x60000000 0x60000000
+ * 0x70000000 0x70000000
+ * 0x80000000 0x80000000
+ * 0x90000000 0x00000000
+ * 0xA0000000 0x10000000
+ * 0xB0000000 0x20000000
+ * 0xC0000000 0x30000000
+ * 0xD0000000 0x10000000
+ * 0xE0000000 0xA0000000
+ * 0xF0000000 0x90000000
+ */
+
+#define MAP_INVALID 0xff
+
+static const uint8_t addr_map[16] = {
+ MAP_INVALID, /* 0x0: SRAM */
+ MAP_INVALID, /* 0x1: Cached access (see below) */
+ 0x4, 0x5, /* 0x2-0x3 */
+ MAP_INVALID, MAP_INVALID, /* 0x4-0x5 (unmapped: registers) */
+ 0x6, 0x7, 0x8, /* 0x6-0x8 */
+ 0x0, 0x1, 0x2, 0x3, /* 0x9-0xc */
+ 0x1, 0xa, 0x9 /* 0xd-0xf */
+};
+
+/*
+ * AP addr : SCP cache addr
+ * 0x50000000 0x10000000
+ */
+#define CACHE_TRANS_AP_ADDR 0x50000000
+#define CACHE_TRANS_SCP_CACHE_ADDR 0x10000000
+
+void scp_memmap_init(void)
+{
+ /*
+ * Default config, LARGE DRAM not active:
+ * REG32(0xA0001F00) & 0x2000 != 0
+ */
+
+ /*
+ * SCP_REMAP_CFG1
+ * EXT_ADDR3[29:24] remap register for addr msb 31~28 equal to 0x7
+ * EXT_ADDR2[21:16] remap register for addr msb 31~28 equal to 0x6
+ * EXT_ADDR1[13:8] remap register for addr msb 31~28 equal to 0x3
+ * EXT_ADDR0[5:0] remap register for addr msb 31~28 equal to 0x2
+ */
+ SCP_REMAP_CFG1 =
+ (uint32_t)addr_map[0x7] << 24 |
+ (uint32_t)addr_map[0x6] << 16 |
+ (uint32_t)addr_map[0x3] << 8 |
+ (uint32_t)addr_map[0x2];
+
+ /*
+ * SCP_REMAP_CFG2
+ * EXT_ADDR7[29:24] remap register for addr msb 31~28 equal to 0xb
+ * EXT_ADDR6[21:16] remap register for addr msb 31~28 equal to 0xa
+ * EXT_ADDR5[13:8] remap register for addr msb 31~28 equal to 0x9
+ * EXT_ADDR4[5:0] remap register for addr msb 31~28 equal to 0x8
+ */
+ SCP_REMAP_CFG2 =
+ (uint32_t)addr_map[0xb] << 24 |
+ (uint32_t)addr_map[0xa] << 16 |
+ (uint32_t)addr_map[0x9] << 8 |
+ (uint32_t)addr_map[0x8];
+ /*
+ * SCP_REMAP_CFG3
+ * AUD_ADDR[31:28] remap register for addr msb 31~28 equal to 0xd
+ * EXT_ADDR10[21:16]remap register for addr msb 31~28 equal to 0xf
+ * EXT_ADDR9[13:8] remap register for addr msb 31~28 equal to 0xe
+ * EXT_ADDR8[5:0] remap register for addr msb 31~28 equal to 0xc
+ */
+ SCP_REMAP_CFG3 =
+ (uint32_t)addr_map[0xd] << 28 |
+ (uint32_t)addr_map[0xf] << 16 |
+ (uint32_t)addr_map[0xe] << 8 |
+ (uint32_t)addr_map[0xc];
+}
+
+int memmap_ap_to_scp(uintptr_t ap_addr, uintptr_t *scp_addr)
+{
+ int i;
+ uint8_t msb = ap_addr >> SCP_REMAP_ADDR_SHIFT;
+
+ for (i = 0; i < ARRAY_SIZE(addr_map); i++) {
+ if (addr_map[i] != msb)
+ continue;
+
+ *scp_addr = (ap_addr & SCP_REMAP_ADDR_LSB_MASK) |
+ (i << SCP_REMAP_ADDR_SHIFT);
+ return EC_SUCCESS;
+ }
+
+ return EC_ERROR_INVAL;
+}
+
+int memmap_scp_to_ap(uintptr_t scp_addr, uintptr_t *ap_addr)
+{
+ int i = scp_addr >> SCP_REMAP_ADDR_SHIFT;
+
+ if (addr_map[i] == MAP_INVALID)
+ return EC_ERROR_INVAL;
+
+ *ap_addr = (scp_addr & SCP_REMAP_ADDR_LSB_MASK) |
+ (addr_map[i] << SCP_REMAP_ADDR_SHIFT);
+ return EC_SUCCESS;
+}
+
+int memmap_ap_to_scp_cache(uintptr_t ap_addr, uintptr_t *scp_addr)
+{
+ if ((ap_addr & SCP_L1_EXT_ADDR_OTHER_MSB_MASK) != CACHE_TRANS_AP_ADDR)
+ return EC_ERROR_INVAL;
+
+ *scp_addr = CACHE_TRANS_SCP_CACHE_ADDR |
+ (ap_addr & SCP_L1_EXT_ADDR_OTHER_LSB_MASK);
+ return EC_SUCCESS;
+}
+
+int memmap_scp_cache_to_ap(uintptr_t scp_addr, uintptr_t *ap_addr)
+{
+ if ((scp_addr & SCP_L1_EXT_ADDR_OTHER_MSB_MASK) !=
+ CACHE_TRANS_SCP_CACHE_ADDR)
+ return EC_ERROR_INVAL;
+
+ *ap_addr = CACHE_TRANS_AP_ADDR |
+ (scp_addr & SCP_L1_EXT_ADDR_OTHER_LSB_MASK);
+ return EC_SUCCESS;
+}
diff --git a/chip/mt_scp/memmap.h b/chip/mt_scp/memmap.h
new file mode 100644
index 0000000000..fbecb5e8cf
--- /dev/null
+++ b/chip/mt_scp/memmap.h
@@ -0,0 +1,49 @@
+/* Copyright 2018 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * SCP memory map
+ */
+
+#ifndef __CROS_EC_MEMMAP_H
+#define __CROS_EC_MEMMAP_H
+
+void scp_memmap_init(void);
+
+/**
+ * Translate AP addr to SCP addr.
+ *
+ * @param ap_addr AP address to translate
+ * @param scp_addr Tranlated AP address
+ * @return EC_SUCCESS or EC_ERROR_INVAL
+ */
+int memmap_ap_to_scp(uintptr_t ap_addr, uintptr_t *scp_addr);
+
+/**
+ * Translate SCP addr to AP addr.
+ *
+ * @param scp_addr SCP address to tranlate
+ * @param ap_addr Translated SCP address
+ * @return EC_SUCCESS or EC_ERROR_INVAL
+ */
+int memmap_scp_to_ap(uintptr_t scp_addr, uintptr_t *ap_addr);
+
+/**
+ * Translate AP addr to SCP cache addr.
+ *
+ * @param ap_addr AP address to translate
+ * @param scp_addr Tranlated AP cache address
+ * @return EC_SUCCESS or EC_ERROR_INVAL
+ */
+int memmap_ap_to_scp_cache(uintptr_t ap_addr, uintptr_t *scp_addr);
+
+/**
+ * Translate SCP addr to AP addr.
+ *
+ * @param scp_addr SCP cache address to tranlate
+ * @param ap_addr Translated SCP cache address
+ * @return EC_SUCCESS or EC_ERROR_INVAL
+ */
+int memmap_scp_cache_to_ap(uintptr_t scp_addr, uintptr_t *ap_addr);
+
+#endif /* #ifndef __CROS_EC_MEMMAP_H */
diff --git a/chip/mt_scp/registers.h b/chip/mt_scp/registers.h
index 718cc82b02..7c0754b854 100644
--- a/chip/mt_scp/registers.h
+++ b/chip/mt_scp/registers.h
@@ -129,15 +129,43 @@
#define AUTO_DDREN (1 << 18)
/* Memory remap control */
+/*
+ * EXT_ADDR3[29:24] remap register for addr msb 31~28 equal to 0x7
+ * EXT_ADDR2[21:16] remap register for addr msb 31~28 equal to 0x6
+ * EXT_ADDR1[13:8] remap register for addr msb 31~28 equal to 0x3
+ * EXT_ADDR0[5:0] remap register for addr msb 31~28 equal to 0x2
+ */
#define SCP_REMAP_CFG1 REG32(SCP_CFG_BASE + 0x120)
+/*
+ * EXT_ADDR7[29:24] remap register for addr msb 31~28 equal to 0xb
+ * EXT_ADDR6[21:16] remap register for addr msb 31~28 equal to 0xa
+ * EXT_ADDR5[13:8] remap register for addr msb 31~28 equal to 0x9
+ * EXT_ADDR4[5:0] remap register for addr msb 31~28 equal to 0x8
+ */
#define SCP_REMAP_CFG2 REG32(SCP_CFG_BASE + 0x124)
+/*
+ * AUD_ADDR[31:28] remap register for addr msb 31~28 equal to 0xd
+ * EXT_ADDR10[21:16]remap register for addr msb 31~28 equal to 0xf
+ * EXT_ADDR9[13:8] remap register for addr msb 31~28 equal to 0xe
+ * EXT_ADDR8[5:0] remap register for addr msb 31~28 equal to 0xc
+ */
#define SCP_REMAP_CFG3 REG32(SCP_CFG_BASE + 0x128)
+
+#define SCP_REMAP_ADDR_SHIFT 28
+#define SCP_REMAP_ADDR_LSB_MASK ((1 << SCP_REMAP_ADDR_SHIFT) - 1)
+#define SCP_REMAP_ADDR_MSB_MASK ((~0) << SCP_REMAP_ADDR_SHIFT)
+
#define SCP_L1_REMAP_CFG0 REG32(SCP_CFG_BASE + 0x130)
#define SCP_L1_REMAP_CFG1 REG32(SCP_CFG_BASE + 0x130)
#define SCP_L1_REMAP_CFG2 REG32(SCP_CFG_BASE + 0x134)
#define SCP_L1_REMAP_CFG3 REG32(SCP_CFG_BASE + 0x138)
#define SCP_L1_REMAP_OTHER REG32(SCP_CFG_BASE + 0x13C)
+#define SCP_L1_EXT_ADDR_SHIFT 20
+#define SCP_L1_EXT_ADDR_OTHER_SHIFT 28
+#define SCP_L1_EXT_ADDR_OTHER_LSB_MASK ((1 << SCP_REMAP_ADDR_SHIFT) - 1)
+#define SCP_L1_EXT_ADDR_OTHER_MSB_MASK ((~0) << SCP_REMAP_ADDR_SHIFT)
+
/* INTC control */
#define SCP_INTC_BASE (SCP_CFG_BASE + 0x2000)
#define SCP_INTC_IRQ_STATUS REG32(SCP_INTC_BASE)
diff --git a/chip/mt_scp/system.c b/chip/mt_scp/system.c
index 5a341a74e0..f10b79ddb5 100644
--- a/chip/mt_scp/system.c
+++ b/chip/mt_scp/system.c
@@ -10,6 +10,7 @@
#include "flash.h"
#include "hooks.h"
#include "host_command.h"
+#include "memmap.h"
#include "registers.h"
#include "system.h"
#include "task.h"
@@ -184,28 +185,6 @@ static void scp_enable_clock(void)
CG_I2C_M | CG_MAD_M;
}
-static void scp_memmap_init(void)
-{
- /*
- * SCP addr : AP addr
- * 0xA0000000 0x10000000
- * 0xB0000000 0x20000000
- * 0xC0000000 0x30000000
- * 0x20000000 0x40000000
- * 0x30000000 0x50000000
- * 0x60000000 0x60000000
- * 0x70000000 0x70000000
- * 0x80000000 0x80000000
- * 0xF0000000 0x90000000
- *
- * Default config, LARGE DRAM not active:
- * REG32(0xA0001F00) & 0x2000 != 0
- */
- SCP_REMAP_CFG1 = 0x07060504;
- SCP_REMAP_CFG2 = 0x02010008;
- SCP_REMAP_CFG3 = 0x10000A03;
-}
-
void system_pre_init(void)
{
/* SRAM */