acpi.h 6.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
#ifndef QEMU_HW_ACPI_H
#define QEMU_HW_ACPI_H
/*
 *  Copyright (c) 2009 Isaku Yamahata <yamahata at valinux co jp>
 *                     VA Linux Systems Japan K.K.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
18 19
 * License along with this library; if not, see
 * <http://www.gnu.org/licenses/>.
20 21
 */

22 23 24 25
#include "qemu/typedefs.h"
#include "qemu/notify.h"
#include "qemu/option.h"
#include "exec/memory.h"
26
#include "hw/irq.h"
27

28
/*
M
Michael S. Tsirkin 已提交
29
 * current device naming scheme supports up to 256 memory devices
30 31 32
 */
#define ACPI_MAX_RAM_SLOTS 256

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
/* from linux include/acpi/actype.h */
/* Default ACPI register widths */

#define ACPI_GPE_REGISTER_WIDTH         8
#define ACPI_PM1_REGISTER_WIDTH         16
#define ACPI_PM2_REGISTER_WIDTH         8
#define ACPI_PM_TIMER_WIDTH             32

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


/* ACPI fixed hardware registers */

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

/* PM1x_STS */
#define ACPI_BITMASK_TIMER_STATUS               0x0001
#define ACPI_BITMASK_BUS_MASTER_STATUS          0x0010
#define ACPI_BITMASK_GLOBAL_LOCK_STATUS         0x0020
#define ACPI_BITMASK_POWER_BUTTON_STATUS        0x0100
#define ACPI_BITMASK_SLEEP_BUTTON_STATUS        0x0200
#define ACPI_BITMASK_RT_CLOCK_STATUS            0x0400
#define ACPI_BITMASK_PCIEXP_WAKE_STATUS         0x4000	/* ACPI 3.0 */
#define ACPI_BITMASK_WAKE_STATUS                0x8000

#define ACPI_BITMASK_ALL_FIXED_STATUS           (\
	ACPI_BITMASK_TIMER_STATUS          | \
	ACPI_BITMASK_BUS_MASTER_STATUS     | \
	ACPI_BITMASK_GLOBAL_LOCK_STATUS    | \
	ACPI_BITMASK_POWER_BUTTON_STATUS   | \
	ACPI_BITMASK_SLEEP_BUTTON_STATUS   | \
	ACPI_BITMASK_RT_CLOCK_STATUS       | \
	ACPI_BITMASK_WAKE_STATUS)

/* PM1x_EN */
#define ACPI_BITMASK_TIMER_ENABLE               0x0001
#define ACPI_BITMASK_GLOBAL_LOCK_ENABLE         0x0020
#define ACPI_BITMASK_POWER_BUTTON_ENABLE        0x0100
#define ACPI_BITMASK_SLEEP_BUTTON_ENABLE        0x0200
#define ACPI_BITMASK_RT_CLOCK_ENABLE            0x0400
#define ACPI_BITMASK_PCIEXP_WAKE_DISABLE        0x4000	/* ACPI 3.0 */

77 78 79 80 81 82
#define ACPI_BITMASK_PM1_COMMON_ENABLED         ( \
        ACPI_BITMASK_RT_CLOCK_ENABLE        | \
        ACPI_BITMASK_POWER_BUTTON_ENABLE    | \
        ACPI_BITMASK_GLOBAL_LOCK_ENABLE     | \
        ACPI_BITMASK_TIMER_ENABLE)

83 84 85 86 87 88 89 90 91 92
/* PM1x_CNT */
#define ACPI_BITMASK_SCI_ENABLE                 0x0001
#define ACPI_BITMASK_BUS_MASTER_RLD             0x0002
#define ACPI_BITMASK_GLOBAL_LOCK_RELEASE        0x0004
#define ACPI_BITMASK_SLEEP_TYPE                 0x1C00
#define ACPI_BITMASK_SLEEP_ENABLE               0x2000

/* PM2_CNT */
#define ACPI_BITMASK_ARB_DISABLE                0x0001

93 94 95 96 97 98 99
/* These values are part of guest ABI, and can not be changed */
typedef enum {
    ACPI_PCI_HOTPLUG_STATUS = 2,
    ACPI_CPU_HOTPLUG_STATUS = 4,
    ACPI_MEMORY_HOTPLUG_STATUS = 8,
} AcpiGPEStatusBits;

G
Gerd Hoffmann 已提交
100
/* structs */
101
typedef struct ACPIPMTimer ACPIPMTimer;
G
Gerd Hoffmann 已提交
102 103 104
typedef struct ACPIPM1EVT ACPIPM1EVT;
typedef struct ACPIPM1CNT ACPIPM1CNT;
typedef struct ACPIGPE ACPIGPE;
G
Gerd Hoffmann 已提交
105
typedef struct ACPIREGS ACPIREGS;
106

G
Gerd Hoffmann 已提交
107
typedef void (*acpi_update_sci_fn)(ACPIREGS *ar);
108 109 110

