1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
/* Copyright 2020 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.
*/
#include "cache.h"
#include "registers.h"
#include "stdint.h"
/*
* Map SCP address (bits 31~28) to AP address
*
* SCP address AP address Note
*
* 0x0000_0000 SRAM
* 0x1000_0000 0x5000_0000 CPU DRAM
* 0x2000_0000 0x7000_0000
* 0x3000_0000
*
* 0x4000_0000
* 0x5000_0000 0x0000_0000
* 0x6000_0000 0x1000_0000
* 0x7000_0000 0xa000_0000
*
* 0x8000_0000
* 0x9000_0000 0x8000_0000
* 0xa000_0000 0x9000_0000
* 0xb000_0000
*
* 0xc000_0000 0x8000_0000
* 0xd000_0000 0x2000_0000
* 0xe000_0000 0x3000_0000
* 0xf000_0000 0x6000_0000
*/
#define REMAP_ADDR_SHIFT 28
#define REMAP_ADDR_LSB_MASK (BIT(REMAP_ADDR_SHIFT) - 1)
#define REMAP_ADDR_MSB_MASK ((~0) << REMAP_ADDR_SHIFT)
#define MAP_INVALID 0xff
static const uint8_t addr_map[16] = {
MAP_INVALID, /* SRAM */
0x5, /* ext_addr_0x1 */
0x7, /* ext_addr_0x2 */
MAP_INVALID, /* no ext_addr_0x3 */
MAP_INVALID, /* no ext_addr_0x4 */
0x0, /* ext_addr_0x5 */
0x1, /* ext_addr_0x6 */
0xa, /* ext_addr_0x7 */
MAP_INVALID, /* no ext_addr_0x8 */
0x8, /* ext_addr_0x9 */
0x9, /* ext_addr_0xa */
MAP_INVALID, /* no ext_addr_0xb */
0x8, /* ext_addr_0xc */
0x2, /* ext_addr_0xd */
0x3, /* ext_addr_0xe */
0x6, /* ext_addr_0xf */
};
void memmap_init(void)
{
SCP_R_REMAP_0X0123 =
(uint32_t)addr_map[0x1] << 8 |
(uint32_t)addr_map[0x2] << 16;
SCP_R_REMAP_0X4567 =
(uint32_t)addr_map[0x5] << 8 |
(uint32_t)addr_map[0x6] << 16 |
(uint32_t)addr_map[0x7] << 24;
SCP_R_REMAP_0X89AB =
(uint32_t)addr_map[0x9] << 8 |
(uint32_t)addr_map[0xa] << 16;
SCP_R_REMAP_0XCDEF =
(uint32_t)addr_map[0xc] |
(uint32_t)addr_map[0xd] << 8 |
(uint32_t)addr_map[0xe] << 16 |
(uint32_t)addr_map[0xf] << 24;
cache_init();
}
int memmap_ap_to_scp(uintptr_t ap_addr, uintptr_t *scp_addr)
{
int i;
uint8_t msb = ap_addr >> REMAP_ADDR_SHIFT;
for (i = 0; i < ARRAY_SIZE(addr_map); ++i) {
if (addr_map[i] != msb)
continue;
*scp_addr = (ap_addr & REMAP_ADDR_LSB_MASK) |
(i << 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 >> REMAP_ADDR_SHIFT;
if (addr_map[i] == MAP_INVALID)
return EC_ERROR_INVAL;
*ap_addr = (scp_addr & REMAP_ADDR_LSB_MASK) |
(addr_map[i] << REMAP_ADDR_SHIFT);
return EC_SUCCESS;
}
|