Statistics
| Branch: | Revision:

root / hw / acpi_piix4.c @ 0b8f9be6

History | View | Annotate | Download (15.5 kB)

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 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
#include "hw.h"
19
#include "pc.h"
20
#include "apm.h"
21
#include "pm_smbus.h"
22
#include "pci.h"
23
#include "acpi.h"
24

    
25
//#define DEBUG
26

    
27
#ifdef DEBUG
28
# define PIIX4_DPRINTF(format, ...)     printf(format, ## __VA_ARGS__)
29
#else
30
# define PIIX4_DPRINTF(format, ...)     do { } while (0)
31
#endif
32

    
33
#define ACPI_DBG_IO_ADDR  0xb044
34

    
35
#define GPE_BASE 0xafe0
36
#define PCI_BASE 0xae00
37
#define PCI_EJ_BASE 0xae08
38

    
39
struct gpe_regs {
40
    uint16_t sts; /* status */
41
    uint16_t en;  /* enabled */
42
};
43

    
44
struct pci_status {
45
    uint32_t up;
46
    uint32_t down;
47
};
48

    
49
typedef struct PIIX4PMState {
50
    PCIDevice dev;
51
    uint16_t pmsts;
52
    uint16_t pmen;
53
    uint16_t pmcntrl;
54

    
55
    APMState apm;
56

    
57
    QEMUTimer *tmr_timer;
58
    int64_t tmr_overflow_time;
59

    
60
    PMSMBus smb;
61
    uint32_t smb_io_base;
62

    
63
    qemu_irq irq;
64
    qemu_irq cmos_s3;
65
    qemu_irq smi_irq;
66
    int kvm_enabled;
67

    
68
    /* for pci hotplug */
69
    struct gpe_regs gpe;
70
    struct pci_status pci0_status;
71
} PIIX4PMState;
72

    
73
static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s);
74

    
75
#define ACPI_ENABLE 0xf1
76
#define ACPI_DISABLE 0xf0
77

    
78
static uint32_t get_pmtmr(PIIX4PMState *s)
79
{
80
    uint32_t d;
81
    d = muldiv64(qemu_get_clock(vm_clock), PM_TIMER_FREQUENCY, get_ticks_per_sec());
82
    return d & 0xffffff;
83
}
84

    
85
static int get_pmsts(PIIX4PMState *s)
86
{
87
    int64_t d;
88

    
89
    d = muldiv64(qemu_get_clock(vm_clock), PM_TIMER_FREQUENCY,
90
                 get_ticks_per_sec());
91
    if (d >= s->tmr_overflow_time)
92
        s->pmsts |= ACPI_BITMASK_TIMER_STATUS;
93
    return s->pmsts;
94
}
95

    
96
static void pm_update_sci(PIIX4PMState *s)
97
{
98
    int sci_level, pmsts;
99
    int64_t expire_time;
100

    
101
    pmsts = get_pmsts(s);
102
    sci_level = (((pmsts & s->pmen) &
103
                  (ACPI_BITMASK_RT_CLOCK_ENABLE |
104
                   ACPI_BITMASK_POWER_BUTTON_ENABLE |
105
                   ACPI_BITMASK_GLOBAL_LOCK_ENABLE |
106
                   ACPI_BITMASK_TIMER_ENABLE)) != 0);
107
    qemu_set_irq(s->irq, sci_level);
108
    /* schedule a timer interruption if needed */
109
    if ((s->pmen & ACPI_BITMASK_TIMER_ENABLE) &&
110
        !(pmsts & ACPI_BITMASK_TIMER_STATUS)) {
111
        expire_time = muldiv64(s->tmr_overflow_time, get_ticks_per_sec(),
112
                               PM_TIMER_FREQUENCY);
113
        qemu_mod_timer(s->tmr_timer, expire_time);
114
    } else {
115
        qemu_del_timer(s->tmr_timer);
116
    }
117
}
118

    
119
static void pm_tmr_timer(void *opaque)
120
{
121
    PIIX4PMState *s = opaque;
122
    pm_update_sci(s);
123
}
124

    
125
static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
126
{
127
    PIIX4PMState *s = opaque;
128
    addr &= 0x3f;
129
    switch(addr) {
130
    case 0x00:
131
        {
132
            int64_t d;
133
            int pmsts;
134
            pmsts = get_pmsts(s);
135
            if (pmsts & val & ACPI_BITMASK_TIMER_STATUS) {
136
                /* if TMRSTS is reset, then compute the new overflow time */
137
                d = muldiv64(qemu_get_clock(vm_clock), PM_TIMER_FREQUENCY,
138
                             get_ticks_per_sec());
139
                s->tmr_overflow_time = (d + 0x800000LL) & ~0x7fffffLL;
140
            }
141
            s->pmsts &= ~val;
142
            pm_update_sci(s);
143
        }
144
        break;
145
    case 0x02:
146
        s->pmen = val;
147
        pm_update_sci(s);
148
        break;
149
    case 0x04:
150
        {
151
            int sus_typ;
152
            s->pmcntrl = val & ~(ACPI_BITMASK_SLEEP_ENABLE);
153
            if (val & ACPI_BITMASK_SLEEP_ENABLE) {
154
                /* change suspend type */
155
                sus_typ = (val >> 10) & 7;
156
                switch(sus_typ) {
157
                case 0: /* soft power off */
158
                    qemu_system_shutdown_request();
159
                    break;
160
                case 1:
161
                    /* ACPI_BITMASK_WAKE_STATUS should be set on resume.
162
                       Pretend that resume was caused by power button */
163
                    s->pmsts |= (ACPI_BITMASK_WAKE_STATUS |
164
                                 ACPI_BITMASK_POWER_BUTTON_STATUS);
165
                    qemu_system_reset_request();
166
                    if (s->cmos_s3) {
167
                        qemu_irq_raise(s->cmos_s3);
168
                    }
169
                default:
170
                    break;
171
                }
172
            }
173
        }
174
        break;
175
    default:
176
        break;
177
    }
178
    PIIX4_DPRINTF("PM writew port=0x%04x val=0x%04x\n", addr, val);
179
}
180

    
181
static uint32_t pm_ioport_readw(void *opaque, uint32_t addr)
182
{
183
    PIIX4PMState *s = opaque;
184
    uint32_t val;
185

    
186
    addr &= 0x3f;
187
    switch(addr) {
188
    case 0x00:
189
        val = get_pmsts(s);
190
        break;
191
    case 0x02:
192
        val = s->pmen;
193
        break;
194
    case 0x04:
195
        val = s->pmcntrl;
196
        break;
197
    default:
198
        val = 0;
199
        break;
200
    }
201
    PIIX4_DPRINTF("PM readw port=0x%04x val=0x%04x\n", addr, val);
202
    return val;
203
}
204

    
205
static void pm_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
206
{
207
    //    PIIX4PMState *s = opaque;
208
    PIIX4_DPRINTF("PM writel port=0x%04x val=0x%08x\n", addr & 0x3f, val);
209
}
210

    
211
static uint32_t pm_ioport_readl(void *opaque, uint32_t addr)
212
{
213
    PIIX4PMState *s = opaque;
214
    uint32_t val;
215

    
216
    addr &= 0x3f;
217
    switch(addr) {
218
    case 0x08:
219
        val = get_pmtmr(s);
220
        break;
221
    default:
222
        val = 0;
223
        break;
224
    }
225
    PIIX4_DPRINTF("PM readl port=0x%04x val=0x%08x\n", addr, val);
226
    return val;
227
}
228

    
229
static void apm_ctrl_changed(uint32_t val, void *arg)
230
{
231
    PIIX4PMState *s = arg;
232

    
233
    /* ACPI specs 3.0, 4.7.2.5 */
234
    if (val == ACPI_ENABLE) {
235
        s->pmcntrl |= ACPI_BITMASK_SCI_ENABLE;
236
    } else if (val == ACPI_DISABLE) {
237
        s->pmcntrl &= ~ACPI_BITMASK_SCI_ENABLE;
238
    }
239

    
240
    if (s->dev.config[0x5b] & (1 << 1)) {
241
        if (s->smi_irq) {
242
            qemu_irq_raise(s->smi_irq);
243
        }
244
    }
245
}
246

    
247
static void acpi_dbg_writel(void *opaque, uint32_t addr, uint32_t val)
248
{
249
    PIIX4_DPRINTF("ACPI: DBG: 0x%08x\n", val);
250
}
251

    
252
static void pm_io_space_update(PIIX4PMState *s)
253
{
254
    uint32_t pm_io_base;
255

    
256
    if (s->dev.config[0x80] & 1) {
257
        pm_io_base = le32_to_cpu(*(uint32_t *)(s->dev.config + 0x40));
258
        pm_io_base &= 0xffc0;
259

    
260
        /* XXX: need to improve memory and ioport allocation */
261
        PIIX4_DPRINTF("PM: mapping to 0x%x\n", pm_io_base);
262
        register_ioport_write(pm_io_base, 64, 2, pm_ioport_writew, s);
263
        register_ioport_read(pm_io_base, 64, 2, pm_ioport_readw, s);
264
        register_ioport_write(pm_io_base, 64, 4, pm_ioport_writel, s);
265
        register_ioport_read(pm_io_base, 64, 4, pm_ioport_readl, s);
266
    }
267
}
268

    
269
static void pm_write_config(PCIDevice *d,
270
                            uint32_t address, uint32_t val, int len)
