1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2024 The FreeBSD Foundation 5 * 6 * This software was developed by Mitchell Horne <mhorne@FreeBSD.org> under 7 * sponsorship from the FreeBSD Foundation. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 #include <sys/param.h> 31 #include <sys/systm.h> 32 33 #include <machine/thead.h> 34 35 bool has_errata_thead_pbmt = false; 36 37 /* ----------------- dcache ops --------------------- */ 38 39 40 /* th.dcache.civa: clean & invalidate at VA stored in t0. */ 41 #define THEAD_DCACHE_CIVA ".long 0x0272800b\n" 42 43 /* th.dcache.iva: invalidate at VA stored in t0. */ 44 #define THEAD_DCACHE_IVA ".long 0x0262800b\n" 45 46 /* th.dcache.cva: clean at VA stored in t0. */ 47 #define THEAD_DCACHE_CVA ".long 0x0252800b\n" 48 49 /* th.sync.s: two-way instruction barrier */ 50 #define THEAD_SYNC_S ".long 0x0190000b\n" 51 52 /* MHTODO: we could parse this information from the device tree. */ 53 #define THEAD_DCACHE_SIZE 64 54 55 static void 56 thead_cpu_dcache_wbinv_range(vm_offset_t va, vm_size_t len) 57 { 58 register vm_offset_t t0 __asm("t0") = rounddown(va, dcache_line_size); 59 60 for (; t0 < va + len; t0 += dcache_line_size) { 61 __asm __volatile(THEAD_DCACHE_CIVA 62 :: "r" (t0) : "memory"); 63 } 64 __asm __volatile(THEAD_SYNC_S ::: "memory"); 65 } 66 67 static void 68 thead_cpu_dcache_inv_range(vm_offset_t va, vm_size_t len) 69 { 70 register vm_offset_t t0 __asm("t0") = rounddown(va, dcache_line_size); 71 72 for (; t0 < va + len; t0 += dcache_line_size) { 73 __asm __volatile(THEAD_DCACHE_IVA 74 :: "r" (t0) : "memory"); 75 } 76 __asm __volatile(THEAD_SYNC_S ::: "memory"); 77 } 78 79 static void 80 thead_cpu_dcache_wb_range(vm_offset_t va, vm_size_t len) 81 { 82 register vm_offset_t t0 __asm("t0") = rounddown(va, dcache_line_size); 83 84 for (; t0 < va + len; t0 += dcache_line_size) { 85 __asm __volatile(THEAD_DCACHE_CVA 86 :: "r" (t0) : "memory"); 87 } 88 __asm __volatile(THEAD_SYNC_S ::: "memory"); 89 } 90 91 void 92 thead_setup_cache(void) 93 { 94 struct riscv_cache_ops thead_ops; 95 96 thead_ops.dcache_wbinv_range = thead_cpu_dcache_wbinv_range; 97 thead_ops.dcache_inv_range = thead_cpu_dcache_inv_range; 98 thead_ops.dcache_wb_range = thead_cpu_dcache_wb_range; 99 100 riscv_cache_install_hooks(&thead_ops, THEAD_DCACHE_SIZE); 101 } 102