Statistics
| Branch: | Revision:

root / hw / lpc_ich9.c @ d8c6d07f

History | View | Annotate | Download (14.7 kB)

1 4d00636e Jason Baron
/*
2 6f918e40 Jason Baron
 * QEMU ICH9 Emulation
3 6f918e40 Jason Baron
 *
4 4d00636e Jason Baron
 * Copyright (c) 2006 Fabrice Bellard
5 6f918e40 Jason Baron
 * Copyright (c) 2009, 2010, 2011
6 6f918e40 Jason Baron
 *               Isaku Yamahata <yamahata at valinux co jp>
7 6f918e40 Jason Baron
 *               VA Linux Systems Japan K.K.
8 6f918e40 Jason Baron
 * Copyright (C) 2012 Jason Baron <jbaron@redhat.com>
9 6f918e40 Jason Baron
 *
10 6f918e40 Jason Baron
 * This is based on piix_pci.c, but heavily modified.
11 4d00636e Jason Baron
 *
12 4d00636e Jason Baron
 * Permission is hereby granted, free of charge, to any person obtaining a copy
13 4d00636e Jason Baron
 * of this software and associated documentation files (the "Software"), to deal
14 4d00636e Jason Baron
 * in the Software without restriction, including without limitation the rights
15 4d00636e Jason Baron
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 4d00636e Jason Baron
 * copies of the Software, and to permit persons to whom the Software is
17 4d00636e Jason Baron
 * furnished to do so, subject to the following conditions:
18 4d00636e Jason Baron
 *
19 4d00636e Jason Baron
 * The above copyright notice and this permission notice shall be included in
20 4d00636e Jason Baron
 * all copies or substantial portions of the Software.
21 4d00636e Jason Baron
 *
22 4d00636e Jason Baron
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 4d00636e Jason Baron
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 4d00636e Jason Baron
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 4d00636e Jason Baron
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 4d00636e Jason Baron
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 4d00636e Jason Baron
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28 4d00636e Jason Baron
 * THE SOFTWARE.
29 4d00636e Jason Baron
 */
30 4d00636e Jason Baron
#include "qemu-common.h"
31 4d00636e Jason Baron
#include "hw.h"
32 1de7afc9 Paolo Bonzini
#include "qemu/range.h"
33 4d00636e Jason Baron
#include "isa.h"
34 4d00636e Jason Baron
#include "sysbus.h"
35 4d00636e Jason Baron
#include "pc.h"
36 4d00636e Jason Baron
#include "apm.h"
37 4d00636e Jason Baron
#include "ioapic.h"
38 a2cb15b0 Michael S. Tsirkin
#include "pci/pci.h"
39 a2cb15b0 Michael S. Tsirkin
#include "pci/pcie_host.h"
40 a2cb15b0 Michael S. Tsirkin
#include "pci/pci_bridge.h"
41 4d00636e Jason Baron
#include "ich9.h"
42 4d00636e Jason Baron
#include "acpi.h"
43 4d00636e Jason Baron
#include "acpi_ich9.h"
44 4d00636e Jason Baron
#include "pam.h"
45 06aac7bd Michael S. Tsirkin
#include "pci/pci_bus.h"
46 022c62cb Paolo Bonzini
#include "exec/address-spaces.h"
47 9c17d615 Paolo Bonzini
#include "sysemu/sysemu.h"
48 4d00636e Jason Baron
49 4d00636e Jason Baron
static int ich9_lpc_sci_irq(ICH9LPCState *lpc);
50 4d00636e Jason Baron
51 4d00636e Jason Baron
/*****************************************************************************/
52 4d00636e Jason Baron
/* ICH9 LPC PCI to ISA bridge */
53 4d00636e Jason Baron
54 4d00636e Jason Baron
static void ich9_lpc_reset(DeviceState *qdev);
55 4d00636e Jason Baron
56 4d00636e Jason Baron
/* chipset configuration register
57 4d00636e Jason Baron
 * to access chipset configuration registers, pci_[sg]et_{byte, word, long}
58 4d00636e Jason Baron
 * are used.
59 4d00636e Jason Baron
 * Although it's not pci configuration space, it's little endian as Intel.
60 4d00636e Jason Baron
 */