271
{
272
    pci_default_write_config(d, address, val, len);
273
    if (range_covers_byte(address, len, 0x80))
274
        pm_io_space_update((PIIX4PMState *)d);
275
}
276

    
277
static int vmstate_acpi_post_load(void *opaque, int version_id)
278
{
279
    PIIX4PMState *s = opaque;
280

    
281
    pm_io_space_update(s);
282
    return 0;
283
}
284

    
285
static const VMStateDescription vmstate_acpi = {
286
    .name = "piix4_pm",
287
    .version_id = 1,
288
    .minimum_version_id = 1,
289
    .minimum_version_id_old = 1,
290
    .post_load = vmstate_acpi_post_load,
291
    .fields      = (VMStateField []) {
292
        VMSTATE_PCI_DEVICE(dev, PIIX4PMState),
293
        VMSTATE_UINT16(pmsts, PIIX4PMState),
294
        VMSTATE_UINT16(pmen, PIIX4PMState),
295
        VMSTATE_UINT16(pmcntrl, PIIX4PMState),
296
        VMSTATE_STRUCT(apm, PIIX4PMState, 0, vmstate_apm, APMState),
297
        VMSTATE_TIMER(tmr_timer, PIIX4PMState),
298
        VMSTATE_INT64(tmr_overflow_time, PIIX4PMState),
299
        VMSTATE_END_OF_LIST()
300
    }
301
};
302

    
303
static void piix4_reset(void *opaque)
304
{
305
    PIIX4PMState *s = opaque;
306
    uint8_t *pci_conf = s->dev.config;
307

    
308
    pci_conf[0x58] = 0;
309
    pci_conf[0x59] = 0;
310
    pci_conf[0x5a] = 0;
311
    pci_conf[0x5b] = 0;
312

    
313
    if (s->kvm_enabled) {
314
        /* Mark SMM as already inited (until KVM supports SMM). */
315
        pci_conf[0x5B] = 0x02;
316
    }
317
}
318

    
319
static void piix4_powerdown(void *opaque, int irq, int power_failing)
320
{
321
    PIIX4PMState *s = opaque;
322

    
323
    if (!s) {
324
        qemu_system_shutdown_request();
325
    } else if (s->pmen & ACPI_BITMASK_POWER_BUTTON_ENABLE) {
326
        s->pmsts |= ACPI_BITMASK_POWER_BUTTON_STATUS;
327
        pm_update_sci(s);
328
    }
329
}
330

    
331
static int piix4_pm_initfn(PCIDevice *dev)
332
{
333
    PIIX4PMState *s = DO_UPCAST(PIIX4PMState, dev, dev);
334
    uint8_t *pci_conf;
335

    
336
    pci_conf = s->dev.config;
337
    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
338
    pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371AB_3);
