1/* cpufunc.h,v 1.40.22.4 2007/11/08 10:59:33 matt Exp */ 2 3/* 4 * Copyright (c) 1997 Mark Brinicombe. 5 * Copyright (c) 1997 Causality Limited 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by Causality Limited. 19 * 4. The name of Causality Limited may not be used to endorse or promote 20 * products derived from this software without specific prior written 21 * permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY CAUSALITY LIMITED ``AS IS'' AND ANY EXPRESS 24 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 * DISCLAIMED. IN NO EVENT SHALL CAUSALITY LIMITED BE LIABLE FOR ANY DIRECT, 27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * RiscBSD kernel project 36 * 37 * cpufunc.h 38 * 39 * Prototypes for cpu, mmu and tlb related functions. 40 */ 41 42#ifndef _ARM32_CPUFUNC_H_ 43#define _ARM32_CPUFUNC_H_ 44 45#ifdef _KERNEL 46 47#include <sys/types.h> 48#include <arm/armreg.h> 49#include <arm/cpuconf.h> 50#include <arm/armreg.h> 51 52struct cpu_functions { 53 54 /* CPU functions */ 55 56 u_int (*cf_id) (void); 57 void (*cf_cpwait) (void); 58 59 /* MMU functions */ 60 61 u_int (*cf_control) (u_int, u_int); 62 void (*cf_domains) (u_int); 63 void (*cf_setttb) (u_int); 64 u_int (*cf_faultstatus) (void); 65 u_int (*cf_faultaddress) (void); 66 67 /* TLB functions */ 68 69 void (*cf_tlb_flushID) (void); 70 void (*cf_tlb_flushID_SE) (u_int); 71 void (*cf_tlb_flushI) (void); 72 void (*cf_tlb_flushI_SE) (u_int); 73 void (*cf_tlb_flushD) (void); 74 void (*cf_tlb_flushD_SE) (u_int); 75 76 /* 77 * Cache operations: 78 * 79 * We define the following primitives: 80 * 81 * icache_sync_all Synchronize I-cache 82 * icache_sync_range Synchronize I-cache range 83 * 84 * dcache_wbinv_all Write-back and Invalidate D-cache 85 * dcache_wbinv_range Write-back and Invalidate D-cache range 86 * dcache_inv_range Invalidate D-cache range 87 * dcache_wb_range Write-back D-cache range 88 * 89 * idcache_wbinv_all Write-back and Invalidate D-cache, 90 * Invalidate I-cache 91 * idcache_wbinv_range Write-back and Invalidate D-cache, 92 * Invalidate I-cache range 93 * 94 * Note that the ARM term for "write-back" is "clean". We use 95 * the term "write-back" since it's a more common way to describe 96 * the operation. 97 * 98 * There are some rules that must be followed: 99 * 100 * I-cache Synch (all or range): 101 * The goal is to synchronize the instruction stream, 102 * so you may beed to write-back dirty D-cache blocks 103 * first. If a range is requested, and you can't 104 * synchronize just a range, you have to hit the whole 105 * thing. 106 * 107 * D-cache Write-Back and Invalidate range: 108 * If you can't WB-Inv a range, you must WB-Inv the 109 * entire D-cache. 110 * 111 * D-cache Invalidate: 112 * If you can't Inv the D-cache, you must Write-Back 113 * and Invalidate. Code that uses this operation 114 * MUST NOT assume that the D-cache will not be written 115 * back to memory. 116 * 117 * D-cache Write-Back: 118 * If you can't Write-back without doing an Inv, 119 * that's fine. Then treat this as a WB-Inv. 120 * Skipping the invalidate is merely an optimization. 121 * 122 * All operations: 123 * Valid virtual addresses must be passed to each 124 * cache operation. 125 */ 126 void (*cf_icache_sync_all) (void); 127 void (*cf_icache_sync_range) (vaddr_t, vsize_t); 128 129 void (*cf_dcache_wbinv_all) (void); 130 void (*cf_dcache_wbinv_range)(vaddr_t, vsize_t); 131 void (*cf_dcache_inv_range) (vaddr_t, vsize_t); 132 void (*cf_dcache_wb_range) (vaddr_t, vsize_t); 133 134 void (*cf_idcache_wbinv_all) (void); 135 void (*cf_idcache_wbinv_range)(vaddr_t, vsize_t); 136 137 /* Other functions */ 138 139 void (*cf_flush_prefetchbuf) (void); 140 void (*cf_drain_writebuf) (void); 141 void (*cf_flush_brnchtgt_C) (void); 142 void (*cf_flush_brnchtgt_E) (u_int); 143 144 void (*cf_sleep) (int mode); 145 146 /* Soft functions */ 147 148 int (*cf_dataabt_fixup) (void *); 149 int (*cf_prefetchabt_fixup) (void *); 150 151 void (*cf_context_switch) (u_int); 152 153 void (*cf_setup) (char *); 154}; 155 156extern struct cpu_functions cpufuncs; 157extern u_int cputype; 158 159#define cpu_id() cpufuncs.cf_id() 160 161#define cpu_control(c, e) cpufuncs.cf_control(c, e) 162#define cpu_domains(d) cpufuncs.cf_domains(d) 163#define cpu_setttb(t) cpufuncs.cf_setttb(t) 164#define cpu_faultstatus() cpufuncs.cf_faultstatus() 165#define cpu_faultaddress() cpufuncs.cf_faultaddress() 166 167#define cpu_tlb_flushID() cpufuncs.cf_tlb_flushID() 168#define cpu_tlb_flushID_SE(e) cpufuncs.cf_tlb_flushID_SE(e) 169#define cpu_tlb_flushI() cpufuncs.cf_tlb_flushI() 170#define cpu_tlb_flushI_SE(e) cpufuncs.cf_tlb_flushI_SE(e) 171#define cpu_tlb_flushD() cpufuncs.cf_tlb_flushD() 172#define cpu_tlb_flushD_SE(e) cpufuncs.cf_tlb_flushD_SE(e) 173 174#define cpu_icache_sync_all() cpufuncs.cf_icache_sync_all() 175#define cpu_icache_sync_range(a, s) cpufuncs.cf_icache_sync_range((a), (s)) 176 177#define cpu_dcache_wbinv_all() cpufuncs.cf_dcache_wbinv_all() 178#define cpu_dcache_wbinv_range(a, s) cpufuncs.cf_dcache_wbinv_range((a), (s)) 179#define cpu_dcache_inv_range(a, s) cpufuncs.cf_dcache_inv_range((a), (s)) 180#define cpu_dcache_wb_range(a, s) cpufuncs.cf_dcache_wb_range((a), (s)) 181 182#define cpu_idcache_wbinv_all() cpufuncs.cf_idcache_wbinv_all() 183#define cpu_idcache_wbinv_range(a, s) cpufuncs.cf_idcache_wbinv_range((a), (s)) 184 185#define cpu_flush_prefetchbuf() cpufuncs.cf_flush_prefetchbuf() 186#define cpu_drain_writebuf() cpufuncs.cf_drain_writebuf() 187#define cpu_flush_brnchtgt_C() cpufuncs.cf_flush_brnchtgt_C() 188#define cpu_flush_brnchtgt_E(e) cpufuncs.cf_flush_brnchtgt_E(e) 189 190#define cpu_sleep(m) cpufuncs.cf_sleep(m) 191 192#define cpu_dataabt_fixup(a) cpufuncs.cf_dataabt_fixup(a) 193#define cpu_prefetchabt_fixup(a) cpufuncs.cf_prefetchabt_fixup(a) 194#define ABORT_FIXUP_OK 0 /* fixup succeeded */ 195#define ABORT_FIXUP_FAILED 1 /* fixup failed */ 196#define ABORT_FIXUP_RETURN 2 /* abort handler should return */ 197 198#define cpu_context_switch(a) cpufuncs.cf_context_switch(a) 199#define cpu_setup(a) cpufuncs.cf_setup(a) 200 201int set_cpufuncs (void); 202int set_cpufuncs_id (u_int); 203#define ARCHITECTURE_NOT_PRESENT 1 /* known but not configured */ 204#define ARCHITECTURE_NOT_SUPPORTED 2 /* not known */ 205 206void cpufunc_nullop (void); 207int cpufunc_null_fixup (void *); 208int early_abort_fixup (void *); 209int late_abort_fixup (void *); 210u_int cpufunc_id (void); 211u_int cpufunc_control (u_int, u_int); 212void cpufunc_domains (u_int); 213u_int cpufunc_faultstatus (void); 214u_int cpufunc_faultaddress (void); 215 216#if defined(CPU_ARM2) || defined(CPU_ARM250) || defined(CPU_ARM3) 217void arm3_cache_flush (void); 218#endif /* CPU_ARM2 || CPU_ARM250 || CPU_ARM3 */ 219 220#ifdef CPU_ARM2 221u_int arm2_id (void); 222#endif /* CPU_ARM2 */ 223 224#ifdef CPU_ARM250 225u_int arm250_id (void); 226#endif 227 228#ifdef CPU_ARM3 229u_int arm3_control (u_int, u_int); 230#endif /* CPU_ARM3 */ 231 232#if defined(CPU_ARM6) || defined(CPU_ARM7) 233void arm67_setttb (u_int); 234void arm67_tlb_flush (void); 235void arm67_tlb_purge (u_int); 236void arm67_cache_flush (void); 237void arm67_context_switch (u_int); 238#endif /* CPU_ARM6 || CPU_ARM7 */ 239 240#ifdef CPU_ARM6 241void arm6_setup (char *); 242#endif /* CPU_ARM6 */ 243 244#ifdef CPU_ARM7 245void arm7_setup (char *); 246#endif /* CPU_ARM7 */ 247 248#ifdef CPU_ARM7TDMI 249int arm7_dataabt_fixup (void *); 250void arm7tdmi_setup (char *); 251void arm7tdmi_setttb (u_int); 252void arm7tdmi_tlb_flushID (void); 253void arm7tdmi_tlb_flushID_SE (u_int); 254void arm7tdmi_cache_flushID (void); 255void arm7tdmi_context_switch (u_int); 256#endif /* CPU_ARM7TDMI */ 257 258#ifdef CPU_ARM8 259void arm8_setttb (u_int); 260void arm8_tlb_flushID (void); 261void arm8_tlb_flushID_SE (u_int); 262void arm8_cache_flushID (void); 263void arm8_cache_flushID_E (u_int); 264void arm8_cache_cleanID (void); 265void arm8_cache_cleanID_E (u_int); 266void arm8_cache_purgeID (void); 267void arm8_cache_purgeID_E (u_int entry); 268 269void arm8_cache_syncI (void); 270void arm8_cache_cleanID_rng (vaddr_t, vsize_t); 271void arm8_cache_cleanD_rng (vaddr_t, vsize_t); 272void arm8_cache_purgeID_rng (vaddr_t, vsize_t); 273void arm8_cache_purgeD_rng (vaddr_t, vsize_t); 274void arm8_cache_syncI_rng (vaddr_t, vsize_t); 275 276void arm8_context_switch (u_int); 277 278void arm8_setup (char *); 279 280u_int arm8_clock_config (u_int, u_int); 281#endif 282 283#ifdef CPU_FA526 284void fa526_setup (char *); 285void fa526_setttb (u_int); 286void fa526_context_switch (u_int); 287void fa526_cpu_sleep (int); 288void fa526_tlb_flushI_SE (u_int); 289void fa526_tlb_flushID_SE (u_int); 290void fa526_flush_prefetchbuf (void); 291void fa526_flush_brnchtgt_E (u_int); 292 293void fa526_icache_sync_all (void); 294void fa526_icache_sync_range(vaddr_t, vsize_t); 295void fa526_dcache_wbinv_all (void); 296void fa526_dcache_wbinv_range(vaddr_t, vsize_t); 297void fa526_dcache_inv_range (vaddr_t, vsize_t); 298void fa526_dcache_wb_range (vaddr_t, vsize_t); 299void fa526_idcache_wbinv_all(void); 300void fa526_idcache_wbinv_range(vaddr_t, vsize_t); 301#endif 302 303#ifdef CPU_SA110 304void sa110_setup (char *); 305void sa110_context_switch (u_int); 306#endif /* CPU_SA110 */ 307 308#if defined(CPU_SA1100) || defined(CPU_SA1110) 309void sa11x0_drain_readbuf (void); 310 311void sa11x0_context_switch (u_int); 312void sa11x0_cpu_sleep (int); 313 314void sa11x0_setup (char *); 315#endif 316 317#if defined(CPU_SA110) || defined(CPU_SA1100) || defined(CPU_SA1110) 318void sa1_setttb (u_int); 319 320void sa1_tlb_flushID_SE (u_int); 321 322void sa1_cache_flushID (void); 323void sa1_cache_flushI (void); 324void sa1_cache_flushD (void); 325void sa1_cache_flushD_SE (u_int); 326 327void sa1_cache_cleanID (void); 328void sa1_cache_cleanD (void); 329void sa1_cache_cleanD_E (u_int); 330 331void sa1_cache_purgeID (void); 332void sa1_cache_purgeID_E (u_int); 333void sa1_cache_purgeD (void); 334void sa1_cache_purgeD_E (u_int); 335 336void sa1_cache_syncI (void); 337void sa1_cache_cleanID_rng (vaddr_t, vsize_t); 338void sa1_cache_cleanD_rng (vaddr_t, vsize_t); 339void sa1_cache_purgeID_rng (vaddr_t, vsize_t); 340void sa1_cache_purgeD_rng (vaddr_t, vsize_t); 341void sa1_cache_syncI_rng (vaddr_t, vsize_t); 342 343#endif 344 345#ifdef CPU_ARM9 346void arm9_setttb (u_int); 347 348void arm9_tlb_flushID_SE (u_int); 349 350void arm9_icache_sync_all (void); 351void arm9_icache_sync_range (vaddr_t, vsize_t); 352 353void arm9_dcache_wbinv_all (void); 354void arm9_dcache_wbinv_range (vaddr_t, vsize_t); 355void arm9_dcache_inv_range (vaddr_t, vsize_t); 356void arm9_dcache_wb_range (vaddr_t, vsize_t); 357 358void arm9_idcache_wbinv_all (void); 359void arm9_idcache_wbinv_range (vaddr_t, vsize_t); 360 361void arm9_context_switch (u_int); 362 363void arm9_setup (char *); 364 365extern unsigned arm9_dcache_sets_max; 366extern unsigned arm9_dcache_sets_inc; 367extern unsigned arm9_dcache_index_max; 368extern unsigned arm9_dcache_index_inc; 369#endif 370 371#if defined(CPU_ARM9E) || defined(CPU_ARM10) || defined(CPU_SHEEVA) 372void arm10_tlb_flushID_SE (u_int); 373void arm10_tlb_flushI_SE (u_int); 374 375void arm10_context_switch (u_int); 376 377void arm10_setup (char *); 378#endif 379 380#if defined(CPU_ARM9E) || defined (CPU_ARM10) || defined(CPU_SHEEVA) 381void armv5_ec_setttb (u_int); 382 383void armv5_ec_icache_sync_all (void); 384void armv5_ec_icache_sync_range (vaddr_t, vsize_t); 385 386void armv5_ec_dcache_wbinv_all (void); 387void armv5_ec_dcache_wbinv_range (vaddr_t, vsize_t); 388void armv5_ec_dcache_inv_range (vaddr_t, vsize_t); 389void armv5_ec_dcache_wb_range (vaddr_t, vsize_t); 390 391void armv5_ec_idcache_wbinv_all (void); 392void armv5_ec_idcache_wbinv_range (vaddr_t, vsize_t); 393#endif 394 395#if defined (CPU_ARM10) || defined (CPU_ARM11MPCORE) 396void armv5_setttb (u_int); 397 398void armv5_icache_sync_all (void); 399void armv5_icache_sync_range (vaddr_t, vsize_t); 400 401void armv5_dcache_wbinv_all (void); 402void armv5_dcache_wbinv_range (vaddr_t, vsize_t); 403void armv5_dcache_inv_range (vaddr_t, vsize_t); 404void armv5_dcache_wb_range (vaddr_t, vsize_t); 405 406void armv5_idcache_wbinv_all (void); 407void armv5_idcache_wbinv_range (vaddr_t, vsize_t); 408 409extern unsigned armv5_dcache_sets_max; 410extern unsigned armv5_dcache_sets_inc; 411extern unsigned armv5_dcache_index_max; 412extern unsigned armv5_dcache_index_inc; 413#endif 414 415#if defined(CPU_ARM11MPCORE) 416void arm11mpcore_setup (char *); 417#endif 418 419#if defined(CPU_ARM11) || defined(CPU_CORTEX) 420void arm11_setttb (u_int); 421 422void arm11_tlb_flushID_SE (u_int); 423void arm11_tlb_flushI_SE (u_int); 424 425void arm11_context_switch (u_int); 426 427void arm11_cpu_sleep (int); 428void arm11_setup (char *string); 429void arm11_tlb_flushID (void); 430void arm11_tlb_flushI (void); 431void arm11_tlb_flushD (void); 432void arm11_tlb_flushD_SE (u_int va); 433 434void armv11_dcache_wbinv_all (void); 435void armv11_idcache_wbinv_all(void); 436 437void arm11_drain_writebuf (void); 438void arm11_sleep (int); 439 440void armv6_setttb (u_int); 441 442void armv6_icache_sync_all (void); 443void armv6_icache_sync_range (vaddr_t, vsize_t); 444 445void armv6_dcache_wbinv_all (void); 446void armv6_dcache_wbinv_range (vaddr_t, vsize_t); 447void armv6_dcache_inv_range (vaddr_t, vsize_t); 448void armv6_dcache_wb_range (vaddr_t, vsize_t); 449 450void armv6_idcache_wbinv_all (void); 451void armv6_idcache_wbinv_range (vaddr_t, vsize_t); 452#endif 453 454#if defined(CPU_CORTEX) 455void armv7_setttb(u_int); 456 457void armv7_icache_sync_range(vaddr_t, vsize_t); 458void armv7_dcache_wb_range(vaddr_t, vsize_t); 459void armv7_dcache_wbinv_range(vaddr_t, vsize_t); 460void armv7_dcache_inv_range(vaddr_t, vsize_t); 461void armv7_idcache_wbinv_range(vaddr_t, vsize_t); 462 463void armv7_dcache_wbinv_all (void); 464void armv7_idcache_wbinv_all(void); 465void armv7_icache_sync_all(void); 466void armv7_cpu_sleep(int); 467void armv7_context_switch(u_int); 468void armv7_tlb_flushID_SE(u_int); 469void armv7_setup (char *string); 470#endif 471 472 473#if defined(CPU_ARM1136) || defined(CPU_ARM1176) 474void arm11x6_setttb (u_int); 475void arm11x6_idcache_wbinv_all (void); 476void arm11x6_dcache_wbinv_all (void); 477void arm11x6_icache_sync_all (void); 478void arm11x6_flush_prefetchbuf (void); 479void arm11x6_icache_sync_range (vaddr_t, vsize_t); 480void arm11x6_idcache_wbinv_range (vaddr_t, vsize_t); 481void arm11x6_setup (char *string); 482void arm11x6_sleep (int); /* no ref. for errata */ 483#endif 484#if defined(CPU_ARM1136) 485void arm1136_sleep_rev0 (int); /* for errata 336501 */ 486#endif 487 488 489#if defined(CPU_ARM9) || defined(CPU_ARM9E) || defined(CPU_ARM10) || \ 490 defined(CPU_SA110) || defined(CPU_SA1100) || defined(CPU_SA1110) || \ 491 defined(CPU_FA526) || \ 492 defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \ 493 defined(__CPU_XSCALE_PXA2XX) || defined(CPU_XSCALE_IXP425) || \ 494 defined(CPU_CORTEX) || defined(CPU_SHEEVA) 495 496void armv4_tlb_flushID (void); 497void armv4_tlb_flushI (void); 498void armv4_tlb_flushD (void); 499void armv4_tlb_flushD_SE (u_int); 500 501void armv4_drain_writebuf (void); 502#endif 503 504#if defined(CPU_IXP12X0) 505void ixp12x0_drain_readbuf (void); 506void ixp12x0_context_switch (u_int); 507void ixp12x0_setup (char *); 508#endif 509 510#if defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \ 511 defined(__CPU_XSCALE_PXA2XX) || defined(CPU_XSCALE_IXP425) || \ 512 defined(CPU_CORTEX) 513 514void xscale_cpwait (void); 515#define cpu_cpwait() cpufuncs.cf_cpwait() 516 517void xscale_cpu_sleep (int); 518 519u_int xscale_control (u_int, u_int); 520 521void xscale_setttb (u_int); 522 523void xscale_tlb_flushID_SE (u_int); 524 525void xscale_cache_flushID (void); 526void xscale_cache_flushI (void); 527void xscale_cache_flushD (void); 528void xscale_cache_flushD_SE (u_int); 529 530void xscale_cache_cleanID (void); 531void xscale_cache_cleanD (void); 532void xscale_cache_cleanD_E (u_int); 533 534void xscale_cache_clean_minidata (void); 535 536void xscale_cache_purgeID (void); 537void xscale_cache_purgeID_E (u_int); 538void xscale_cache_purgeD (void); 539void xscale_cache_purgeD_E (u_int); 540 541void xscale_cache_syncI (void); 542void xscale_cache_cleanID_rng (vaddr_t, vsize_t); 543void xscale_cache_cleanD_rng (vaddr_t, vsize_t); 544void xscale_cache_purgeID_rng (vaddr_t, vsize_t); 545void xscale_cache_purgeD_rng (vaddr_t, vsize_t); 546void xscale_cache_syncI_rng (vaddr_t, vsize_t); 547void xscale_cache_flushD_rng (vaddr_t, vsize_t); 548 549void xscale_context_switch (u_int); 550 551void xscale_setup (char *); 552#endif /* CPU_XSCALE_80200 || CPU_XSCALE_80321 || __CPU_XSCALE_PXA2XX || CPU_XSCALE_IXP425 || CPU_CORTEX */ 553 554#if defined(CPU_SHEEVA) 555void sheeva_dcache_wbinv_range (vaddr_t, vsize_t); 556void sheeva_dcache_inv_range (vaddr_t, vsize_t); 557void sheeva_dcache_wb_range (vaddr_t, vsize_t); 558void sheeva_idcache_wbinv_range (vaddr_t, vsize_t); 559void sheeva_setup(char *); 560#endif 561 562#define tlb_flush cpu_tlb_flushID 563#define setttb cpu_setttb 564#define drain_writebuf cpu_drain_writebuf 565 566#ifndef cpu_cpwait 567#define cpu_cpwait() 568#endif 569 570/* 571 * Macros for manipulating CPU interrupts 572 */ 573#ifdef __PROG32 574static __inline u_int32_t __set_cpsr_c(uint32_t bic, uint32_t eor) __attribute__((__unused__)); 575static __inline u_int32_t disable_interrupts(uint32_t mask) __attribute__((__unused__)); 576static __inline u_int32_t enable_interrupts(uint32_t mask) __attribute__((__unused__)); 577 578static __inline uint32_t 579__set_cpsr_c(uint32_t bic, uint32_t eor) 580{ 581 uint32_t tmp, ret; 582 583 __asm volatile( 584 "mrs %0, cpsr\n" /* Get the CPSR */ 585 "bic %1, %0, %2\n" /* Clear bits */ 586 "eor %1, %1, %3\n" /* XOR bits */ 587 "msr cpsr_c, %1\n" /* Set the control field of CPSR */ 588 : "=&r" (ret), "=&r" (tmp) 589 : "r" (bic), "r" (eor) : "memory"); 590 591 return ret; 592} 593 594static __inline uint32_t 595disable_interrupts(uint32_t mask) 596{ 597 uint32_t tmp, ret; 598 mask &= (I32_bit | F32_bit); 599 600 __asm volatile( 601 "mrs %0, cpsr\n" /* Get the CPSR */ 602 "orr %1, %0, %2\n" /* set bits */ 603 "msr cpsr_c, %1\n" /* Set the control field of CPSR */ 604 : "=&r" (ret), "=&r" (tmp) 605 : "r" (mask) 606 : "memory"); 607 608 return ret; 609} 610 611static __inline uint32_t 612enable_interrupts(uint32_t mask) 613{ 614 uint32_t ret, tmp; 615 mask &= (I32_bit | F32_bit); 616 617 __asm volatile( 618 "mrs %0, cpsr\n" /* Get the CPSR */ 619 "bic %1, %0, %2\n" /* Clear bits */ 620 "msr cpsr_c, %1\n" /* Set the control field of CPSR */ 621 : "=&r" (ret), "=&r" (tmp) 622 : "r" (mask) 623 : "memory"); 624 625 return ret; 626} 627 628#define restore_interrupts(old_cpsr) \ 629 (__set_cpsr_c((I32_bit | F32_bit), (old_cpsr) & (I32_bit | F32_bit))) 630 631static inline void cpsie(register_t psw) __attribute__((__unused__)); 632static inline register_t cpsid(register_t psw) __attribute__((__unused__)); 633 634static inline void 635cpsie(register_t psw) 636{ 637#ifdef _ARM_ARCH_6 638 if (!__builtin_constant_p(psw)) { 639 enable_interrupts(psw); 640 return; 641 } 642 switch (psw & (I32_bit|F32_bit)) { 643 case I32_bit: __asm("cpsie\ti"); break; 644 case F32_bit: __asm("cpsie\tf"); break; 645 case I32_bit|F32_bit: __asm("cpsie\tif"); break; 646 } 647#else 648 enable_interrupts(psw); 649#endif 650} 651 652static inline register_t 653cpsid(register_t psw) 654{ 655#ifdef _ARM_ARCH_6 656 register_t oldpsw; 657 if (!__builtin_constant_p(psw)) 658 return disable_interrupts(psw); 659 660 __asm("mrs %0, cpsr" : "=r"(oldpsw)); 661 switch (psw & (I32_bit|F32_bit)) { 662 case I32_bit: __asm("cpsid\ti"); break; 663 case F32_bit: __asm("cpsid\tf"); break; 664 case I32_bit|F32_bit: __asm("cpsid\tif"); break; 665 } 666 return oldpsw; 667#else 668 return disable_interrupts(psw); 669#endif 670} 671 672#else /* ! __PROG32 */ 673#define disable_interrupts(mask) \ 674 (set_r15((mask) & (R15_IRQ_DISABLE | R15_FIQ_DISABLE), \ 675 (mask) & (R15_IRQ_DISABLE | R15_FIQ_DISABLE))) 676 677#define enable_interrupts(mask) \ 678 (set_r15((mask) & (R15_IRQ_DISABLE | R15_FIQ_DISABLE), 0)) 679 680#define restore_interrupts(old_r15) \ 681 (set_r15((R15_IRQ_DISABLE | R15_FIQ_DISABLE), \ 682 (old_r15) & (R15_IRQ_DISABLE | R15_FIQ_DISABLE))) 683#endif /* __PROG32 */ 684 685#ifdef __PROG32 686/* Functions to manipulate the CPSR. */ 687u_int SetCPSR(u_int, u_int); 688u_int GetCPSR(void); 689#else 690/* Functions to manipulate the processor control bits in r15. */ 691u_int set_r15(u_int, u_int); 692u_int get_r15(void); 693#endif /* __PROG32 */ 694 695/* 696 * Functions to manipulate cpu r13 697 * (in arm/arm32/setstack.S) 698 */ 699 700void set_stackptr (u_int, u_int); 701u_int get_stackptr (u_int); 702 703/* 704 * Miscellany 705 */ 706 707int get_pc_str_offset (void); 708 709/* 710 * CPU functions from locore.S 711 */ 712 713void cpu_reset (void) __attribute__((__noreturn__)); 714 715/* 716 * Cache info variables. 717 */ 718 719/* PRIMARY CACHE VARIABLES */ 720extern int arm_picache_size; 721extern int arm_picache_line_size; 722extern int arm_picache_ways; 723 724extern int arm_pdcache_size; /* and unified */ 725extern int arm_pdcache_line_size; 726extern int arm_pdcache_ways; 727extern int arm_cache_prefer_mask; 728 729extern int arm_pcache_type; 730extern int arm_pcache_unified; 731 732extern int arm_dcache_align; 733extern int arm_dcache_align_mask; 734 735#endif /* _KERNEL */ 736#endif /* _ARM32_CPUFUNC_H_ */ 737 738/* End of cpufunc.h */ 739