61 4d00636e Jason Baron
62 4d00636e Jason Baron
static void ich9_cc_update_ir(uint8_t irr[PCI_NUM_PINS], uint16_t ir)
63 4d00636e Jason Baron
{
64 4d00636e Jason Baron
    int intx;
65 4d00636e Jason Baron
    for (intx = 0; intx < PCI_NUM_PINS; intx++) {
66 4d00636e Jason Baron
        irr[intx] = (ir >> (intx * ICH9_CC_DIR_SHIFT)) & ICH9_CC_DIR_MASK;
67 4d00636e Jason Baron
    }
68 4d00636e Jason Baron
}
69 4d00636e Jason Baron
70 4d00636e Jason Baron
static void ich9_cc_update(ICH9LPCState *lpc)
71 4d00636e Jason Baron
{
72 4d00636e Jason Baron
    int slot;
73 4d00636e Jason Baron
    int pci_intx;
74 4d00636e Jason Baron
75 4d00636e Jason Baron
    const int reg_offsets[] = {
76 4d00636e Jason Baron
        ICH9_CC_D25IR,
77 4d00636e Jason Baron
        ICH9_CC_D26IR,
78 4d00636e Jason Baron
        ICH9_CC_D27IR,
79 4d00636e Jason Baron
        ICH9_CC_D28IR,
80 4d00636e Jason Baron
        ICH9_CC_D29IR,
81 4d00636e Jason Baron
        ICH9_CC_D30IR,
82 4d00636e Jason Baron
        ICH9_CC_D31IR,
83 4d00636e Jason Baron
    };
84 4d00636e Jason Baron
    const int *offset;
85 4d00636e Jason Baron
86 4d00636e Jason Baron
    /* D{25 - 31}IR, but D30IR is read only to 0. */
87 4d00636e Jason Baron
    for (slot = 25, offset = reg_offsets; slot < 32; slot++, offset++) {
88 4d00636e Jason Baron
        if (slot == 30) {
89 4d00636e Jason Baron
            continue;
90 4d00636e Jason Baron
        }
91 4d00636e Jason Baron
        ich9_cc_update_ir(lpc->irr[slot],
92 4d00636e Jason Baron
                          pci_get_word(lpc->chip_config + *offset));
93 4d00636e Jason Baron
    }
94 4d00636e Jason Baron
95 4d00636e Jason Baron
    /*
96 4d00636e Jason Baron
     * D30: DMI2PCI bridge
97 4d00636e Jason Baron
     * It is arbitrarily decided how INTx lines of PCI devicesbehind the bridge
98 4d00636e Jason Baron
     * are connected to pirq lines. Our choice is PIRQ[E-H].
99 4d00636e Jason Baron
     * INT[A-D] are connected to PIRQ[E-H]
100 4d00636e Jason Baron
     */
101 4d00636e Jason Baron
    for (pci_intx = 0; pci_intx < PCI_NUM_PINS; pci_intx++) {
102 4d00636e Jason Baron
        lpc->irr[30][pci_intx] = pci_intx + 4;
103 4d00636e Jason Baron
    }
104 4d00636e Jason Baron
}
105 4d00636e Jason Baron
106 4d00636e Jason Baron
static void ich9_cc_init(ICH9LPCState *lpc)
107 4d00636e Jason Baron
{
108 4d00636e Jason Baron
    int slot;
109 4d00636e Jason Baron
    int intx;
110 4d00636e Jason Baron
111 4d00636e Jason Baron
    /* the default irq routing is arbitrary as long as it matches with
112 4d00636e Jason Baron
     * acpi irq routing table.
113 4d00636e Jason Baron
     * The one that is incompatible with piix_pci(= bochs) one is
114 4d00636e Jason Baron
     * intentionally chosen to let the users know that the different
115 4d00636e Jason Baron
     * board is used.
116 4d00636e Jason Baron
     *
117 4d00636e Jason Baron
     * int[A-D] -> pirq[E-F]
118 4d00636e Jason Baron
     * avoid pirq A-D because they are used for pci express port
119 4d00636e Jason Baron
     */
120 4d00636e Jason Baron
    for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
121 4d00636e Jason Baron
        for (intx = 0; intx < PCI_NUM_PINS; intx++) {
122 4d00636e Jason Baron
            lpc->irr[slot][intx] = (slot + intx) % 4 + 4;
123 4d00636e Jason Baron
        }
124 4d00636e Jason Baron
    }
125 4d00636e Jason Baron
    ich9_cc_update(lpc);
126 4d00636e Jason Baron
}
127 4d00636e Jason Baron
128 4d00636e Jason Baron
static void ich9_cc_reset(ICH9LPCState *lpc)
129 4d00636e Jason Baron
{
130 4d00636e Jason Baron
    uint8_t *c = lpc->chip_config;
131 4d00636e Jason Baron
132 4d00636e Jason Baron
    memset(lpc->chip_config, 0, sizeof(lpc->chip_config));
133 4d00636e Jason Baron
134 4d00636e Jason Baron
    pci_set_long(c + ICH9_CC_D31IR, ICH9_CC_DIR_DEFAULT);
135 4d00636e Jason Baron
    pci_set_long(c + ICH9_CC_D30IR, ICH9_CC_D30IR_DEFAULT);
136 4d00636e Jason Baron
    pci_set_long(c + ICH9_CC_D29IR, ICH9_CC_DIR_DEFAULT);
137 4d00636e Jason Baron
    pci_set_long(c + ICH9_CC_D28IR, ICH9_CC_DIR_DEFAULT);
138 4d00636e Jason Baron
    pci_set_long(c + ICH9_CC_D27IR, ICH9_CC_DIR_DEFAULT);
139 4d00636e Jason Baron
    pci_set_long(c + ICH9_CC_D26IR, ICH9_CC_DIR_DEFAULT);
140 4d00636e Jason Baron
    pci_set_long(c + ICH9_CC_D25IR, ICH9_CC_DIR_DEFAULT);
141 4d00636e Jason Baron
142 4d00636e Jason Baron
    ich9_cc_update(lpc);
143 4d00636e Jason Baron
}
144 4d00636e Jason Baron
145 4d00636e Jason Baron
static void ich9_cc_addr_len(uint64_t *addr, unsigned *len)
146 4d00636e Jason Baron
{
147 4d00636e Jason Baron
    *addr &= ICH9_CC_ADDR_MASK;
148 4d00636e Jason Baron
    if (*addr + *len >= ICH9_CC_SIZE) {
149 4d00636e Jason Baron
        *len = ICH9_CC_SIZE - *addr;
150 4d00636e Jason Baron
    }
151 4d00636e Jason Baron
}
152 4d00636e Jason Baron
153 4d00636e Jason Baron
/* val: little endian */
154 4d00636e Jason Baron
static void ich9_cc_write(void *opaque, hwaddr addr,
155 4d00636e Jason Baron
                          uint64_t val, unsigned len)
