Revision ee0ea1d0 hw/piix_pci.c

b/hw/piix_pci.c
52 52
    return (irq_num + slot_addend) & 3;
53 53
}
54 54

  
55
PCIBus *i440fx_init(void)
55
static uint32_t isa_page_descs[384 / 4];
56
static uint8_t smm_enabled;
57

  
58
static const uint32_t mar_addresses[15] = {
59
    0xa0000,
60
    0xc0000,
61
    0xc4000,
62
    0xc8000,
63
    0xcc000,
64
    0xd0000,
65
    0xd4000,
66
    0xd8000,
67
    0xdc000,
68
    0xe0000,
69
    0xe4000,
70
    0xe8000,
71
    0xec000,
72
    0xf0000,
73
    0x100000,
74
};
75

  
76
static void i440fx_update_memory_mappings(PCIDevice *d)
77
{
78
    int i, r;
79
    uint32_t start, end, addr;
80
    uint32_t smram, smbase, smsize;
81

  
82
    for(i = 0; i < 14; i++) {
83
        r = (d->config[(i >> 1) + 0x61] >> ((i & 1) * 4)) & 3;
84
        start = mar_addresses[i];
85
        end = mar_addresses[i + 1];
86
        //        printf("ISA mapping %08x: %d\n", start, r);
87
        switch(r) {
88
        case 3:
89
            /* RAM */
90
            cpu_register_physical_memory(start, end - start, 
91
                                         start);
92
            break;
93
        case 2:
94
            /* ROM (XXX: not quite correct) */
95
            cpu_register_physical_memory(start, end - start, 
96
                                         start | IO_MEM_ROM);
97
            break;
98
        case 1:
99
        case 0:
100
            /* XXX: should distinguish read/write cases */
101
            for(addr = start; addr < end; addr += 4096) {
102
                cpu_register_physical_memory(addr, 4096, 
103
                                             isa_page_descs[(addr - 0xa0000) >> 12]);
104
            }
105
            break;
106
        }
107
    }
108
    smram = le32_to_cpu(*(uint32_t *)(d->config + 0x6c));
109
    if ((smm_enabled && (smram & 0x80000000)) || (smram & (1 << 26))) {
110
        /* Note: we assume the SMM area is in the 0xa0000-0x100000 range */
111
        smbase = (smram & 0xffff) << 16;
112
        smsize = (((smram >> 20) & 0xf) + 1) << 16;
113
        if (smbase >= 0xa0000 && (smbase + smsize) <= 0x100000) {
114
            cpu_register_physical_memory(smbase, smsize, smbase);
115
        }
116
    }
117
}
118

  
119
void i440fx_set_smm(PCIDevice *d, int val)
120
{
121
    val = (val != 0);
122
    if (smm_enabled != val) {
123
        smm_enabled = val;
124
        i440fx_update_memory_mappings(d);
125
    }
126
}
127

  
128

  
129
/* XXX: suppress when better memory API. We make the assumption that
130
   no device (in particular the VGA) changes the memory mappings in
131
   the 0xa0000-0x100000 range */
132
void i440fx_init_memory_mappings(PCIDevice *d)
133
{
134
    int i;
135
    for(i = 0; i < 96; i++) {
136
        isa_page_descs[i] = cpu_get_physical_page_desc(0xa0000 + i * 0x1000);
137
    }
138
}
139

  
140
static void i440fx_write_config(PCIDevice *d, 
141
                                uint32_t address, uint32_t val, int len)
142
{
143
    /* XXX: implement SMRAM.D_LOCK */
144
    pci_default_write_config(d, address, val, len);
145
    if ((address >= 0x61 && address <= 0x67) || address == 0x6c)
146
        i440fx_update_memory_mappings(d);
147
}
148

  
149
static void i440fx_save(QEMUFile* f, void *opaque)
150
{
151
    PCIDevice *d = opaque;
152
    pci_device_save(d, f);
153
    qemu_put_8s(f, &smm_enabled);
154
}
155

  
156
static int i440fx_load(QEMUFile* f, void *opaque, int version_id)
157
{
158
    PCIDevice *d = opaque;
159
    int ret;
160

  
161
    if (version_id != 1)
162
        return -EINVAL;
163
    ret = pci_device_load(d, f);
164
    if (ret < 0)
165
        return ret;
166
    i440fx_update_memory_mappings(d);
167
    qemu_get_8s(f, &smm_enabled);
168
    return 0;
169
}
170

  
171
PCIBus *i440fx_init(PCIDevice **pi440fx_state)
56 172
{
57 173
    PCIBus *b;
58 174
    PCIDevice *d;
......
73 189
    register_ioport_read(0xcfc, 4, 4, pci_host_data_readl, s);
74 190

  
75 191
    d = pci_register_device(b, "i440FX", sizeof(PCIDevice), 0, 
76
                            NULL, NULL);
192
                            NULL, i440fx_write_config);
