19b476841SSoby Mathew/* 27791ce21SBoyan Karatotev * Copyright (c) 2014-2025, Arm Limited and Contributors. All rights reserved. 39b476841SSoby Mathew * 482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause 59b476841SSoby Mathew */ 69b476841SSoby Mathew 79b476841SSoby Mathew#include <arch.h> 89b476841SSoby Mathew#include <asm_macros.S> 99b476841SSoby Mathew#include <assert_macros.S> 10c2ad38ceSVarun Wadekar#include <common/bl_common.h> 1109d40e0eSAntonio Nino Diaz#include <common/debug.h> 1255c70cb7SDavid Cunado#include <cpu_macros.S> 13007433d8SBoyan Karatotev#include <lib/cpus/cpu_ops.h> 146bb96fa6SBoyan Karatotev#include <lib/cpus/errata.h> 1509d40e0eSAntonio Nino Diaz#include <lib/el3_runtime/cpu_data.h> 169b476841SSoby Mathew 173d8256b2SMasahiro Yamada#if defined(IMAGE_BL31) && CRASH_REPORTING 18d3f70af6SSoby Mathew /* 19d3f70af6SSoby Mathew * The cpu specific registers which need to be reported in a crash 20d3f70af6SSoby Mathew * are reported via cpu_ops cpu_reg_dump function. After a matching 21d3f70af6SSoby Mathew * cpu_ops structure entry is found, the correponding cpu_reg_dump 22d3f70af6SSoby Mathew * in the cpu_ops is invoked. 23d3f70af6SSoby Mathew */ 24d3f70af6SSoby Mathew .globl do_cpu_reg_dump 25d3f70af6SSoby Mathewfunc do_cpu_reg_dump 26d3f70af6SSoby Mathew mov x16, x30 27d3f70af6SSoby Mathew 28d3f70af6SSoby Mathew /* Get the matching cpu_ops pointer */ 29d3f70af6SSoby Mathew bl get_cpu_ops_ptr 30d3f70af6SSoby Mathew cbz x0, 1f 31d3f70af6SSoby Mathew 32d3f70af6SSoby Mathew /* Get the cpu_ops cpu_reg_dump */ 33d3f70af6SSoby Mathew ldr x2, [x0, #CPU_REG_DUMP] 34d3f70af6SSoby Mathew cbz x2, 1f 35d3f70af6SSoby Mathew blr x2 36d3f70af6SSoby Mathew1: 37d3f70af6SSoby Mathew mov x30, x16 38d3f70af6SSoby Mathew ret 398b779620SKévin Petitendfunc do_cpu_reg_dump 40d3f70af6SSoby Mathew#endif 41d3f70af6SSoby Mathew 429b476841SSoby Mathew /* 439b476841SSoby Mathew * The below function returns the cpu_ops structure matching the 449b476841SSoby Mathew * midr of the core. It reads the MIDR_EL1 and finds the matching 459b476841SSoby Mathew * entry in cpu_ops entries. Only the implementation and part number 469b476841SSoby Mathew * are used to match the entries. 471994e562SJavier Almansa Sobrino * 481994e562SJavier Almansa Sobrino * If cpu_ops for the MIDR_EL1 cannot be found and 491994e562SJavier Almansa Sobrino * SUPPORT_UNKNOWN_MPID is enabled, it will try to look for a 501994e562SJavier Almansa Sobrino * default cpu_ops with an MIDR value of 0. 512e61d687SOlivier Deprez * (Implementation number 0x0 should be reserved for software use 521994e562SJavier Almansa Sobrino * and therefore no clashes should happen with that default value). 531994e562SJavier Almansa Sobrino * 549b476841SSoby Mathew * Return : 559b476841SSoby Mathew * x0 - The matching cpu_ops pointer on Success 569b476841SSoby Mathew * x0 - 0 on failure. 579b476841SSoby Mathew * Clobbers : x0 - x5 589b476841SSoby Mathew */ 599b476841SSoby Mathew .globl get_cpu_ops_ptr 609b476841SSoby Mathewfunc get_cpu_ops_ptr 619b476841SSoby Mathew /* Read the MIDR_EL1 */ 629b476841SSoby Mathew mrs x2, midr_el1 639b476841SSoby Mathew mov_imm x3, CPU_IMPL_PN_MASK 649b476841SSoby Mathew 659b476841SSoby Mathew /* Retain only the implementation and part number using mask */ 669b476841SSoby Mathew and w2, w2, w3 671994e562SJavier Almansa Sobrino 681994e562SJavier Almansa Sobrino /* Get the cpu_ops end location */ 69a5c4212fSHsin-Hsiung Wang adr_l x5, (__CPU_OPS_END__ + CPU_MIDR) 701994e562SJavier Almansa Sobrino 711994e562SJavier Almansa Sobrino /* Initialize the return parameter */ 721994e562SJavier Almansa Sobrino mov x0, #0 739b476841SSoby Mathew1: 741994e562SJavier Almansa Sobrino /* Get the cpu_ops start location */ 75a5c4212fSHsin-Hsiung Wang adr_l x4, (__CPU_OPS_START__ + CPU_MIDR) 761994e562SJavier Almansa Sobrino 771994e562SJavier Almansa Sobrino2: 789b476841SSoby Mathew /* Check if we have reached end of list */ 799b476841SSoby Mathew cmp x4, x5 801994e562SJavier Almansa Sobrino b.eq search_def_ptr 819b476841SSoby Mathew 829b476841SSoby Mathew /* load the midr from the cpu_ops */ 839b476841SSoby Mathew ldr x1, [x4], #CPU_OPS_SIZE 849b476841SSoby Mathew and w1, w1, w3 859b476841SSoby Mathew 869b476841SSoby Mathew /* Check if midr matches to midr of this core */ 879b476841SSoby Mathew cmp w1, w2 881994e562SJavier Almansa Sobrino b.ne 2b 899b476841SSoby Mathew 909b476841SSoby Mathew /* Subtract the increment and offset to get the cpu-ops pointer */ 919b476841SSoby Mathew sub x0, x4, #(CPU_OPS_SIZE + CPU_MIDR) 92601e3ed2SVarun Wadekar#if ENABLE_ASSERTIONS 93601e3ed2SVarun Wadekar cmp x0, #0 94601e3ed2SVarun Wadekar ASM_ASSERT(ne) 95601e3ed2SVarun Wadekar#endif 961994e562SJavier Almansa Sobrino#ifdef SUPPORT_UNKNOWN_MPID 971994e562SJavier Almansa Sobrino cbnz x2, exit_mpid_found 981994e562SJavier Almansa Sobrino /* Mark the unsupported MPID flag */ 991994e562SJavier Almansa Sobrino adrp x1, unsupported_mpid_flag 1001994e562SJavier Almansa Sobrino add x1, x1, :lo12:unsupported_mpid_flag 1011994e562SJavier Almansa Sobrino str w2, [x1] 1021994e562SJavier Almansa Sobrinoexit_mpid_found: 1031994e562SJavier Almansa Sobrino#endif 1041994e562SJavier Almansa Sobrino ret 1051994e562SJavier Almansa Sobrino 1061994e562SJavier Almansa Sobrino /* 1071994e562SJavier Almansa Sobrino * Search again for a default pointer (MIDR = 0x0) 1081994e562SJavier Almansa Sobrino * or return error if already searched. 1091994e562SJavier Almansa Sobrino */ 1101994e562SJavier Almansa Sobrinosearch_def_ptr: 1111994e562SJavier Almansa Sobrino#ifdef SUPPORT_UNKNOWN_MPID 1121994e562SJavier Almansa Sobrino cbz x2, error_exit 1131994e562SJavier Almansa Sobrino mov x2, #0 1141994e562SJavier Almansa Sobrino b 1b 1159b476841SSoby Mathewerror_exit: 1161994e562SJavier Almansa Sobrino#endif 117*0d020822SBoyan Karatotev#if ENABLE_ASSERTIONS 118*0d020822SBoyan Karatotev /* 119*0d020822SBoyan Karatotev * Assert if invalid cpu_ops obtained. If this is not valid, it may 120*0d020822SBoyan Karatotev * suggest that the proper CPU file hasn't been included. 121*0d020822SBoyan Karatotev */ 122*0d020822SBoyan Karatotev cmp x0, #0 123*0d020822SBoyan Karatotev ASM_ASSERT(ne) 124*0d020822SBoyan Karatotev#endif 1259b476841SSoby Mathew ret 1268b779620SKévin Petitendfunc get_cpu_ops_ptr 1277395a725SSoby Mathew 12810bcd761SJeenu Viswambharan .globl cpu_get_rev_var 12910bcd761SJeenu Viswambharanfunc cpu_get_rev_var 13036eeb59fSBoyan Karatotev get_rev_var x0, x1 13110bcd761SJeenu Viswambharan ret 13210bcd761SJeenu Viswambharanendfunc cpu_get_rev_var 133