156 4d00636e Jason Baron
{
157 4d00636e Jason Baron
    ICH9LPCState *lpc = (ICH9LPCState *)opaque;
158 4d00636e Jason Baron
159 4d00636e Jason Baron
    ich9_cc_addr_len(&addr, &len);
160 4d00636e Jason Baron
    memcpy(lpc->chip_config + addr, &val, len);
161 4d00636e Jason Baron
    ich9_cc_update(lpc);
162 4d00636e Jason Baron
}
163 4d00636e Jason Baron
164 4d00636e Jason Baron
/* return value: little endian */
165 4d00636e Jason Baron
static uint64_t ich9_cc_read(void *opaque, hwaddr addr,
166 4d00636e Jason Baron
                              unsigned len)
167 4d00636e Jason Baron
{
168 4d00636e Jason Baron
    ICH9LPCState *lpc = (ICH9LPCState *)opaque;
169 4d00636e Jason Baron
170 4d00636e Jason Baron
    uint32_t val = 0;
171 4d00636e Jason Baron
    ich9_cc_addr_len(&addr, &len);
172 4d00636e Jason Baron
    memcpy(&val, lpc->chip_config + addr, len);
173 4d00636e Jason Baron
    return val;
174 4d00636e Jason Baron
}
175 4d00636e Jason Baron
176 4d00636e Jason Baron
/* IRQ routing */
177 4d00636e Jason Baron
/* */
178 4d00636e Jason Baron
static void ich9_lpc_rout(uint8_t pirq_rout, int *pic_irq, int *pic_dis)
179 4d00636e Jason Baron
{
180 4d00636e Jason Baron
    *pic_irq = pirq_rout & ICH9_LPC_PIRQ_ROUT_MASK;
181 4d00636e Jason Baron
    *pic_dis = pirq_rout & ICH9_LPC_PIRQ_ROUT_IRQEN;
182 4d00636e Jason Baron
}
183 4d00636e Jason Baron
184 4d00636e Jason Baron
static void ich9_lpc_pic_irq(ICH9LPCState *lpc, int pirq_num,
185 4d00636e Jason Baron
                             int *pic_irq, int *pic_dis)
