|
23 | 23 | #ifndef __ASM_ASSEMBLER_H
|
24 | 24 | #define __ASM_ASSEMBLER_H
|
25 | 25 |
|
| 26 | +#include <asm/cputype.h> |
26 | 27 | #include <asm/ptrace.h>
|
27 | 28 | #include <asm/thread_info.h>
|
28 | 29 |
|
@@ -224,4 +225,43 @@ lr .req x30 // link register
|
224 | 225 | movk \reg, :abs_g0_nc:\val
|
225 | 226 | .endm
|
226 | 227 |
|
| 228 | +/* |
| 229 | + * Check the MIDR_EL1 of the current CPU for a given model and a range of |
| 230 | + * variant/revision. See asm/cputype.h for the macros used below. |
| 231 | + * |
| 232 | + * model: MIDR_CPU_PART of CPU |
| 233 | + * rv_min: Minimum of MIDR_CPU_VAR_REV() |
| 234 | + * rv_max: Maximum of MIDR_CPU_VAR_REV() |
| 235 | + * res: Result register. |
| 236 | + * tmp1, tmp2, tmp3: Temporary registers |
| 237 | + * |
| 238 | + * Corrupts: res, tmp1, tmp2, tmp3 |
| 239 | + * Returns: 0, if the CPU id doesn't match. Non-zero otherwise |
| 240 | + */ |
| 241 | + .macro cpu_midr_match model, rv_min, rv_max, res, tmp1, tmp2, tmp3 |
| 242 | + mrs \res, midr_el1 |
| 243 | + mov_q \tmp1, (MIDR_REVISION_MASK | MIDR_VARIANT_MASK) |
| 244 | + mov_q \tmp2, MIDR_CPU_PART_MASK |
| 245 | + and \tmp3, \res, \tmp2 // Extract model |
| 246 | + and \tmp1, \res, \tmp1 // rev & variant |
| 247 | + mov_q \tmp2, \model |
| 248 | + cmp \tmp3, \tmp2 |
| 249 | + cset \res, eq |
| 250 | + cbz \res, .Ldone\@ // Model matches ? |
| 251 | + |
| 252 | + .if (\rv_min != 0) // Skip min check if rv_min == 0 |
| 253 | + mov_q \tmp3, \rv_min |
| 254 | + cmp \tmp1, \tmp3 |
| 255 | + cset \res, ge |
| 256 | + .endif // \rv_min != 0 |
| 257 | + /* Skip rv_max check if rv_min == rv_max && rv_min != 0 */ |
| 258 | + .if ((\rv_min != \rv_max) || \rv_min == 0) |
| 259 | + mov_q \tmp2, \rv_max |
| 260 | + cmp \tmp1, \tmp2 |
| 261 | + cset \tmp2, le |
| 262 | + and \res, \res, \tmp2 |
| 263 | + .endif |
| 264 | +.Ldone\@: |
| 265 | + .endm |
| 266 | + |
227 | 267 | #endif /* __ASM_ASSEMBLER_H */
|
0 commit comments