cpu-v4.h revision 280985
1276333Sian/*- 2276333Sian * Copyright 2014 Svatopluk Kraus <onwahe@gmail.com> 3276333Sian * Copyright 2014 Michal Meloun <meloun@miracle.cz> 4276333Sian * All rights reserved. 5276333Sian * 6276333Sian * Redistribution and use in source and binary forms, with or without 7276333Sian * modification, are permitted provided that the following conditions 8276333Sian * are met: 9276333Sian * 1. Redistributions of source code must retain the above copyright 10276333Sian * notice, this list of conditions and the following disclaimer. 11276333Sian * 2. Redistributions in binary form must reproduce the above copyright 12276333Sian * notice, this list of conditions and the following disclaimer in the 13276333Sian * documentation and/or other materials provided with the distribution. 14276333Sian * 15276333Sian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16276333Sian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17276333Sian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18276333Sian * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19276333Sian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20276333Sian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21276333Sian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22276333Sian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23276333Sian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24276333Sian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25276333Sian * SUCH DAMAGE. 26276333Sian * 27276333Sian * $FreeBSD: head/sys/arm/include/cpu-v6.h 280985 2015-04-02 12:56:06Z andrew $ 28276333Sian */ 29276333Sian#ifndef MACHINE_CPU_V6_H 30276333Sian#define MACHINE_CPU_V6_H 31276333Sian 32276333Sian#include "machine/atomic.h" 33276333Sian#include "machine/cpufunc.h" 34276333Sian#include "machine/cpuinfo.h" 35276333Sian#include "machine/sysreg.h" 36276333Sian 37276333Sian 38276333Sian#define CPU_ASID_KERNEL 0 39276333Sian 40279811Sianvm_offset_t dcache_wb_pou_checked(vm_offset_t, vm_size_t); 41279811Sianvm_offset_t icache_inv_pou_checked(vm_offset_t, vm_size_t); 42279811Sian 43276333Sian/* 44276333Sian * Macros to generate CP15 (system control processor) read/write functions. 45276333Sian */ 46276333Sian#define _FX(s...) #s 47276333Sian 48276333Sian#define _RF0(fname, aname...) \ 49276333Sianstatic __inline register_t \ 50276333Sianfname(void) \ 51276333Sian{ \ 52276333Sian register_t reg; \ 53276333Sian __asm __volatile("mrc\t" _FX(aname): "=r" (reg)); \ 54276333Sian return(reg); \ 55276333Sian} 56276333Sian 57280985Sandrew#define _R64F0(fname, aname) \ 58280985Sandrewstatic __inline uint64_t \ 59280985Sandrewfname(void) \ 60280985Sandrew{ \ 61280985Sandrew uint64_t reg; \ 62280985Sandrew __asm __volatile("mrrc\t" _FX(aname): "=r" (reg)); \ 63280985Sandrew return(reg); \ 64280985Sandrew} 65280985Sandrew 66276333Sian#define _WF0(fname, aname...) \ 67276333Sianstatic __inline void \ 68276333Sianfname(void) \ 69276333Sian{ \ 70276333Sian __asm __volatile("mcr\t" _FX(aname)); \ 71276333Sian} 72276333Sian 73276333Sian#define _WF1(fname, aname...) \ 74276333Sianstatic __inline void \ 75276333Sianfname(register_t reg) \ 76276333Sian{ \ 77276333Sian __asm __volatile("mcr\t" _FX(aname):: "r" (reg)); \ 78276333Sian} 79276333Sian 80280985Sandrew#define _W64F1(fname, aname...) \ 81280985Sandrewstatic __inline void \ 82280985Sandrewfname(uint64_t reg) \ 83280985Sandrew{ \ 84280985Sandrew __asm __volatile("mcrr\t" _FX(aname):: "r" (reg)); \ 85280985Sandrew} 86280985Sandrew 87276333Sian/* 88276333Sian * Raw CP15 maintenance operations 89276333Sian * !!! not for external use !!! 90276333Sian */ 91276333Sian 92276333Sian/* TLB */ 93276333Sian 94276333Sian_WF0(_CP15_TLBIALL, CP15_TLBIALL) /* Invalidate entire unified TLB */ 95276333Sian#if __ARM_ARCH >= 7 && defined SMP 96276333Sian_WF0(_CP15_TLBIALLIS, CP15_TLBIALLIS) /* Invalidate entire unified TLB IS */ 97276333Sian#endif 98276333Sian_WF1(_CP15_TLBIASID, CP15_TLBIASID(%0)) /* Invalidate unified TLB by ASID */ 99276333Sian#if __ARM_ARCH >= 7 && defined SMP 100276333Sian_WF1(_CP15_TLBIASIDIS, CP15_TLBIASIDIS(%0)) /* Invalidate unified TLB by ASID IS */ 101276333Sian#endif 102276333Sian_WF1(_CP15_TLBIMVAA, CP15_TLBIMVAA(%0)) /* Invalidate unified TLB by MVA, all ASID */ 103276333Sian#if __ARM_ARCH >= 7 && defined SMP 104276333Sian_WF1(_CP15_TLBIMVAAIS, CP15_TLBIMVAAIS(%0)) /* Invalidate unified TLB by MVA, all ASID IS */ 105276333Sian#endif 106276333Sian_WF1(_CP15_TLBIMVA, CP15_TLBIMVA(%0)) /* Invalidate unified TLB by MVA */ 107276333Sian 108276333Sian_WF1(_CP15_TTB_SET, CP15_TTBR0(%0)) 109276333Sian 110276333Sian/* Cache and Branch predictor */ 111276333Sian 112276333Sian_WF0(_CP15_BPIALL, CP15_BPIALL) /* Branch predictor invalidate all */ 113276333Sian#if __ARM_ARCH >= 7 && defined SMP 114276333Sian_WF0(_CP15_BPIALLIS, CP15_BPIALLIS) /* Branch predictor invalidate all IS */ 115276333Sian#endif 116276333Sian_WF1(_CP15_BPIMVA, CP15_BPIMVA(%0)) /* Branch predictor invalidate by MVA */ 117276333Sian_WF1(_CP15_DCCIMVAC, CP15_DCCIMVAC(%0)) /* Data cache clean and invalidate by MVA PoC */ 118276333Sian_WF1(_CP15_DCCISW, CP15_DCCISW(%0)) /* Data cache clean and invalidate by set/way */ 119276333Sian_WF1(_CP15_DCCMVAC, CP15_DCCMVAC(%0)) /* Data cache clean by MVA PoC */ 120276333Sian#if __ARM_ARCH >= 7 121276333Sian_WF1(_CP15_DCCMVAU, CP15_DCCMVAU(%0)) /* Data cache clean by MVA PoU */ 122276333Sian#endif 123276333Sian_WF1(_CP15_DCCSW, CP15_DCCSW(%0)) /* Data cache clean by set/way */ 124276333Sian_WF1(_CP15_DCIMVAC, CP15_DCIMVAC(%0)) /* Data cache invalidate by MVA PoC */ 125276333Sian_WF1(_CP15_DCISW, CP15_DCISW(%0)) /* Data cache invalidate by set/way */ 126276333Sian_WF0(_CP15_ICIALLU, CP15_ICIALLU) /* Instruction cache invalidate all PoU */ 127276333Sian#if __ARM_ARCH >= 7 && defined SMP 128276333Sian_WF0(_CP15_ICIALLUIS, CP15_ICIALLUIS) /* Instruction cache invalidate all PoU IS */ 129276333Sian#endif 130276333Sian_WF1(_CP15_ICIMVAU, CP15_ICIMVAU(%0)) /* Instruction cache invalidate */ 131276333Sian 132276333Sian/* 133276333Sian * Publicly accessible functions 134276333Sian */ 135276333Sian 136276333Sian/* Various control registers */ 137276333Sian 138276333Sian_RF0(cp15_dfsr_get, CP15_DFSR(%0)) 139276333Sian_RF0(cp15_ifsr_get, CP15_IFSR(%0)) 140276333Sian_WF1(cp15_prrr_set, CP15_PRRR(%0)) 141276333Sian_WF1(cp15_nmrr_set, CP15_NMRR(%0)) 142276333Sian_RF0(cp15_ttbr_get, CP15_TTBR0(%0)) 143276333Sian_RF0(cp15_dfar_get, CP15_DFAR(%0)) 144276333Sian#if __ARM_ARCH >= 7 145276333Sian_RF0(cp15_ifar_get, CP15_IFAR(%0)) 146276333Sian#endif 147276333Sian 148276333Sian/*CPU id registers */ 149276333Sian_RF0(cp15_midr_get, CP15_MIDR(%0)) 150276333Sian_RF0(cp15_ctr_get, CP15_CTR(%0)) 151276333Sian_RF0(cp15_tcmtr_get, CP15_TCMTR(%0)) 152276333Sian_RF0(cp15_tlbtr_get, CP15_TLBTR(%0)) 153276333Sian_RF0(cp15_mpidr_get, CP15_MPIDR(%0)) 154276333Sian_RF0(cp15_revidr_get, CP15_REVIDR(%0)) 155276333Sian_RF0(cp15_aidr_get, CP15_AIDR(%0)) 156276333Sian_RF0(cp15_id_pfr0_get, CP15_ID_PFR0(%0)) 157276333Sian_RF0(cp15_id_pfr1_get, CP15_ID_PFR1(%0)) 158276333Sian_RF0(cp15_id_dfr0_get, CP15_ID_DFR0(%0)) 159276333Sian_RF0(cp15_id_afr0_get, CP15_ID_AFR0(%0)) 160276333Sian_RF0(cp15_id_mmfr0_get, CP15_ID_MMFR0(%0)) 161276333Sian_RF0(cp15_id_mmfr1_get, CP15_ID_MMFR1(%0)) 162276333Sian_RF0(cp15_id_mmfr2_get, CP15_ID_MMFR2(%0)) 163276333Sian_RF0(cp15_id_mmfr3_get, CP15_ID_MMFR3(%0)) 164276333Sian_RF0(cp15_id_isar0_get, CP15_ID_ISAR0(%0)) 165276333Sian_RF0(cp15_id_isar1_get, CP15_ID_ISAR1(%0)) 166276333Sian_RF0(cp15_id_isar2_get, CP15_ID_ISAR2(%0)) 167276333Sian_RF0(cp15_id_isar3_get, CP15_ID_ISAR3(%0)) 168276333Sian_RF0(cp15_id_isar4_get, CP15_ID_ISAR4(%0)) 169276333Sian_RF0(cp15_id_isar5_get, CP15_ID_ISAR5(%0)) 170276333Sian_RF0(cp15_cbar_get, CP15_CBAR(%0)) 171276333Sian 172276803Sian/* Performance Monitor registers */ 173276803Sian 174276803Sian#if __ARM_ARCH == 6 && defined(CPU_ARM1176) 175276803Sian_RF0(cp15_pmccntr_get, CP15_PMCCNTR(%0)) 176276803Sian_WF1(cp15_pmccntr_set, CP15_PMCCNTR(%0)) 177276803Sian#elif __ARM_ARCH > 6 178276803Sian_RF0(cp15_pmcr_get, CP15_PMCR(%0)) 179276803Sian_WF1(cp15_pmcr_set, CP15_PMCR(%0)) 180276803Sian_RF0(cp15_pmcnten_get, CP15_PMCNTENSET(%0)) 181276803Sian_WF1(cp15_pmcnten_set, CP15_PMCNTENSET(%0)) 182276803Sian_WF1(cp15_pmcnten_clr, CP15_PMCNTENCLR(%0)) 183276803Sian_RF0(cp15_pmovsr_get, CP15_PMOVSR(%0)) 184276803Sian_WF1(cp15_pmovsr_set, CP15_PMOVSR(%0)) 185276803Sian_WF1(cp15_pmswinc_set, CP15_PMSWINC(%0)) 186276803Sian_RF0(cp15_pmselr_get, CP15_PMSELR(%0)) 187276803Sian_WF1(cp15_pmselr_set, CP15_PMSELR(%0)) 188276803Sian_RF0(cp15_pmccntr_get, CP15_PMCCNTR(%0)) 189276803Sian_WF1(cp15_pmccntr_set, CP15_PMCCNTR(%0)) 190276803Sian_RF0(cp15_pmxevtyper_get, CP15_PMXEVTYPER(%0)) 191276803Sian_WF1(cp15_pmxevtyper_set, CP15_PMXEVTYPER(%0)) 192276803Sian_RF0(cp15_pmxevcntr_get, CP15_PMXEVCNTRR(%0)) 193276803Sian_WF1(cp15_pmxevcntr_set, CP15_PMXEVCNTRR(%0)) 194276803Sian_RF0(cp15_pmuserenr_get, CP15_PMUSERENR(%0)) 195276803Sian_WF1(cp15_pmuserenr_set, CP15_PMUSERENR(%0)) 196276803Sian_RF0(cp15_pminten_get, CP15_PMINTENSET(%0)) 197276803Sian_WF1(cp15_pminten_set, CP15_PMINTENSET(%0)) 198276803Sian_WF1(cp15_pminten_clr, CP15_PMINTENCLR(%0)) 199276803Sian#endif 200276803Sian 201277415Sandrew_RF0(cp15_tpidrurw_get, CP15_TPIDRURW(%0)) 202277415Sandrew_WF1(cp15_tpidrurw_set, CP15_TPIDRURW(%0)) 203277415Sandrew_RF0(cp15_tpidruro_get, CP15_TPIDRURO(%0)) 204277415Sandrew_WF1(cp15_tpidruro_set, CP15_TPIDRURO(%0)) 205277415Sandrew_RF0(cp15_tpidrpwr_get, CP15_TPIDRPRW(%0)) 206277415Sandrew_WF1(cp15_tpidrpwr_set, CP15_TPIDRPRW(%0)) 207277415Sandrew 208280985Sandrew/* Generic Timer registers - only use when you know the hardware is available */ 209280985Sandrew_RF0(cp15_cntfrq_get, CP15_CNTFRQ(%0)) 210280985Sandrew_WF1(cp15_cntfrq_set, CP15_CNTFRQ(%0)) 211280985Sandrew_RF0(cp15_cntkctl_get, CP15_CNTKCTL(%0)) 212280985Sandrew_WF1(cp15_cntkctl_set, CP15_CNTKCTL(%0)) 213280985Sandrew_RF0(cp15_cntp_tval_get, CP15_CNTP_TVAL(%0)) 214280985Sandrew_WF1(cp15_cntp_tval_set, CP15_CNTP_TVAL(%0)) 215280985Sandrew_RF0(cp15_cntp_ctl_get, CP15_CNTP_CTL(%0)) 216280985Sandrew_WF1(cp15_cntp_ctl_set, CP15_CNTP_CTL(%0)) 217280985Sandrew_RF0(cp15_cntv_tval_get, CP15_CNTV_TVAL(%0)) 218280985Sandrew_WF1(cp15_cntv_tval_set, CP15_CNTV_TVAL(%0)) 219280985Sandrew_RF0(cp15_cntv_ctl_get, CP15_CNTV_CTL(%0)) 220280985Sandrew_WF1(cp15_cntv_ctl_set, CP15_CNTV_CTL(%0)) 221280985Sandrew_RF0(cp15_cnthctl_get, CP15_CNTHCTL(%0)) 222280985Sandrew_WF1(cp15_cnthctl_set, CP15_CNTHCTL(%0)) 223280985Sandrew_RF0(cp15_cnthp_tval_get, CP15_CNTHP_TVAL(%0)) 224280985Sandrew_WF1(cp15_cnthp_tval_set, CP15_CNTHP_TVAL(%0)) 225280985Sandrew_RF0(cp15_cnthp_ctl_get, CP15_CNTHP_CTL(%0)) 226280985Sandrew_WF1(cp15_cnthp_ctl_set, CP15_CNTHP_CTL(%0)) 227280985Sandrew 228280985Sandrew_R64F0(cp15_cntpct_get, CP15_CNTPCT(%Q0, %R0)) 229280985Sandrew_R64F0(cp15_cntvct_get, CP15_CNTVCT(%Q0, %R0)) 230280985Sandrew_R64F0(cp15_cntp_cval_get, CP15_CNTP_CVAL(%Q0, %R0)) 231280985Sandrew_W64F1(cp15_cntp_cval_set, CP15_CNTP_CVAL(%Q0, %R0)) 232280985Sandrew_R64F0(cp15_cntv_cval_get, CP15_CNTV_CVAL(%Q0, %R0)) 233280985Sandrew_W64F1(cp15_cntv_cval_set, CP15_CNTV_CVAL(%Q0, %R0)) 234280985Sandrew_R64F0(cp15_cntvoff_get, CP15_CNTVOFF(%Q0, %R0)) 235280985Sandrew_W64F1(cp15_cntvoff_set, CP15_CNTVOFF(%Q0, %R0)) 236280985Sandrew_R64F0(cp15_cnthp_cval_get, CP15_CNTHP_CVAL(%Q0, %R0)) 237280985Sandrew_W64F1(cp15_cnthp_cval_set, CP15_CNTHP_CVAL(%Q0, %R0)) 238280985Sandrew 239276333Sian#undef _FX 240276333Sian#undef _RF0 241276333Sian#undef _WF0 242276333Sian#undef _WF1 243276333Sian 244276334Sian/* 245276334Sian * TLB maintenance operations. 246276334Sian */ 247276334Sian 248276334Sian/* Local (i.e. not broadcasting ) operations. */ 249276334Sian 250276334Sian/* Flush all TLB entries (even global). */ 251276334Sianstatic __inline void 252276334Siantlb_flush_all_local(void) 253276334Sian{ 254276334Sian 255276334Sian dsb(); 256276334Sian _CP15_TLBIALL(); 257276334Sian dsb(); 258276334Sian} 259276334Sian 260276334Sian/* Flush all not global TLB entries. */ 261276334Sianstatic __inline void 262276334Siantlb_flush_all_ng_local(void) 263276334Sian{ 264276334Sian 265276334Sian dsb(); 266276334Sian _CP15_TLBIASID(CPU_ASID_KERNEL); 267276334Sian dsb(); 268276334Sian} 269276334Sian 270276334Sian/* Flush single TLB entry (even global). */ 271276334Sianstatic __inline void 272276334Siantlb_flush_local(vm_offset_t sva) 273276334Sian{ 274276334Sian 275276334Sian dsb(); 276276334Sian _CP15_TLBIMVA((sva & ~PAGE_MASK ) | CPU_ASID_KERNEL); 277276334Sian dsb(); 278276334Sian} 279276334Sian 280276334Sian/* Flush range of TLB entries (even global). */ 281276334Sianstatic __inline void 282276334Siantlb_flush_range_local(vm_offset_t sva, vm_size_t size) 283276334Sian{ 284276334Sian vm_offset_t va; 285276334Sian vm_offset_t eva = sva + size; 286276334Sian 287276334Sian dsb(); 288276334Sian for (va = sva; va < eva; va += PAGE_SIZE) 289276334Sian _CP15_TLBIMVA((va & ~PAGE_MASK ) | CPU_ASID_KERNEL); 290276334Sian dsb(); 291276334Sian} 292276334Sian 293276334Sian/* Broadcasting operations. */ 294276803Sian#if __ARM_ARCH >= 7 && defined SMP 295276334Sian 296276334Sianstatic __inline void 297276334Siantlb_flush_all(void) 298276334Sian{ 299276334Sian 300276334Sian dsb(); 301276334Sian _CP15_TLBIALLIS(); 302276334Sian dsb(); 303276334Sian} 304276334Sian 305276334Sianstatic __inline void 306276340Siantlb_flush_all_ng(void) 307276334Sian{ 308276334Sian 309276334Sian dsb(); 310276334Sian _CP15_TLBIASIDIS(CPU_ASID_KERNEL); 311276334Sian dsb(); 312276334Sian} 313276334Sian 314276334Sianstatic __inline void 315276334Siantlb_flush(vm_offset_t sva) 316276334Sian{ 317276334Sian 318276334Sian dsb(); 319276334Sian _CP15_TLBIMVAAIS(sva); 320276334Sian dsb(); 321276334Sian} 322276334Sian 323276334Sianstatic __inline void 324276334Siantlb_flush_range(vm_offset_t sva, vm_size_t size) 325276334Sian{ 326276334Sian vm_offset_t va; 327276334Sian vm_offset_t eva = sva + size; 328276334Sian 329276334Sian dsb(); 330276334Sian for (va = sva; va < eva; va += PAGE_SIZE) 331276334Sian _CP15_TLBIMVAAIS(va); 332276334Sian dsb(); 333276334Sian} 334276803Sian#else /* SMP */ 335276803Sian 336276803Sian#define tlb_flush_all() tlb_flush_all_local() 337276803Sian#define tlb_flush_all_ng() tlb_flush_all_ng_local() 338276803Sian#define tlb_flush(sva) tlb_flush_local(sva) 339276803Sian#define tlb_flush_range(sva, size) tlb_flush_range_local(sva, size) 340276803Sian 341276334Sian#endif /* SMP */ 342276334Sian 343276334Sian/* 344276334Sian * Cache maintenance operations. 345276334Sian */ 346276334Sian 347276334Sian/* Sync I and D caches to PoU */ 348276334Sianstatic __inline void 349276334Sianicache_sync(vm_offset_t sva, vm_size_t size) 350276334Sian{ 351276334Sian vm_offset_t va; 352276334Sian vm_offset_t eva = sva + size; 353276334Sian 354276334Sian dsb(); 355279811Sian for (va = sva; va < eva; va += cpuinfo.dcache_line_size) { 356276803Sian#if __ARM_ARCH >= 7 && defined SMP 357276334Sian _CP15_DCCMVAU(va); 358276334Sian#else 359276334Sian _CP15_DCCMVAC(va); 360276334Sian#endif 361276334Sian } 362276334Sian dsb(); 363276803Sian#if __ARM_ARCH >= 7 && defined SMP 364276334Sian _CP15_ICIALLUIS(); 365276334Sian#else 366276334Sian _CP15_ICIALLU(); 367276334Sian#endif 368276334Sian dsb(); 369276334Sian isb(); 370276334Sian} 371276334Sian 372276334Sian/* Invalidate I cache */ 373276334Sianstatic __inline void 374276334Sianicache_inv_all(void) 375276334Sian{ 376276803Sian#if __ARM_ARCH >= 7 && defined SMP 377276334Sian _CP15_ICIALLUIS(); 378276334Sian#else 379276334Sian _CP15_ICIALLU(); 380276334Sian#endif 381276334Sian dsb(); 382276334Sian isb(); 383276334Sian} 384276334Sian 385279811Sian/* Invalidate branch predictor buffer */ 386279811Sianstatic __inline void 387279811Sianbpb_inv_all(void) 388279811Sian{ 389279811Sian#if __ARM_ARCH >= 7 && defined SMP 390279811Sian _CP15_BPIALLIS(); 391279811Sian#else 392279811Sian _CP15_BPIALL(); 393279811Sian#endif 394279811Sian dsb(); 395279811Sian isb(); 396279811Sian} 397279811Sian 398276334Sian/* Write back D-cache to PoU */ 399276334Sianstatic __inline void 400276334Siandcache_wb_pou(vm_offset_t sva, vm_size_t size) 401276334Sian{ 402276334Sian vm_offset_t va; 403276334Sian vm_offset_t eva = sva + size; 404276334Sian 405276334Sian dsb(); 406279811Sian for (va = sva; va < eva; va += cpuinfo.dcache_line_size) { 407276803Sian#if __ARM_ARCH >= 7 && defined SMP 408276334Sian _CP15_DCCMVAU(va); 409276334Sian#else 410276334Sian _CP15_DCCMVAC(va); 411276334Sian#endif 412276334Sian } 413276334Sian dsb(); 414276334Sian} 415276334Sian 416276334Sian/* Invalidate D-cache to PoC */ 417276334Sianstatic __inline void 418276334Siandcache_inv_poc(vm_offset_t sva, vm_paddr_t pa, vm_size_t size) 419276334Sian{ 420276334Sian vm_offset_t va; 421276334Sian vm_offset_t eva = sva + size; 422276334Sian 423276334Sian /* invalidate L1 first */ 424279811Sian for (va = sva; va < eva; va += cpuinfo.dcache_line_size) { 425276334Sian _CP15_DCIMVAC(va); 426276334Sian } 427276334Sian dsb(); 428276334Sian 429276334Sian /* then L2 */ 430276334Sian cpu_l2cache_inv_range(pa, size); 431276334Sian dsb(); 432276334Sian 433276334Sian /* then L1 again */ 434279811Sian for (va = sva; va < eva; va += cpuinfo.dcache_line_size) { 435276334Sian _CP15_DCIMVAC(va); 436276334Sian } 437276334Sian dsb(); 438276334Sian} 439276334Sian 440276334Sian/* Write back D-cache to PoC */ 441276334Sianstatic __inline void 442276334Siandcache_wb_poc(vm_offset_t sva, vm_paddr_t pa, vm_size_t size) 443276334Sian{ 444276334Sian vm_offset_t va; 445276334Sian vm_offset_t eva = sva + size; 446276334Sian 447276334Sian dsb(); 448276334Sian 449279811Sian for (va = sva; va < eva; va += cpuinfo.dcache_line_size) { 450276334Sian _CP15_DCCMVAC(va); 451276334Sian } 452276334Sian dsb(); 453276334Sian 454276334Sian cpu_l2cache_wb_range(pa, size); 455276334Sian} 456276334Sian 457276334Sian/* Write back and invalidate D-cache to PoC */ 458276334Sianstatic __inline void 459276334Siandcache_wbinv_poc(vm_offset_t sva, vm_paddr_t pa, vm_size_t size) 460276334Sian{ 461276334Sian vm_offset_t va; 462276334Sian vm_offset_t eva = sva + size; 463276334Sian 464276334Sian dsb(); 465276334Sian 466276334Sian /* write back L1 first */ 467279811Sian for (va = sva; va < eva; va += cpuinfo.dcache_line_size) { 468276334Sian _CP15_DCCMVAC(va); 469276334Sian } 470276334Sian dsb(); 471276334Sian 472276334Sian /* then write back and invalidate L2 */ 473276334Sian cpu_l2cache_wbinv_range(pa, size); 474276334Sian 475276334Sian /* then invalidate L1 */ 476279811Sian for (va = sva; va < eva; va += cpuinfo.dcache_line_size) { 477276334Sian _CP15_DCIMVAC(va); 478276334Sian } 479276334Sian dsb(); 480276334Sian} 481276334Sian 482276334Sian/* Set TTB0 register */ 483276334Sianstatic __inline void 484276334Siancp15_ttbr_set(uint32_t reg) 485276334Sian{ 486276334Sian dsb(); 487276334Sian _CP15_TTB_SET(reg); 488276334Sian dsb(); 489276334Sian _CP15_BPIALL(); 490276334Sian dsb(); 491276334Sian isb(); 492276334Sian tlb_flush_all_ng_local(); 493276334Sian} 494276334Sian 495276333Sian#endif /* !MACHINE_CPU_V6_H */ 496