77 193

  
78 194
    d->config[0x00] = 0x86; // vendor_id
79 195
    d->config[0x01] = 0x80;
......
83 199
    d->config[0x0a] = 0x00; // class_sub = host2pci
84 200
    d->config[0x0b] = 0x06; // class_base = PCI_bridge
85 201
    d->config[0x0e] = 0x00; // header_type
202

  
203
    d->config[0x6c] = 0x0a; /* SMRAM */
204

  
205
    register_savevm("I440FX", 0, 1, i440fx_save, i440fx_load, d);
206
    *pi440fx_state = d;
86 207
    return b;
87 208
}
88 209

  
......
188 309
    piix3_reset(d);
189 310
    return d->devfn;
190 311
}
191

  
192
/***********************************************************/
193
/* XXX: the following should be moved to the PC BIOS */
194

  
195
static __attribute__((unused)) uint32_t isa_inb(uint32_t addr)
196
{
197
    return cpu_inb(NULL, addr);
198
}
199

  
200
static void isa_outb(uint32_t val, uint32_t addr)
201
{
202
    cpu_outb(NULL, addr, val);
203
}
204

  
205
static __attribute__((unused)) uint32_t isa_inw(uint32_t addr)
206
{
207
    return cpu_inw(NULL, addr);
208
}
209

  
210
static __attribute__((unused)) void isa_outw(uint32_t val, uint32_t addr)
211
{
212
    cpu_outw(NULL, addr, val);
213
}
214

  
215
static __attribute__((unused)) uint32_t isa_inl(uint32_t addr)
216
{
217
    return cpu_inl(NULL, addr);
218
}
219

  
220
static __attribute__((unused)) void isa_outl(uint32_t val, uint32_t addr)
221
{
222
    cpu_outl(NULL, addr, val);
223
}
224

  
225
static uint32_t pci_bios_io_addr;
226
static uint32_t pci_bios_mem_addr;
227
/* host irqs corresponding to PCI irqs A-D */
228
static uint8_t pci_irqs[4] = { 11, 9, 11, 9 };
229
static int pci_bios_next_bus;
230

  
231
static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val)
232
{
233
    PCIBus *s = d->bus;
234
    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
235
    pci_data_write(s, addr, val, 4);
236
}
237

  
238
static void pci_config_writew(PCIDevice *d, uint32_t addr, uint32_t val)
239
{
240
    PCIBus *s = d->bus;
241
    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
242
    pci_data_write(s, addr, val, 2);
243
}
244

  
245
static void pci_config_writeb(PCIDevice *d, uint32_t addr, uint32_t val)
246
{
247
    PCIBus *s = d->bus;
248
    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
249
    pci_data_write(s, addr, val, 1);
250
}
251

  
252
static __attribute__((unused)) uint32_t pci_config_readl(PCIDevice *d, uint32_t addr)
253
{
254
    PCIBus *s = d->bus;
255
    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
256
    return pci_data_read(s, addr, 4);
257
}
258

  
259
static uint32_t pci_config_readw(PCIDevice *d, uint32_t addr)
260
{
261
    PCIBus *s = d->bus;
262
    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
263
    return pci_data_read(s, addr, 2);
264
}
265

  
266
static uint32_t pci_config_readb(PCIDevice *d, uint32_t addr)
267
{
268
    PCIBus *s = d->bus;
269
    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
270
    return pci_data_read(s, addr, 1);
271
}
272

  
273
static void pci_set_io_region_addr(PCIDevice *d, int region_num, uint32_t addr)
274
{
275
    PCIIORegion *r;
276
    uint16_t cmd;
277
    uint32_t ofs;
278

  
279
    if ( region_num == PCI_ROM_SLOT ) {
280
        ofs = 0x30;
281
    }else{
282
        ofs = 0x10 + region_num * 4;
283
    }
284

  
285
    pci_config_writel(d, ofs, addr);
286
    r = &d->io_regions[region_num];
287

  
288
    /* enable memory mappings */
289
    cmd = pci_config_readw(d, PCI_COMMAND);
290
    if ( region_num == PCI_ROM_SLOT )
291
        cmd |= 2;
292
    else if (r->type & PCI_ADDRESS_SPACE_IO)
293
        cmd |= 1;
294
    else
295
        cmd |= 2;
296
    pci_config_writew(d, PCI_COMMAND, cmd);
297
}
298

  
299
static void pci_bios_init_device(PCIDevice *d)
300
{
301
    int class;
302
    PCIIORegion *r;
303
    uint32_t *paddr;
304
    int i, pin, pic_irq, vendor_id, device_id;
305

  
306
    class = pci_config_readw(d, PCI_CLASS_DEVICE);
307
    vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
308
    device_id = pci_config_readw(d, PCI_DEVICE_ID);
309
    switch(class) {
310
    case 0x0101:
311
        if (vendor_id == 0x8086 && device_id == 0x7010) {
312
            /* PIIX3 IDE */
313
            pci_config_writew(d, 0x40, 0x8000); // enable IDE0
314
            pci_config_writew(d, 0x42, 0x8000); // enable IDE1
315
            goto default_map;
316
        } else {
317
            /* IDE: we map it as in ISA mode */
318
            pci_set_io_region_addr(d, 0, 0x1f0);
319
            pci_set_io_region_addr(d, 1, 0x3f4);
320
            pci_set_io_region_addr(d, 2, 0x170);
321
            pci_set_io_region_addr(d, 3, 0x374);
322
        }
323
        break;
324
    case 0x0604:
325
        /* PCI to PCI bridge.  Assign bus ID and recurse to configure
326
           devices on the secondary bus.  */
327
        i = pci_bios_next_bus++;
328
        pci_config_writeb(d, 0x18, pci_bus_num(d->bus));
329
        pci_config_writeb(d, 0x19, i);
330
        pci_for_each_device(i, pci_bios_init_device);
331
        break;
332
    case 0x0300:
333
        if (vendor_id != 0x1234)
334
            goto default_map;
335
        /* VGA: map frame buffer to default Bochs VBE address */
336
        pci_set_io_region_addr(d, 0, 0xE0000000);
337
        break;
338
    case 0x0800:
339
        /* PIC */
340
        vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
341
        device_id = pci_config_readw(d, PCI_DEVICE_ID);
342
        if (vendor_id == 0x1014) {
343
            /* IBM */
344
            if (device_id == 0x0046 || device_id == 0xFFFF) {
345
                /* MPIC & MPIC2 */
346
                pci_set_io_region_addr(d, 0, 0x80800000 + 0x00040000);
347
            }
348
        }
349
        break;
350
    case 0xff00:
351
        if (vendor_id == 0x0106b &&
352
            (device_id == 0x0017 || device_id == 0x0022)) {
353
            /* macio bridge */
354
            pci_set_io_region_addr(d, 0, 0x80800000);
355
        }
356
        break;
357
    default:
358
    default_map:
359
        /* default memory mappings */
360
        for(i = 0; i < PCI_NUM_REGIONS; i++) {
361
            r = &d->io_regions[i];
362
            if (r->size) {
363
                if (r->type & PCI_ADDRESS_SPACE_IO)
364
                    paddr = &pci_bios_io_addr;
365
                else
366
                    paddr = &pci_bios_mem_addr;
367
                *paddr = (*paddr + r->size - 1) & ~(r->size - 1);
368
                pci_set_io_region_addr(d, i, *paddr);
369
                *paddr += r->size;
370
            }
371
        }
372
        break;
373
    }
374

  
375
    /* map the interrupt */
376
    pin = pci_config_readb(d, PCI_INTERRUPT_PIN);
377
    if (pin != 0) {
378
        pin = pci_slot_get_pirq(d, pin - 1);
379
        pic_irq = pci_irqs[pin];
380
        pci_config_writeb(d, PCI_INTERRUPT_LINE, pic_irq);
381
    }
382
}
383

  
384
/*
385
 * This function initializes the PCI devices as a normal PCI BIOS
386
 * would do. It is provided just in case the BIOS has no support for
387
 * PCI.
388
 */
389
void pci_bios_init(void)
390
{
391
    int i, irq;
392
    uint8_t elcr[2];
393

  
394
    pci_bios_io_addr = 0xc000;
395
    pci_bios_mem_addr = 0xf0000000;
396

  
397
    /* activate IRQ mappings */
398
    elcr[0] = 0x00;
399
    elcr[1] = 0x00;
400
    for(i = 0; i < 4; i++) {
401
        irq = pci_irqs[i];
402
        /* set to trigger level */
403
        elcr[irq >> 3] |= (1 << (irq & 7));
404
        /* activate irq remapping in PIIX */
405
        pci_config_writeb(piix3_dev, 0x60 + i, irq);
406
    }
407
    isa_outb(elcr[0], 0x4d0);
408
    isa_outb(elcr[1], 0x4d1);
409

  
410
    pci_bios_next_bus = 1;
411
    pci_for_each_device(0, pci_bios_init_device);
412
}
413

  

Also available in: Unified diff