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