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