186 4d00636e Jason Baron
{
187 4d00636e Jason Baron
    switch (pirq_num) {
188 4d00636e Jason Baron
    case 0 ... 3: /* A-D */
189 4d00636e Jason Baron
        ich9_lpc_rout(lpc->d.config[ICH9_LPC_PIRQA_ROUT + pirq_num],
190 4d00636e Jason Baron
                      pic_irq, pic_dis);
191 4d00636e Jason Baron
        return;
192 4d00636e Jason Baron
    case 4 ... 7: /* E-H */
193 4d00636e Jason Baron
        ich9_lpc_rout(lpc->d.config[ICH9_LPC_PIRQE_ROUT + (pirq_num - 4)],
194 4d00636e Jason Baron
                      pic_irq, pic_dis);
195 4d00636e Jason Baron
        return;
196 4d00636e Jason Baron
    default:
197 4d00636e Jason Baron
        break;
198 4d00636e Jason Baron
    }
199 4d00636e Jason Baron
    abort();
200 4d00636e Jason Baron
}
201 4d00636e Jason Baron
202 4d00636e Jason Baron
/* pic_irq: i8254 irq 0-15 */
203 4d00636e Jason Baron
static void ich9_lpc_update_pic(ICH9LPCState *lpc, int pic_irq)
204 4d00636e Jason Baron
{
205 4d00636e Jason Baron
    int i, pic_level;
206 4d00636e Jason Baron
207 4d00636e Jason Baron
    /* The pic level is the logical OR of all the PCI irqs mapped to it */
208 4d00636e Jason Baron
    pic_level = 0;
209 4d00636e Jason Baron
    for (i = 0; i < ICH9_LPC_NB_PIRQS; i++) {
210 4d00636e Jason Baron
        int tmp_irq;
211 4d00636e Jason Baron
        int tmp_dis;
212 4d00636e Jason Baron
        ich9_lpc_pic_irq(lpc, i, &tmp_irq, &tmp_dis);
213 4d00636e Jason Baron
        if (!tmp_dis && pic_irq == tmp_irq) {
214 4d00636e Jason Baron
            pic_level |= pci_bus_get_irq_level(lpc->d.bus, i);
215 4d00636e Jason Baron
        }
216 4d00636e Jason Baron
    }
217 4d00636e Jason Baron
    if (pic_irq == ich9_lpc_sci_irq(lpc)) {
218 4d00636e Jason Baron
        pic_level |= lpc->sci_level;
219 4d00636e Jason Baron
    }
220 4d00636e Jason Baron
221 4d00636e Jason Baron
    qemu_set_irq(lpc->pic[pic_irq], pic_level);
222 4d00636e Jason Baron
}
223 4d00636e Jason Baron
224 4d00636e Jason Baron
/* pirq: pirq[A-H] 0-7*/
225 4d00636e Jason Baron
static void ich9_lpc_update_by_pirq(ICH9LPCState *lpc, int pirq)
226 4d00636e Jason Baron
{
227 4d00636e Jason Baron
    int pic_irq;
228 4d00636e Jason Baron
    int pic_dis;
229 4d00636e Jason Baron
230 4d00636e Jason Baron
    ich9_lpc_pic_irq(lpc, pirq, &pic_irq, &pic_dis);
231 4d00636e Jason Baron
    assert(pic_irq < ICH9_LPC_PIC_NUM_PINS);
232 4d00636e Jason Baron
    if (pic_dis) {
233 4d00636e Jason Baron
        return;
234 4d00636e Jason Baron
    }
235 4d00636e Jason Baron
236 4d00636e Jason Baron
    ich9_lpc_update_pic(lpc, pic_irq);
237 4d00636e Jason Baron
}
238 4d00636e Jason Baron
239 4d00636e Jason Baron
/* APIC mode: GSIx: PIRQ[A-H] -> GSI 16, ... no pirq shares same APIC pins. */
240 4d00636e Jason Baron
static int ich9_pirq_to_gsi(int pirq)
241 4d00636e Jason Baron
{
242 4d00636e Jason Baron
    return pirq + ICH9_LPC_PIC_NUM_PINS;
243 4d00636e Jason Baron
}
244 4d00636e Jason Baron
245 4d00636e Jason Baron
static int ich9_gsi_to_pirq(int gsi)
246 4d00636e Jason Baron
{
247 4d00636e Jason Baron
    return gsi - ICH9_LPC_PIC_NUM_PINS;
248 4d00636e Jason Baron
}
249 4d00636e Jason Baron
250 4d00636e Jason Baron
static void ich9_lpc_update_apic(ICH9LPCState *lpc, int gsi)
251 4d00636e Jason Baron
{
252 243b9511 Jan Kiszka
    int level = 0;
253 4d00636e Jason Baron
254 243b9511 Jan Kiszka
    if (gsi >= ICH9_LPC_PIC_NUM_PINS) {
255 243b9511 Jan Kiszka
        level |= pci_bus_get_irq_level(lpc->d.bus, ich9_gsi_to_pirq(gsi));
256 243b9511 Jan Kiszka
    }
257 4d00636e Jason Baron
    if (gsi == ich9_lpc_sci_irq(lpc)) {
258 4d00636e Jason Baron
        level |= lpc->sci_level;
259 4d00636e Jason Baron
    }
260 4d00636e Jason Baron
261 4d00636e Jason Baron
    qemu_set_irq(lpc->ioapic[gsi], level);
262 4d00636e Jason Baron
}
263 4d00636e Jason Baron
264 4d00636e Jason Baron
void ich9_lpc_set_irq(void *opaque, int pirq, int level)
265 4d00636e Jason Baron
{
266 4d00636e Jason Baron
    ICH9LPCState *lpc = opaque;
267 4d00636e Jason Baron
268 4d00636e Jason Baron
    assert(0 <= pirq);
269 4d00636e Jason Baron
    assert(pirq < ICH9_LPC_NB_PIRQS);
270 4d00636e Jason Baron
271 4d00636e Jason Baron
    ich9_lpc_update_apic(lpc, ich9_pirq_to_gsi(pirq));
272 4d00636e Jason Baron
    ich9_lpc_update_by_pirq(lpc, pirq);
273 4d00636e Jason Baron
}
274 4d00636e Jason Baron
275 4d00636e Jason Baron
/* return the pirq number (PIRQ[A-H]:0-7) corresponding to
276 4d00636e Jason Baron
 * a given device irq pin.
277 4d00636e Jason Baron
 */
