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