|
25 | 25 |
|
26 | 26 | #include <asm/asm-offsets.h> |
27 | 27 | #include <asm/cpufeature.h> |
| 28 | +#include <asm/cputype.h> |
28 | 29 | #include <asm/page.h> |
29 | 30 | #include <asm/pgtable-hwdef.h> |
30 | 31 | #include <asm/ptrace.h> |
@@ -435,4 +436,43 @@ alternative_endif |
435 | 436 | and \phys, \pte, #(((1 << (48 - PAGE_SHIFT)) - 1) << PAGE_SHIFT) |
436 | 437 | .endm |
437 | 438 |
|
| 439 | +/* |
| 440 | + * Check the MIDR_EL1 of the current CPU for a given model and a range of |
| 441 | + * variant/revision. See asm/cputype.h for the macros used below. |
| 442 | + * |
| 443 | + * model: MIDR_CPU_MODEL of CPU |
| 444 | + * rv_min: Minimum of MIDR_CPU_VAR_REV() |
| 445 | + * rv_max: Maximum of MIDR_CPU_VAR_REV() |
| 446 | + * res: Result register. |
| 447 | + * tmp1, tmp2, tmp3: Temporary registers |
| 448 | + * |
| 449 | + * Corrupts: res, tmp1, tmp2, tmp3 |
| 450 | + * Returns: 0, if the CPU id doesn't match. Non-zero otherwise |
| 451 | + */ |
| 452 | + .macro cpu_midr_match model, rv_min, rv_max, res, tmp1, tmp2, tmp3 |
| 453 | + mrs \res, midr_el1 |
| 454 | + mov_q \tmp1, (MIDR_REVISION_MASK | MIDR_VARIANT_MASK) |
| 455 | + mov_q \tmp2, MIDR_CPU_MODEL_MASK |
| 456 | + and \tmp3, \res, \tmp2 // Extract model |
| 457 | + and \tmp1, \res, \tmp1 // rev & variant |
| 458 | + mov_q \tmp2, \model |
| 459 | + cmp \tmp3, \tmp2 |
| 460 | + cset \res, eq |
| 461 | + cbz \res, .Ldone\@ // Model matches ? |
| 462 | + |
| 463 | + .if (\rv_min != 0) // Skip min check if rv_min == 0 |
| 464 | + mov_q \tmp3, \rv_min |
| 465 | + cmp \tmp1, \tmp3 |
| 466 | + cset \res, ge |
| 467 | + .endif // \rv_min != 0 |
| 468 | + /* Skip rv_max check if rv_min == rv_max && rv_min != 0 */ |
| 469 | + .if ((\rv_min != \rv_max) || \rv_min == 0) |
| 470 | + mov_q \tmp2, \rv_max |
| 471 | + cmp \tmp1, \tmp2 |
| 472 | + cset \tmp2, le |
| 473 | + and \res, \res, \tmp2 |
| 474 | + .endif |
| 475 | +.Ldone\@: |
| 476 | + .endm |
| 477 | + |
438 | 478 | #endif /* __ASM_ASSEMBLER_H */ |
0 commit comments