1#pragma once
2
3#include <uacpi/acpi.h>
4#include <uacpi/types.h>
5#include <uacpi/uacpi.h>
6#include <uacpi/internal/dynamic_array.h>
7#include <uacpi/internal/shareable.h>
8#include <uacpi/context.h>
9
10struct uacpi_runtime_context {
11 /*
12 * A local copy of FADT that has been verified & converted to most optimal
13 * format for faster access to the registers.
14 */
15 struct acpi_fadt fadt;
16
17 /*
18 * A cached pointer to FACS so that we don't have to look it up in interrupt
19 * contexts as we can't take mutexes.
20 */
21 struct acpi_facs *facs;
22
23 /*
24 * pm1{a,b}_evt_blk split into two registers for convenience
25 */
26 struct acpi_gas pm1a_status_blk;
27 struct acpi_gas pm1b_status_blk;
28 struct acpi_gas pm1a_enable_blk;
29 struct acpi_gas pm1b_enable_blk;
30
31 uacpi_u64 flags;
32
33#define UACPI_SLEEP_TYP_INVALID 0xFF
34 uacpi_u8 last_sleep_typ_a;
35 uacpi_u8 last_sleep_typ_b;
36
37 uacpi_u8 s0_sleep_typ_a;
38 uacpi_u8 s0_sleep_typ_b;
39
40 /*
41 * This is a per-table value but we mimic the NT implementation:
42 * treat all other definition blocks as if they were the same revision
43 * as DSDT.
44 */
45 uacpi_bool is_rev1;
46 uacpi_bool global_lock_acquired;
47
48#ifndef UACPI_REDUCED_HARDWARE
49 uacpi_bool is_hardware_reduced;
50 uacpi_bool has_global_lock;
51 uacpi_handle sci_handle;
52#endif
53 uacpi_u32 loop_timeout_seconds;
54 uacpi_u32 max_call_stack_depth;
55
56 uacpi_u32 global_lock_seq_num;
57 uacpi_handle *global_lock_mutex;
58
59#ifndef UACPI_REDUCED_HARDWARE
60 uacpi_handle *global_lock_event;
61 uacpi_handle *global_lock_spinlock;
62 uacpi_bool global_lock_pending;
63#endif
64
65 uacpi_u8 log_level;
66
67#define UACPI_INIT_LEVEL_EARLY 0
68#define UACPI_INIT_LEVEL_TABLES_LOADED 1
69#define UACPI_INIT_LEVEL_NAMESPACE_LOADED 2
70#define UACPI_INIT_LEVEL_NAMESPACE_INITIALIZED 3
71 uacpi_u8 init_level;
72};
73
74static inline const uacpi_char *uacpi_init_level_to_string(uacpi_u8 lvl)
75{
76 switch (lvl) {
77 case UACPI_INIT_LEVEL_EARLY:
78 return "early";
79 case UACPI_INIT_LEVEL_TABLES_LOADED:
80 return "tables loaded";
81 case UACPI_INIT_LEVEL_NAMESPACE_LOADED:
82 return "namespace loaded";
83 case UACPI_INIT_LEVEL_NAMESPACE_INITIALIZED:
84 return "namespace initialized";
85 default:
86 return "<invalid>";
87 }
88}
89
90#define UACPI_ENSURE_INIT_LEVEL_AT_LEAST(lvl) \
91 do { \
92 if (uacpi_unlikely(g_uacpi_rt_ctx.init_level < lvl)) { \
93 uacpi_error( \
94 "while evaluating %s: init level %d (%s) is too low, " \
95 "expected at least %d (%s)\n", __FUNCTION__, \
96 g_uacpi_rt_ctx.init_level, \
97 uacpi_init_level_to_string(g_uacpi_rt_ctx.init_level), lvl, \
98 uacpi_init_level_to_string(lvl) \
99 ); \
100 return UACPI_STATUS_INIT_LEVEL_MISMATCH; \
101 } \
102 } while (0)
103
104#define UACPI_ENSURE_INIT_LEVEL_IS(lvl) \
105 do { \
106 if (uacpi_unlikely(g_uacpi_rt_ctx.init_level != lvl)) { \
107 uacpi_error( \
108 "while evaluating %s: invalid init level %d (%s), " \
109 "expected %d (%s)\n", __FUNCTION__, \
110 g_uacpi_rt_ctx.init_level, \
111 uacpi_init_level_to_string(g_uacpi_rt_ctx.init_level), lvl, \
112 uacpi_init_level_to_string(lvl) \
113 ); \
114 return UACPI_STATUS_INIT_LEVEL_MISMATCH; \
115 } \
116 } while (0)
117
118extern struct uacpi_runtime_context g_uacpi_rt_ctx;
119
120static inline uacpi_bool uacpi_check_flag(uacpi_u64 flag)
121{
122 return (g_uacpi_rt_ctx.flags & flag) == flag;
123}
124
125static inline uacpi_bool uacpi_should_log(enum uacpi_log_level lvl)
126{
127 return lvl <= g_uacpi_rt_ctx.log_level;
128}
129
130static inline uacpi_bool uacpi_is_hardware_reduced(void)
131{
132#ifndef UACPI_REDUCED_HARDWARE
133 return g_uacpi_rt_ctx.is_hardware_reduced;
134#else
135 return UACPI_TRUE;
136#endif
137}
138