struct ACPIPMTimer {
    QEMUTimer *timer;
G
Gerd Hoffmann 已提交
111
    MemoryRegion io;
112 113 114 115 116
    int64_t overflow_time;

    acpi_update_sci_fn update_sci;
};

G
Gerd Hoffmann 已提交
117
struct ACPIPM1EVT {
G
Gerd Hoffmann 已提交
118
    MemoryRegion io;
G
Gerd Hoffmann 已提交
119 120
    uint16_t sts;
    uint16_t en;
G
Gerd Hoffmann 已提交
121
    acpi_update_sci_fn update_sci;
G
Gerd Hoffmann 已提交
122 123 124
};

struct ACPIPM1CNT {
G
Gerd Hoffmann 已提交
125
    MemoryRegion io;
G
Gerd Hoffmann 已提交
126
    uint16_t cnt;
G
Gerd Hoffmann 已提交
127
    uint8_t s4_val;
G
Gerd Hoffmann 已提交
128 129 130 131 132 133 134 135 136
};

struct ACPIGPE {
    uint8_t len;

    uint8_t *sts;
    uint8_t *en;
};

G
Gerd Hoffmann 已提交
137 138 139 140 141 142 143
struct ACPIREGS {
    ACPIPMTimer     tmr;
    ACPIGPE         gpe;
    struct {
        ACPIPM1EVT  evt;
        ACPIPM1CNT  cnt;
    } pm1;
144
    Notifier wakeup;
G
Gerd Hoffmann 已提交
145 146
};

G
Gerd Hoffmann 已提交
147
/* PM_TMR */
G
Gerd Hoffmann 已提交
148 149
void acpi_pm_tmr_update(ACPIREGS *ar, bool enable);
void acpi_pm_tmr_calc_overflow_time(ACPIREGS *ar);
G
Gerd Hoffmann 已提交
150 151
void acpi_pm_tmr_init(ACPIREGS *ar, acpi_update_sci_fn update_sci,
                      MemoryRegion *parent);
G
Gerd Hoffmann 已提交
152
void acpi_pm_tmr_reset(ACPIREGS *ar);
153

154
#include "qemu/timer.h"
155 156
static inline int64_t acpi_pm_tmr_get_clock(void)
{
157
    return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), PM_TIMER_FREQUENCY,
158 159
                    get_ticks_per_sec());
}
160

161
/* PM1a_EVT: piix and ich9 don't implement PM1b. */
162
uint16_t acpi_pm1_evt_get_sts(ACPIREGS *ar);
G
Gerd Hoffmann 已提交
163 164
void acpi_pm1_evt_power_down(ACPIREGS *ar);
void acpi_pm1_evt_reset(ACPIREGS *ar);
G
Gerd Hoffmann 已提交
165 166
void acpi_pm1_evt_init(ACPIREGS *ar, acpi_update_sci_fn update_sci,
                       MemoryRegion *parent);
167

168
/* PM1a_CNT: piix and ich9 don't implement PM1b CNT. */
169 170
void acpi_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent,
                       bool disable_s3, bool disable_s4, uint8_t s4_val);
G
Gerd Hoffmann 已提交
171
void acpi_pm1_cnt_update(ACPIREGS *ar,
172
                         bool sci_enable, bool sci_disable);
G
Gerd Hoffmann 已提交
173
void acpi_pm1_cnt_reset(ACPIREGS *ar);
174

175
/* GPE0 */
G
Gerd Hoffmann 已提交
176 177
void acpi_gpe_init(ACPIREGS *ar, uint8_t len);
void acpi_gpe_reset(ACPIREGS *ar);
178

G
Gerd Hoffmann 已提交
179 180
void acpi_gpe_ioport_writeb(ACPIREGS *ar, uint32_t addr, uint32_t val);
uint32_t acpi_gpe_ioport_readb(ACPIREGS *ar, uint32_t addr);
181

182 183 184
void acpi_send_gpe_event(ACPIREGS *ar, qemu_irq irq,
                         AcpiGPEStatusBits status);

185 186
void acpi_update_sci(ACPIREGS *acpi_regs, qemu_irq irq);

187 188 189 190 191
/* acpi.c */
extern int acpi_enabled;
extern char unsigned *acpi_tables;
extern size_t acpi_tables_len;

192 193 194
uint8_t *acpi_table_first(void);
uint8_t *acpi_table_next(uint8_t *current);
unsigned acpi_table_len(void *current);
195
void acpi_table_add(const QemuOpts *opts, Error **errp);
196
void acpi_table_add_builtin(const QemuOpts *opts, Error **errp);
197

198 199 200 201 202 203 204
typedef struct AcpiSlicOem AcpiSlicOem;
struct AcpiSlicOem {
  char *id;
  char *table_id;
};
int acpi_get_slic_oem(AcpiSlicOem *oem);

205
#endif /* !QEMU_HW_ACPI_H */