339
    pci_conf[0x06] = 0x80;
340
    pci_conf[0x07] = 0x02;
341
    pci_conf[0x08] = 0x03; // revision number
342
    pci_conf[0x09] = 0x00;
343
    pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_OTHER);
344
    pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type
345
    pci_conf[0x3d] = 0x01; // interrupt pin 1
346

    
347
    pci_conf[0x40] = 0x01; /* PM io base read only bit */
348

    
349
    /* APM */
350
    apm_init(&s->apm, apm_ctrl_changed, s);
351

    
352
    register_ioport_write(ACPI_DBG_IO_ADDR, 4, 4, acpi_dbg_writel, s);
353

    
354
    if (s->kvm_enabled) {
355
        /* Mark SMM as already inited to prevent SMM from running.  KVM does not
356
         * support SMM mode. */
357
        pci_conf[0x5B] = 0x02;
358
    }
359

    
360
    /* XXX: which specification is used ? The i82731AB has different
361
       mappings */
362
    pci_conf[0x5f] = (parallel_hds[0] != NULL ? 0x80 : 0) | 0x10;
363
    pci_conf[0x63] = 0x60;
364
    pci_conf[0x67] = (serial_hds[0] != NULL ? 0x08 : 0) |
365
        (serial_hds[1] != NULL ? 0x90 : 0);
