Revision 990b150e

b/hw/acpi.c
24 24
#include "sysemu.h"
25 25
#include "i2c.h"
26 26
#include "smbus.h"
27
#include "acpi.h"
27 28

  
28 29
//#define DEBUG
29 30

  
30
/* i82731AB (PIIX4) compatible power management function */
31
#define PM_FREQ 3579545
32

  
33 31
#define ACPI_DBG_IO_ADDR  0xb044
34 32

  
35 33
typedef struct PIIX4PMState {
......
51 49
    int kvm_enabled;
52 50
} PIIX4PMState;
53 51

  
54
#define RSM_STS (1 << 15)
55
#define PWRBTN_STS (1 << 8)
56
#define RTC_EN (1 << 10)
57
#define PWRBTN_EN (1 << 8)
58
#define GBL_EN (1 << 5)
59
#define TMROF_EN (1 << 0)
60

  
61
#define SCI_EN (1 << 0)
62

  
63
#define SUS_EN (1 << 13)
64

  
65 52
#define ACPI_ENABLE 0xf1
66 53
#define ACPI_DISABLE 0xf0
67 54

  
......
70 57
static uint32_t get_pmtmr(PIIX4PMState *s)
71 58
{
72 59
    uint32_t d;
73
    d = muldiv64(qemu_get_clock(vm_clock), PM_FREQ, get_ticks_per_sec());
60
    d = muldiv64(qemu_get_clock(vm_clock), PM_TIMER_FREQUENCY, get_ticks_per_sec());
74 61
    return d & 0xffffff;
75 62
}
76 63

  
......
78 65
{
79 66
    int64_t d;
80 67

  
81
    d = muldiv64(qemu_get_clock(vm_clock), PM_FREQ, get_ticks_per_sec());
68
    d = muldiv64(qemu_get_clock(vm_clock), PM_TIMER_FREQUENCY,
69
                 get_ticks_per_sec());
82 70
    if (d >= s->tmr_overflow_time)
83
        s->pmsts |= TMROF_EN;
71
        s->pmsts |= ACPI_BITMASK_TIMER_STATUS;
84 72
    return s->pmsts;
85 73
}
86 74

  
......
91 79

  
92 80
    pmsts = get_pmsts(s);
93 81
    sci_level = (((pmsts & s->pmen) &
94
                  (RTC_EN | PWRBTN_EN | GBL_EN | TMROF_EN)) != 0);
82
                  (ACPI_BITMASK_RT_CLOCK_ENABLE |
83
                   ACPI_BITMASK_POWER_BUTTON_ENABLE |
84
                   ACPI_BITMASK_GLOBAL_LOCK_ENABLE |
85
                   ACPI_BITMASK_TIMER_ENABLE)) != 0);
95 86
    qemu_set_irq(s->irq, sci_level);
96 87
    /* schedule a timer interruption if needed */
