master
c 765 lines 21.9 KB
Raw
1 /*
2 * ACPI implementation
3 *
4 * Copyright (c) 2006 Fabrice Bellard
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License version 2.1 as published by the Free Software Foundation.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, see <http://www.gnu.org/licenses/>
17 *
18 * Contributions after 2012-01-13 are licensed under the terms of the
19 * GNU GPL, version 2 or (at your option) any later version.
20 */
21
22 #include "qemu/osdep.h"
23 #include "hw/core/irq.h"
24 #include "hw/acpi/acpi.h"
25 #include "hw/acpi/acpi_dev_interface.h"
26 #include "hw/nvram/fw_cfg.h"
27 #include "qemu/config-file.h"
28 #include "qapi/error.h"
29 #include "qapi/opts-visitor.h"
30 #include "qapi/qapi-events-run-state.h"
31 #include "qapi/qapi-visit-acpi.h"
32 #include "qemu/error-report.h"
33 #include "qemu/module.h"
34 #include "qemu/option.h"
35 #include "system/runstate.h"
36 #include "trace.h"
37
38 struct acpi_table_header {
39 uint16_t _length; /* our length, not actual part of the hdr */
40 /* allows easier parsing for fw_cfg clients */
41 char sig[4]
42 QEMU_NONSTRING; /* ACPI signature (4 ASCII characters) */
43 uint32_t length; /* Length of table, in bytes, including header */
44 uint8_t revision; /* ACPI Specification minor version # */
45 uint8_t checksum; /* To make sum of entire table == 0 */
46 char oem_id[6]
47 QEMU_NONSTRING; /* OEM identification */
48 char oem_table_id[8]
49 QEMU_NONSTRING; /* OEM table identification */
50 uint32_t oem_revision; /* OEM revision number */
51 char asl_compiler_id[4]
52 QEMU_NONSTRING; /* ASL compiler vendor ID */
53 uint32_t asl_compiler_revision; /* ASL compiler revision number */
54 } QEMU_PACKED;
55
56 #define ACPI_TABLE_HDR_SIZE sizeof(struct acpi_table_header)
57 #define ACPI_TABLE_PFX_SIZE sizeof(uint16_t) /* size of the extra prefix */
58
59 static const char unsigned dfl_hdr[ACPI_TABLE_HDR_SIZE - ACPI_TABLE_PFX_SIZE] =
60 "QEMU\0\0\0\0\1\0" /* sig (4), len(4), revno (1), csum (1) */
61 "QEMUQEQEMUQEMU\1\0\0\0" /* OEM id (6), table (8), revno (4) */
62 "QEMU\1\0\0\0" /* ASL compiler ID (4), version (4) */
63 ;
64
65 char unsigned *acpi_tables;
66 size_t acpi_tables_len;
67
68 static QemuOptsList qemu_acpi_opts = {
69 .name = "acpi",
70 .implied_opt_name = "data",
71 .head = QTAILQ_HEAD_INITIALIZER(qemu_acpi_opts.head),
72 .desc = { { 0 } } /* validated with OptsVisitor */
73 };
74
75 static void acpi_register_config(void)
76 {
77 qemu_add_opts(&qemu_acpi_opts);
78 }
79
80 opts_init(acpi_register_config);
81
82 bool acpi_builtin(void)
83 {
84 return true;
85 }
86
87 /* Calculate the ACPI checksum value so that if used in the corresponding
88 * header field, the ACPI checksum verification will be successful.
89 */
90 int acpi_checksum(const uint8_t *data, int len)
91 {
92 int sum, i;
93 sum = 0;
94 for (i = 0; i < len; i++) {
95 sum += data[i];
96 }
97 return (-sum) & 0xff;
98 }
99
100
101 /* Install a copy of the ACPI table specified in @blob.
102 *
103 * If @has_header is set, @blob starts with the System Description Table Header
104 * structure. Otherwise, "dfl_hdr" is prepended. In any case, each header field
105 * is optionally overwritten from @hdrs.
106 *
107 * It is valid to call this function with
108 * (@blob == NULL && bloblen == 0 && !has_header).
109 *
110 * @hdrs->file and @hdrs->data are ignored.
111 *
112 * SIZE_MAX is considered "infinity" in this function.
113 *
114 * The number of tables that can be installed is not limited, but the 16-bit
115 * counter at the beginning of "acpi_tables" wraps around after UINT16_MAX.
116 */
117 static void acpi_table_install(const char unsigned *blob, size_t bloblen,
118 bool has_header,
119 const struct AcpiTableOptions *hdrs,
120 Error **errp)
121 {
122 size_t body_start;
123 const char unsigned *hdr_src;
124 size_t body_size, acpi_payload_size;
125 struct acpi_table_header *ext_hdr;
126 unsigned changed_fields;
127
128 /* Calculate where the ACPI table body starts within the blob, plus where
129 * to copy the ACPI table header from.
130 */
131 if (has_header) {
132 /* _length | ACPI header in blob | blob body
133 * ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^
134 * ACPI_TABLE_PFX_SIZE sizeof dfl_hdr body_size
135 * == body_start
136 *
137 * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
138 * acpi_payload_size == bloblen
139 */
140 body_start = sizeof dfl_hdr;
141
142 if (bloblen < body_start) {
143 error_setg(errp, "ACPI table claiming to have header is too "
144 "short, available: %zu, expected: %zu", bloblen,
145 body_start);
146 return;
147 }
148 hdr_src = blob;
149 } else {
150 /* _length | ACPI header in template | blob body
151 * ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^
152 * ACPI_TABLE_PFX_SIZE sizeof dfl_hdr body_size
153 * == bloblen
154 *
155 * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
156 * acpi_payload_size
157 */
158 body_start = 0;
159 hdr_src = dfl_hdr;
160 }
161 body_size = bloblen - body_start;
162 acpi_payload_size = sizeof dfl_hdr + body_size;
163
164 if (acpi_payload_size > UINT16_MAX) {
165 error_setg(errp, "ACPI table too big, requested: %zu, max: %u",
166 acpi_payload_size, (unsigned)UINT16_MAX);
167 return;
168 }
169
170 /* We won't fail from here on. Initialize / extend the globals. */
171 if (acpi_tables == NULL) {
172 acpi_tables_len = sizeof(uint16_t);
173 acpi_tables = g_malloc0(acpi_tables_len);
174 }
175
176 acpi_tables = g_realloc(acpi_tables, acpi_tables_len +
177 ACPI_TABLE_PFX_SIZE +
178 sizeof dfl_hdr + body_size);
179
180 ext_hdr = (struct acpi_table_header *)(acpi_tables + acpi_tables_len);
181 acpi_tables_len += ACPI_TABLE_PFX_SIZE;
182
183 memcpy(acpi_tables + acpi_tables_len, hdr_src, sizeof dfl_hdr);
184 acpi_tables_len += sizeof dfl_hdr;
185
186 if (blob != NULL) {
187 memcpy(acpi_tables + acpi_tables_len, blob + body_start, body_size);
188 acpi_tables_len += body_size;
189 }
190
191 /* increase number of tables */
192 stw_le_p(acpi_tables, lduw_le_p(acpi_tables) + 1u);
193
194 /* Update the header fields. The strings need not be NUL-terminated. */
195 changed_fields = 0;
196 ext_hdr->_length = cpu_to_le16(acpi_payload_size);
197
198 if (hdrs->sig) {
199 strncpy(ext_hdr->sig, hdrs->sig, sizeof ext_hdr->sig);
200 ++changed_fields;
201 }
202
203 if (has_header && le32_to_cpu(ext_hdr->length) != acpi_payload_size) {
204 warn_report("ACPI table has wrong length, header says "
205 "%" PRIu32 ", actual size %zu bytes",
206 le32_to_cpu(ext_hdr->length), acpi_payload_size);
207 }
208 ext_hdr->length = cpu_to_le32(acpi_payload_size);
209
210 if (hdrs->has_rev) {
211 ext_hdr->revision = hdrs->rev;
212 ++changed_fields;
213 }
214
215 ext_hdr->checksum = 0;
216
217 if (hdrs->oem_id) {
218 strncpy(ext_hdr->oem_id, hdrs->oem_id, sizeof ext_hdr->oem_id);
219 ++changed_fields;
220 }
221 if (hdrs->oem_table_id) {
222 strncpy(ext_hdr->oem_table_id, hdrs->oem_table_id,
223 sizeof ext_hdr->oem_table_id);
224 ++changed_fields;
225 }
226 if (hdrs->has_oem_rev) {
227 ext_hdr->oem_revision = cpu_to_le32(hdrs->oem_rev);
228 ++changed_fields;
229 }
230 if (hdrs->asl_compiler_id) {
231 strncpy(ext_hdr->asl_compiler_id, hdrs->asl_compiler_id,
232 sizeof ext_hdr->asl_compiler_id);
233 ++changed_fields;
234 }
235 if (hdrs->has_asl_compiler_rev) {
236 ext_hdr->asl_compiler_revision = cpu_to_le32(hdrs->asl_compiler_rev);
237 ++changed_fields;
238 }
239
240 if (!has_header && changed_fields == 0) {
241 warn_report("ACPI table: no headers are specified");
242 }
243
244 /* recalculate checksum */
245 ext_hdr->checksum = acpi_checksum((const char unsigned *)ext_hdr +
246 ACPI_TABLE_PFX_SIZE, acpi_payload_size);
247 }
248
249 void acpi_table_add(const QemuOpts *opts, Error **errp)
250 {
251 AcpiTableOptions *hdrs = NULL;
252 char **pathnames = NULL;
253 char **cur;
254 size_t bloblen = 0;
255 char unsigned *blob = NULL;
256
257 {
258 Visitor *v;
259
260 v = opts_visitor_new(opts);
261 visit_type_AcpiTableOptions(v, NULL, &hdrs, errp);
262 visit_free(v);
263 }
264
265 if (!hdrs) {
266 goto out;
267 }
268 if (!hdrs->file == !hdrs->data) {
269 error_setg(errp, "'-acpitable' requires one of 'data' or 'file'");
270 goto out;
271 }
272
273 pathnames = g_strsplit(hdrs->file ?: hdrs->data, ":", 0);
274 if (pathnames == NULL || pathnames[0] == NULL) {
275 error_setg(errp, "'-acpitable' requires at least one pathname");
276 goto out;
277 }
278
279 /* now read in the data files, reallocating buffer as needed */
280 for (cur = pathnames; *cur; ++cur) {
281 int fd = open(*cur, O_RDONLY | O_BINARY);
282
283 if (fd < 0) {
284 error_setg_file_open(errp, errno, *cur);
285 goto out;
286 }
287
288 for (;;) {
289 char unsigned data[8192];
290 ssize_t r;
291
292 r = read(fd, data, sizeof data);
293 if (r == 0) {
294 break;
295 } else if (r > 0) {
296 blob = g_realloc(blob, bloblen + r);
297 memcpy(blob + bloblen, data, r);
298 bloblen += r;
299 } else if (errno != EINTR) {
300 error_setg_errno(errp, errno, "can't read file %s", *cur);
301 close(fd);
302 goto out;
303 }
304 }
305
306 close(fd);
307 }
308
309 acpi_table_install(blob, bloblen, !!hdrs->file, hdrs, errp);
310
311 out:
312 g_free(blob);
313 g_strfreev(pathnames);
314 qapi_free_AcpiTableOptions(hdrs);
315 }
316
317 unsigned acpi_table_len(void *current)
318 {
319 struct acpi_table_header *hdr = current - sizeof(hdr->_length);
320 return hdr->_length;
321 }
322
323 static
324 void *acpi_table_hdr(void *h)
325 {
326 struct acpi_table_header *hdr = h;
327 return &hdr->sig;
328 }
329
330 uint8_t *acpi_table_first(void)
331 {
332 if (!acpi_tables) {
333 return NULL;
334 }
335 return acpi_table_hdr(acpi_tables + ACPI_TABLE_PFX_SIZE);
336 }
337
338 uint8_t *acpi_table_next(uint8_t *current)
339 {
340 uint8_t *next = current + acpi_table_len(current);
341
342 if (next - acpi_tables >= acpi_tables_len) {
343 return NULL;
344 } else {
345 return acpi_table_hdr(next);
346 }
347 }
348
349 int acpi_get_slic_oem(AcpiSlicOem *oem)
350 {
351 uint8_t *u;
352
353 for (u = acpi_table_first(); u; u = acpi_table_next(u)) {
354 struct acpi_table_header *hdr = (void *)(u - sizeof(hdr->_length));
355
356 if (memcmp(hdr->sig, "SLIC", 4) == 0) {
357 oem->id = g_strndup(hdr->oem_id, 6);
358 oem->table_id = g_strndup(hdr->oem_table_id, 8);
359 return 0;
360 }
361 }
362 return -1;
363 }
364
365 static void acpi_notify_wakeup(Notifier *notifier, void *data)
366 {
367 ACPIREGS *ar = container_of(notifier, ACPIREGS, wakeup);
368 WakeupReason *reason = data;
369
370 switch (*reason) {
371 case QEMU_WAKEUP_REASON_RTC:
372 ar->pm1.evt.sts |=
373 (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_RT_CLOCK_STATUS);
374 break;
375 case QEMU_WAKEUP_REASON_PMTIMER:
376 ar->pm1.evt.sts |=
377 (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_TIMER_STATUS);
378 break;
379 case QEMU_WAKEUP_REASON_OTHER:
380 /* ACPI_BITMASK_WAKE_STATUS should be set on resume.
381 Pretend that resume was caused by power button */
382 ar->pm1.evt.sts |=
383 (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_POWER_BUTTON_STATUS);
384 break;
385 default:
386 break;
387 }
388 }
389
390 /* ACPI PM1a EVT */
391 uint16_t acpi_pm1_evt_get_sts(ACPIREGS *ar)
392 {
393 /* Compare ns-clock, not PM timer ticks, because
394 acpi_pm_tmr_update function uses ns for setting the timer. */
395 int64_t d = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
396 if (d >= muldiv64(ar->tmr.overflow_time,
397 NANOSECONDS_PER_SECOND, PM_TIMER_FREQUENCY)) {
398 ar->pm1.evt.sts |= ACPI_BITMASK_TIMER_STATUS;
399 }
400 return ar->pm1.evt.sts;
401 }
402
403 static void acpi_pm1_evt_write_sts(ACPIREGS *ar, uint16_t val)
404 {
405 uint16_t pm1_sts = acpi_pm1_evt_get_sts(ar);
406 if (pm1_sts & val & ACPI_BITMASK_TIMER_STATUS) {
407 /* if TMRSTS is reset, then compute the new overflow time */
408 acpi_pm_tmr_calc_overflow_time(ar);
409 }
410 ar->pm1.evt.sts &= ~val;
411 }
412
413 static void acpi_pm1_evt_write_en(ACPIREGS *ar, uint16_t val)
414 {
415 ar->pm1.evt.en = val;
416 qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_RTC,
417 val & ACPI_BITMASK_RT_CLOCK_ENABLE);
418 qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_PMTIMER,
419 val & ACPI_BITMASK_TIMER_ENABLE);
420 }
421
422 void acpi_pm1_evt_power_down(ACPIREGS *ar)
423 {
424 if (ar->pm1.evt.en & ACPI_BITMASK_POWER_BUTTON_ENABLE) {
425 ar->pm1.evt.sts |= ACPI_BITMASK_POWER_BUTTON_STATUS;
426 ar->tmr.update_sci(ar);
427 }
428 }
429
430 void acpi_pm1_evt_reset(ACPIREGS *ar)
431 {
432 ar->pm1.evt.sts = 0;
433 ar->pm1.evt.en = 0;
434 qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_RTC, 0);
435 qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_PMTIMER, 0);
436 }
437
438 static uint64_t acpi_pm_evt_read(void *opaque, hwaddr addr, unsigned width)
439 {
440 ACPIREGS *ar = opaque;
441 switch (addr) {
442 case 0:
443 return acpi_pm1_evt_get_sts(ar);
444 case 2:
445 return ar->pm1.evt.en;
446 default:
447 return 0;
448 }
449 }
450
451 static void acpi_pm_evt_write(void *opaque, hwaddr addr, uint64_t val,
452 unsigned width)
453 {
454 ACPIREGS *ar = opaque;
455 switch (addr) {
456 case 0:
457 acpi_pm1_evt_write_sts(ar, val);
458 ar->pm1.evt.update_sci(ar);
459 break;
460 case 2:
461 acpi_pm1_evt_write_en(ar, val);
462 ar->pm1.evt.update_sci(ar);
463 break;
464 }
465 }
466
467 static const MemoryRegionOps acpi_pm_evt_ops = {
468 .read = acpi_pm_evt_read,
469 .write = acpi_pm_evt_write,
470 .impl.min_access_size = 2,
471 .valid.min_access_size = 1,
472 .valid.max_access_size = 2,
473 .endianness = DEVICE_LITTLE_ENDIAN,
474 };
475
476 void acpi_pm1_evt_init(ACPIREGS *ar, acpi_update_sci_fn update_sci,
477 MemoryRegion *parent)
478 {
479 ar->pm1.evt.update_sci = update_sci;
480 memory_region_init_io(&ar->pm1.evt.io, memory_region_owner(parent),
481 &acpi_pm_evt_ops, ar, "acpi-evt", 4);
482 memory_region_add_subregion(parent, 0, &ar->pm1.evt.io);
483 }
484
485 /* ACPI PM_TMR */
486 void acpi_pm_tmr_update(ACPIREGS *ar, bool enable)
487 {
488 int64_t expire_time;
489
490 /* schedule a timer interruption if needed */
491 if (enable) {
492 expire_time = muldiv64(ar->tmr.overflow_time, NANOSECONDS_PER_SECOND,
493 PM_TIMER_FREQUENCY);
494 timer_mod(ar->tmr.timer, expire_time);
495 } else {
496 timer_del(ar->tmr.timer);
497 }
498 }
499
500 static inline int64_t acpi_pm_tmr_get_clock(void)
501 {
502 return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), PM_TIMER_FREQUENCY,
503 NANOSECONDS_PER_SECOND);
504 }
505
506 void acpi_pm_tmr_calc_overflow_time(ACPIREGS *ar)
507 {
508 int64_t d = acpi_pm_tmr_get_clock();
509 ar->tmr.overflow_time = (d + 0x800000LL) & ~0x7fffffLL;
510 }
511
512 static uint32_t acpi_pm_tmr_get(ACPIREGS *ar)
513 {
514 uint32_t d = acpi_pm_tmr_get_clock();
515 return d & 0xffffff;
516 }
517
518 static void acpi_pm_tmr_timer(void *opaque)
519 {
520 ACPIREGS *ar = opaque;
521
522 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_PMTIMER, NULL);
523 ar->tmr.update_sci(ar);
524 }
525
526 static uint64_t acpi_pm_tmr_read(void *opaque, hwaddr addr, unsigned width)
527 {
528 return acpi_pm_tmr_get(opaque);
529 }
530
531 static void acpi_pm_tmr_write(void *opaque, hwaddr addr, uint64_t val,
532 unsigned width)
533 {
534 /* nothing */
535 }
536
537 static const MemoryRegionOps acpi_pm_tmr_ops = {
538 .read = acpi_pm_tmr_read,
539 .write = acpi_pm_tmr_write,
540 .impl.min_access_size = 4,
541 .valid.min_access_size = 1,
542 .valid.max_access_size = 4,
543 .endianness = DEVICE_LITTLE_ENDIAN,
544 };
545
546 void acpi_pm_tmr_init(ACPIREGS *ar, acpi_update_sci_fn update_sci,
547 MemoryRegion *parent)
548 {
549 ar->tmr.update_sci = update_sci;
550 ar->tmr.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, acpi_pm_tmr_timer, ar);
551 memory_region_init_io(&ar->tmr.io, memory_region_owner(parent),
552 &acpi_pm_tmr_ops, ar, "acpi-tmr", 4);
553 memory_region_enable_lockless_io(&ar->tmr.io);
554 memory_region_add_subregion(parent, 8, &ar->tmr.io);
555 }
556
557 void acpi_pm_tmr_reset(ACPIREGS *ar)
558 {
559 ar->tmr.overflow_time = 0;
560 timer_del(ar->tmr.timer);
561 }
562
563 /* ACPI PM1aCNT */
564 void acpi_pm1_cnt_update(ACPIREGS *ar,
565 bool sci_enable, bool sci_disable)
566 {
567 /* ACPI specs 3.0, 4.7.2.5 */
568 if (ar->pm1.cnt.acpi_only) {
569 return;
570 }
571
572 if (sci_enable) {
573 ar->pm1.cnt.cnt |= ACPI_BITMASK_SCI_ENABLE;
574 } else if (sci_disable) {
575 ar->pm1.cnt.cnt &= ~ACPI_BITMASK_SCI_ENABLE;
576 }
577 }
578
579 static uint64_t acpi_pm_cnt_read(void *opaque, hwaddr addr, unsigned width)
580 {
581 ACPIREGS *ar = opaque;
582 return ar->pm1.cnt.cnt >> addr * 8;
583 }
584
585 static void acpi_pm_cnt_write(void *opaque, hwaddr addr, uint64_t val,
586 unsigned width)
587 {
588 ACPIREGS *ar = opaque;
589
590 if (addr == 1) {
591 val = val << 8 | (ar->pm1.cnt.cnt & 0xff);
592 }
593 ar->pm1.cnt.cnt = val & ~(ACPI_BITMASK_SLEEP_ENABLE);
594
595 if (val & ACPI_BITMASK_SLEEP_ENABLE) {
596 /* change suspend type */
597 uint16_t sus_typ = (val >> 10) & 7;
598 switch (sus_typ) {
599 case 0: /* soft power off */
600 qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
601 break;
602 case 1:
603 qemu_system_suspend_request();
604 break;
605 default:
606 if (sus_typ == ar->pm1.cnt.s4_val) { /* S4 request */
607 qapi_event_send_suspend_disk();
608 qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
609 }
610 break;
611 }
612 }
613 }
614
615 static const MemoryRegionOps acpi_pm_cnt_ops = {
616 .read = acpi_pm_cnt_read,
617 .write = acpi_pm_cnt_write,
618 .impl.min_access_size = 2,
619 .valid.min_access_size = 1,
620 .valid.max_access_size = 2,
621 .endianness = DEVICE_LITTLE_ENDIAN,
622 };
623
624 void acpi_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent,
625 bool disable_s3, bool disable_s4, uint8_t s4_val,
626 bool acpi_only)
627 {
628 FWCfgState *fw_cfg;
629
630 ar->pm1.cnt.s4_val = s4_val;
631 ar->pm1.cnt.acpi_only = acpi_only;
632 ar->wakeup.notify = acpi_notify_wakeup;
633 qemu_register_wakeup_notifier(&ar->wakeup);
634
635 /*
636 * Register wake-up support in QMP query-current-machine API
637 */
638 qemu_register_wakeup_support();
639
640 memory_region_init_io(&ar->pm1.cnt.io, memory_region_owner(parent),
641 &acpi_pm_cnt_ops, ar, "acpi-cnt", 2);
642 memory_region_add_subregion(parent, 4, &ar->pm1.cnt.io);
643
644 fw_cfg = fw_cfg_find();
645 if (fw_cfg) {
646 uint8_t suspend[6] = {128, 0, 0, 129, 128, 128};
647 suspend[3] = 1 | ((!disable_s3) << 7);
648 suspend[4] = s4_val | ((!disable_s4) << 7);
649
650 fw_cfg_add_file(fw_cfg, "etc/system-states", g_memdup(suspend, 6), 6);
651 }
652 }
653
654 void acpi_pm1_cnt_reset(ACPIREGS *ar)
655 {
656 ar->pm1.cnt.cnt = 0;
657 if (ar->pm1.cnt.acpi_only) {
658 ar->pm1.cnt.cnt |= ACPI_BITMASK_SCI_ENABLE;
659 }
660 }
661
662 /* ACPI GPE */
663 void acpi_gpe_init(ACPIREGS *ar, uint8_t len)
664 {
665 ar->gpe.len = len;
666 /* Only first len / 2 bytes are ever used,
667 * but the caller in ich9.c migrates full len bytes.
668 * TODO: fix ich9.c and drop the extra allocation.
669 */
670 ar->gpe.sts = g_malloc0(len);
671 ar->gpe.en = g_malloc0(len);
672 }
673
674 void acpi_gpe_reset(ACPIREGS *ar)
675 {
676 memset(ar->gpe.sts, 0, ar->gpe.len / 2);
677 memset(ar->gpe.en, 0, ar->gpe.len / 2);
678 }
679
680 static uint8_t *acpi_gpe_ioport_get_ptr(ACPIREGS *ar, uint32_t addr)
681 {
682 uint8_t *cur = NULL;
683
684 if (addr < ar->gpe.len / 2) {
685 cur = ar->gpe.sts + addr;
686 } else if (addr < ar->gpe.len) {
687 cur = ar->gpe.en + addr - ar->gpe.len / 2;
688 } else {
689 abort();
690 }
691
692 return cur;
693 }
694
695 void acpi_gpe_ioport_writeb(ACPIREGS *ar, uint32_t addr, uint32_t val)
696 {
697 uint8_t *cur;
698
699 cur = acpi_gpe_ioport_get_ptr(ar, addr);
700 if (addr < ar->gpe.len / 2) {
701 trace_acpi_gpe_sts_ioport_writeb(addr, val);
702 /* GPE_STS */
703 *cur = (*cur) & ~val;
704 } else if (addr < ar->gpe.len) {
705 trace_acpi_gpe_en_ioport_writeb(addr - (ar->gpe.len / 2), val);
706 /* GPE_EN */
707 *cur = val;
708 } else {
709 abort();
710 }
711 }
712
713 uint32_t acpi_gpe_ioport_readb(ACPIREGS *ar, uint32_t addr)
714 {
715 uint8_t *cur;
716 uint32_t val;
717
718 cur = acpi_gpe_ioport_get_ptr(ar, addr);
719 val = 0;
720 if (cur != NULL) {
721 val = *cur;
722 }
723
724 if (addr < ar->gpe.len / 2) {
725 trace_acpi_gpe_sts_ioport_readb(addr, val);
726 } else {
727 trace_acpi_gpe_en_ioport_readb(addr - (ar->gpe.len / 2), val);
728 }
729
730 return val;
731 }
732
733 void acpi_send_gpe_event(ACPIREGS *ar, qemu_irq irq,
734 AcpiEventStatusBits status)
735 {
736 ar->gpe.sts[0] |= status;
737 acpi_update_sci(ar, irq);
738 }
739
740 void acpi_update_sci(ACPIREGS *regs, qemu_irq irq)
741 {
742 int sci_level, pm1a_sts;
743
744 pm1a_sts = acpi_pm1_evt_get_sts(regs);
745
746 sci_level = ((pm1a_sts &
747 regs->pm1.evt.en & ACPI_BITMASK_PM1_COMMON_ENABLED) != 0) ||
748 ((regs->gpe.sts[0] & regs->gpe.en[0]) != 0);
749
750 qemu_set_irq(irq, sci_level);
751
752 /* schedule a timer interruption if needed */
753 acpi_pm_tmr_update(regs,
754 (regs->pm1.evt.en & ACPI_BITMASK_TIMER_ENABLE) &&
755 !(pm1a_sts & ACPI_BITMASK_TIMER_STATUS));
756 }
757
758 void acpi_send_event(DeviceState *dev, AcpiEventStatusBits event)
759 {
760 AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_GET_CLASS(dev);
761 if (adevc->send_event) {
762 AcpiDeviceIf *adev = ACPI_DEVICE_IF(dev);
763 adevc->send_event(adev, event);
764 }
765 }