1*4cc10308SMauro Carvalho Chehab#!/usr/bin/env python3 2*4cc10308SMauro Carvalho Chehab# 3*4cc10308SMauro Carvalho Chehab# pylint: disable=C0301,C0114,R0903,R0912,R0913,R0914,R0915,W0511 4*4cc10308SMauro Carvalho Chehab# SPDX-License-Identifier: GPL-2.0-or-later 5*4cc10308SMauro Carvalho Chehab# 6*4cc10308SMauro Carvalho Chehab# Copyright (C) 2024-2025 Mauro Carvalho Chehab <mchehab+huawei@kernel.org> 7*4cc10308SMauro Carvalho Chehab 8*4cc10308SMauro Carvalho Chehab# TODO: current implementation has dummy defaults. 9*4cc10308SMauro Carvalho Chehab# 10*4cc10308SMauro Carvalho Chehab# For a better implementation, a QMP addition/call is needed to 11*4cc10308SMauro Carvalho Chehab# retrieve some data for ARM Processor Error injection: 12*4cc10308SMauro Carvalho Chehab# 13*4cc10308SMauro Carvalho Chehab# - ARM registers: power_state, mpidr. 14*4cc10308SMauro Carvalho Chehab 15*4cc10308SMauro Carvalho Chehab""" 16*4cc10308SMauro Carvalho ChehabGenerate an ARM processor error CPER, compatible with 17*4cc10308SMauro Carvalho ChehabUEFI 2.9A Errata. 18*4cc10308SMauro Carvalho Chehab 19*4cc10308SMauro Carvalho ChehabInjecting such errors can be done using: 20*4cc10308SMauro Carvalho Chehab 21*4cc10308SMauro Carvalho Chehab $ ./scripts/ghes_inject.py arm 22*4cc10308SMauro Carvalho Chehab Error injected. 23*4cc10308SMauro Carvalho Chehab 24*4cc10308SMauro Carvalho ChehabProduces a simple CPER register, as detected on a Linux guest: 25*4cc10308SMauro Carvalho Chehab 26*4cc10308SMauro Carvalho Chehab[Hardware Error]: Hardware error from APEI Generic Hardware Error Source: 1 27*4cc10308SMauro Carvalho Chehab[Hardware Error]: event severity: recoverable 28*4cc10308SMauro Carvalho Chehab[Hardware Error]: Error 0, type: recoverable 29*4cc10308SMauro Carvalho Chehab[Hardware Error]: section_type: ARM processor error 30*4cc10308SMauro Carvalho Chehab[Hardware Error]: MIDR: 0x0000000000000000 31*4cc10308SMauro Carvalho Chehab[Hardware Error]: running state: 0x0 32*4cc10308SMauro Carvalho Chehab[Hardware Error]: Power State Coordination Interface state: 0 33*4cc10308SMauro Carvalho Chehab[Hardware Error]: Error info structure 0: 34*4cc10308SMauro Carvalho Chehab[Hardware Error]: num errors: 2 35*4cc10308SMauro Carvalho Chehab[Hardware Error]: error_type: 0x02: cache error 36*4cc10308SMauro Carvalho Chehab[Hardware Error]: error_info: 0x000000000091000f 37*4cc10308SMauro Carvalho Chehab[Hardware Error]: transaction type: Data Access 38*4cc10308SMauro Carvalho Chehab[Hardware Error]: cache error, operation type: Data write 39*4cc10308SMauro Carvalho Chehab[Hardware Error]: cache level: 2 40*4cc10308SMauro Carvalho Chehab[Hardware Error]: processor context not corrupted 41*4cc10308SMauro Carvalho Chehab[Firmware Warn]: GHES: Unhandled processor error type 0x02: cache error 42*4cc10308SMauro Carvalho Chehab 43*4cc10308SMauro Carvalho ChehabThe ARM Processor Error message can be customized via command line 44*4cc10308SMauro Carvalho Chehabparameters. For instance: 45*4cc10308SMauro Carvalho Chehab 46*4cc10308SMauro Carvalho Chehab $ ./scripts/ghes_inject.py arm --mpidr 0x444 --running --affinity 1 \ 47*4cc10308SMauro Carvalho Chehab --error-info 12345678 --vendor 0x13,123,4,5,1 --ctx-array 0,1,2,3,4,5 \ 48*4cc10308SMauro Carvalho Chehab -t cache tlb bus micro-arch tlb,micro-arch 49*4cc10308SMauro Carvalho Chehab Error injected. 50*4cc10308SMauro Carvalho Chehab 51*4cc10308SMauro Carvalho ChehabInjects this error, as detected on a Linux guest: 52*4cc10308SMauro Carvalho Chehab 53*4cc10308SMauro Carvalho Chehab[Hardware Error]: Hardware error from APEI Generic Hardware Error Source: 1 54*4cc10308SMauro Carvalho Chehab[Hardware Error]: event severity: recoverable 55*4cc10308SMauro Carvalho Chehab[Hardware Error]: Error 0, type: recoverable 56*4cc10308SMauro Carvalho Chehab[Hardware Error]: section_type: ARM processor error 57*4cc10308SMauro Carvalho Chehab[Hardware Error]: MIDR: 0x0000000000000000 58*4cc10308SMauro Carvalho Chehab[Hardware Error]: Multiprocessor Affinity Register (MPIDR): 0x0000000000000000 59*4cc10308SMauro Carvalho Chehab[Hardware Error]: error affinity level: 0 60*4cc10308SMauro Carvalho Chehab[Hardware Error]: running state: 0x1 61*4cc10308SMauro Carvalho Chehab[Hardware Error]: Power State Coordination Interface state: 0 62*4cc10308SMauro Carvalho Chehab[Hardware Error]: Error info structure 0: 63*4cc10308SMauro Carvalho Chehab[Hardware Error]: num errors: 2 64*4cc10308SMauro Carvalho Chehab[Hardware Error]: error_type: 0x02: cache error 65*4cc10308SMauro Carvalho Chehab[Hardware Error]: error_info: 0x0000000000bc614e 66*4cc10308SMauro Carvalho Chehab[Hardware Error]: cache level: 2 67*4cc10308SMauro Carvalho Chehab[Hardware Error]: processor context not corrupted 68*4cc10308SMauro Carvalho Chehab[Hardware Error]: Error info structure 1: 69*4cc10308SMauro Carvalho Chehab[Hardware Error]: num errors: 2 70*4cc10308SMauro Carvalho Chehab[Hardware Error]: error_type: 0x04: TLB error 71*4cc10308SMauro Carvalho Chehab[Hardware Error]: error_info: 0x000000000054007f 72*4cc10308SMauro Carvalho Chehab[Hardware Error]: transaction type: Instruction 73*4cc10308SMauro Carvalho Chehab[Hardware Error]: TLB error, operation type: Instruction fetch 74*4cc10308SMauro Carvalho Chehab[Hardware Error]: TLB level: 1 75*4cc10308SMauro Carvalho Chehab[Hardware Error]: processor context not corrupted 76*4cc10308SMauro Carvalho Chehab[Hardware Error]: the error has not been corrected 77*4cc10308SMauro Carvalho Chehab[Hardware Error]: PC is imprecise 78*4cc10308SMauro Carvalho Chehab[Hardware Error]: Error info structure 2: 79*4cc10308SMauro Carvalho Chehab[Hardware Error]: num errors: 2 80*4cc10308SMauro Carvalho Chehab[Hardware Error]: error_type: 0x08: bus error 81*4cc10308SMauro Carvalho Chehab[Hardware Error]: error_info: 0x00000080d6460fff 82*4cc10308SMauro Carvalho Chehab[Hardware Error]: transaction type: Generic 83*4cc10308SMauro Carvalho Chehab[Hardware Error]: bus error, operation type: Generic read (type of instruction or data request cannot be determined) 84*4cc10308SMauro Carvalho Chehab[Hardware Error]: affinity level at which the bus error occurred: 1 85*4cc10308SMauro Carvalho Chehab[Hardware Error]: processor context corrupted 86*4cc10308SMauro Carvalho Chehab[Hardware Error]: the error has been corrected 87*4cc10308SMauro Carvalho Chehab[Hardware Error]: PC is imprecise 88*4cc10308SMauro Carvalho Chehab[Hardware Error]: Program execution can be restarted reliably at the PC associated with the error. 89*4cc10308SMauro Carvalho Chehab[Hardware Error]: participation type: Local processor observed 90*4cc10308SMauro Carvalho Chehab[Hardware Error]: request timed out 91*4cc10308SMauro Carvalho Chehab[Hardware Error]: address space: External Memory Access 92*4cc10308SMauro Carvalho Chehab[Hardware Error]: memory access attributes:0x20 93*4cc10308SMauro Carvalho Chehab[Hardware Error]: access mode: secure 94*4cc10308SMauro Carvalho Chehab[Hardware Error]: Error info structure 3: 95*4cc10308SMauro Carvalho Chehab[Hardware Error]: num errors: 2 96*4cc10308SMauro Carvalho Chehab[Hardware Error]: error_type: 0x10: micro-architectural error 97*4cc10308SMauro Carvalho Chehab[Hardware Error]: error_info: 0x0000000078da03ff 98*4cc10308SMauro Carvalho Chehab[Hardware Error]: Error info structure 4: 99*4cc10308SMauro Carvalho Chehab[Hardware Error]: num errors: 2 100*4cc10308SMauro Carvalho Chehab[Hardware Error]: error_type: 0x14: TLB error|micro-architectural error 101*4cc10308SMauro Carvalho Chehab[Hardware Error]: Context info structure 0: 102*4cc10308SMauro Carvalho Chehab[Hardware Error]: register context type: AArch64 EL1 context registers 103*4cc10308SMauro Carvalho Chehab[Hardware Error]: 00000000: 00000000 00000000 104*4cc10308SMauro Carvalho Chehab[Hardware Error]: Vendor specific error info has 5 bytes: 105*4cc10308SMauro Carvalho Chehab[Hardware Error]: 00000000: 13 7b 04 05 01 .{... 106*4cc10308SMauro Carvalho Chehab[Firmware Warn]: GHES: Unhandled processor error type 0x02: cache error 107*4cc10308SMauro Carvalho Chehab[Firmware Warn]: GHES: Unhandled processor error type 0x04: TLB error 108*4cc10308SMauro Carvalho Chehab[Firmware Warn]: GHES: Unhandled processor error type 0x08: bus error 109*4cc10308SMauro Carvalho Chehab[Firmware Warn]: GHES: Unhandled processor error type 0x10: micro-architectural error 110*4cc10308SMauro Carvalho Chehab[Firmware Warn]: GHES: Unhandled processor error type 0x14: TLB error|micro-architectural error 111*4cc10308SMauro Carvalho Chehab""" 112*4cc10308SMauro Carvalho Chehab 113*4cc10308SMauro Carvalho Chehabimport argparse 114*4cc10308SMauro Carvalho Chehabimport re 115*4cc10308SMauro Carvalho Chehab 116*4cc10308SMauro Carvalho Chehabfrom qmp_helper import qmp, util, cper_guid 117*4cc10308SMauro Carvalho Chehab 118*4cc10308SMauro Carvalho Chehab 119*4cc10308SMauro Carvalho Chehabclass ArmProcessorEinj: 120*4cc10308SMauro Carvalho Chehab """ 121*4cc10308SMauro Carvalho Chehab Implements ARM Processor Error injection via GHES 122*4cc10308SMauro Carvalho Chehab """ 123*4cc10308SMauro Carvalho Chehab 124*4cc10308SMauro Carvalho Chehab DESC = """ 125*4cc10308SMauro Carvalho Chehab Generates an ARM processor error CPER, compatible with 126*4cc10308SMauro Carvalho Chehab UEFI 2.9A Errata. 127*4cc10308SMauro Carvalho Chehab """ 128*4cc10308SMauro Carvalho Chehab 129*4cc10308SMauro Carvalho Chehab ACPI_GHES_ARM_CPER_LENGTH = 40 130*4cc10308SMauro Carvalho Chehab ACPI_GHES_ARM_CPER_PEI_LENGTH = 32 131*4cc10308SMauro Carvalho Chehab 132*4cc10308SMauro Carvalho Chehab # Context types 133*4cc10308SMauro Carvalho Chehab CONTEXT_AARCH32_EL1 = 1 134*4cc10308SMauro Carvalho Chehab CONTEXT_AARCH64_EL1 = 5 135*4cc10308SMauro Carvalho Chehab CONTEXT_MISC_REG = 8 136*4cc10308SMauro Carvalho Chehab 137*4cc10308SMauro Carvalho Chehab def __init__(self, subparsers): 138*4cc10308SMauro Carvalho Chehab """Initialize the error injection class and add subparser""" 139*4cc10308SMauro Carvalho Chehab 140*4cc10308SMauro Carvalho Chehab # Valid choice values 141*4cc10308SMauro Carvalho Chehab self.arm_valid_bits = { 142*4cc10308SMauro Carvalho Chehab "mpidr": util.bit(0), 143*4cc10308SMauro Carvalho Chehab "affinity": util.bit(1), 144*4cc10308SMauro Carvalho Chehab "running": util.bit(2), 145*4cc10308SMauro Carvalho Chehab "vendor": util.bit(3), 146*4cc10308SMauro Carvalho Chehab } 147*4cc10308SMauro Carvalho Chehab 148*4cc10308SMauro Carvalho Chehab self.pei_flags = { 149*4cc10308SMauro Carvalho Chehab "first": util.bit(0), 150*4cc10308SMauro Carvalho Chehab "last": util.bit(1), 151*4cc10308SMauro Carvalho Chehab "propagated": util.bit(2), 152*4cc10308SMauro Carvalho Chehab "overflow": util.bit(3), 153*4cc10308SMauro Carvalho Chehab } 154*4cc10308SMauro Carvalho Chehab 155*4cc10308SMauro Carvalho Chehab self.pei_error_types = { 156*4cc10308SMauro Carvalho Chehab "cache": util.bit(1), 157*4cc10308SMauro Carvalho Chehab "tlb": util.bit(2), 158*4cc10308SMauro Carvalho Chehab "bus": util.bit(3), 159*4cc10308SMauro Carvalho Chehab "micro-arch": util.bit(4), 160*4cc10308SMauro Carvalho Chehab } 161*4cc10308SMauro Carvalho Chehab 162*4cc10308SMauro Carvalho Chehab self.pei_valid_bits = { 163*4cc10308SMauro Carvalho Chehab "multiple-error": util.bit(0), 164*4cc10308SMauro Carvalho Chehab "flags": util.bit(1), 165*4cc10308SMauro Carvalho Chehab "error-info": util.bit(2), 166*4cc10308SMauro Carvalho Chehab "virt-addr": util.bit(3), 167*4cc10308SMauro Carvalho Chehab "phy-addr": util.bit(4), 168*4cc10308SMauro Carvalho Chehab } 169*4cc10308SMauro Carvalho Chehab 170*4cc10308SMauro Carvalho Chehab self.data = bytearray() 171*4cc10308SMauro Carvalho Chehab 172*4cc10308SMauro Carvalho Chehab parser = subparsers.add_parser("arm", description=self.DESC) 173*4cc10308SMauro Carvalho Chehab 174*4cc10308SMauro Carvalho Chehab arm_valid_bits = ",".join(self.arm_valid_bits.keys()) 175*4cc10308SMauro Carvalho Chehab flags = ",".join(self.pei_flags.keys()) 176*4cc10308SMauro Carvalho Chehab error_types = ",".join(self.pei_error_types.keys()) 177*4cc10308SMauro Carvalho Chehab pei_valid_bits = ",".join(self.pei_valid_bits.keys()) 178*4cc10308SMauro Carvalho Chehab 179*4cc10308SMauro Carvalho Chehab # UEFI N.16 ARM Validation bits 180*4cc10308SMauro Carvalho Chehab g_arm = parser.add_argument_group("ARM processor") 181*4cc10308SMauro Carvalho Chehab g_arm.add_argument("--arm", "--arm-valid", 182*4cc10308SMauro Carvalho Chehab help=f"ARM valid bits: {arm_valid_bits}") 183*4cc10308SMauro Carvalho Chehab g_arm.add_argument("-a", "--affinity", "--level", "--affinity-level", 184*4cc10308SMauro Carvalho Chehab type=lambda x: int(x, 0), 185*4cc10308SMauro Carvalho Chehab help="Affinity level (when multiple levels apply)") 186*4cc10308SMauro Carvalho Chehab g_arm.add_argument("-l", "--mpidr", type=lambda x: int(x, 0), 187*4cc10308SMauro Carvalho Chehab help="Multiprocessor Affinity Register") 188*4cc10308SMauro Carvalho Chehab g_arm.add_argument("-i", "--midr", type=lambda x: int(x, 0), 189*4cc10308SMauro Carvalho Chehab help="Main ID Register") 190*4cc10308SMauro Carvalho Chehab g_arm.add_argument("-r", "--running", 191*4cc10308SMauro Carvalho Chehab action=argparse.BooleanOptionalAction, 192*4cc10308SMauro Carvalho Chehab default=None, 193*4cc10308SMauro Carvalho Chehab help="Indicates if the processor is running or not") 194*4cc10308SMauro Carvalho Chehab g_arm.add_argument("--psci", "--psci-state", 195*4cc10308SMauro Carvalho Chehab type=lambda x: int(x, 0), 196*4cc10308SMauro Carvalho Chehab help="Power State Coordination Interface - PSCI state") 197*4cc10308SMauro Carvalho Chehab 198*4cc10308SMauro Carvalho Chehab # TODO: Add vendor-specific support 199*4cc10308SMauro Carvalho Chehab 200*4cc10308SMauro Carvalho Chehab # UEFI N.17 bitmaps (type and flags) 201*4cc10308SMauro Carvalho Chehab g_pei = parser.add_argument_group("ARM Processor Error Info (PEI)") 202*4cc10308SMauro Carvalho Chehab g_pei.add_argument("-t", "--type", nargs="+", 203*4cc10308SMauro Carvalho Chehab help=f"one or more error types: {error_types}") 204*4cc10308SMauro Carvalho Chehab g_pei.add_argument("-f", "--flags", nargs="*", 205*4cc10308SMauro Carvalho Chehab help=f"zero or more error flags: {flags}") 206*4cc10308SMauro Carvalho Chehab g_pei.add_argument("-V", "--pei-valid", "--error-valid", nargs="*", 207*4cc10308SMauro Carvalho Chehab help=f"zero or more PEI valid bits: {pei_valid_bits}") 208*4cc10308SMauro Carvalho Chehab 209*4cc10308SMauro Carvalho Chehab # UEFI N.17 Integer values 210*4cc10308SMauro Carvalho Chehab g_pei.add_argument("-m", "--multiple-error", nargs="+", 211*4cc10308SMauro Carvalho Chehab help="Number of errors: 0: Single error, 1: Multiple errors, 2-65535: Error count if known") 212*4cc10308SMauro Carvalho Chehab g_pei.add_argument("-e", "--error-info", nargs="+", 213*4cc10308SMauro Carvalho Chehab help="Error information (UEFI 2.10 tables N.18 to N.20)") 214*4cc10308SMauro Carvalho Chehab g_pei.add_argument("-p", "--physical-address", nargs="+", 215*4cc10308SMauro Carvalho Chehab help="Physical address") 216*4cc10308SMauro Carvalho Chehab g_pei.add_argument("-v", "--virtual-address", nargs="+", 217*4cc10308SMauro Carvalho Chehab help="Virtual address") 218*4cc10308SMauro Carvalho Chehab 219*4cc10308SMauro Carvalho Chehab # UEFI N.21 Context 220*4cc10308SMauro Carvalho Chehab g_ctx = parser.add_argument_group("Processor Context") 221*4cc10308SMauro Carvalho Chehab g_ctx.add_argument("--ctx-type", "--context-type", nargs="*", 222*4cc10308SMauro Carvalho Chehab help="Type of the context (0=ARM32 GPR, 5=ARM64 EL1, other values supported)") 223*4cc10308SMauro Carvalho Chehab g_ctx.add_argument("--ctx-size", "--context-size", nargs="*", 224*4cc10308SMauro Carvalho Chehab help="Minimal size of the context") 225*4cc10308SMauro Carvalho Chehab g_ctx.add_argument("--ctx-array", "--context-array", nargs="*", 226*4cc10308SMauro Carvalho Chehab help="Comma-separated arrays for each context") 227*4cc10308SMauro Carvalho Chehab 228*4cc10308SMauro Carvalho Chehab # Vendor-specific data 229*4cc10308SMauro Carvalho Chehab g_vendor = parser.add_argument_group("Vendor-specific data") 230*4cc10308SMauro Carvalho Chehab g_vendor.add_argument("--vendor", "--vendor-specific", nargs="+", 231*4cc10308SMauro Carvalho Chehab help="Vendor-specific byte arrays of data") 232*4cc10308SMauro Carvalho Chehab 233*4cc10308SMauro Carvalho Chehab # Add arguments for Generic Error Data 234*4cc10308SMauro Carvalho Chehab qmp.argparse(parser) 235*4cc10308SMauro Carvalho Chehab 236*4cc10308SMauro Carvalho Chehab parser.set_defaults(func=self.send_cper) 237*4cc10308SMauro Carvalho Chehab 238*4cc10308SMauro Carvalho Chehab def send_cper(self, args): 239*4cc10308SMauro Carvalho Chehab """Parse subcommand arguments and send a CPER via QMP""" 240*4cc10308SMauro Carvalho Chehab 241*4cc10308SMauro Carvalho Chehab qmp_cmd = qmp(args.host, args.port, args.debug) 242*4cc10308SMauro Carvalho Chehab 243*4cc10308SMauro Carvalho Chehab # Handle Generic Error Data arguments if any 244*4cc10308SMauro Carvalho Chehab qmp_cmd.set_args(args) 245*4cc10308SMauro Carvalho Chehab 246*4cc10308SMauro Carvalho Chehab is_cpu_type = re.compile(r"^([\w+]+\-)?arm\-cpu$") 247*4cc10308SMauro Carvalho Chehab cpus = qmp_cmd.search_qom("/machine/unattached/device", 248*4cc10308SMauro Carvalho Chehab "type", is_cpu_type) 249*4cc10308SMauro Carvalho Chehab 250*4cc10308SMauro Carvalho Chehab cper = {} 251*4cc10308SMauro Carvalho Chehab pei = {} 252*4cc10308SMauro Carvalho Chehab ctx = {} 253*4cc10308SMauro Carvalho Chehab vendor = {} 254*4cc10308SMauro Carvalho Chehab 255*4cc10308SMauro Carvalho Chehab arg = vars(args) 256*4cc10308SMauro Carvalho Chehab 257*4cc10308SMauro Carvalho Chehab # Handle global parameters 258*4cc10308SMauro Carvalho Chehab if args.arm: 259*4cc10308SMauro Carvalho Chehab arm_valid_init = False 260*4cc10308SMauro Carvalho Chehab cper["valid"] = util.get_choice(name="valid", 261*4cc10308SMauro Carvalho Chehab value=args.arm, 262*4cc10308SMauro Carvalho Chehab choices=self.arm_valid_bits, 263*4cc10308SMauro Carvalho Chehab suffixes=["-error", "-err"]) 264*4cc10308SMauro Carvalho Chehab else: 265*4cc10308SMauro Carvalho Chehab cper["valid"] = 0 266*4cc10308SMauro Carvalho Chehab arm_valid_init = True 267*4cc10308SMauro Carvalho Chehab 268*4cc10308SMauro Carvalho Chehab if "running" in arg: 269*4cc10308SMauro Carvalho Chehab if args.running: 270*4cc10308SMauro Carvalho Chehab cper["running-state"] = util.bit(0) 271*4cc10308SMauro Carvalho Chehab else: 272*4cc10308SMauro Carvalho Chehab cper["running-state"] = 0 273*4cc10308SMauro Carvalho Chehab else: 274*4cc10308SMauro Carvalho Chehab cper["running-state"] = 0 275*4cc10308SMauro Carvalho Chehab 276*4cc10308SMauro Carvalho Chehab if arm_valid_init: 277*4cc10308SMauro Carvalho Chehab if args.affinity: 278*4cc10308SMauro Carvalho Chehab cper["valid"] |= self.arm_valid_bits["affinity"] 279*4cc10308SMauro Carvalho Chehab 280*4cc10308SMauro Carvalho Chehab if args.mpidr: 281*4cc10308SMauro Carvalho Chehab cper["valid"] |= self.arm_valid_bits["mpidr"] 282*4cc10308SMauro Carvalho Chehab 283*4cc10308SMauro Carvalho Chehab if "running-state" in cper: 284*4cc10308SMauro Carvalho Chehab cper["valid"] |= self.arm_valid_bits["running"] 285*4cc10308SMauro Carvalho Chehab 286*4cc10308SMauro Carvalho Chehab if args.psci: 287*4cc10308SMauro Carvalho Chehab cper["valid"] |= self.arm_valid_bits["running"] 288*4cc10308SMauro Carvalho Chehab 289*4cc10308SMauro Carvalho Chehab # Handle PEI 290*4cc10308SMauro Carvalho Chehab if not args.type: 291*4cc10308SMauro Carvalho Chehab args.type = ["cache-error"] 292*4cc10308SMauro Carvalho Chehab 293*4cc10308SMauro Carvalho Chehab util.get_mult_choices( 294*4cc10308SMauro Carvalho Chehab pei, 295*4cc10308SMauro Carvalho Chehab name="valid", 296*4cc10308SMauro Carvalho Chehab values=args.pei_valid, 297*4cc10308SMauro Carvalho Chehab choices=self.pei_valid_bits, 298*4cc10308SMauro Carvalho Chehab suffixes=["-valid", "--addr"], 299*4cc10308SMauro Carvalho Chehab ) 300*4cc10308SMauro Carvalho Chehab util.get_mult_choices( 301*4cc10308SMauro Carvalho Chehab pei, 302*4cc10308SMauro Carvalho Chehab name="type", 303*4cc10308SMauro Carvalho Chehab values=args.type, 304*4cc10308SMauro Carvalho Chehab choices=self.pei_error_types, 305*4cc10308SMauro Carvalho Chehab suffixes=["-error", "-err"], 306*4cc10308SMauro Carvalho Chehab ) 307*4cc10308SMauro Carvalho Chehab util.get_mult_choices( 308*4cc10308SMauro Carvalho Chehab pei, 309*4cc10308SMauro Carvalho Chehab name="flags", 310*4cc10308SMauro Carvalho Chehab values=args.flags, 311*4cc10308SMauro Carvalho Chehab choices=self.pei_flags, 312*4cc10308SMauro Carvalho Chehab suffixes=["-error", "-cap"], 313*4cc10308SMauro Carvalho Chehab ) 314*4cc10308SMauro Carvalho Chehab util.get_mult_int(pei, "error-info", args.error_info) 315*4cc10308SMauro Carvalho Chehab util.get_mult_int(pei, "multiple-error", args.multiple_error) 316*4cc10308SMauro Carvalho Chehab util.get_mult_int(pei, "phy-addr", args.physical_address) 317*4cc10308SMauro Carvalho Chehab util.get_mult_int(pei, "virt-addr", args.virtual_address) 318*4cc10308SMauro Carvalho Chehab 319*4cc10308SMauro Carvalho Chehab # Handle context 320*4cc10308SMauro Carvalho Chehab util.get_mult_int(ctx, "type", args.ctx_type, allow_zero=True) 321*4cc10308SMauro Carvalho Chehab util.get_mult_int(ctx, "minimal-size", args.ctx_size, allow_zero=True) 322*4cc10308SMauro Carvalho Chehab util.get_mult_array(ctx, "register", args.ctx_array, allow_zero=True) 323*4cc10308SMauro Carvalho Chehab 324*4cc10308SMauro Carvalho Chehab util.get_mult_array(vendor, "bytes", args.vendor, max_val=255) 325*4cc10308SMauro Carvalho Chehab 326*4cc10308SMauro Carvalho Chehab # Store PEI 327*4cc10308SMauro Carvalho Chehab pei_data = bytearray() 328*4cc10308SMauro Carvalho Chehab default_flags = self.pei_flags["first"] 329*4cc10308SMauro Carvalho Chehab default_flags |= self.pei_flags["last"] 330*4cc10308SMauro Carvalho Chehab 331*4cc10308SMauro Carvalho Chehab error_info_num = 0 332*4cc10308SMauro Carvalho Chehab 333*4cc10308SMauro Carvalho Chehab for i, p in pei.items(): # pylint: disable=W0612 334*4cc10308SMauro Carvalho Chehab error_info_num += 1 335*4cc10308SMauro Carvalho Chehab 336*4cc10308SMauro Carvalho Chehab # UEFI 2.10 doesn't define how to encode error information 337*4cc10308SMauro Carvalho Chehab # when multiple types are raised. So, provide a default only 338*4cc10308SMauro Carvalho Chehab # if a single type is there 339*4cc10308SMauro Carvalho Chehab if "error-info" not in p: 340*4cc10308SMauro Carvalho Chehab if p["type"] == util.bit(1): 341*4cc10308SMauro Carvalho Chehab p["error-info"] = 0x0091000F 342*4cc10308SMauro Carvalho Chehab if p["type"] == util.bit(2): 343*4cc10308SMauro Carvalho Chehab p["error-info"] = 0x0054007F 344*4cc10308SMauro Carvalho Chehab if p["type"] == util.bit(3): 345*4cc10308SMauro Carvalho Chehab p["error-info"] = 0x80D6460FFF 346*4cc10308SMauro Carvalho Chehab if p["type"] == util.bit(4): 347*4cc10308SMauro Carvalho Chehab p["error-info"] = 0x78DA03FF 348*4cc10308SMauro Carvalho Chehab 349*4cc10308SMauro Carvalho Chehab if "valid" not in p: 350*4cc10308SMauro Carvalho Chehab p["valid"] = 0 351*4cc10308SMauro Carvalho Chehab if "multiple-error" in p: 352*4cc10308SMauro Carvalho Chehab p["valid"] |= self.pei_valid_bits["multiple-error"] 353*4cc10308SMauro Carvalho Chehab 354*4cc10308SMauro Carvalho Chehab if "flags" in p: 355*4cc10308SMauro Carvalho Chehab p["valid"] |= self.pei_valid_bits["flags"] 356*4cc10308SMauro Carvalho Chehab 357*4cc10308SMauro Carvalho Chehab if "error-info" in p: 358*4cc10308SMauro Carvalho Chehab p["valid"] |= self.pei_valid_bits["error-info"] 359*4cc10308SMauro Carvalho Chehab 360*4cc10308SMauro Carvalho Chehab if "phy-addr" in p: 361*4cc10308SMauro Carvalho Chehab p["valid"] |= self.pei_valid_bits["phy-addr"] 362*4cc10308SMauro Carvalho Chehab 363*4cc10308SMauro Carvalho Chehab if "virt-addr" in p: 364*4cc10308SMauro Carvalho Chehab p["valid"] |= self.pei_valid_bits["virt-addr"] 365*4cc10308SMauro Carvalho Chehab 366*4cc10308SMauro Carvalho Chehab # Version 367*4cc10308SMauro Carvalho Chehab util.data_add(pei_data, 0, 1) 368*4cc10308SMauro Carvalho Chehab 369*4cc10308SMauro Carvalho Chehab util.data_add(pei_data, 370*4cc10308SMauro Carvalho Chehab self.ACPI_GHES_ARM_CPER_PEI_LENGTH, 1) 371*4cc10308SMauro Carvalho Chehab 372*4cc10308SMauro Carvalho Chehab util.data_add(pei_data, p["valid"], 2) 373*4cc10308SMauro Carvalho Chehab util.data_add(pei_data, p["type"], 1) 374*4cc10308SMauro Carvalho Chehab util.data_add(pei_data, p.get("multiple-error", 1), 2) 375*4cc10308SMauro Carvalho Chehab util.data_add(pei_data, p.get("flags", default_flags), 1) 376*4cc10308SMauro Carvalho Chehab util.data_add(pei_data, p.get("error-info", 0), 8) 377*4cc10308SMauro Carvalho Chehab util.data_add(pei_data, p.get("virt-addr", 0xDEADBEEF), 8) 378*4cc10308SMauro Carvalho Chehab util.data_add(pei_data, p.get("phy-addr", 0xABBA0BAD), 8) 379*4cc10308SMauro Carvalho Chehab 380*4cc10308SMauro Carvalho Chehab # Store Context 381*4cc10308SMauro Carvalho Chehab ctx_data = bytearray() 382*4cc10308SMauro Carvalho Chehab context_info_num = 0 383*4cc10308SMauro Carvalho Chehab 384*4cc10308SMauro Carvalho Chehab if ctx: 385*4cc10308SMauro Carvalho Chehab ret = qmp_cmd.send_cmd("query-target", may_open=True) 386*4cc10308SMauro Carvalho Chehab 387*4cc10308SMauro Carvalho Chehab default_ctx = self.CONTEXT_MISC_REG 388*4cc10308SMauro Carvalho Chehab 389*4cc10308SMauro Carvalho Chehab if "arch" in ret: 390*4cc10308SMauro Carvalho Chehab if ret["arch"] == "aarch64": 391*4cc10308SMauro Carvalho Chehab default_ctx = self.CONTEXT_AARCH64_EL1 392*4cc10308SMauro Carvalho Chehab elif ret["arch"] == "arm": 393*4cc10308SMauro Carvalho Chehab default_ctx = self.CONTEXT_AARCH32_EL1 394*4cc10308SMauro Carvalho Chehab 395*4cc10308SMauro Carvalho Chehab for k in sorted(ctx.keys()): 396*4cc10308SMauro Carvalho Chehab context_info_num += 1 397*4cc10308SMauro Carvalho Chehab 398*4cc10308SMauro Carvalho Chehab if "type" not in ctx[k]: 399*4cc10308SMauro Carvalho Chehab ctx[k]["type"] = default_ctx 400*4cc10308SMauro Carvalho Chehab 401*4cc10308SMauro Carvalho Chehab if "register" not in ctx[k]: 402*4cc10308SMauro Carvalho Chehab ctx[k]["register"] = [] 403*4cc10308SMauro Carvalho Chehab 404*4cc10308SMauro Carvalho Chehab reg_size = len(ctx[k]["register"]) 405*4cc10308SMauro Carvalho Chehab size = 0 406*4cc10308SMauro Carvalho Chehab 407*4cc10308SMauro Carvalho Chehab if "minimal-size" in ctx: 408*4cc10308SMauro Carvalho Chehab size = ctx[k]["minimal-size"] 409*4cc10308SMauro Carvalho Chehab 410*4cc10308SMauro Carvalho Chehab size = max(size, reg_size) 411*4cc10308SMauro Carvalho Chehab 412*4cc10308SMauro Carvalho Chehab size = (size + 1) % 0xFFFE 413*4cc10308SMauro Carvalho Chehab 414*4cc10308SMauro Carvalho Chehab # Version 415*4cc10308SMauro Carvalho Chehab util.data_add(ctx_data, 0, 2) 416*4cc10308SMauro Carvalho Chehab 417*4cc10308SMauro Carvalho Chehab util.data_add(ctx_data, ctx[k]["type"], 2) 418*4cc10308SMauro Carvalho Chehab 419*4cc10308SMauro Carvalho Chehab util.data_add(ctx_data, 8 * size, 4) 420*4cc10308SMauro Carvalho Chehab 421*4cc10308SMauro Carvalho Chehab for r in ctx[k]["register"]: 422*4cc10308SMauro Carvalho Chehab util.data_add(ctx_data, r, 8) 423*4cc10308SMauro Carvalho Chehab 424*4cc10308SMauro Carvalho Chehab for i in range(reg_size, size): # pylint: disable=W0612 425*4cc10308SMauro Carvalho Chehab util.data_add(ctx_data, 0, 8) 426*4cc10308SMauro Carvalho Chehab 427*4cc10308SMauro Carvalho Chehab # Vendor-specific bytes are not grouped 428*4cc10308SMauro Carvalho Chehab vendor_data = bytearray() 429*4cc10308SMauro Carvalho Chehab if vendor: 430*4cc10308SMauro Carvalho Chehab for k in sorted(vendor.keys()): 431*4cc10308SMauro Carvalho Chehab for b in vendor[k]["bytes"]: 432*4cc10308SMauro Carvalho Chehab util.data_add(vendor_data, b, 1) 433*4cc10308SMauro Carvalho Chehab 434*4cc10308SMauro Carvalho Chehab # Encode ARM Processor Error 435*4cc10308SMauro Carvalho Chehab data = bytearray() 436*4cc10308SMauro Carvalho Chehab 437*4cc10308SMauro Carvalho Chehab util.data_add(data, cper["valid"], 4) 438*4cc10308SMauro Carvalho Chehab 439*4cc10308SMauro Carvalho Chehab util.data_add(data, error_info_num, 2) 440*4cc10308SMauro Carvalho Chehab util.data_add(data, context_info_num, 2) 441*4cc10308SMauro Carvalho Chehab 442*4cc10308SMauro Carvalho Chehab # Calculate the length of the CPER data 443*4cc10308SMauro Carvalho Chehab cper_length = self.ACPI_GHES_ARM_CPER_LENGTH 444*4cc10308SMauro Carvalho Chehab cper_length += len(pei_data) 445*4cc10308SMauro Carvalho Chehab cper_length += len(vendor_data) 446*4cc10308SMauro Carvalho Chehab cper_length += len(ctx_data) 447*4cc10308SMauro Carvalho Chehab util.data_add(data, cper_length, 4) 448*4cc10308SMauro Carvalho Chehab 449*4cc10308SMauro Carvalho Chehab util.data_add(data, arg.get("affinity-level", 0), 1) 450*4cc10308SMauro Carvalho Chehab 451*4cc10308SMauro Carvalho Chehab # Reserved 452*4cc10308SMauro Carvalho Chehab util.data_add(data, 0, 3) 453*4cc10308SMauro Carvalho Chehab 454*4cc10308SMauro Carvalho Chehab if "midr-el1" not in arg: 455*4cc10308SMauro Carvalho Chehab if cpus: 456*4cc10308SMauro Carvalho Chehab cmd_arg = { 457*4cc10308SMauro Carvalho Chehab 'path': cpus[0], 458*4cc10308SMauro Carvalho Chehab 'property': "midr" 459*4cc10308SMauro Carvalho Chehab } 460*4cc10308SMauro Carvalho Chehab ret = qmp_cmd.send_cmd("qom-get", cmd_arg, may_open=True) 461*4cc10308SMauro Carvalho Chehab if isinstance(ret, int): 462*4cc10308SMauro Carvalho Chehab arg["midr-el1"] = ret 463*4cc10308SMauro Carvalho Chehab 464*4cc10308SMauro Carvalho Chehab util.data_add(data, arg.get("mpidr-el1", 0), 8) 465*4cc10308SMauro Carvalho Chehab util.data_add(data, arg.get("midr-el1", 0), 8) 466*4cc10308SMauro Carvalho Chehab util.data_add(data, cper["running-state"], 4) 467*4cc10308SMauro Carvalho Chehab util.data_add(data, arg.get("psci-state", 0), 4) 468*4cc10308SMauro Carvalho Chehab 469*4cc10308SMauro Carvalho Chehab # Add PEI 470*4cc10308SMauro Carvalho Chehab data.extend(pei_data) 471*4cc10308SMauro Carvalho Chehab data.extend(ctx_data) 472*4cc10308SMauro Carvalho Chehab data.extend(vendor_data) 473*4cc10308SMauro Carvalho Chehab 474*4cc10308SMauro Carvalho Chehab self.data = data 475*4cc10308SMauro Carvalho Chehab 476*4cc10308SMauro Carvalho Chehab qmp_cmd.send_cper(cper_guid.CPER_PROC_ARM, self.data) 477