278 4d00636e Jason Baron
int ich9_lpc_map_irq(PCIDevice *pci_dev, int intx)
279 4d00636e Jason Baron
{
280 4d00636e Jason Baron
    BusState *bus = qdev_get_parent_bus(&pci_dev->qdev);
281 4d00636e Jason Baron
    PCIBus *pci_bus = PCI_BUS(bus);
282 4d00636e Jason Baron
    PCIDevice *lpc_pdev =
283 4d00636e Jason Baron
            pci_bus->devices[PCI_DEVFN(ICH9_LPC_DEV, ICH9_LPC_FUNC)];
284 4d00636e Jason Baron
    ICH9LPCState *lpc = ICH9_LPC_DEVICE(lpc_pdev);
285 4d00636e Jason Baron
286 4d00636e Jason Baron
    return lpc->irr[PCI_SLOT(pci_dev->devfn)][intx];
287 4d00636e Jason Baron
}
288 4d00636e Jason Baron
289 4d00636e Jason Baron
static int ich9_lpc_sci_irq(ICH9LPCState *lpc)
290 4d00636e Jason Baron
{
291 4d00636e Jason Baron
    switch (lpc->d.config[ICH9_LPC_ACPI_CTRL] &
292 4d00636e Jason Baron
            ICH9_LPC_ACPI_CTRL_SCI_IRQ_SEL_MASK) {
293 4d00636e Jason Baron
    case ICH9_LPC_ACPI_CTRL_9:
294 4d00636e Jason Baron
        return 9;
295 4d00636e Jason Baron
    case ICH9_LPC_ACPI_CTRL_10:
296 4d00636e Jason Baron
        return 10;
297 4d00636e Jason Baron
    case ICH9_LPC_ACPI_CTRL_11:
298 4d00636e Jason Baron
        return 11;
299 4d00636e Jason Baron
    case ICH9_LPC_ACPI_CTRL_20:
300 4d00636e Jason Baron
        return 20;
301 4d00636e Jason Baron
    case ICH9_LPC_ACPI_CTRL_21:
302 4d00636e Jason Baron
        return 21;
303 4d00636e Jason Baron
    default:
304 4d00636e Jason Baron
        /* reserved */
305 4d00636e Jason Baron
        break;
306 4d00636e Jason Baron
    }
307 4d00636e Jason Baron
    return -1;
308 4d00636e Jason Baron
}
309 4d00636e Jason Baron
310 4d00636e Jason Baron
static void ich9_set_sci(void *opaque, int irq_num, int level)
311 4d00636e Jason Baron
{
312 4d00636e Jason Baron
    ICH9LPCState *lpc = opaque;
313 4d00636e Jason Baron
    int irq;
314 4d00636e Jason Baron
315 4d00636e Jason Baron
    assert(irq_num == 0);
316 4d00636e Jason Baron
    level = !!level;
317 4d00636e Jason Baron
    if (level == lpc->sci_level) {
318 4d00636e Jason Baron
        return;
319 4d00636e Jason Baron
    }
320 4d00636e Jason Baron
    lpc->sci_level = level;
321 4d00636e Jason Baron
322 4d00636e Jason Baron
    irq = ich9_lpc_sci_irq(lpc);
323 4d00636e Jason Baron
    if (irq < 0) {
324 4d00636e Jason Baron
        return;
325 4d00636e Jason Baron
    }
326 4d00636e Jason Baron
327 4d00636e Jason Baron
    ich9_lpc_update_apic(lpc, irq);
328 4d00636e Jason Baron
    if (irq < ICH9_LPC_PIC_NUM_PINS) {
329 4d00636e Jason Baron
        ich9_lpc_update_pic(lpc, irq);
330 4d00636e Jason Baron
    }
331 4d00636e Jason Baron
}
332 4d00636e Jason Baron
333 4d00636e Jason Baron
void ich9_lpc_pm_init(PCIDevice *lpc_pci, qemu_irq cmos_s3)
334 4d00636e Jason Baron
{
335 4d00636e Jason Baron
    ICH9LPCState *lpc = ICH9_LPC_DEVICE(lpc_pci);
336 4d00636e Jason Baron
    qemu_irq *sci_irq;
337 4d00636e Jason Baron
338 4d00636e Jason Baron
    sci_irq = qemu_allocate_irqs(ich9_set_sci, lpc, 1);
339 503b19fc Gerd Hoffmann
    ich9_pm_init(lpc_pci, &lpc->pm, sci_irq[0], cmos_s3);
340 4d00636e Jason Baron
341 4d00636e Jason Baron
    ich9_lpc_reset(&lpc->d.qdev);
342 4d00636e Jason Baron
}
343 4d00636e Jason Baron
344 4d00636e Jason Baron
/* APM */
345 4d00636e Jason Baron
346 4d00636e Jason Baron
static void ich9_apm_ctrl_changed(uint32_t val, void *arg)
347 4d00636e Jason Baron
{
348 4d00636e Jason Baron
    ICH9LPCState *lpc = arg;
349 4d00636e Jason Baron
350 4d00636e Jason Baron
    /* ACPI specs 3.0, 4.7.2.5 */
351 4d00636e Jason Baron
    acpi_pm1_cnt_update(&lpc->pm.acpi_regs,
352 4d00636e Jason Baron
                        val == ICH9_APM_ACPI_ENABLE,
353 4d00636e Jason Baron
                        val == ICH9_APM_ACPI_DISABLE);
354 4d00636e Jason Baron
355 4d00636e Jason Baron
    /* SMI_EN = PMBASE + 30. SMI control and enable register */
356 4d00636e Jason Baron
    if (lpc->pm.smi_en & ICH9_PMIO_SMI_EN_APMC_EN) {
357 4d00636e Jason Baron
        cpu_interrupt(first_cpu, CPU_INTERRUPT_SMI);
358 4d00636e Jason Baron
    }
359 4d00636e Jason Baron
}
360 4d00636e Jason Baron
361 4d00636e Jason Baron
/* config:PMBASE */
362 4d00636e Jason Baron
static void
363 4d00636e Jason Baron
ich9_lpc_pmbase_update(ICH9LPCState *lpc)
364 4d00636e Jason Baron
{
365 4d00636e Jason Baron
    uint32_t pm_io_base = pci_get_long(lpc->d.config + ICH9_LPC_PMBASE);
366 4d00636e Jason Baron
    pm_io_base &= ICH9_LPC_PMBASE_BASE_ADDRESS_MASK;
367 4d00636e Jason Baron
368 4d00636e Jason Baron
    ich9_pm_iospace_update(&lpc->pm, pm_io_base);
369 4d00636e Jason Baron
}
370 4d00636e Jason Baron
371 4d00636e Jason Baron
/* config:RBCA */
372 4d00636e Jason Baron
static void ich9_lpc_rcba_update(ICH9LPCState *lpc, uint32_t rbca_old)
373 4d00636e Jason Baron
{
374 4d00636e Jason Baron
    uint32_t rbca = pci_get_long(lpc->d.config + ICH9_LPC_RCBA);
375 4d00636e Jason Baron
376 4d00636e Jason Baron
    if (rbca_old & ICH9_LPC_RCBA_EN) {
377 4d00636e Jason Baron
            memory_region_del_subregion(get_system_memory(), &lpc->rbca_mem);
378 4d00636e Jason Baron
    }
379 4d00636e Jason Baron
    if (rbca & ICH9_LPC_RCBA_EN) {
380 4d00636e Jason Baron
            memory_region_add_subregion_overlap(get_system_memory(),
381 4d00636e Jason Baron
                                                rbca & ICH9_LPC_RCBA_BA_MASK,
382 4d00636e Jason Baron
                                                &lpc->rbca_mem, 1);
383 4d00636e Jason Baron
    }
384 4d00636e Jason Baron
}
385 4d00636e Jason Baron
386 4d00636e Jason Baron
static int ich9_lpc_post_load(void *opaque, int version_id)
387 4d00636e Jason Baron
{
388 4d00636e Jason Baron
    ICH9LPCState *lpc = opaque;
389 4d00636e Jason Baron
390 4d00636e Jason Baron
    ich9_lpc_pmbase_update(lpc);
391 4d00636e Jason Baron
    ich9_lpc_rcba_update(lpc, 0 /* disabled ICH9_LPC_RBCA_EN */);
392 4d00636e Jason Baron
    return 0;
393 4d00636e Jason Baron
}
394 4d00636e Jason Baron
395 4d00636e Jason Baron
static void ich9_lpc_config_write(PCIDevice *d,
396 4d00636e Jason Baron
                                  uint32_t addr, uint32_t val, int len)
