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