1 /*
2 * Copyright (c) 2021-2022 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include "hpm_l1c_drv.h"
9 #include <assert.h>
10
11
12 #define ASSERT_ADDR_SIZE(addr, size) do { \
13 assert(address % HPM_L1C_CACHELINE_SIZE == 0); \
14 assert(size % HPM_L1C_CACHELINE_SIZE == 0); \
15 } while (0)
16
l1c_op(uint8_t opcode,uint32_t address,uint32_t size)17 static void l1c_op(uint8_t opcode, uint32_t address, uint32_t size)
18 {
19 register uint32_t i;
20 register uint32_t next_address;
21 register uint32_t tmp;
22 register uint32_t csr;
23
24 csr = read_clear_csr(CSR_MSTATUS, CSR_MSTATUS_MIE_MASK);
25
26 #define CCTL_VERSION (3U << 18)
27
28 if ((read_csr(CSR_MMSC_CFG) & CCTL_VERSION)) {
29 l1c_cctl_address(address);
30 next_address = address;
31 while ((next_address < (address + size)) && (next_address >= address)) {
32 l1c_cctl_cmd(opcode);
33 next_address = l1c_cctl_get_address();
34 }
35 } else {
36 for (i = 0, tmp = 0; tmp < size; i++) {
37 l1c_cctl_address_cmd(opcode, address + i * HPM_L1C_CACHELINE_SIZE);
38 tmp += HPM_L1C_CACHELINE_SIZE;
39 }
40 }
41
42 write_csr(CSR_MSTATUS, csr);
43 }
44
l1c_dc_enable(void)45 void l1c_dc_enable(void)
46 {
47 if (!l1c_dc_is_enabled()) {
48 clear_csr(CSR_MCACHE_CTL, HPM_MCACHE_CTL_DC_WAROUND_MASK);
49 set_csr(CSR_MCACHE_CTL,
50 #ifdef L1C_DC_WAROUND_VALUE
51 HPM_MCACHE_CTL_DC_WAROUND(L1C_DC_WAROUND_VALUE) |
52 #endif
53 HPM_MCACHE_CTL_DPREF_EN_MASK
54 | HPM_MCACHE_CTL_DC_EN_MASK);
55 }
56 }
57
l1c_dc_disable(void)58 void l1c_dc_disable(void)
59 {
60 if (l1c_dc_is_enabled()) {
61 clear_csr(CSR_MCACHE_CTL, HPM_MCACHE_CTL_DC_EN_MASK);
62 }
63 }
64
l1c_ic_enable(void)65 void l1c_ic_enable(void)
66 {
67 if (!l1c_ic_is_enabled()) {
68 set_csr(CSR_MCACHE_CTL, HPM_MCACHE_CTL_IPREF_EN_MASK
69 | HPM_MCACHE_CTL_CCTL_SUEN_MASK
70 | HPM_MCACHE_CTL_IC_EN_MASK);
71 }
72 }
73
l1c_ic_disable(void)74 void l1c_ic_disable(void)
75 {
76 if (l1c_ic_is_enabled()) {
77 clear_csr(CSR_MCACHE_CTL, HPM_MCACHE_CTL_IC_EN_MASK);
78 }
79 }
80
l1c_fence_i(void)81 void l1c_fence_i(void)
82 {
83 __asm("fence.i");
84 }
85
l1c_dc_invalidate_all(void)86 void l1c_dc_invalidate_all(void)
87 {
88 l1c_cctl_cmd(HPM_L1C_CCTL_CMD_L1D_INVAL_ALL);
89 }
90
l1c_dc_writeback_all(void)91 void l1c_dc_writeback_all(void)
92 {
93 l1c_cctl_cmd(HPM_L1C_CCTL_CMD_L1D_WB_ALL);
94 }
95
l1c_dc_flush_all(void)96 void l1c_dc_flush_all(void)
97 {
98 l1c_cctl_cmd(HPM_L1C_CCTL_CMD_L1D_WBINVAL_ALL);
99 }
100
l1c_dc_fill_lock(uint32_t address,uint32_t size)101 void l1c_dc_fill_lock(uint32_t address, uint32_t size)
102 {
103 ASSERT_ADDR_SIZE(address, size);
104 l1c_op(HPM_L1C_CCTL_CMD_L1D_VA_LOCK, address, size);
105 }
106
l1c_dc_invalidate(uint32_t address,uint32_t size)107 void l1c_dc_invalidate(uint32_t address, uint32_t size)
108 {
109 ASSERT_ADDR_SIZE(address, size);
110 l1c_op(HPM_L1C_CCTL_CMD_L1D_VA_INVAL, address, size);
111 }
112
l1c_dc_writeback(uint32_t address,uint32_t size)113 void l1c_dc_writeback(uint32_t address, uint32_t size)
114 {
115 ASSERT_ADDR_SIZE(address, size);
116 l1c_op(HPM_L1C_CCTL_CMD_L1D_VA_WB, address, size);
117 }
118
l1c_dc_flush(uint32_t address,uint32_t size)119 void l1c_dc_flush(uint32_t address, uint32_t size)
120 {
121 ASSERT_ADDR_SIZE(address, size);
122 l1c_op(HPM_L1C_CCTL_CMD_L1D_VA_WBINVAL, address, size);
123 }
124
l1c_ic_invalidate(uint32_t address,uint32_t size)125 void l1c_ic_invalidate(uint32_t address, uint32_t size)
126 {
127 ASSERT_ADDR_SIZE(address, size);
128 l1c_op(HPM_L1C_CCTL_CMD_L1I_VA_INVAL, address, size);
129 }
130
l1c_ic_fill_lock(uint32_t address,uint32_t size)131 void l1c_ic_fill_lock(uint32_t address, uint32_t size)
132 {
133 ASSERT_ADDR_SIZE(address, size);
134 l1c_op(HPM_L1C_CCTL_CMD_L1I_VA_LOCK, address, size);
135 }
136