162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * apei-internal.h - ACPI Platform Error Interface internal 462306a36Sopenharmony_ci * definitions. 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#ifndef APEI_INTERNAL_H 862306a36Sopenharmony_ci#define APEI_INTERNAL_H 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <linux/acpi.h> 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_cistruct apei_exec_context; 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_citypedef int (*apei_exec_ins_func_t)(struct apei_exec_context *ctx, 1562306a36Sopenharmony_ci struct acpi_whea_header *entry); 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#define APEI_EXEC_INS_ACCESS_REGISTER 0x0001 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_cistruct apei_exec_ins_type { 2062306a36Sopenharmony_ci u32 flags; 2162306a36Sopenharmony_ci apei_exec_ins_func_t run; 2262306a36Sopenharmony_ci}; 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_cistruct apei_exec_context { 2562306a36Sopenharmony_ci u32 ip; 2662306a36Sopenharmony_ci u64 value; 2762306a36Sopenharmony_ci u64 var1; 2862306a36Sopenharmony_ci u64 var2; 2962306a36Sopenharmony_ci u64 src_base; 3062306a36Sopenharmony_ci u64 dst_base; 3162306a36Sopenharmony_ci struct apei_exec_ins_type *ins_table; 3262306a36Sopenharmony_ci u32 instructions; 3362306a36Sopenharmony_ci struct acpi_whea_header *action_table; 3462306a36Sopenharmony_ci u32 entries; 3562306a36Sopenharmony_ci}; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_civoid apei_exec_ctx_init(struct apei_exec_context *ctx, 3862306a36Sopenharmony_ci struct apei_exec_ins_type *ins_table, 3962306a36Sopenharmony_ci u32 instructions, 4062306a36Sopenharmony_ci struct acpi_whea_header *action_table, 4162306a36Sopenharmony_ci u32 entries); 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_cistatic inline void apei_exec_ctx_set_input(struct apei_exec_context *ctx, 4462306a36Sopenharmony_ci u64 input) 4562306a36Sopenharmony_ci{ 4662306a36Sopenharmony_ci ctx->value = input; 4762306a36Sopenharmony_ci} 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_cistatic inline u64 apei_exec_ctx_get_output(struct apei_exec_context *ctx) 5062306a36Sopenharmony_ci{ 5162306a36Sopenharmony_ci return ctx->value; 5262306a36Sopenharmony_ci} 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ciint __apei_exec_run(struct apei_exec_context *ctx, u8 action, bool optional); 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_cistatic inline int apei_exec_run(struct apei_exec_context *ctx, u8 action) 5762306a36Sopenharmony_ci{ 5862306a36Sopenharmony_ci return __apei_exec_run(ctx, action, 0); 5962306a36Sopenharmony_ci} 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci/* It is optional whether the firmware provides the action */ 6262306a36Sopenharmony_cistatic inline int apei_exec_run_optional(struct apei_exec_context *ctx, u8 action) 6362306a36Sopenharmony_ci{ 6462306a36Sopenharmony_ci return __apei_exec_run(ctx, action, 1); 6562306a36Sopenharmony_ci} 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci/* Common instruction implementation */ 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci/* IP has been set in instruction function */ 7062306a36Sopenharmony_ci#define APEI_EXEC_SET_IP 1 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ciint apei_map_generic_address(struct acpi_generic_address *reg); 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_cistatic inline void apei_unmap_generic_address(struct acpi_generic_address *reg) 7562306a36Sopenharmony_ci{ 7662306a36Sopenharmony_ci acpi_os_unmap_generic_address(reg); 7762306a36Sopenharmony_ci} 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ciint apei_read(u64 *val, struct acpi_generic_address *reg); 8062306a36Sopenharmony_ciint apei_write(u64 val, struct acpi_generic_address *reg); 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ciint __apei_exec_read_register(struct acpi_whea_header *entry, u64 *val); 8362306a36Sopenharmony_ciint __apei_exec_write_register(struct acpi_whea_header *entry, u64 val); 8462306a36Sopenharmony_ciint apei_exec_read_register(struct apei_exec_context *ctx, 8562306a36Sopenharmony_ci struct acpi_whea_header *entry); 8662306a36Sopenharmony_ciint apei_exec_read_register_value(struct apei_exec_context *ctx, 8762306a36Sopenharmony_ci struct acpi_whea_header *entry); 8862306a36Sopenharmony_ciint apei_exec_write_register(struct apei_exec_context *ctx, 8962306a36Sopenharmony_ci struct acpi_whea_header *entry); 9062306a36Sopenharmony_ciint apei_exec_write_register_value(struct apei_exec_context *ctx, 9162306a36Sopenharmony_ci struct acpi_whea_header *entry); 9262306a36Sopenharmony_ciint apei_exec_noop(struct apei_exec_context *ctx, 9362306a36Sopenharmony_ci struct acpi_whea_header *entry); 9462306a36Sopenharmony_ciint apei_exec_pre_map_gars(struct apei_exec_context *ctx); 9562306a36Sopenharmony_ciint apei_exec_post_unmap_gars(struct apei_exec_context *ctx); 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_cistruct apei_resources { 9862306a36Sopenharmony_ci struct list_head iomem; 9962306a36Sopenharmony_ci struct list_head ioport; 10062306a36Sopenharmony_ci}; 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_cistatic inline void apei_resources_init(struct apei_resources *resources) 10362306a36Sopenharmony_ci{ 10462306a36Sopenharmony_ci INIT_LIST_HEAD(&resources->iomem); 10562306a36Sopenharmony_ci INIT_LIST_HEAD(&resources->ioport); 10662306a36Sopenharmony_ci} 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_civoid apei_resources_fini(struct apei_resources *resources); 10962306a36Sopenharmony_ciint apei_resources_add(struct apei_resources *resources, 11062306a36Sopenharmony_ci unsigned long start, unsigned long size, 11162306a36Sopenharmony_ci bool iomem); 11262306a36Sopenharmony_ciint apei_resources_sub(struct apei_resources *resources1, 11362306a36Sopenharmony_ci struct apei_resources *resources2); 11462306a36Sopenharmony_ciint apei_resources_request(struct apei_resources *resources, 11562306a36Sopenharmony_ci const char *desc); 11662306a36Sopenharmony_civoid apei_resources_release(struct apei_resources *resources); 11762306a36Sopenharmony_ciint apei_exec_collect_resources(struct apei_exec_context *ctx, 11862306a36Sopenharmony_ci struct apei_resources *resources); 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_cistruct dentry; 12162306a36Sopenharmony_cistruct dentry *apei_get_debugfs_dir(void); 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_cistatic inline u32 cper_estatus_len(struct acpi_hest_generic_status *estatus) 12462306a36Sopenharmony_ci{ 12562306a36Sopenharmony_ci if (estatus->raw_data_length) 12662306a36Sopenharmony_ci return estatus->raw_data_offset + \ 12762306a36Sopenharmony_ci estatus->raw_data_length; 12862306a36Sopenharmony_ci else 12962306a36Sopenharmony_ci return sizeof(*estatus) + estatus->data_length; 13062306a36Sopenharmony_ci} 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ciint apei_osc_setup(void); 13362306a36Sopenharmony_ci#endif 134