Thu Jun 18 11:14:14 2009 UTC ()
implement ACPI S3 support for Dom0.
ok jym@


(cegger)
diff -r1.4 -r1.4.24.1 src/sys/arch/xen/xen/xen_acpi_machdep.c

cvs diff -r1.4 -r1.4.24.1 src/sys/arch/xen/xen/xen_acpi_machdep.c (expand / switch to unified diff)

--- src/sys/arch/xen/xen/xen_acpi_machdep.c 2008/02/17 14:03:16 1.4
+++ src/sys/arch/xen/xen/xen_acpi_machdep.c 2009/06/18 11:14:14 1.4.24.1
@@ -1,18 +1,122 @@ @@ -1,18 +1,122 @@
1/* $NetBSD: xen_acpi_machdep.c,v 1.4 2008/02/17 14:03:16 bouyer Exp $ */ 1/* $NetBSD: xen_acpi_machdep.c,v 1.4.24.1 2009/06/18 11:14:14 cegger Exp $ */
2 2
3#include "acpi.h" 3#include "acpi.h"
4 4
5#include <sys/cdefs.h> 5#include <sys/cdefs.h>
6__KERNEL_RCSID(0, "$NetBSD: xen_acpi_machdep.c,v 1.4 2008/02/17 14:03:16 bouyer Exp $"); 6__KERNEL_RCSID(0, "$NetBSD: xen_acpi_machdep.c,v 1.4.24.1 2009/06/18 11:14:14 cegger Exp $");
7 7
8#include <dev/acpi/acpica.h> 8#include <dev/acpi/acpica.h>
9#include <dev/acpi/acpivar.h> 9#include <dev/acpi/acpivar.h>
10#define ACPI_MACHDEP_PRIVATE 10#define ACPI_MACHDEP_PRIVATE
11#include <machine/acpi_machdep.h> 11#include <machine/acpi_machdep.h>
 12#include <xen/xen3-public/version.h>
 13
 14static int
 15xen_dom0_sleepenter(int sleep_state, int pm1a_control, int pm1b_control)
 16{
 17 struct xen_platform_op op = {
 18 .cmd = XENPF_enter_acpi_sleep,
 19 .interface_version = XENPF_INTERFACE_VERSION,
 20 .u = {
 21 .enter_acpi_sleep = {
 22 .pm1a_cnt_val = pm1a_control,
 23 .pm1b_cnt_val = pm1b_control,
 24 .sleep_state = sleep_state,
 25 },
 26 },
 27 };
 28
 29 return HYPERVISOR_platform_op(&op);
 30}
 31
 32static ACPI_STATUS
 33acpi_md_get_pm1controls(uint32_t *pm1a_control, uint32_t *pm1b_control)
 34{
 35 ACPI_STATUS status = 0;
 36 uint32_t pm1a, pm1b;
 37 struct acpi_bit_register_info *sleep_type_reg_info;
 38 struct acpi_bit_register_info *sleep_enable_reg_info;
 39
 40 *pm1a_control = *pm1b_control = 0;
 41
 42 sleep_type_reg_info =
 43 AcpiHwGetBitRegisterInfo(ACPI_BITREG_SLEEP_TYPE_A);
 44 sleep_enable_reg_info =
 45 AcpiHwGetBitRegisterInfo(ACPI_BITREG_SLEEP_ENABLE);
 46
 47 status = AcpiHwRegisterRead(ACPI_MTX_DO_NOT_LOCK,
 48 ACPI_REGISTER_PM1_CONTROL, &pm1a);
 49 if (ACPI_FAILURE(status))
 50 return status;
 51
 52 /* Clear SLP_EN and SLP_TYP fields */
 53 pm1a &= ~(sleep_type_reg_info->AccessBitMask |
 54 sleep_enable_reg_info->AccessBitMask);
 55 pm1b = pm1a;
 56
 57 /* Insert SLP_TYP bits */
 58 pm1a |= (AcpiGbl_SleepTypeA << sleep_type_reg_info->BitPosition);
 59 pm1b |= (AcpiGbl_SleepTypeB << sleep_type_reg_info->BitPosition);
 60
 61 /* Split the writes of SLP_TYP and SLP_EN to workaround
 62 * poorly implemented hardware
 63 */
 64
 65 /* Write #1: fill in SLP_TYP data */
 66 status = AcpiHwRegisterWrite(ACPI_MTX_DO_NOT_LOCK,
 67 ACPI_REGISTER_PM1A_CONTROL,
 68 pm1a);
 69 if (ACPI_FAILURE(status))
 70 return status;
 71
 72 status = AcpiHwRegisterWrite(ACPI_MTX_DO_NOT_LOCK,
 73 ACPI_REGISTER_PM1B_CONTROL,
 74 pm1b);
 75 if (ACPI_FAILURE(status))
 76 return status;
 77
 78 /* Insert SLP_ENABLE bit */
 79
 80 pm1a |= sleep_enable_reg_info->AccessBitMask;
 81 pm1b |= sleep_enable_reg_info->AccessBitMask;
 82
 83 ACPI_FLUSH_CPU_CACHE();
 84
 85 *pm1a_control = pm1a;
 86 *pm1b_control = pm1b;
 87
 88 return status;
 89}
12 90
13int 91int
14acpi_md_sleep(int state) 92acpi_md_sleep(int state)
15{ 93{
16 printf("acpi: sleep not implemented\n"); 94 int error;
17 return (-1); 95 ACPI_STATUS status;
 96 uint32_t pm1a_control, pm1b_control;
 97 uint32_t xen_version, xen_vermajor, xen_verminor;
 98
 99 xen_version = HYPERVISOR_xen_version(XENVER_version, NULL);
 100 xen_vermajor = (xen_version & 0xffff0000) >> 16;
 101 xen_verminor = (xen_version & 0x0000ffff);
 102
 103 /* Xen version check. We require Xen 3.x */
 104 KASSERT(xen_vermajor >= 3);
 105
 106 /* Xen 3.2 and older have no s3 support. */
 107 if (xen_verminor < 3) {
 108 printf("xenacpi: Xen 3.2 and older have no S3 support.\n");
 109 return -1;
 110 }
 111
 112 status = acpi_md_get_pm1controls(&pm1a_control, &pm1b_control);
 113 if (ACPI_FAILURE(status)) {
 114 printf("xenacpi: can't enter sleep mode. acpi error %i\n",
 115 status);
 116 return -1;
 117 }
 118
 119 error = xen_dom0_sleepenter(state, pm1a_control, pm1b_control);
 120
 121 return error;
18} 122}