97
    if ((s->pmen & TMROF_EN) && !(pmsts & TMROF_EN)) {
98
        expire_time = muldiv64(s->tmr_overflow_time, get_ticks_per_sec(), PM_FREQ);
88
    if ((s->pmen & ACPI_BITMASK_TIMER_ENABLE) &&
89
        !(pmsts & ACPI_BITMASK_TIMER_STATUS)) {
90
        expire_time = muldiv64(s->tmr_overflow_time, get_ticks_per_sec(),
91
                               PM_TIMER_FREQUENCY);
99 92
        qemu_mod_timer(s->tmr_timer, expire_time);
100 93
    } else {
101 94
        qemu_del_timer(s->tmr_timer);
......
118 111
            int64_t d;
119 112
            int pmsts;
120 113
            pmsts = get_pmsts(s);
121
            if (pmsts & val & TMROF_EN) {
114
            if (pmsts & val & ACPI_BITMASK_TIMER_STATUS) {
122 115
                /* if TMRSTS is reset, then compute the new overflow time */
123
                d = muldiv64(qemu_get_clock(vm_clock), PM_FREQ,
116
                d = muldiv64(qemu_get_clock(vm_clock), PM_TIMER_FREQUENCY,
124 117
                             get_ticks_per_sec());
125 118
                s->tmr_overflow_time = (d + 0x800000LL) & ~0x7fffffLL;
126 119
            }
......
135 128
    case 0x04:
136 129
        {
137 130
            int sus_typ;
138
            s->pmcntrl = val & ~(SUS_EN);
139
            if (val & SUS_EN) {
131
            s->pmcntrl = val & ~(ACPI_BITMASK_SLEEP_ENABLE);
132
            if (val & ACPI_BITMASK_SLEEP_ENABLE) {
140 133
                /* change suspend type */
141 134
                sus_typ = (val >> 10) & 7;
142 135
                switch(sus_typ) {
......
144 137
                    qemu_system_shutdown_request();
145 138
                    break;
146 139
                case 1:
147
                    /* RSM_STS should be set on resume. Pretend that resume
148
                       was caused by power button */
149
                    s->pmsts |= (RSM_STS | PWRBTN_STS);
140
                    /* ACPI_BITMASK_WAKE_STATUS should be set on resume.
141
                       Pretend that resume was caused by power button */
142
                    s->pmsts |= (ACPI_BITMASK_WAKE_STATUS |
143
                                 ACPI_BITMASK_POWER_BUTTON_STATUS);
150 144
                    qemu_system_reset_request();
151 145
                    if (s->cmos_s3) {
152 146
                        qemu_irq_raise(s->cmos_s3);
......
226 220

  
227 221
    /* ACPI specs 3.0, 4.7.2.5 */
228 222
    if (val == ACPI_ENABLE) {
229
        s->pmcntrl |= SCI_EN;
223
        s->pmcntrl |= ACPI_BITMASK_SCI_ENABLE;
230 224
    } else if (val == ACPI_DISABLE) {
231
        s->pmcntrl &= ~SCI_EN;
225
        s->pmcntrl &= ~ACPI_BITMASK_SCI_ENABLE;
232 226
    }
233 227

  
234 228
    if (s->dev.config[0x5b] & (1 << 1)) {
......
320 314

  
321 315
    if (!s) {
322 316
        qemu_system_shutdown_request();
323
    } else if (s->pmen & PWRBTN_EN) {
324
        s->pmsts |= PWRBTN_EN;
317
    } else if (s->pmen & ACPI_BITMASK_POWER_BUTTON_ENABLE) {
318
        s->pmsts |= ACPI_BITMASK_POWER_BUTTON_STATUS;
325 319
        pm_update_sci(s);
326 320
    }
327 321
}
b/hw/acpi.h
1
#ifndef QEMU_HW_ACPI_H
2
#define QEMU_HW_ACPI_H
3
/*
4
 *  Copyright (c) 2009 Isaku Yamahata <yamahata at valinux co jp>
5
 *                     VA Linux Systems Japan K.K.
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2 of the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
20
 */
21

  
22
/* from linux include/acpi/actype.h */
23
/* Default ACPI register widths */
24

  
25
#define ACPI_GPE_REGISTER_WIDTH         8
26
#define ACPI_PM1_REGISTER_WIDTH         16
27
#define ACPI_PM2_REGISTER_WIDTH         8
28
#define ACPI_PM_TIMER_WIDTH             32
29

  
30
/* PM Timer ticks per second (HZ) */
31
#define PM_TIMER_FREQUENCY  3579545
32

  
33

  
34
/* ACPI fixed hardware registers */
35

  
36
/* from linux/drivers/acpi/acpica/aclocal.h */
37
/* Masks used to access the bit_registers */
38

  
39
/* PM1x_STS */
40
#define ACPI_BITMASK_TIMER_STATUS               0x0001
41
#define ACPI_BITMASK_BUS_MASTER_STATUS          0x0010
42
#define ACPI_BITMASK_GLOBAL_LOCK_STATUS         0x0020
43
#define ACPI_BITMASK_POWER_BUTTON_STATUS        0x0100
44
#define ACPI_BITMASK_SLEEP_BUTTON_STATUS        0x0200
45
#define ACPI_BITMASK_RT_CLOCK_STATUS            0x0400
46
#define ACPI_BITMASK_PCIEXP_WAKE_STATUS         0x4000	/* ACPI 3.0 */
47
#define ACPI_BITMASK_WAKE_STATUS                0x8000
48

  
49
#define ACPI_BITMASK_ALL_FIXED_STATUS           (\
50
	ACPI_BITMASK_TIMER_STATUS          | \
51
	ACPI_BITMASK_BUS_MASTER_STATUS     | \
52
	ACPI_BITMASK_GLOBAL_LOCK_STATUS    | \
53
	ACPI_BITMASK_POWER_BUTTON_STATUS   | \
54
	ACPI_BITMASK_SLEEP_BUTTON_STATUS   | \
55
	ACPI_BITMASK_RT_CLOCK_STATUS       | \
56
	ACPI_BITMASK_WAKE_STATUS)
57

  
58
/* PM1x_EN */
59
#define ACPI_BITMASK_TIMER_ENABLE               0x0001
60
#define ACPI_BITMASK_GLOBAL_LOCK_ENABLE         0x0020
61
#define ACPI_BITMASK_POWER_BUTTON_ENABLE        0x0100
62
#define ACPI_BITMASK_SLEEP_BUTTON_ENABLE        0x0200
63
#define ACPI_BITMASK_RT_CLOCK_ENABLE            0x0400
64
#define ACPI_BITMASK_PCIEXP_WAKE_DISABLE        0x4000	/* ACPI 3.0 */
65

  
66
/* PM1x_CNT */
67
#define ACPI_BITMASK_SCI_ENABLE                 0x0001
68
#define ACPI_BITMASK_BUS_MASTER_RLD             0x0002
69
#define ACPI_BITMASK_GLOBAL_LOCK_RELEASE        0x0004
70
#define ACPI_BITMASK_SLEEP_TYPE                 0x1C00
71
#define ACPI_BITMASK_SLEEP_ENABLE               0x2000
72

  
73
/* PM2_CNT */
74
#define ACPI_BITMASK_ARB_DISABLE                0x0001
75

  
76
/* PM_TMR */
77

  
78
#endif /* !QEMU_HW_ACPI_H */

Also available in: Unified diff