1 /* SPDX-License-Identifier: BSD-2-Clause */ 2 /* 3 * Copyright (c) 2016, Linaro Limited 4 * Copyright (c) 2014, STMicroelectronics International N.V. 5 */ 6 7 #ifndef ARM32_H 8 #define ARM32_H 9 10 #include <sys/cdefs.h> 11 #include <stdint.h> 12 #include <util.h> 13 14 #define CPSR_MODE_MASK ARM32_CPSR_MODE_MASK 15 #define CPSR_MODE_USR ARM32_CPSR_MODE_USR 16 #define CPSR_MODE_FIQ ARM32_CPSR_MODE_FIQ 17 #define CPSR_MODE_IRQ ARM32_CPSR_MODE_IRQ 18 #define CPSR_MODE_SVC ARM32_CPSR_MODE_SVC 19 #define CPSR_MODE_MON ARM32_CPSR_MODE_MON 20 #define CPSR_MODE_ABT ARM32_CPSR_MODE_ABT 21 #define CPSR_MODE_UND ARM32_CPSR_MODE_UND 22 #define CPSR_MODE_SYS ARM32_CPSR_MODE_SYS 23 24 #define CPSR_T ARM32_CPSR_T 25 #define CPSR_F_SHIFT ARM32_CPSR_F_SHIFT 26 #define CPSR_F ARM32_CPSR_F 27 #define CPSR_I ARM32_CPSR_I 28 #define CPSR_A ARM32_CPSR_A 29 #define CPSR_FIA ARM32_CPSR_FIA 30 #define CPSR_IT_MASK ARM32_CPSR_IT_MASK 31 #define CPSR_IT_MASK1 ARM32_CPSR_IT_MASK1 32 #define CPSR_IT_MASK2 ARM32_CPSR_IT_MASK2 33 34 #define SCR_NS BIT32(0) 35 #define SCR_IRQ BIT32(1) 36 #define SCR_FIQ BIT32(2) 37 #define SCR_EA BIT32(3) 38 #define SCR_FW BIT32(4) 39 #define SCR_AW BIT32(5) 40 #define SCR_NET BIT32(6) 41 #define SCR_SCD BIT32(7) 42 #define SCR_HCE BIT32(8) 43 #define SCR_SIF BIT32(9) 44 45 #define SCTLR_M BIT32(0) 46 #define SCTLR_A BIT32(1) 47 #define SCTLR_C BIT32(2) 48 #define SCTLR_CP15BEN BIT32(5) 49 #define SCTLR_SW BIT32(10) 50 #define SCTLR_Z BIT32(11) 51 #define SCTLR_I BIT32(12) 52 #define SCTLR_V BIT32(13) 53 #define SCTLR_RR BIT32(14) 54 #define SCTLR_HA BIT32(17) 55 #define SCTLR_WXN BIT32(19) 56 #define SCTLR_UWXN BIT32(20) 57 #define SCTLR_FI BIT32(21) 58 #define SCTLR_VE BIT32(24) 59 #define SCTLR_EE BIT32(25) 60 #define SCTLR_NMFI BIT32(26) 61 #define SCTLR_TRE BIT32(28) 62 #define SCTLR_AFE BIT32(29) 63 #define SCTLR_TE BIT32(30) 64 65 /* Only valid for Cortex-A15 */ 66 #define ACTLR_CA15_ENABLE_INVALIDATE_BTB BIT(0) 67 /* Only valid for Cortex-A8 */ 68 #define ACTLR_CA8_ENABLE_INVALIDATE_BTB BIT(6) 69 /* Only valid for Cortex-A9 */ 70 #define ACTLR_CA9_WFLZ BIT(3) 71 72 #define ACTLR_SMP BIT32(6) 73 74 #define NSACR_CP10 BIT32(10) 75 #define NSACR_CP11 BIT32(11) 76 #define NSACR_NSD32DIS BIT32(14) 77 #define NSACR_NSASEDIS BIT32(15) 78 #define NSACR_NS_L2ERR BIT32(17) 79 #define NSACR_NS_SMP BIT32(18) 80 81 #define CPACR_ASEDIS BIT32(31) 82 #define CPACR_D32DIS BIT32(30) 83 #define CPACR_CP(co_proc, access) SHIFT_U32((access), ((co_proc) * 2)) 84 #define CPACR_CP_ACCESS_DENIED 0x0 85 #define CPACR_CP_ACCESS_PL1_ONLY 0x1 86 #define CPACR_CP_ACCESS_FULL 0x3 87 88 89 #define DACR_DOMAIN(num, perm) SHIFT_U32((perm), ((num) * 2)) 90 #define DACR_DOMAIN_PERM_NO_ACCESS 0x0 91 #define DACR_DOMAIN_PERM_CLIENT 0x1 92 #define DACR_DOMAIN_PERM_MANAGER 0x3 93 94 #define PAR_F BIT32(0) 95 #define PAR_SS BIT32(1) 96 #define PAR_LPAE BIT32(11) 97 #define PAR_PA_SHIFT 12 98 #define PAR32_PA_MASK (BIT32(20) - 1) 99 #define PAR64_PA_MASK (BIT64(28) - 1) 100 101 /* 102 * TTBCR has different register layout if LPAE is enabled or not. 103 * TTBCR.EAE == 0 => LPAE is not enabled 104 * TTBCR.EAE == 1 => LPAE is enabled 105 */ 106 #define TTBCR_EAE BIT32(31) 107 108 /* When TTBCR.EAE == 0 */ 109 #define TTBCR_PD0 BIT32(4) 110 #define TTBCR_PD1 BIT32(5) 111 112 /* When TTBCR.EAE == 1 */ 113 #define TTBCR_T0SZ_SHIFT 0 114 #define TTBCR_EPD0 BIT32(7) 115 #define TTBCR_IRGN0_SHIFT 8 116 #define TTBCR_ORGN0_SHIFT 10 117 #define TTBCR_SH0_SHIFT 12 118 #define TTBCR_T1SZ_SHIFT 16 119 #define TTBCR_A1 BIT32(22) 120 #define TTBCR_EPD1 BIT32(23) 121 #define TTBCR_IRGN1_SHIFT 24 122 #define TTBCR_ORGN1_SHIFT 26 123 #define TTBCR_SH1_SHIFT 28 124 125 /* Normal memory, Inner/Outer Non-cacheable */ 126 #define TTBCR_XRGNX_NC 0x0 127 /* Normal memory, Inner/Outer Write-Back Write-Allocate Cacheable */ 128 #define TTBCR_XRGNX_WB 0x1 129 /* Normal memory, Inner/Outer Write-Through Cacheable */ 130 #define TTBCR_XRGNX_WT 0x2 131 /* Normal memory, Inner/Outer Write-Back no Write-Allocate Cacheable */ 132 #define TTBCR_XRGNX_WBWA 0x3 133 134 /* Non-shareable */ 135 #define TTBCR_SHX_NSH 0x0 136 /* Outer Shareable */ 137 #define TTBCR_SHX_OSH 0x2 138 /* Inner Shareable */ 139 #define TTBCR_SHX_ISH 0x3 140 141 #define TTBR_ASID_MASK 0xff 142 #define TTBR_ASID_SHIFT 48 143 144 145 #define FSR_LPAE BIT32(9) 146 #define FSR_WNR BIT32(11) 147 148 /* Valid if FSR.LPAE is 1 */ 149 #define FSR_STATUS_MASK (BIT32(6) - 1) 150 151 /* Valid if FSR.LPAE is 0 */ 152 #define FSR_FS_MASK (BIT32(10) | (BIT32(4) - 1)) 153 154 /* ID_PFR1 bit fields */ 155 #define IDPFR1_VIRT_SHIFT 12 156 #define IDPFR1_VIRT_MASK (0xF << IDPFR1_VIRT_SHIFT) 157 #define IDPFR1_GENTIMER_SHIFT 16 158 #define IDPFR1_GENTIMER_MASK (0xF << IDPFR1_GENTIMER_SHIFT) 159 160 #ifndef ASM 161 static inline uint32_t read_midr(void) 162 { 163 uint32_t midr; 164 165 asm volatile ("mrc p15, 0, %[midr], c0, c0, 0" 166 : [midr] "=r" (midr) 167 ); 168 169 return midr; 170 } 171 172 static inline uint32_t read_mpidr(void) 173 { 174 uint32_t mpidr; 175 176 asm volatile ("mrc p15, 0, %[mpidr], c0, c0, 5" 177 : [mpidr] "=r" (mpidr) 178 ); 179 180 return mpidr; 181 } 182 183 static inline uint32_t read_sctlr(void) 184 { 185 uint32_t sctlr; 186 187 asm volatile ("mrc p15, 0, %[sctlr], c1, c0, 0" 188 : [sctlr] "=r" (sctlr) 189 ); 190 191 return sctlr; 192 } 193 194 static inline void write_sctlr(uint32_t sctlr) 195 { 196 asm volatile ("mcr p15, 0, %[sctlr], c1, c0, 0" 197 : : [sctlr] "r" (sctlr) 198 ); 199 } 200 201 static inline uint32_t read_cpacr(void) 202 { 203 uint32_t cpacr; 204 205 asm volatile ("mrc p15, 0, %[cpacr], c1, c0, 2" 206 : [cpacr] "=r" (cpacr) 207 ); 208 209 return cpacr; 210 } 211 212 static inline void write_cpacr(uint32_t cpacr) 213 { 214 asm volatile ("mcr p15, 0, %[cpacr], c1, c0, 2" 215 : : [cpacr] "r" (cpacr) 216 ); 217 } 218 219 static inline void write_ttbr0(uint32_t ttbr0) 220 { 221 asm volatile ("mcr p15, 0, %[ttbr0], c2, c0, 0" 222 : : [ttbr0] "r" (ttbr0) 223 ); 224 } 225 226 static inline void write_ttbr0_64bit(uint64_t ttbr0) 227 { 228 asm volatile ("mcrr p15, 0, %Q[ttbr0], %R[ttbr0], c2" 229 : : [ttbr0] "r" (ttbr0) 230 ); 231 } 232 233 static inline uint32_t read_ttbr0(void) 234 { 235 uint32_t ttbr0; 236 237 asm volatile ("mrc p15, 0, %[ttbr0], c2, c0, 0" 238 : [ttbr0] "=r" (ttbr0) 239 ); 240 241 return ttbr0; 242 } 243 244 static inline uint64_t read_ttbr0_64bit(void) 245 { 246 uint64_t ttbr0; 247 248 asm volatile ("mrrc p15, 0, %Q[ttbr0], %R[ttbr0], c2" 249 : [ttbr0] "=r" (ttbr0) 250 ); 251 252 return ttbr0; 253 } 254 255 static inline void write_ttbr1(uint32_t ttbr1) 256 { 257 asm volatile ("mcr p15, 0, %[ttbr1], c2, c0, 1" 258 : : [ttbr1] "r" (ttbr1) 259 ); 260 } 261 262 static inline void write_ttbr1_64bit(uint64_t ttbr1) 263 { 264 asm volatile ("mcrr p15, 1, %Q[ttbr1], %R[ttbr1], c2" 265 : : [ttbr1] "r" (ttbr1) 266 ); 267 } 268 269 static inline uint32_t read_ttbr1(void) 270 { 271 uint32_t ttbr1; 272 273 asm volatile ("mrc p15, 0, %[ttbr1], c2, c0, 1" 274 : [ttbr1] "=r" (ttbr1) 275 ); 276 277 return ttbr1; 278 } 279 280 281 static inline void write_ttbcr(uint32_t ttbcr) 282 { 283 asm volatile ("mcr p15, 0, %[ttbcr], c2, c0, 2" 284 : : [ttbcr] "r" (ttbcr) 285 ); 286 } 287 288 static inline uint32_t read_ttbcr(void) 289 { 290 uint32_t ttbcr; 291 292 asm volatile ("mrc p15, 0, %[ttbcr], c2, c0, 2" 293 : [ttbcr] "=r" (ttbcr) 294 ); 295 296 return ttbcr; 297 } 298 299 static inline void write_dacr(uint32_t dacr) 300 { 301 asm volatile ("mcr p15, 0, %[dacr], c3, c0, 0" 302 : : [dacr] "r" (dacr) 303 ); 304 } 305 306 static inline uint32_t read_ifar(void) 307 { 308 uint32_t ifar; 309 310 asm volatile ("mrc p15, 0, %[ifar], c6, c0, 2" 311 : [ifar] "=r" (ifar) 312 ); 313 314 return ifar; 315 } 316 317 static inline uint32_t read_dfar(void) 318 { 319 uint32_t dfar; 320 321 asm volatile ("mrc p15, 0, %[dfar], c6, c0, 0" 322 : [dfar] "=r" (dfar) 323 ); 324 325 return dfar; 326 } 327 328 static inline uint32_t read_dfsr(void) 329 { 330 uint32_t dfsr; 331 332 asm volatile ("mrc p15, 0, %[dfsr], c5, c0, 0" 333 : [dfsr] "=r" (dfsr) 334 ); 335 336 return dfsr; 337 } 338 339 static inline uint32_t read_ifsr(void) 340 { 341 uint32_t ifsr; 342 343 asm volatile ("mrc p15, 0, %[ifsr], c5, c0, 1" 344 : [ifsr] "=r" (ifsr) 345 ); 346 347 return ifsr; 348 } 349 350 static inline void write_scr(uint32_t scr) 351 { 352 asm volatile ("mcr p15, 0, %[scr], c1, c1, 0" 353 : : [scr] "r" (scr) 354 ); 355 } 356 357 static inline void isb(void) 358 { 359 asm volatile ("isb"); 360 } 361 362 static inline void dsb(void) 363 { 364 asm volatile ("dsb"); 365 } 366 367 static inline void dsb_ish(void) 368 { 369 asm volatile ("dsb ish"); 370 } 371 372 static inline void dsb_ishst(void) 373 { 374 asm volatile ("dsb ishst"); 375 } 376 377 static inline void dmb(void) 378 { 379 asm volatile ("dmb"); 380 } 381 382 static inline void sev(void) 383 { 384 asm volatile ("sev"); 385 } 386 387 static inline void wfe(void) 388 { 389 asm volatile ("wfe"); 390 } 391 392 /* Address translate privileged write translation (current state secure PL1) */ 393 static inline void write_ats1cpw(uint32_t va) 394 { 395 asm volatile ("mcr p15, 0, %0, c7, c8, 1" : : "r" (va)); 396 } 397 398 static inline void write_ats1cpr(uint32_t va) 399 { 400 asm volatile ("mcr p15, 0, %0, c7, c8, 0" : : "r" (va)); 401 } 402 403 static inline void write_ats1cpuw(uint32_t va) 404 { 405 asm volatile ("mcr p15, 0, %0, c7, c8, 3" : : "r" (va)); 406 } 407 408 static inline void write_ats1cpur(uint32_t va) 409 { 410 asm volatile ("mcr p15, 0, %0, c7, c8, 2" : : "r" (va)); 411 } 412 413 static inline uint32_t read_par32(void) 414 { 415 uint32_t val; 416 417 asm volatile ("mrc p15, 0, %0, c7, c4, 0" : "=r" (val)); 418 return val; 419 } 420 421 #ifdef CFG_WITH_LPAE 422 static inline uint64_t read_par64(void) 423 { 424 uint64_t val; 425 426 asm volatile ("mrrc p15, 0, %Q0, %R0, c7" : "=r" (val)); 427 return val; 428 } 429 #endif 430 431 static inline void write_tlbimvaais(uint32_t mva) 432 { 433 asm volatile ("mcr p15, 0, %[mva], c8, c3, 3" 434 : : [mva] "r" (mva) 435 ); 436 } 437 438 static inline void write_mair0(uint32_t mair0) 439 { 440 asm volatile ("mcr p15, 0, %[mair0], c10, c2, 0" 441 : : [mair0] "r" (mair0) 442 ); 443 } 444 445 static inline void write_prrr(uint32_t prrr) 446 { 447 /* 448 * Same physical register as MAIR0. 449 * 450 * When an implementation includes the Large Physical Address 451 * Extension, and address translation is using the Long-descriptor 452 * translation table formats, MAIR0 replaces the PRRR 453 */ 454 write_mair0(prrr); 455 } 456 457 static inline void write_mair1(uint32_t mair1) 458 { 459 asm volatile ("mcr p15, 0, %[mair1], c10, c2, 1" 460 : : [mair1] "r" (mair1) 461 ); 462 } 463 464 static inline void write_nmrr(uint32_t nmrr) 465 { 466 /* 467 * Same physical register as MAIR1. 468 * 469 * When an implementation includes the Large Physical Address 470 * Extension, and address translation is using the Long-descriptor 471 * translation table formats, MAIR1 replaces the NMRR 472 */ 473 write_mair1(nmrr); 474 } 475 476 static inline uint32_t read_contextidr(void) 477 { 478 uint32_t contextidr; 479 480 asm volatile ("mrc p15, 0, %[contextidr], c13, c0, 1" 481 : [contextidr] "=r" (contextidr) 482 ); 483 484 return contextidr; 485 } 486 487 static inline void write_contextidr(uint32_t contextidr) 488 { 489 asm volatile ("mcr p15, 0, %[contextidr], c13, c0, 1" 490 : : [contextidr] "r" (contextidr) 491 ); 492 } 493 494 static inline uint32_t read_cpsr(void) 495 { 496 uint32_t cpsr; 497 498 asm volatile ("mrs %[cpsr], cpsr" 499 : [cpsr] "=r" (cpsr) 500 ); 501 return cpsr; 502 } 503 504 static inline void write_cpsr(uint32_t cpsr) 505 { 506 asm volatile ("msr cpsr_fsxc, %[cpsr]" 507 : : [cpsr] "r" (cpsr) 508 ); 509 } 510 511 static inline uint32_t read_spsr(void) 512 { 513 uint32_t spsr; 514 515 asm volatile ("mrs %[spsr], spsr" 516 : [spsr] "=r" (spsr) 517 ); 518 return spsr; 519 } 520 521 static inline uint32_t read_actlr(void) 522 { 523 uint32_t actlr; 524 525 asm volatile ("mrc p15, 0, %[actlr], c1, c0, 1" 526 : [actlr] "=r" (actlr) 527 ); 528 529 return actlr; 530 } 531 532 static inline void write_actlr(uint32_t actlr) 533 { 534 asm volatile ("mcr p15, 0, %[actlr], c1, c0, 1" 535 : : [actlr] "r" (actlr) 536 ); 537 } 538 539 static inline uint32_t read_nsacr(void) 540 { 541 uint32_t nsacr; 542 543 asm volatile ("mrc p15, 0, %[nsacr], c1, c1, 2" 544 : [nsacr] "=r" (nsacr) 545 ); 546 547 return nsacr; 548 } 549 550 static inline void write_nsacr(uint32_t nsacr) 551 { 552 asm volatile ("mcr p15, 0, %[nsacr], c1, c1, 2" 553 : : [nsacr] "r" (nsacr) 554 ); 555 } 556 557 static inline uint64_t read_cntpct(void) 558 { 559 uint64_t val; 560 561 asm volatile("mrrc p15, 0, %Q0, %R0, c14" : "=r" (val)); 562 return val; 563 } 564 565 static inline uint32_t read_cntfrq(void) 566 { 567 uint32_t frq; 568 569 asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (frq)); 570 return frq; 571 } 572 573 static inline void write_cntfrq(uint32_t frq) 574 { 575 asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r" (frq)); 576 } 577 578 static inline uint32_t read_cntkctl(void) 579 { 580 uint32_t cntkctl; 581 582 asm volatile("mrc p15, 0, %0, c14, c1, 0" : "=r" (cntkctl)); 583 return cntkctl; 584 } 585 586 static inline void write_cntkctl(uint32_t cntkctl) 587 { 588 asm volatile("mcr p15, 0, %0, c14, c1, 0" : : "r" (cntkctl)); 589 } 590 591 static __always_inline uint32_t read_pc(void) 592 { 593 uint32_t val; 594 595 asm volatile ("adr %0, ." : "=r" (val)); 596 return val; 597 } 598 599 static __always_inline uint32_t read_sp(void) 600 { 601 uint32_t val; 602 603 asm volatile ("mov %0, sp" : "=r" (val)); 604 return val; 605 } 606 607 static __always_inline uint32_t read_lr(void) 608 { 609 uint32_t val; 610 611 asm volatile ("mov %0, lr" : "=r" (val)); 612 return val; 613 } 614 615 static __always_inline uint32_t read_fp(void) 616 { 617 uint32_t val; 618 619 asm volatile ("mov %0, fp" : "=r" (val)); 620 return val; 621 } 622 623 static __always_inline uint32_t read_r7(void) 624 { 625 uint32_t val; 626 627 asm volatile ("mov %0, r7" : "=r" (val)); 628 return val; 629 } 630 631 /* Register read/write functions for GICC registers by using system interface */ 632 static inline uint32_t read_icc_ctlr(void) 633 { 634 uint32_t v; 635 636 asm volatile ("mrc p15,0,%0,c12,c12,4" : "=r" (v)); 637 return v; 638 } 639 640 static inline void write_icc_ctlr(uint32_t v) 641 { 642 asm volatile ("mcr p15,0,%0,c12,c12,4" : : "r" (v)); 643 } 644 645 static inline void write_icc_pmr(uint32_t v) 646 { 647 asm volatile ("mcr p15,0,%0,c4,c6,0" : : "r" (v)); 648 } 649 650 static inline uint32_t read_icc_iar0(void) 651 { 652 uint32_t v; 653 654 asm volatile ("mrc p15,0,%0,c12,c8,0" : "=r" (v)); 655 return v; 656 } 657 658 static inline void write_icc_eoir0(uint32_t v) 659 { 660 asm volatile ("mcr p15,0,%0,c12,c8,1" : : "r" (v)); 661 } 662 663 static inline uint64_t read_pmu_ccnt(void) 664 { 665 uint32_t val; 666 667 asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(val)); 668 return val; 669 } 670 671 static inline void wfi(void) 672 { 673 asm volatile("wfi"); 674 } 675 #endif /*ASM*/ 676 677 #endif /*ARM32_H*/ 678