diff options
author | Yilun Lin <yllin@google.com> | 2018-12-20 17:05:24 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2019-01-24 00:51:28 -0800 |
commit | fa379e1983ec568e6ca475311af3f77dec9327ff (patch) | |
tree | 431922bd6b7625bf41b19eb55676f3bccbe8d83d /chip | |
parent | 579719f073c3b526d5801a3b0cc886cc8246821f (diff) | |
download | chrome-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.mk | 2 | ||||
-rw-r--r-- | chip/mt_scp/memmap.c | 145 | ||||
-rw-r--r-- | chip/mt_scp/memmap.h | 49 | ||||
-rw-r--r-- | chip/mt_scp/registers.h | 28 | ||||
-rw-r--r-- | chip/mt_scp/system.c | 23 |
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 */ |