1 /*
2  * Copyright (c) 2018 - 2019 Antmicro <www.antmicro.com>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef __RISCV32_LITEX_VEXRISCV_SOC_H_
8 #define __RISCV32_LITEX_VEXRISCV_SOC_H_
9 
10 #include <zephyr/devicetree.h>
11 #include <zephyr/arch/riscv/sys_io.h>
12 
13 #ifndef _ASMLANGUAGE
14 /* CSR access helpers */
15 
litex_read8(unsigned long addr)16 static inline unsigned char litex_read8(unsigned long addr)
17 {
18 #if CONFIG_LITEX_CSR_DATA_WIDTH >= 8
19 	return sys_read8(addr);
20 #else
21 #error CSR data width less than 8
22 #endif
23 }
24 
litex_read16(unsigned long addr)25 static inline unsigned short litex_read16(unsigned long addr)
26 {
27 #if CONFIG_LITEX_CSR_DATA_WIDTH == 8
28 	return (sys_read8(addr) << 8)
29 		| sys_read8(addr + 0x4);
30 #elif CONFIG_LITEX_CSR_DATA_WIDTH >= 16
31 	return sys_read16(addr);
32 #else
33 #error Unsupported CSR data width
34 #endif
35 }
36 
litex_read32(unsigned long addr)37 static inline unsigned int litex_read32(unsigned long addr)
38 {
39 #if CONFIG_LITEX_CSR_DATA_WIDTH == 8
40 	return (sys_read8(addr) << 24)
41 		| (sys_read8(addr + 0x4) << 16)
42 		| (sys_read8(addr + 0x8) << 8)
43 		| sys_read8(addr + 0xc);
44 #elif CONFIG_LITEX_CSR_DATA_WIDTH >= 32
45 	return sys_read32(addr);
46 #else
47 #error Unsupported CSR data width
48 #endif
49 }
50 
litex_read64(unsigned long addr)51 static inline uint64_t litex_read64(unsigned long addr)
52 {
53 #if CONFIG_LITEX_CSR_DATA_WIDTH == 8
54 	return (((uint64_t)sys_read8(addr)) << 56)
55 		| ((uint64_t)sys_read8(addr + 0x4) << 48)
56 		| ((uint64_t)sys_read8(addr + 0x8) << 40)
57 		| ((uint64_t)sys_read8(addr + 0xc) << 32)
58 		| ((uint64_t)sys_read8(addr + 0x10) << 24)
59 		| ((uint64_t)sys_read8(addr + 0x14) << 16)
60 		| ((uint64_t)sys_read8(addr + 0x18) << 8)
61 		| (uint64_t)sys_read8(addr + 0x1c);
62 #elif CONFIG_LITEX_CSR_DATA_WIDTH == 32
63 	return ((uint64_t)sys_read32(addr) << 32) | (uint64_t)sys_read32(addr + 0x4);
64 #elif CONFIG_LITEX_CSR_DATA_WIDTH >= 64
65 	return sys_read64(addr);
66 #else
67 #error Unsupported CSR data width
68 #endif
69 }
70 
litex_write8(unsigned char value,unsigned long addr)71 static inline void litex_write8(unsigned char value, unsigned long addr)
72 {
73 #if CONFIG_LITEX_CSR_DATA_WIDTH >= 8
74 	sys_write8(value, addr);
75 #else
76 #error CSR data width less than 8
77 #endif
78 }
79 
litex_write16(unsigned short value,unsigned long addr)80 static inline void litex_write16(unsigned short value, unsigned long addr)
81 {
82 #if CONFIG_LITEX_CSR_DATA_WIDTH == 8
83 	sys_write8(value >> 8, addr);
84 	sys_write8(value, addr + 0x4);
85 #elif CONFIG_LITEX_CSR_DATA_WIDTH >= 16
86 	sys_write16(value, addr);
87 #else
88 #error Unsupported CSR data width
89 #endif
90 }
91 
litex_write32(unsigned int value,unsigned long addr)92 static inline void litex_write32(unsigned int value, unsigned long addr)
93 {
94 #if CONFIG_LITEX_CSR_DATA_WIDTH == 8
95 	sys_write8(value >> 24, addr);
96 	sys_write8(value >> 16, addr + 0x4);
97 	sys_write8(value >> 8, addr + 0x8);
98 	sys_write8(value, addr + 0xC);
99 #elif CONFIG_LITEX_CSR_DATA_WIDTH >= 32
100 	sys_write32(value, addr);
101 #else
102 #error Unsupported CSR data width
103 #endif
104 }
105 
litex_write64(uint64_t value,unsigned long addr)106 static inline void litex_write64(uint64_t value, unsigned long addr)
107 {
108 #if CONFIG_LITEX_CSR_DATA_WIDTH == 8
109 	sys_write8(value >> 56, addr);
110 	sys_write8(value >> 48, addr + 0x4);
111 	sys_write8(value >> 40, addr + 0x8);
112 	sys_write8(value >> 32, addr + 0xC);
113 	sys_write8(value >> 24, addr + 0x10);
114 	sys_write8(value >> 16, addr + 0x14);
115 	sys_write8(value >> 8, addr + 0x18);
116 	sys_write8(value, addr + 0x1C);
117 #elif CONFIG_LITEX_CSR_DATA_WIDTH == 32
118 	sys_write32(value >> 32, addr);
119 	sys_write32(value, addr + 0x4);
120 #elif CONFIG_LITEX_CSR_DATA_WIDTH >= 64
121 	sys_write64(value, addr);
122 #else
123 #error Unsupported CSR data width
124 #endif
125 }
126 
127 /*
128  * Operates on uint32_t values only
129  * Size is in bytes and meaningful are 1, 2 or 4
130  * Address must be aligned to 4 bytes
131  */
litex_write(uint32_t addr,uint32_t size,uint32_t value)132 static inline void litex_write(uint32_t addr, uint32_t size, uint32_t value)
133 {
134 	switch (size) {
135 	case 1:
136 		litex_write8(value, addr);
137 		break;
138 	case 2:
139 		litex_write16(value, addr);
140 		break;
141 	case 4:
142 		litex_write32(value, addr);
143 		break;
144 	default:
145 		break;
146 	}
147 }
148 
149 /*
150  * Operates on uint32_t values only
151  * Size is in bytes and meaningful are 1, 2 or 4
152  * Address must be aligned to 4 bytes
153  */
litex_read(uint32_t addr,uint32_t size)154 static inline uint32_t litex_read(uint32_t addr, uint32_t size)
155 {
156 	switch (size) {
157 	case 1:
158 		return litex_read8(addr);
159 	case 2:
160 		return litex_read16(addr);
161 	case 4:
162 		return litex_read32(addr);
163 	default:
164 		return 0;
165 	}
166 }
167 
168 #endif /* _ASMLANGUAGE */
169 
170 #endif /* __RISCV32_LITEX_VEXRISCV_SOC_H_ */
171