1 /* $NetBSD: cache.c,v 1.12 2021/12/11 19:24:21 mrg Exp $ */ 2 3 /* 4 * Copyright (c) 2011 Matthew R. Green 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 /* 30 * Handle picking the right types of the different cache call. 31 * 32 * This module could take on a larger role. 33 */ 34 35 #include <sys/cdefs.h> 36 __KERNEL_RCSID(0, "$NetBSD: cache.c,v 1.12 2021/12/11 19:24:21 mrg Exp $"); 37 38 #include "opt_multiprocessor.h" 39 40 #include <sys/param.h> 41 #include <sys/reboot.h> 42 43 #include <machine/cpu.h> 44 45 #include <sparc64/sparc64/cache.h> 46 47 static void 48 cache_nop(void) 49 { 50 } 51 52 static void 53 blast_dcache_real(void) 54 { 55 56 sp_blast_dcache(dcache_size, dcache_line_size); 57 } 58 59 static void 60 sp_dcache_flush_page_cpuset(paddr_t pa, sparc64_cpuset_t cs) 61 { 62 63 dcache_flush_page(pa); 64 } 65 66 void (*dcache_flush_page)(paddr_t) = dcache_flush_page_us; 67 void (*dcache_flush_page_cpuset)(paddr_t, sparc64_cpuset_t) = 68 sp_dcache_flush_page_cpuset; 69 void (*blast_dcache)(void) = blast_dcache_real; 70 void (*blast_icache)(void) = blast_icache_us; 71 72 #ifdef MULTIPROCESSOR 73 void (*sp_dcache_flush_page)(paddr_t) = dcache_flush_page_us; 74 #endif 75 76 void (*sp_tlb_flush_pte)(vaddr_t, int) = sp_tlb_flush_pte_us; 77 void (*sp_tlb_flush_all)(void) = sp_tlb_flush_all_us; 78 79 void (*cache_flush_phys)(paddr_t, psize_t, int) = cache_flush_phys_us; 80 81 static void 82 sp_tlb_flush_pte_sun4v(vaddr_t va, int ctx) 83 { 84 int64_t hv_rc; 85 hv_rc = hv_mmu_demap_page(va, ctx, MAP_DTLB|MAP_ITLB); 86 if ( hv_rc != H_EOK ) 87 panic("hv_mmu_demap_page(%p,%d) failed - rc = %" PRIx64 "\n", (void*)va, ctx, hv_rc); 88 } 89 90 static void 91 sp_tlb_flush_all_sun4v(void) 92 { 93 panic("sp_tlb_flush_all_sun4v() not implemented yet"); 94 } 95 96 97 static void 98 cache_flush_phys_sun4v(paddr_t pa, psize_t size, int ecache) 99 { 100 panic("cache_flush_phys_sun4v() not implemented yet"); 101 } 102 103 void 104 cache_setup_funcs(void) 105 { 106 107 if (CPU_ISSUN4US || CPU_ISSUN4V) { 108 dcache_flush_page = (void (*)(paddr_t)) cache_nop; 109 #ifdef MULTIPROCESSOR 110 /* XXXMRG shouldn't be necessary -- only caller is nop'ed out */ 111 sp_dcache_flush_page = (void (*)(paddr_t)) cache_nop; 112 #endif 113 blast_dcache = cache_nop; 114 blast_icache = cache_nop; 115 } else { 116 if (CPU_IS_USIII_UP()) { 117 dcache_flush_page = dcache_flush_page_usiii; 118 #ifdef MULTIPROCESSOR 119 sp_dcache_flush_page = dcache_flush_page_usiii; 120 #endif 121 blast_icache = blast_icache_usiii; 122 } 123 #ifdef MULTIPROCESSOR 124 if (sparc_ncpus > 1 && (boothowto & RB_MD1) == 0) { 125 dcache_flush_page = smp_dcache_flush_page_allcpu; 126 dcache_flush_page_cpuset = smp_dcache_flush_page_cpuset; 127 blast_dcache = smp_blast_dcache; 128 } 129 #endif 130 } 131 132 /* Prepare sp_tlb_flush_* and cache_flush_phys() functions */ 133 if (CPU_ISSUN4V) { 134 sp_tlb_flush_pte = sp_tlb_flush_pte_sun4v; 135 sp_tlb_flush_all = sp_tlb_flush_all_sun4v; 136 cache_flush_phys = cache_flush_phys_sun4v; 137 } else { 138 if (CPU_IS_USIII_UP() || CPU_IS_SPARC64_V_UP()) { 139 sp_tlb_flush_pte = sp_tlb_flush_pte_usiii; 140 sp_tlb_flush_all = sp_tlb_flush_all_usiii; 141 cache_flush_phys = cache_flush_phys_usiii; 142 } 143 } 144 145 } 146