366

    
367
    pci_conf[0x90] = s->smb_io_base | 1;
368
    pci_conf[0x91] = s->smb_io_base >> 8;
369
    pci_conf[0xd2] = 0x09;
370
    register_ioport_write(s->smb_io_base, 64, 1, smb_ioport_writeb, &s->smb);
371
    register_ioport_read(s->smb_io_base, 64, 1, smb_ioport_readb, &s->smb);
372

    
373
    s->tmr_timer = qemu_new_timer(vm_clock, pm_tmr_timer, s);
374

    
375
    qemu_system_powerdown = *qemu_allocate_irqs(piix4_powerdown, s, 1);
376

    
377
    pm_smbus_init(&s->dev.qdev, &s->smb);
378
    qemu_register_reset(piix4_reset, s);
379
    piix4_acpi_system_hot_add_init(dev->bus, s);
380

    
381
    return 0;
382
}
383

    
384
i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
385
                       qemu_irq sci_irq, qemu_irq cmos_s3, qemu_irq smi_irq,
386
                       int kvm_enabled)
387
{
388
    PCIDevice *dev;
389
    PIIX4PMState *s;
390

    
391
    dev = pci_create(bus, devfn, "PIIX4_PM");
392
    qdev_prop_set_uint32(&dev->qdev, "smb_io_base", smb_io_base);
393

    
394
    s = DO_UPCAST(PIIX4PMState, dev, dev);
395
    s->irq = sci_irq;
396
    s->cmos_s3 = cmos_s3;
397
    s->smi_irq = smi_irq;
398
    s->kvm_enabled = kvm_enabled;
399

    
400
    qdev_init_nofail(&dev->qdev);
401

    
402
    return s->smb.smbus;
403
}
404

    
405
static PCIDeviceInfo piix4_pm_info = {
406
    .qdev.name          = "PIIX4_PM",
407
    .qdev.desc          = "PM",
408
    .qdev.size          = sizeof(PIIX4PMState),
409
    .qdev.vmsd          = &vmstate_acpi,
410
    .init               = piix4_pm_initfn,
411
    .config_write       = pm_write_config,
412
    .qdev.props         = (Property[]) {
413
        DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0),
414
        DEFINE_PROP_END_OF_LIST(),
415
    }
