blob: dd2451718d0090b4ea669ec6afe29c9d0e5ad43f (
plain)
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Copyright (C) 2024 Andes Technology Corporation
*/
#ifndef _RISCV_ANDES_H
#define _RISCV_ANDES_H
#include <sbi/sbi_bitops.h>
#include <sbi/sbi_scratch.h>
/* Memory and Miscellaneous Registers */
#define CSR_MPFT_CTL 0x7c5
#define CSR_MCACHE_CTL 0x7ca
#define CSR_MCCTLCOMMAND 0x7cc
#define CSR_MMISC_CTL 0x7d0
/* Configuration Control & Status Registers */
#define CSR_MICM_CFG 0xfc0
#define CSR_MDCM_CFG 0xfc1
#define CSR_MMSC_CFG 0xfc2
/* Trap Related Registers */
#define CSR_MXSTATUS 0x7c4
#define CSR_MSLIDELEG 0x7d5
#define CSR_SLIE 0x9c4
#define CSR_SLIP 0x9c5
/* Counter Related Registers */
#define CSR_MCOUNTERWEN 0x7ce
#define CSR_MCOUNTERINTEN 0x7cf
#define CSR_MCOUNTERMASK_M 0x7d1
#define CSR_MCOUNTERMASK_S 0x7d2
#define CSR_MCOUNTERMASK_U 0x7d3
#define CSR_MCOUNTEROVF 0x7d4
/* PMA Related Registers */
#define CSR_PMACFG0 0xbc0
#define CSR_PMAADDR0 0xbd0
#define MICM_CFG_ISZ_OFFSET 6
#define MICM_CFG_ISZ_MASK (7 << MICM_CFG_ISZ_OFFSET)
#define MDCM_CFG_DSZ_OFFSET 6
#define MDCM_CFG_DSZ_MASK (7 << MDCM_CFG_DSZ_OFFSET)
#define MMSC_CFG_CCTLCSR_OFFSET 16
#define MMSC_CFG_CCTLCSR_MASK (1 << MMSC_CFG_CCTLCSR_OFFSET)
#define MMSC_CFG_PPMA_OFFSET 30
#define MMSC_CFG_PPMA_MASK (1 << MMSC_CFG_PPMA_OFFSET)
#define MMSC_IOCP_OFFSET 47
#define MMSC_IOCP_MASK (1ULL << MMSC_IOCP_OFFSET)
#define MCACHE_CTL_IC_EN_MASK BIT(0)
#define MCACHE_CTL_DC_EN_MASK BIT(1)
#define MCACHE_CTL_CCTL_SUEN_OFFSET 8
#define MCACHE_CTL_CCTL_SUEN_MASK (1 << MCACHE_CTL_CCTL_SUEN_OFFSET)
#define MCACHE_CTL_DC_COHEN_MASK BIT(19)
#define MCACHE_CTL_DC_COHSTA_MASK BIT(20)
/* Performance monitor */
#define MMSC_CFG_PMNDS_MASK (1 << 15)
#define MIP_PMOVI (1 << 18)
/* Cache control commands */
#define MCCTLCOMMAND_L1D_WBINVAL_ALL 6
/* AE350 platform specific sleep types */
#define SBI_SUSP_AE350_LIGHT_SLEEP SBI_SUSP_PLATFORM_SLEEP_START
#ifndef __ASSEMBLER__
#define is_andes(series) \
({ \
char value = csr_read(CSR_MARCHID) & 0xff; \
(series) == (value >> 4) * 10 + (value & 0x0f); \
})
#define has_andes_pmu() \
({ \
(((csr_read(CSR_MMSC_CFG) & \
MMSC_CFG_PMNDS_MASK) \
&& misa_extension('S')) ? true : false); \
})
#endif /* __ASSEMBLER__ */
struct andes_hart_data {
unsigned long mcache_ctl;
unsigned long mmisc_ctl;
unsigned long mpft_ctl;
unsigned long mslideleg;
unsigned long mxstatus;
unsigned long slie;
unsigned long slip;
unsigned long pmacfg0;
unsigned long pmacfg2;
unsigned long pmaaddrX[16];
};
void ae350_non_ret_save(struct sbi_scratch *scratch);
void ae350_non_ret_restore(struct sbi_scratch *scratch);
void ae350_enable_coherency_warmboot(void);
/*
* On Andes 4X-series CPUs, disabling the L1 data cache causes the CPU to fetch
* data directly from RAM. However, L1 cache flushes write data back to the
* Last Level Cache (LLC). This discrepancy can lead to return address
* corruption on the stack. To prevent this, the following functions must
* be inlined.
*/
static inline void ae350_disable_coherency(void)
{
/*
* To disable cache coherency of a core in AE350 platform, follow below steps:
*
* 1) Disable I/D-Cache
* 2) Write back and invalidate D-Cache
* 3) Disable D-Cache coherency
* 4) Wait for D-Cache disengaged from the coherence management
*/
csr_clear(CSR_MCACHE_CTL, MCACHE_CTL_IC_EN_MASK | MCACHE_CTL_DC_EN_MASK);
csr_write(CSR_MCCTLCOMMAND, MCCTLCOMMAND_L1D_WBINVAL_ALL);
csr_clear(CSR_MCACHE_CTL, MCACHE_CTL_DC_COHEN_MASK);
while (csr_read(CSR_MCACHE_CTL) & MCACHE_CTL_DC_COHSTA_MASK)
;
}
static inline void ae350_enable_coherency(void)
{
/*
* To enable cache coherency of a core in AE350 platform, follow below steps:
*
* 1) Enable D-Cache coherency
* 2) Wait for D-Cache engaging in the coherence management
* 3) Enable I/D-Cache
*/
csr_set(CSR_MCACHE_CTL, MCACHE_CTL_DC_COHEN_MASK);
/*
* mcache_ctl.DC_COHEN is hardwired to 0 if there is no coherence
* manager. In such situation, just enable the I/D-Cache to prevent
* permanently being stuck in the while loop.
*/
if (csr_read(CSR_MCACHE_CTL) & MCACHE_CTL_DC_COHEN_MASK)
while (!(csr_read(CSR_MCACHE_CTL) & MCACHE_CTL_DC_COHSTA_MASK))
;
csr_set(CSR_MCACHE_CTL, MCACHE_CTL_IC_EN_MASK | MCACHE_CTL_DC_EN_MASK);
}
#endif /* _RISCV_ANDES_H */
|