1/***************************************************************************//**
2 * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
3 *
4 * SPDX-License-Identifier: MIT
5 *
6 * MPFS HAL Embedded Software
7 *
8 * Hardware registers access functions.
9 * The implementation of these function is platform and toolchain specific.
10 * The functions declared here are implemented using assembler as part of the
11 * processor/toolchain specific HAL.
12 *
13 */
14
15.section .text
16    .globl HW_set_32bit_reg
17    .globl HW_get_32bit_reg
18    .globl HW_set_32bit_reg_field
19    .globl HW_get_32bit_reg_field
20    .globl HW_set_16bit_reg
21    .globl HW_get_16bit_reg
22    .globl HW_set_16bit_reg_field
23    .globl HW_get_16bit_reg_field
24    .globl HW_set_8bit_reg
25    .globl HW_get_8bit_reg
26    .globl HW_set_8bit_reg_field
27    .globl HW_get_8bit_reg_field
28
29
30/***************************************************************************//**
31 * HW_set_32bit_reg is used to write the content of a 32 bits wide peripheral
32 * register.
33 *
34 * a0:   addr_t reg_addr
35 * a1:   uint32_t value
36 */
37HW_set_32bit_reg:
38    sw a1, 0(a0)
39    ret
40
41/***************************************************************************//**
42 * HW_get_32bit_reg is used to read the content of a 32 bits wide peripheral
43 * register.
44 *
45 * a0:   addr_t reg_addr
46
47 * @return          32 bits value read from the peripheral register.
48 */
49HW_get_32bit_reg:
50    lw a0, 0(a0)
51    ret
52
53/***************************************************************************//**
54 * HW_set_32bit_reg_field is used to set the content of a field in a 32 bits
55 * wide peripheral register.
56 *
57 * a0:   addr_t reg_addr
58 * a1:   int_fast8_t shift
59 * a2:   uint32_t mask
60 * a3:   uint32_t value
61 */
62HW_set_32bit_reg_field:
63    mv t3, a3
64    sll t3, t3, a1
65    and  t3, t3, a2
66    lw t1, 0(a0)
67    mv t2, a2
68    not t2, t2
69    and t1, t1, t2
70    or t1, t1, t3
71    sw t1, 0(a0)
72    ret
73
74/***************************************************************************//**
75 * HW_get_32bit_reg_field is used to read the content of a field out of a
76 * 32 bits wide peripheral register.
77 *
78 * a0:   addr_t reg_addr
79 * a1:   int_fast8_t shift
80 * a2:   uint32_t mask
81 *
82 * @return          32 bits value containing the register field value specified
83 *                  as parameter.
84 */
85HW_get_32bit_reg_field:
86    lw a0, 0(a0)
87    and a0, a0, a2
88    srl a0, a0, a1
89    ret
90
91/***************************************************************************//**
92 * HW_set_16bit_reg is used to write the content of a 16 bits wide peripheral
93 * register.
94 *
95 * a0:   addr_t reg_addr
96 * a1:   uint_fast16_t value
97 */
98HW_set_16bit_reg:
99    sh a1, 0(a0)
100    ret
101
102/***************************************************************************//**
103 * HW_get_16bit_reg is used to read the content of a 16 bits wide peripheral
104 * register.
105 *
106 * a0:   addr_t reg_addr
107
108 * @return          16 bits value read from the peripheral register.
109 */
110HW_get_16bit_reg:
111    lh a0, (a0)
112    ret
113
114/***************************************************************************//**
115 * HW_set_16bit_reg_field is used to set the content of a field in a 16 bits
116 * wide peripheral register.
117 *
118 * a0:   addr_t reg_addr
119 * a1:   int_fast8_t shift
120 * a2:   uint_fast16_t mask
121 * a3:   uint_fast16_t value
122 * @param value     Value to be written in the specified field.
123 */
124HW_set_16bit_reg_field:
125    mv t3, a3
126    sll t3, t3, a1
127    and  t3, t3, a2
128    lh t1, 0(a0)
129    mv t2, a2
130    not t2, t2
131    and t1, t1, t2
132    or t1, t1, t3
133    sh t1, 0(a0)
134    ret
135
136/***************************************************************************//**
137 * HW_get_16bit_reg_field is used to read the content of a field from a
138 * 16 bits wide peripheral register.
139 *
140 * a0:   addr_t reg_addr
141 * a1:   int_fast8_t shift
142 * a2:   uint_fast16_t mask
143 *
144 * @return          16 bits value containing the register field value specified
145 *                  as parameter.
146 */
147HW_get_16bit_reg_field:
148    lh a0, 0(a0)
149    and a0, a0, a2
150    srl a0, a0, a1
151    ret
152
153/***************************************************************************//**
154 * HW_set_8bit_reg is used to write the content of a 8 bits wide peripheral
155 * register.
156 *
157 * a0:   addr_t reg_addr
158 * a1:   uint_fast8_t value
159 */
160HW_set_8bit_reg:
161    sb a1, 0(a0)
162    ret
163
164/***************************************************************************//**
165 * HW_get_8bit_reg is used to read the content of a 8 bits wide peripheral
166 * register.
167 *
168 * a0:   addr_t reg_addr
169
170 * @return          8 bits value read from the peripheral register.
171 */
172HW_get_8bit_reg:
173    lb a0, 0(a0)
174    ret
175
176/***************************************************************************//**
177 * HW_set_8bit_reg_field is used to set the content of a field in a 8 bits
178 * wide peripheral register.
179 *
180 * a0:   addr_t reg_addr,
181 * a1:   int_fast8_t shift
182 * a2:   uint_fast8_t mask
183 * a3:   uint_fast8_t value
184 */
185HW_set_8bit_reg_field:
186    mv t3, a3
187    sll t3, t3, a1
188    and  t3, t3, a2
189    lb t1, 0(a0)
190    mv t2, a2
191    not t2, t2
192    and t1, t1, t2
193    or t1, t1, t3
194    sb t1, 0(a0)
195    ret
196
197/***************************************************************************//**
198 * HW_get_8bit_reg_field is used to read the content of a field from a
199 * 8 bits wide peripheral register.
200 *
201 * a0:   addr_t reg_addr
202 * a1:   int_fast8_t shift
203 * a2:   uint_fast8_t mask
204 *
205 * @return          8 bits value containing the register field value specified
206 *                  as parameter.
207 */
208HW_get_8bit_reg_field:
209    lb a0, 0(a0)
210    and a0, a0, a2
211    srl a0, a0, a1
212    ret
213
214.end
215