416
};
417

    
418
static void piix4_pm_register(void)
419
{
420
    pci_qdev_register(&piix4_pm_info);
421
}
422

    
423
device_init(piix4_pm_register);
424

    
425
static uint32_t gpe_read_val(uint16_t val, uint32_t addr)
426
{
427
    if (addr & 1)
428
        return (val >> 8) & 0xff;
429
    return val & 0xff;
430
}
431

    
432
static uint32_t gpe_readb(void *opaque, uint32_t addr)
433
{
434
    uint32_t val = 0;
435
    struct gpe_regs *g = opaque;
436
    switch (addr) {
437
        case GPE_BASE:
438
        case GPE_BASE + 1:
439
            val = gpe_read_val(g->sts, addr);
440
            break;
441
        case GPE_BASE + 2:
442
        case GPE_BASE + 3:
443
            val = gpe_read_val(g->en, addr);
444
            break;
445
        default:
446
            break;
447
    }
448

    
449
    PIIX4_DPRINTF("gpe read %x == %x\n", addr, val);
450
    return val;
451
}
452

    
453
static void gpe_write_val(uint16_t *cur, int addr, uint32_t val)
454
{
455
    if (addr & 1)
456
        *cur = (*cur & 0xff) | (val << 8);
457
    else
458
        *cur = (*cur & 0xff00) | (val & 0xff);
459
}
460

    
461
static void gpe_reset_val(uint16_t *cur, int addr, uint32_t val)
462
{
463
    uint16_t x1, x0 = val & 0xff;
464
    int shift = (addr & 1) ? 8 : 0;
465

    
466
    x1 = (*cur >> shift) & 0xff;
467

    
468
    x1 = x1 & ~x0;
469

    
470
    *cur = (*cur & (0xff << (8 - shift))) | (x1 << shift);
471
}
472

    
473
static void gpe_writeb(void *opaque, uint32_t addr, uint32_t val)
474
{
475
    struct gpe_regs *g = opaque;
476
    switch (addr) {
477
        case GPE_BASE:
478
        case GPE_BASE + 1:
479
            gpe_reset_val(&g->sts, addr, val);
480
            break;
481
        case GPE_BASE + 2:
482
        case GPE_BASE + 3:
483
            gpe_write_val(&g->en, addr, val);
484
            break;
485
        default:
486
            break;
487
   }
488

    
489
    PIIX4_DPRINTF("gpe write %x <== %d\n", addr, val);
490
}
491

    
492
static uint32_t pcihotplug_read(void *opaque, uint32_t addr)
493
{
494
    uint32_t val = 0;
495
    struct pci_status *g = opaque;
496
    switch (addr) {
497
        case PCI_BASE:
498
            val = g->up;
499
            break;
500
        case PCI_BASE + 4:
501
            val = g->down;
502
            break;
503
        default:
504
            break;
505
    }
506

    
507
    PIIX4_DPRINTF("pcihotplug read %x == %x\n", addr, val);
508
    return val;
509
}
510

    
511
static void pcihotplug_write(void *opaque, uint32_t addr, uint32_t val)
512
{
513
    struct pci_status *g = opaque;
514
    switch (addr) {
515
        case PCI_BASE:
516
            g->up = val;
517
            break;
518
        case PCI_BASE + 4:
519
            g->down = val;
520
            break;
521
   }
522

    
523
    PIIX4_DPRINTF("pcihotplug write %x <== %d\n", addr, val);
524
}
525

    
526
static uint32_t pciej_read(void *opaque, uint32_t addr)
527
{
528
    PIIX4_DPRINTF("pciej read %x\n", addr);
529
    return 0;
530
}
531

    
532
static void pciej_write(void *opaque, uint32_t addr, uint32_t val)
533
{
534
    BusState *bus = opaque;
535
    DeviceState *qdev, *next;
536
    PCIDevice *dev;
537
    int slot = ffs(val) - 1;
538

    
539
    QLIST_FOREACH_SAFE(qdev, &bus->children, sibling, next) {
540
        dev = DO_UPCAST(PCIDevice, qdev, qdev);
541
        if (PCI_SLOT(dev->devfn) == slot) {
542
            qdev_free(qdev);
543
        }
544
    }
545

    
546

    
547
    PIIX4_DPRINTF("pciej write %x <== %d\n", addr, val);
548
}
549

    
550
static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev, int state);
551

    
552
static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s)
553
{
554
    struct gpe_regs *gpe = &s->gpe;
555
    struct pci_status *pci0_status = &s->pci0_status;
556

    
557
    register_ioport_write(GPE_BASE, 4, 1, gpe_writeb, gpe);
558
    register_ioport_read(GPE_BASE, 4, 1,  gpe_readb, gpe);
559

    
560
    register_ioport_write(PCI_BASE, 8, 4, pcihotplug_write, pci0_status);
561
    register_ioport_read(PCI_BASE, 8, 4,  pcihotplug_read, pci0_status);
562

    
563
    register_ioport_write(PCI_EJ_BASE, 4, 4, pciej_write, bus);
564
    register_ioport_read(PCI_EJ_BASE, 4, 4,  pciej_read, bus);
565

    
566
    pci_bus_hotplug(bus, piix4_device_hotplug, &s->dev.qdev);
567
}
568

    
569
static void enable_device(PIIX4PMState *s, int slot)
570
{
571
    s->gpe.sts |= 2;
572
    s->pci0_status.up |= (1 << slot);
573
}
574

    
575
static void disable_device(PIIX4PMState *s, int slot)
576
{
577
    s->gpe.sts |= 2;
578
    s->pci0_status.down |= (1 << slot);
579
}
580

    
581
static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev, int state)
582
{
583
    int slot = PCI_SLOT(dev->devfn);
584
    PIIX4PMState *s = DO_UPCAST(PIIX4PMState, dev,
585
                                DO_UPCAST(PCIDevice, qdev, qdev));
586

    
587
    s->pci0_status.up = 0;
588
    s->pci0_status.down = 0;
589
    if (state) {
590
        enable_device(s, slot);
591
    } else {
592
        disable_device(s, slot);
593
    }
594
    if (s->gpe.en & 2) {
595
        qemu_set_irq(s->irq, 1);
596
        qemu_set_irq(s->irq, 0);
597
    }
598
    return 0;
599
}