1a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying/* 2a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying * apei-internal.h - ACPI Platform Error Interface internal 3a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying * definations. 4a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying */ 5a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying 6a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying#ifndef APEI_INTERNAL_H 7a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying#define APEI_INTERNAL_H 8a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying 906d65deade9aabba58e0518df86dcd324e86b832Huang Ying#include <linux/cper.h> 10890b3d0ea620c942718dd29d601a7aaa4362280bHuang Ying#include <linux/acpi.h> 11890b3d0ea620c942718dd29d601a7aaa4362280bHuang Ying#include <linux/acpi_io.h> 1206d65deade9aabba58e0518df86dcd324e86b832Huang Ying 13a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Yingstruct apei_exec_context; 14a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying 15a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Yingtypedef int (*apei_exec_ins_func_t)(struct apei_exec_context *ctx, 16a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying struct acpi_whea_header *entry); 17a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying 18a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying#define APEI_EXEC_INS_ACCESS_REGISTER 0x0001 19a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying 20a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Yingstruct apei_exec_ins_type { 21a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying u32 flags; 22a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying apei_exec_ins_func_t run; 23a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying}; 24a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying 25a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Yingstruct apei_exec_context { 26a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying u32 ip; 27a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying u64 value; 28a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying u64 var1; 29a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying u64 var2; 30a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying u64 src_base; 31a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying u64 dst_base; 32a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying struct apei_exec_ins_type *ins_table; 33a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying u32 instructions; 34a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying struct acpi_whea_header *action_table; 35a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying u32 entries; 36a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying}; 37a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying 38a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Yingvoid apei_exec_ctx_init(struct apei_exec_context *ctx, 39a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying struct apei_exec_ins_type *ins_table, 40a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying u32 instructions, 41a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying struct acpi_whea_header *action_table, 42a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying u32 entries); 43a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying 44a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Yingstatic inline void apei_exec_ctx_set_input(struct apei_exec_context *ctx, 45a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying u64 input) 46a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying{ 47a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying ctx->value = input; 48a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying} 49a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying 50a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Yingstatic inline u64 apei_exec_ctx_get_output(struct apei_exec_context *ctx) 51a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying{ 52a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying return ctx->value; 53a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying} 54a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying 55eecf2f7124834dd1cad21807526a8ea031ba8217Huang Yingint __apei_exec_run(struct apei_exec_context *ctx, u8 action, bool optional); 56eecf2f7124834dd1cad21807526a8ea031ba8217Huang Ying 57eecf2f7124834dd1cad21807526a8ea031ba8217Huang Yingstatic inline int apei_exec_run(struct apei_exec_context *ctx, u8 action) 58eecf2f7124834dd1cad21807526a8ea031ba8217Huang Ying{ 59eecf2f7124834dd1cad21807526a8ea031ba8217Huang Ying return __apei_exec_run(ctx, action, 0); 60eecf2f7124834dd1cad21807526a8ea031ba8217Huang Ying} 61eecf2f7124834dd1cad21807526a8ea031ba8217Huang Ying 62eecf2f7124834dd1cad21807526a8ea031ba8217Huang Ying/* It is optional whether the firmware provides the action */ 63eecf2f7124834dd1cad21807526a8ea031ba8217Huang Yingstatic inline int apei_exec_run_optional(struct apei_exec_context *ctx, u8 action) 64eecf2f7124834dd1cad21807526a8ea031ba8217Huang Ying{ 65eecf2f7124834dd1cad21807526a8ea031ba8217Huang Ying return __apei_exec_run(ctx, action, 1); 66eecf2f7124834dd1cad21807526a8ea031ba8217Huang Ying} 67a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying 68a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying/* Common instruction implementation */ 69a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying 70a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying/* IP has been set in instruction function */ 71a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying#define APEI_EXEC_SET_IP 1 72a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying 73890b3d0ea620c942718dd29d601a7aaa4362280bHuang Yingint apei_map_generic_address(struct acpi_generic_address *reg); 74890b3d0ea620c942718dd29d601a7aaa4362280bHuang Ying 75890b3d0ea620c942718dd29d601a7aaa4362280bHuang Yingstatic inline void apei_unmap_generic_address(struct acpi_generic_address *reg) 76890b3d0ea620c942718dd29d601a7aaa4362280bHuang Ying{ 77890b3d0ea620c942718dd29d601a7aaa4362280bHuang Ying acpi_os_unmap_generic_address(reg); 78890b3d0ea620c942718dd29d601a7aaa4362280bHuang Ying} 79890b3d0ea620c942718dd29d601a7aaa4362280bHuang Ying 80700130b41f4ee54520ac2ef2f7f1d072789711a4Myron Stoweint apei_read(u64 *val, struct acpi_generic_address *reg); 81700130b41f4ee54520ac2ef2f7f1d072789711a4Myron Stoweint apei_write(u64 val, struct acpi_generic_address *reg); 82700130b41f4ee54520ac2ef2f7f1d072789711a4Myron Stowe 83a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Yingint __apei_exec_read_register(struct acpi_whea_header *entry, u64 *val); 84a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Yingint __apei_exec_write_register(struct acpi_whea_header *entry, u64 val); 85a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Yingint apei_exec_read_register(struct apei_exec_context *ctx, 86a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying struct acpi_whea_header *entry); 87a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Yingint apei_exec_read_register_value(struct apei_exec_context *ctx, 88a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying struct acpi_whea_header *entry); 89a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Yingint apei_exec_write_register(struct apei_exec_context *ctx, 90a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying struct acpi_whea_header *entry); 91a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Yingint apei_exec_write_register_value(struct apei_exec_context *ctx, 92a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying struct acpi_whea_header *entry); 93a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Yingint apei_exec_noop(struct apei_exec_context *ctx, 94a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying struct acpi_whea_header *entry); 95a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Yingint apei_exec_pre_map_gars(struct apei_exec_context *ctx); 96a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Yingint apei_exec_post_unmap_gars(struct apei_exec_context *ctx); 97a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying 98a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Yingstruct apei_resources { 99a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying struct list_head iomem; 100a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying struct list_head ioport; 101a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying}; 102a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying 103a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Yingstatic inline void apei_resources_init(struct apei_resources *resources) 104a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying{ 105a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying INIT_LIST_HEAD(&resources->iomem); 106a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying INIT_LIST_HEAD(&resources->ioport); 107a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying} 108a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying 109a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Yingvoid apei_resources_fini(struct apei_resources *resources); 110fdea163d8c17ba08814142259a467ba3e899010dHuang Yingint apei_resources_add(struct apei_resources *resources, 111fdea163d8c17ba08814142259a467ba3e899010dHuang Ying unsigned long start, unsigned long size, 112fdea163d8c17ba08814142259a467ba3e899010dHuang Ying bool iomem); 113a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Yingint apei_resources_sub(struct apei_resources *resources1, 114a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying struct apei_resources *resources2); 115a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Yingint apei_resources_request(struct apei_resources *resources, 116a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying const char *desc); 117a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Yingvoid apei_resources_release(struct apei_resources *resources); 118a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Yingint apei_exec_collect_resources(struct apei_exec_context *ctx, 119a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying struct apei_resources *resources); 120a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying 121a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Yingstruct dentry; 122a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Yingstruct dentry *apei_get_debugfs_dir(void); 12306d65deade9aabba58e0518df86dcd324e86b832Huang Ying 12406d65deade9aabba58e0518df86dcd324e86b832Huang Ying#define apei_estatus_for_each_section(estatus, section) \ 12506d65deade9aabba58e0518df86dcd324e86b832Huang Ying for (section = (struct acpi_hest_generic_data *)(estatus + 1); \ 12606d65deade9aabba58e0518df86dcd324e86b832Huang Ying (void *)section - (void *)estatus < estatus->data_length; \ 12706d65deade9aabba58e0518df86dcd324e86b832Huang Ying section = (void *)(section+1) + section->error_data_length) 12806d65deade9aabba58e0518df86dcd324e86b832Huang Ying 12906d65deade9aabba58e0518df86dcd324e86b832Huang Yingstatic inline u32 apei_estatus_len(struct acpi_hest_generic_status *estatus) 13006d65deade9aabba58e0518df86dcd324e86b832Huang Ying{ 13106d65deade9aabba58e0518df86dcd324e86b832Huang Ying if (estatus->raw_data_length) 13206d65deade9aabba58e0518df86dcd324e86b832Huang Ying return estatus->raw_data_offset + \ 13306d65deade9aabba58e0518df86dcd324e86b832Huang Ying estatus->raw_data_length; 13406d65deade9aabba58e0518df86dcd324e86b832Huang Ying else 13506d65deade9aabba58e0518df86dcd324e86b832Huang Ying return sizeof(*estatus) + estatus->data_length; 13606d65deade9aabba58e0518df86dcd324e86b832Huang Ying} 13706d65deade9aabba58e0518df86dcd324e86b832Huang Ying 138f59c55d04b43bd72df8efa692dd07224fe94d1acHuang Yingvoid apei_estatus_print(const char *pfx, 139f59c55d04b43bd72df8efa692dd07224fe94d1acHuang Ying const struct acpi_hest_generic_status *estatus); 14006d65deade9aabba58e0518df86dcd324e86b832Huang Yingint apei_estatus_check_header(const struct acpi_hest_generic_status *estatus); 14106d65deade9aabba58e0518df86dcd324e86b832Huang Yingint apei_estatus_check(const struct acpi_hest_generic_status *estatus); 1429fb0bfe1408d5506b7b83d13d1eed573fd71d67dHuang Ying 1439fb0bfe1408d5506b7b83d13d1eed573fd71d67dHuang Yingint apei_osc_setup(void); 144a643ce207f3e70030bdb431e2a363cc111a60c1aHuang Ying#endif 145