xref: /netbsd-src/sys/arch/riscv/riscv/bus_space_generic.S (revision 6f60f891c42d9b2faeefeb7252ae193c785ed546)
1/*	$NetBSD: bus_space_generic.S,v 1.5 2024/07/13 15:20:55 skrll Exp $	*/
2
3/*-
4 * Copyright (c) 2022 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Nick Hudson
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32
33#include <riscv/asm.h>
34#include "assym.h"
35
36RCSID("$NetBSD: bus_space_generic.S,v 1.5 2024/07/13 15:20:55 skrll Exp $")
37
38
39/* void bs_c_1(a0: tag, a1: src, srcoffset, dst, dstoffset, count); */
40/* void bs_c_2(a0: tag, a1: src, srcoffset, dst, dstoffset, count); */
41/* void bs_c_4(a0: tag, a1: src, srcoffset, dst, dstoffset, count); */
42/* void bs_c_8(a0: tag, a1: src, srcoffset, dst, dstoffset, count); */
43
44/* void bs_sr_1(a0: tag, a1: addr, a2: offset, a3: value, a4: count); */
45/* void bs_sr_2(a0: tag, a1: addr, a2: offset, a3: value, a4: count); */
46/* void bs_sr_4(a0: tag, a1: addr, a2: offset, a3: value, a4: count); */
47/* void bs_sr_8(a0: tag, a1: addr, a2: offset, a3: value, a4: count); */
48
49
50/* uint8_t bs_r_1(a0: tag, a1: addr, a2: offset); */
51ENTRY_NP(generic_bs_r_1)
52	PTR_L	a5, BS_STRIDE(a0)	/* stride */
53	PTR_SLL	a2, a2, a5		/* offset <<= stride */
54	PTR_ADD	a2, a2, a1		/* add to address */
55	lbu	a0, 0(a2)		/* load 8-bit */
56	ret
57END(generic_bs_r_1)
58
59
60/* uint16_t bs_r_2(a0: tag, a1: addr, a2: offset); */
61ENTRY_NP(generic_bs_r_2)
62	PTR_L	a5, BS_STRIDE(a0)	/* stride */
63	PTR_SLL	a2, a2, a5		/* offset <<= stride */
64	PTR_ADD	a2, a2, a1		/* add to address */
65	lhu	a0, 0(a2)		/* load 16-bit */
66	ret
67END(generic_bs_r_2)
68
69
70/* uint32_t bs_r_4(a0: tag, a1: addr, a2: offset); */
71ENTRY_NP(generic_bs_r_4)
72	PTR_L	a5, BS_STRIDE(a0)	/* stride */
73	PTR_SLL	a2, a2, a5		/* offset <<= stride */
74	PTR_ADD	a2, a2, a1		/* add to address */
75	lw	a0, 0(a2)		/* load 32-bit */
76	ret
77END(generic_bs_r_4)
78
79
80#ifdef _LP64
81/* uint64_t bs_r_8(a0: tag, a1: addr, a2: offset); */
82ENTRY_NP(generic_bs_r_8)
83	PTR_L	a5, BS_STRIDE(a0)	/* stride */
84	PTR_SLL	a2, a2, a5		/* offset <<= stride */
85	PTR_ADD	a2, a2, a1		/* add to address */
86	ld	a0, 0(a2)		/* load 64-bit */
87	ret
88END(generic_bs_r_8)
89#endif
90
91
92/* void bs_rm_1(a0: tag, a1: addr, a2: offset, a3: datap, a4: count); */
93ENTRY_NP(generic_bs_rm_1)
94#ifdef DIAGNOSTIC
95	beqz	a4, 2f
96#endif
97	PTR_L	a5, BS_STRIDE(a0)	/* stride */
98	PTR_SLL	a2, a2, a5		/* offset <<= stride */
99	PTR_ADD	a2, a2, a1		/* add to address */
1001:
101	lbu	a0, 0(a2)		/* load 8-bit */
102	sb	a0, 0(a3)
103	add	a3, a3, 1
104	add	a4, a4, -1		/* count-- */
105	bnez	a4, 1b
106	ret
1072:
108	la	a0, 3f
109	tail	_C_LABEL(panic)
1103:
111	.asciz	"_bs_rm_1: count == 0"
112END(generic_bs_rm_1)
113
114
115/* void bs_rm_2(a0: tag, a1: addr, a2: offset, a3: datap, a4: count); */
116ENTRY_NP(generic_bs_rm_2)
117#ifdef DIAGNOSTIC
118	beqz	a4, 2f
119#endif
120	PTR_L	a5, BS_STRIDE(a0)	/* stride */
121	PTR_SLL	a2, a2, a5		/* offset <<= stride */
122	PTR_ADD	a2, a2, a1		/* add to address */
1231:
124	lhu	a0, 0(a2)		/* load 16-bit */
125	sh	a0, 0(a3)		/* store 16-bit */
126	add	a3, a3, 2
127	add	a4, a4, -1		/* count-- */
128	bnez	a4, 1b
129	ret
1302:
131	la	a0, 3f
132	tail	_C_LABEL(panic)
1333:
134	.asciz	"_bs_rm_2: count == 0"
135END(generic_bs_rm_2)
136
137
138/* void bs_rm_4(a0: tag, a1: addr, a2: offset, a3: datap, a4: count); */
139ENTRY_NP(generic_bs_rm_4)
140#ifdef DIAGNOSTIC
141	beqz	a4, 2f
142#endif
143	PTR_L	a5, BS_STRIDE(a0)	/* stride */
144	PTR_SLL	a2, a2, a5		/* offset <<= stride */
145	PTR_ADD	a2, a2, a1		/* add to address */
1461:
147	lw	a0, 0(a2)		/* load 32-bit */
148	sw	a0, 0(a3)		/* store 32-bit */
149	add	a3, a3, 4
150	add	a4, a4, -1		/* count-- */
151	bnez	a4, 1b
152	ret
1532:
154	la	a0, 3f
155	tail	_C_LABEL(panic)
1563:
157	.asciz	"_bs_rm_4: count == 0"
158END(generic_bs_rm_4)
159
160
161#ifdef _LP64
162/* void bs_rm_8(a0: tag, a1: addr, a2: offset, a3: datap, a4: count); */
163ENTRY_NP(generic_bs_rm_8)
164#ifdef DIAGNOSTIC
165	beqz	a4, 2f
166#endif
167	PTR_L	a5, BS_STRIDE(a0)	/* stride */
168	PTR_SLL	a2, a2, a5		/* offset <<= stride */
169	PTR_ADD	a2, a2, a1		/* add to address */
1701:
171	ld	a0, 0(a2)		/* load 64-bit */
172	sd	a0, 0(a3)		/* store 64-bit */
173	add	a3, a3, 8
174	add	a4, a4, -1		/* count-- */
175	bnez	a4, 1b
176	ret
1772:
178	la	a0, 3f
179	tail	_C_LABEL(panic)
1803:
181	.asciz	"_bs_rm_8: count == 0"
182END(generic_bs_rm_8)
183#endif
184
185
186/* void bs_rr_1(a0: tag, a1: addr, a2: offset, a3: datap, a4: count); */
187ENTRY_NP(generic_bs_rr_1)
188#ifdef DIAGNOSTIC
189	beqz	a4, 2f
190#endif
191	PTR_L	a5, BS_STRIDE(a0)	/* stride */
192	li	t0, 1
193	srl	t0, t0, a5		/* delta = 1 << stride */
194	PTR_SLL	a2, a2, a5		/* offset <<= stride */
195	PTR_ADD	a2, a2, a1		/* add to address */
1961:
197	lbu	a0, 0(a2)		/* load 8-bit */
198	sb	a0, 0(a3)		/* *dst = value */
199	add	a2, a2, t0		/* src += delta */
200	add	a3, a3, 1		/* dst++ */
201	add	a4, a4, -1		/* count-- */
202	bnez	a4, 1b
203	ret
2042:
205	la	a0, 3f
206	tail	_C_LABEL(panic)
2073:
208	.asciz	"_bs_rr_1: count == 0"
209END(generic_bs_rr_1)
210
211
212/* void bs_rr_2(a0: tag, a1: addr, a2: offset, a3: datap, a4: count); */
213ENTRY_NP(generic_bs_rr_2)
214#ifdef DIAGNOSTIC
215	beqz	a4, 2f
216#endif
217	PTR_L	a5, BS_STRIDE(a0)	/* stride */
218	li	t0, 1
219	srl	t0, t0, a5		/* delta = 1 << stride */
220// if (delta < 2)
221//     delta = 2
222
223
224	PTR_SLL	a2, a2, a5		/* offset <<= stride */
225	PTR_ADD	a2, a2, a1		/* add to address */
2261:
227	lhu	a0, 0(a2)		/* load 16-bit */
228	sh	a0, 0(a3)		/* *dst = value */
229	add	a2, a2, t0		/* src += delta */
230	add	a3, a3, 2		/* dst++ */
231	add	a4, a4, -1		/* count-- */
232	bnez	a4, 1b
233	ret
2342:
235	la	a0, 3f
236	tail	_C_LABEL(panic)
2373:
238	.asciz	"_bs_rr_2: count == 0"
239END(generic_bs_rr_2)
240
241
242/* void bs_rr_4(a0: tag, a1: addr, a2: offset, a3: datap, a4: count); */
243/* void bs_rr_8(a0: tag, a1: addr, a2: offset, a3: datap, a4: count); */
244
245
246
247/* void bs_w_1(a0: tag, a1: addr, a2: offset, a3: value); */
248ENTRY_NP(generic_bs_w_1)
249	PTR_L	a5, BS_STRIDE(a0)	/* stride */
250	PTR_SLL	a2, a2, a5		/* offset <<= stride */
251	PTR_ADD	a2, a2, a1		/* add to address */
252	sb	a3, 0(a2)		/* store 8-bit */
253	ret
254END(generic_bs_w_1)
255
256
257/* void bs_w_2(a0: tag, a1: addr, a2: offset, a3: value); */
258ENTRY_NP(generic_bs_w_2)
259	PTR_L	a5, BS_STRIDE(a0)	/* stride */
260	PTR_SLL	a2, a2, a5		/* offset <<= stride */
261	PTR_ADD	a2, a2, a1		/* add to address */
262	sh	a3, 0(a2)		/* store 16-bit */
263	ret
264END(generic_bs_w_2)
265
266
267/* void bs_w_4(a0: tag, a1: addr, a2: offset, a3: value); */
268ENTRY_NP(generic_bs_w_4)
269	PTR_L	a5, BS_STRIDE(a0)	/* stride */
270	PTR_SLL	a2, a2, a5		/* offset <<= stride */
271	PTR_ADD	a2, a2, a1		/* add to address */
272	sw	a3, 0(a2)		/* store 32-bit */
273	ret
274END(generic_bs_w_4)
275
276
277#ifdef _LP64
278/* void bs_w_8(a0: tag, a1: addr, a2: offset, a3: value); */
279ENTRY_NP(generic_bs_w_8)
280	PTR_L	a5, BS_STRIDE(a0)	/* stride */
281	PTR_SLL	a2, a2, a5		/* offset <<= stride */
282	PTR_ADD	a2, a2, a1		/* add to address */
283	sd	a3, 0(a2)		/* store 64-bit */
284	ret
285END(generic_bs_w_8)
286#endif
287
288
289/* void bs_wm_1(a0: tag, a1: addr, a2: offset, a3: datap, a4: count); */
290ENTRY_NP(generic_bs_wm_1)
291#ifdef DIAGNOSTIC
292	beqz	a4, 2f
293#endif
294	PTR_L	a5, BS_STRIDE(a0)	/* stride */
295	PTR_SLL	a2, a2, a5		/* offset <<= stride */
296	PTR_ADD	a2, a2, a1		/* add to address */
2971:
298	lbu	a0, 0(a3)		/* load 8-bit */
299	sb	a0, 0(a2)
300	add	a3, a3, 1
301	add	a4, a4, -1		/* count-- */
302	bnez	a4, 1b
303	ret
3042:
305	la	a0, 3f
306	tail	_C_LABEL(panic)
3073:
308	.asciz	"_bs_wm_1: count == 0"
309END(generic_bs_wm_1)
310
311
312/* void bs_wm_2(a0: tag, a1: addr, a2: offset, a3: datap, a4: count); */
313ENTRY_NP(generic_bs_wm_2)
314#ifdef DIAGNOSTIC
315	beqz	a4, 2f
316#endif
317	PTR_L	a5, BS_STRIDE(a0)	/* stride */
318	PTR_SLL	a2, a2, a5		/* offset <<= stride */
319	PTR_ADD	a2, a2, a1		/* add to address */
3201:
321	lhu	a0, 0(a3)		/* load 16-bit */
322	sh	a0, 0(a2)		/* store 16-bit */
323	add	a3, a3, 2
324	add	a4, a4, -1		/* count-- */
325	bnez	a4, 1b
326	ret
3272:
328	la	a0, 3f
329	tail	_C_LABEL(panic)
3303:
331	.asciz	"_bs_wm_2: count == 0"
332END(generic_bs_wm_2)
333
334
335/* void bs_wm_4(a0: tag, a1: addr, a2: offset, a3: datap, a4: count); */
336ENTRY_NP(generic_bs_wm_4)
337#ifdef DIAGNOSTIC
338	beqz	a4, 2f
339#endif
340	PTR_L	a5, BS_STRIDE(a0)	/* stride */
341	PTR_SLL	a2, a2, a5		/* offset <<= stride */
342	PTR_ADD	a2, a2, a1		/* add to address */
3431:
344	lw	a0, 0(a3)		/* load 32-bit */
345	sw	a0, 0(a2)		/* store 32-bit */
346	add	a3, a3, 4
347	add	a4, a4, -1		/* count-- */
348	bnez	a4, 1b
349	ret
3502:
351	la	a0, 3f
352	tail	_C_LABEL(panic)
3533:
354	.asciz	"_bs_wm_4: count == 0"
355END(generic_bs_wm_4)
356
357
358#ifdef _LP64
359/* void bs_wm_8(a0: tag, a1: addr, a2: offset, a3: datap, a4: count); */
360ENTRY_NP(generic_bs_wm_8)
361#ifdef DIAGNOSTIC
362	beqz	a4, 2f
363#endif
364	PTR_L	a5, BS_STRIDE(a0)	/* stride */
365	PTR_SLL	a2, a2, a5		/* offset <<= stride */
366	PTR_ADD	a2, a2, a1		/* add to address */
3671:
368	ld	a0, 0(a3)		/* load 64-bit */
369	sd	a0, 0(a2)		/* store 64-bit */
370	add	a3, a3, 8
371	add	a4, a4, -1		/* count-- */
372	bnez	a4, 1b
373	ret
3742:
375	la	a0, 3f
376	tail	_C_LABEL(panic)
3773:
378	.asciz	"_bs_wm_8: count == 0"
379END(generic_bs_wm_8)
380#endif
381
382/* void bs_wr_1(a0: tag, a1: addr, a2: offset, a3: datap, a4: count); */
383/* void bs_wr_2(a0: tag, a1: addr, a2: offset, a3: datap, a4: count); */
384/* void bs_wr_4(a0: tag, a1: addr, a2: offset, a3: datap, a4: count); */
385/* void bs_wr_8(a0: tag, a1: addr, a2: offset, a3: datap, a4: count); */
386