397 4d00636e Jason Baron
{
398 4d00636e Jason Baron
    ICH9LPCState *lpc = ICH9_LPC_DEVICE(d);
399 4d00636e Jason Baron
    uint32_t rbca_old = pci_get_long(d->config + ICH9_LPC_RCBA);
400 4d00636e Jason Baron
401 4d00636e Jason Baron
    pci_default_write_config(d, addr, val, len);
402 4d00636e Jason Baron
    if (ranges_overlap(addr, len, ICH9_LPC_PMBASE, 4)) {
403 4d00636e Jason Baron
        ich9_lpc_pmbase_update(lpc);
404 4d00636e Jason Baron
    }
405 4d00636e Jason Baron
    if (ranges_overlap(addr, len, ICH9_LPC_RCBA, 4)) {
406 4d00636e Jason Baron
        ich9_lpc_rcba_update(lpc, rbca_old);
407 4d00636e Jason Baron
    }
408 4d00636e Jason Baron
}
409 4d00636e Jason Baron
410 4d00636e Jason Baron
static void ich9_lpc_reset(DeviceState *qdev)
411 4d00636e Jason Baron
{
412 4d00636e Jason Baron
    PCIDevice *d = PCI_DEVICE(qdev);
413 4d00636e Jason Baron
    ICH9LPCState *lpc = ICH9_LPC_DEVICE(d);
414 4d00636e Jason Baron
    uint32_t rbca_old = pci_get_long(d->config + ICH9_LPC_RCBA);
415 4d00636e Jason Baron
    int i;
416 4d00636e Jason Baron
417 4d00636e Jason Baron
    for (i = 0; i < 4; i++) {
418 4d00636e Jason Baron
        pci_set_byte(d->config + ICH9_LPC_PIRQA_ROUT + i,
419 4d00636e Jason Baron
                     ICH9_LPC_PIRQ_ROUT_DEFAULT);
420 4d00636e Jason Baron
    }
421 4d00636e Jason Baron
    for (i = 0; i < 4; i++) {
422 4d00636e Jason Baron
        pci_set_byte(d->config + ICH9_LPC_PIRQE_ROUT + i,
423 4d00636e Jason Baron
                     ICH9_LPC_PIRQ_ROUT_DEFAULT);
424 4d00636e Jason Baron
    }
425 4d00636e Jason Baron
    pci_set_byte(d->config + ICH9_LPC_ACPI_CTRL, ICH9_LPC_ACPI_CTRL_DEFAULT);
426 4d00636e Jason Baron
427 4d00636e Jason Baron
    pci_set_long(d->config + ICH9_LPC_PMBASE, ICH9_LPC_PMBASE_DEFAULT);
428 4d00636e Jason Baron
    pci_set_long(d->config + ICH9_LPC_RCBA, ICH9_LPC_RCBA_DEFAULT);
429 4d00636e Jason Baron
430 4d00636e Jason Baron
    ich9_cc_reset(lpc);
431 4d00636e Jason Baron
432 4d00636e Jason Baron
    ich9_lpc_pmbase_update(lpc);
433 4d00636e Jason Baron
    ich9_lpc_rcba_update(lpc, rbca_old);
434 4d00636e Jason Baron
435 4d00636e Jason Baron
    lpc->sci_level = 0;
436 4d00636e Jason Baron
}
437 4d00636e Jason Baron
438 4d00636e Jason Baron
static const MemoryRegionOps rbca_mmio_ops = {
439 4d00636e Jason Baron
    .read = ich9_cc_read,
440 4d00636e Jason Baron
    .write = ich9_cc_write,
441 4d00636e Jason Baron
    .endianness = DEVICE_LITTLE_ENDIAN,
442 4d00636e Jason Baron
};
443 4d00636e Jason Baron
444 3f5bc9e8 Gerd Hoffmann
static void ich9_lpc_machine_ready(Notifier *n, void *opaque)
445 3f5bc9e8 Gerd Hoffmann
{
446 3f5bc9e8 Gerd Hoffmann
    ICH9LPCState *s = container_of(n, ICH9LPCState, machine_ready);
447 3f5bc9e8 Gerd Hoffmann
    uint8_t *pci_conf;
448 3f5bc9e8 Gerd Hoffmann
449 3f5bc9e8 Gerd Hoffmann
    pci_conf = s->d.config;
450 3f5bc9e8 Gerd Hoffmann
    if (isa_is_ioport_assigned(0x3f8)) {
451 3f5bc9e8 Gerd Hoffmann
        /* com1 */
452 3f5bc9e8 Gerd Hoffmann
        pci_conf[0x82] |= 0x01;
453 3f5bc9e8 Gerd Hoffmann
    }
454 3f5bc9e8 Gerd Hoffmann
    if (isa_is_ioport_assigned(0x2f8)) {
455 3f5bc9e8 Gerd Hoffmann
        /* com2 */
456 3f5bc9e8 Gerd Hoffmann
        pci_conf[0x82] |= 0x02;
457 3f5bc9e8 Gerd Hoffmann
    }
458 3f5bc9e8 Gerd Hoffmann
    if (isa_is_ioport_assigned(0x378)) {
459 3f5bc9e8 Gerd Hoffmann
        /* lpt */
460 3f5bc9e8 Gerd Hoffmann
        pci_conf[0x82] |= 0x04;
461 3f5bc9e8 Gerd Hoffmann
    }
462 3f5bc9e8 Gerd Hoffmann
    if (isa_is_ioport_assigned(0x3f0)) {
463 3f5bc9e8 Gerd Hoffmann
        /* floppy */
464 3f5bc9e8 Gerd Hoffmann
        pci_conf[0x82] |= 0x08;
465 3f5bc9e8 Gerd Hoffmann
    }
466 3f5bc9e8 Gerd Hoffmann
}
467 3f5bc9e8 Gerd Hoffmann
468 4d00636e Jason Baron
static int ich9_lpc_initfn(PCIDevice *d)
469 4d00636e Jason Baron
{
470 4d00636e Jason Baron
    ICH9LPCState *lpc = ICH9_LPC_DEVICE(d);
471 4d00636e Jason Baron
    ISABus *isa_bus;
472 4d00636e Jason Baron
473 4d00636e Jason Baron
    isa_bus = isa_bus_new(&d->qdev, get_system_io());
474 4d00636e Jason Baron
475 4d00636e Jason Baron
    pci_set_long(d->wmask + ICH9_LPC_PMBASE,
476 4d00636e Jason Baron
                 ICH9_LPC_PMBASE_BASE_ADDRESS_MASK);
477 4d00636e Jason Baron
478 4d00636e Jason Baron
    memory_region_init_io(&lpc->rbca_mem, &rbca_mmio_ops, lpc,
479 4d00636e Jason Baron
                            "lpc-rbca-mmio", ICH9_CC_SIZE);
480 4d00636e Jason Baron
481 4d00636e Jason Baron
    lpc->isa_bus = isa_bus;
482 4d00636e Jason Baron
483 4d00636e Jason Baron
    ich9_cc_init(lpc);
484 42d8a3cf Julien Grall
    apm_init(d, &lpc->apm, ich9_apm_ctrl_changed, lpc);
485 3f5bc9e8 Gerd Hoffmann
486 3f5bc9e8 Gerd Hoffmann
    lpc->machine_ready.notify = ich9_lpc_machine_ready;
487 3f5bc9e8 Gerd Hoffmann
    qemu_add_machine_init_done_notifier(&lpc->machine_ready);
488 3f5bc9e8 Gerd Hoffmann
489 4d00636e Jason Baron
    return 0;
490 4d00636e Jason Baron
}
491 4d00636e Jason Baron
492 4d00636e Jason Baron
static const VMStateDescription vmstate_ich9_lpc = {
493 4d00636e Jason Baron
    .name = "ICH9LPC",
494 4d00636e Jason Baron
    .version_id = 1,
495 4d00636e Jason Baron
    .minimum_version_id = 1,
496 4d00636e Jason Baron
    .minimum_version_id_old = 1,
497 4d00636e Jason Baron
    .post_load = ich9_lpc_post_load,
498 4d00636e Jason Baron
    .fields = (VMStateField[]) {
499 4d00636e Jason Baron
        VMSTATE_PCI_DEVICE(d, ICH9LPCState),
500 4d00636e Jason Baron
        VMSTATE_STRUCT(apm, ICH9LPCState, 0, vmstate_apm, APMState),
501 4d00636e Jason Baron
        VMSTATE_STRUCT(pm, ICH9LPCState, 0, vmstate_ich9_pm, ICH9LPCPMRegs),
502 4d00636e Jason Baron
        VMSTATE_UINT8_ARRAY(chip_config, ICH9LPCState, ICH9_CC_SIZE),
503 4d00636e Jason Baron
        VMSTATE_UINT32(sci_level, ICH9LPCState),
504 4d00636e Jason Baron
        VMSTATE_END_OF_LIST()
505 4d00636e Jason Baron
    }
506 4d00636e Jason Baron
};
507 4d00636e Jason Baron
508 4d00636e Jason Baron
static void ich9_lpc_class_init(ObjectClass *klass, void *data)
509 4d00636e Jason Baron
{
510 4d00636e Jason Baron
    DeviceClass *dc = DEVICE_CLASS(klass);
511 4d00636e Jason Baron
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
512 4d00636e Jason Baron
513 4d00636e Jason Baron
    dc->reset = ich9_lpc_reset;
514 4d00636e Jason Baron
    k->init = ich9_lpc_initfn;
515 4d00636e Jason Baron
    dc->vmsd = &vmstate_ich9_lpc;
516 4d00636e Jason Baron
    dc->no_user = 1;
517 4d00636e Jason Baron
    k->config_write = ich9_lpc_config_write;
518 4d00636e Jason Baron
    dc->desc = "ICH9 LPC bridge";
519 4d00636e Jason Baron
    k->vendor_id = PCI_VENDOR_ID_INTEL;
520 4d00636e Jason Baron
    k->device_id = PCI_DEVICE_ID_INTEL_ICH9_8;
521 4d00636e Jason Baron
    k->revision = ICH9_A2_LPC_REVISION;
522 4d00636e Jason Baron
    k->class_id = PCI_CLASS_BRIDGE_ISA;
523 4d00636e Jason Baron
524 4d00636e Jason Baron
}
525 4d00636e Jason Baron
526 4d00636e Jason Baron
static const TypeInfo ich9_lpc_info = {
527 4d00636e Jason Baron
    .name       = TYPE_ICH9_LPC_DEVICE,
528 4d00636e Jason Baron
    .parent     = TYPE_PCI_DEVICE,
529 4d00636e Jason Baron
    .instance_size = sizeof(struct ICH9LPCState),
530 4d00636e Jason Baron
    .class_init  = ich9_lpc_class_init,
531 4d00636e Jason Baron
};
532 4d00636e Jason Baron
533 4d00636e Jason Baron
static void ich9_lpc_register(void)
534 4d00636e Jason Baron
{
535 4d00636e Jason Baron
    type_register_static(&ich9_lpc_info);
536 4d00636e Jason Baron
}
537 4d00636e Jason Baron
538 4d00636e Jason Baron
type_init(ich9_lpc_register);