aboutsummaryrefslogtreecommitdiff
path: root/kernel/inc/drivers/acpi.h
blob: 29dcd325f1e8bab1ce506e914c3ef4cab4a2629b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
// MIT License, Copyright (c) 2020 Marvin Borner

#ifndef ACPI_H
#define ACPI_H

#include <def.h>

#define RSDP_MAGIC "RSD PTR "
#define RSDT_MAGIC "RSDT"
#define MADT_MAGIC "APIC"
#define FADT_MAGIC "FACP"
#define HPET_MAGIC "HPET"

#define HPET_MAX_PERIOD 0x05F5E100

struct address_structure {
	u8 address_space_id;
	u8 register_bit_width;
	u8 register_bit_offset;
	u8 reserved;
	u32 phys; // Actually u64
};

/**
 * General headers
 */

struct sdt_header {
	char signature[4];
	u32 length;
	u8 revision;
	u8 checksum;
	char oem_id[6];
	char oem_table_id[8];
	u32 oem_revision;
	u32 creator_id;
	u32 creator_revision;
};

struct sdp_header {
	char signature[8];
	u8 checksum;
	char oem_id[6];
	u8 revision;
};

/**
 * RSDT
 */

struct rsdt {
	struct sdt_header header;
	u32 sdt_pointer[];
};

/**
 * MADT
 */

struct madt_entry_header {
	u8 type;
	u8 length;
};

struct madt {
	struct sdt_header header;
	u32 local_address;
	u32 flags;
	struct madt_entry_header entry;
} PACKED;

#define MADT_LOCAL_APIC_ENTRY 0
#define MADT_IO_APIC_ENTRY 1
#define MADT_INT_SRC_OVERRIDE_ENTRY 2
#define MADT_NON_MASKABLE_INT_ENTRY 4 // Where's 3?
#define MADT_LOCAL_APIC_OVERRIDE_ENTRY 5

struct madt_local_apic_entry {
	struct madt_entry_header header;
	u8 processor_id;
	u8 id;
	u32 flags;
} PACKED;

struct madt_io_apic_entry {
	struct madt_entry_header header;
	u8 id;
	u8 reserved;
	u32 address;
	u32 global_system_interrupt_base;
} PACKED;

struct madt_int_src_override_entry {
	struct madt_entry_header header;
	u8 bus_source;
	u8 irq_source;
	u32 global_system_interrupt;
	u16 flags;
} PACKED;

struct madt_non_maskable_int_entry {
	struct madt_entry_header header;
	u8 processor_id;
	u16 flags;
	u8 lint_number;
} PACKED;

struct madt_local_apic_override_entry {
	struct madt_entry_header header;
	u16 reserved;
	u64 address;
} PACKED;

/**
 * FADT
 */

struct fadt {
	struct sdt_header header;
	// TODO: FADT table (big!)
} PACKED;

/**
 * HPET
 */

struct hpet {
	struct sdt_header header;
	u8 hardware_rev_id;
	u8 comparator_count : 5;
	u8 counter_size : 1;
	u8 reserved : 1;
	u8 legacy_replacement : 1;
	u16 pci_vendor_id;
	struct address_structure address;
	u8 hpet_number;
	u16 minimum_tick;
	u8 page_protection;
} PACKED;

enum hpet_features { hpet_counter_size = 1 << 3, hpet_legacy_replacement_support = 1 << 5 };
enum hpet_config { hpet_enable = 1 << 0, hpet_legacy_replacement = 1 << 1 };
enum hpet_timer {
	hpet_type = 1 << 1,
	hpet_enable_timer = 1 << 2,
	hpet_periodic = 1 << 3,
	hpet_periodic_support = 1 << 4,
	hpet_size = 1 << 5, // 1 if 64 bit
	hpet_set_accumulator = 1 << 6,
	hpet_force_32 = 1 << 8, // For 64 bit
	hpet_apic_routing = 1 << 13,
	hpet_fsb = 1 << 14,
	hpet_fsb_support = 1 << 15,
	/* routing_capability = 1 << 63 */
};

struct hpet_registers {
	u32 features; // enum hpet_features
	u32 tick_period;
	u64 reserved1;
	u64 config; // enum hpet_config
	u64 reserved2;
	u32 int_status; // For timer #n
	u32 reserved3;
	u8 reserved4[200]; // Why?!
	u32 counter;
	u32 counter_high; // 0 due to 64 bit
	u64 reserved5;
	u64 timer0; // enum hpet_timer
	u64 timer_comparator0; // In femtoseconds
} PACKED;

/**
 * RSDP
 */

struct rsdp {
	struct sdp_header header;
	struct rsdt *rsdt;
};

struct madt *madt;
struct fadt *fadt;
struct hpet *hpet;

void acpi_install(void);
void hpet_install(u32 period);
void madt_install(void);

#endif