Revision ae0a5466

b/hw/pc.c
964 964
                    const char *kernel_cmdline,
965 965
                    const char *initrd_filename,
966 966
                    ram_addr_t below_4g_mem_size,
967
                    ram_addr_t above_4g_mem_size)
967
                    ram_addr_t above_4g_mem_size,
968
                    MemoryRegion *pci_memory,
969
                    MemoryRegion **ram_memory)
968 970
{
969 971
    char *filename;
970 972
    int ret, linux_boot, i;
......
982 984
    ram = g_malloc(sizeof(*ram));
983 985
    memory_region_init_ram(ram, NULL, "pc.ram",
984 986
                           below_4g_mem_size + above_4g_mem_size);
987
    *ram_memory = ram;
985 988
    ram_below_4g = g_malloc(sizeof(*ram_below_4g));
986 989
    memory_region_init_alias(ram_below_4g, "ram-below-4g", ram,
987 990
                             0, below_4g_mem_size);
......
1026 1029
    isa_bios = g_malloc(sizeof(*isa_bios));
1027 1030
    memory_region_init_alias(isa_bios, "isa-bios", bios,
1028 1031
                             bios_size - isa_bios_size, isa_bios_size);
1029
    memory_region_add_subregion_overlap(system_memory,
1032
    memory_region_add_subregion_overlap(pci_memory,
1030 1033
                                        0x100000 - isa_bios_size,
1031 1034
                                        isa_bios,
1032 1035
                                        1);
......
1034 1037

  
1035 1038
    option_rom_mr = g_malloc(sizeof(*option_rom_mr));
1036 1039
    memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE);
1037
    memory_region_add_subregion_overlap(system_memory,
1040
    memory_region_add_subregion_overlap(pci_memory,
1038 1041
                                        PC_ROM_MIN_VGA,
1039 1042
                                        option_rom_mr,
1040 1043
                                        1);
1041 1044

  
1042 1045
    /* map all the bios at the top of memory */
1043
    memory_region_add_subregion(system_memory,
1046
    memory_region_add_subregion(pci_memory,
1044 1047
                                (uint32_t)(-bios_size),
1045 1048
                                bios);
1046 1049

  
b/hw/pc.h
136 136
                    const char *kernel_cmdline,
137 137
                    const char *initrd_filename,
138 138
                    ram_addr_t below_4g_mem_size,
139
                    ram_addr_t above_4g_mem_size);
139
                    ram_addr_t above_4g_mem_size,
140
                    MemoryRegion *pci_memory,
141
                    MemoryRegion **ram_memory);
140 142
qemu_irq *pc_allocate_cpu_irq(void);
141 143
void pc_vga_init(PCIBus *pci_bus);
142 144
void pc_basic_device_init(qemu_irq *isa_irq,
......
182 184
                    qemu_irq *pic,
183 185
                    MemoryRegion *address_space_mem,
184 186
                    MemoryRegion *address_space_io,
185
                    ram_addr_t ram_size);
186
void i440fx_init_memory_mappings(PCII440FXState *d);
187
                    ram_addr_t ram_size,
188
                    target_phys_addr_t pci_hole_start,
189
                    target_phys_addr_t pci_hole_size,
190
                    target_phys_addr_t pci_hole64_start,
191
                    target_phys_addr_t pci_hole64_size,
192
                    MemoryRegion *pci_memory,
193
                    MemoryRegion *ram_memory);
187 194

  
188 195
/* piix4.c */
189 196
extern PCIDevice *piix4_dev;
b/hw/pc_piix.c
22 22
 * THE SOFTWARE.
23 23
 */
24 24

  
25
#include <glib.h>
26

  
25 27
#include "hw.h"
26 28
#include "pc.h"
27 29
#include "apic.h"
......
93 95
    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
94 96
    BusState *idebus[MAX_IDE_BUS];
95 97
    ISADevice *rtc_state;
98
    MemoryRegion *ram_memory;
99
    MemoryRegion *pci_memory;
96 100

  
97 101
    pc_cpus_init(cpu_model);
98 102

  
......
108 112
        below_4g_mem_size = ram_size;
109 113
    }
110 114

  
115
    pci_memory = g_new(MemoryRegion, 1);
116
    memory_region_init(pci_memory, "pci", INT64_MAX);
117

  
111 118
    /* allocate ram and load rom/bios */
112 119
    if (!xen_enabled()) {
113 120
        pc_memory_init(system_memory,
114 121
                       kernel_filename, kernel_cmdline, initrd_filename,
115
                       below_4g_mem_size, above_4g_mem_size);
122
                       below_4g_mem_size, above_4g_mem_size,
123
                       pci_memory, &ram_memory);
116 124
    }
117 125

  
118 126
    if (!xen_enabled()) {
......
130 138

  
131 139
    if (pci_enabled) {
132 140
        pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq,
133
                              system_memory, system_io, ram_size);
141
                              system_memory, system_io, ram_size,
142
                              below_4g_mem_size,
143
                              0x100000000ULL - below_4g_mem_size,
144
                              0x100000000ULL + above_4g_mem_size,
145
                              (sizeof(target_phys_addr_t) == 4
146
                               ? 0
147
                               : ((uint64_t)1 << 62)),
148
                              pci_memory, ram_memory);
134 149
    } else {
135 150
        pci_bus = NULL;
136 151
        i440fx_state = NULL;
......
202 217
        smbus_eeprom_init(smbus, 8, NULL, 0);
203 218
    }
204 219

  
205
    if (i440fx_state) {
206
        i440fx_init_memory_mappings(i440fx_state);
207
    }
208

  
209 220
    if (pci_enabled) {
210 221
        pc_pci_device_init(pci_bus);
211 222
    }
b/hw/piix_pci.c
66 66
    int32_t pci_irq_levels_vmstate[PIIX_NUM_PIRQS];
67 67
} PIIX3State;
68 68

  
69
typedef struct PAMMemoryRegion {
70
    MemoryRegion mem;
71
    bool initialized;
72
} PAMMemoryRegion;
73

  
69 74
struct PCII440FXState {
70 75
    PCIDevice dev;
71
    target_phys_addr_t isa_page_descs[384 / 4];
76
    MemoryRegion *system_memory;
77
    MemoryRegion *pci_address_space;
78
    MemoryRegion *ram_memory;
79
    MemoryRegion pci_hole;
80
    MemoryRegion pci_hole_64bit;
81
    PAMMemoryRegion pam_regions[13];
82
    MemoryRegion smram_region;
72 83
    uint8_t smm_enabled;
84
    bool smram_enabled;
73 85
    PIIX3State *piix3;
74 86
};
75 87

  
......
92 104
    return (pci_intx + slot_addend) & 3;
93 105
}
94 106

  
95
static void update_pam(PCII440FXState *d, uint32_t start, uint32_t end, int r)
107
static void update_pam(PCII440FXState *d, uint32_t start, uint32_t end, int r,
108
                       PAMMemoryRegion *mem)
96 109
{
97
    uint32_t addr;
110
    if (mem->initialized) {
111
        memory_region_del_subregion(d->system_memory, &mem->mem);
112
        memory_region_destroy(&mem->mem);
113
    }
98 114

  
99 115
    //    printf("ISA mapping %08x-0x%08x: %d\n", start, end, r);
100 116
    switch(r) {
101 117
    case 3:
102 118
        /* RAM */
103
        cpu_register_physical_memory(start, end - start,
104
                                     start);
119
        memory_region_init_alias(&mem->mem, "pam-ram", d->ram_memory,
120
                                 start, end - start);
105 121
        break;
106 122
    case 1:
107 123
        /* ROM (XXX: not quite correct) */
108
        cpu_register_physical_memory(start, end - start,
109
                                     start | IO_MEM_ROM);
124
        memory_region_init_alias(&mem->mem, "pam-rom", d->ram_memory,
125
                                 start, end - start);
126
        memory_region_set_readonly(&mem->mem, true);
110 127
        break;
111 128
    case 2:
112 129
    case 0:
113 130
        /* XXX: should distinguish read/write cases */
114
        for(addr = start; addr < end; addr += 4096) {
115
            cpu_register_physical_memory(addr, 4096,
116
                                         d->isa_page_descs[(addr - 0xa0000) >> 12]);
117
        }
131
        memory_region_init_alias(&mem->mem, "pam-pci", d->pci_address_space,
132
                                 start, end - start);
118 133
        break;
119 134
    }
135
    memory_region_add_subregion_overlap(d->system_memory,
136
                                        start, &mem->mem, 1);
137
    mem->initialized = true;
120 138
}
121 139

  
122 140
static void i440fx_update_memory_mappings(PCII440FXState *d)
123 141
{
124 142
    int i, r;
125
    uint32_t smram, addr;
143
    uint32_t smram;
126 144

  
127
    update_pam(d, 0xf0000, 0x100000, (d->dev.config[I440FX_PAM] >> 4) & 3);
145
    update_pam(d, 0xf0000, 0x100000, (d->dev.config[I440FX_PAM] >> 4) & 3,
146
               &d->pam_regions[0]);
128 147
    for(i = 0; i < 12; i++) {
129 148
        r = (d->dev.config[(i >> 1) + (I440FX_PAM + 1)] >> ((i & 1) * 4)) & 3;
130
        update_pam(d, 0xc0000 + 0x4000 * i, 0xc0000 + 0x4000 * (i + 1), r);
149
        update_pam(d, 0xc0000 + 0x4000 * i, 0xc0000 + 0x4000 * (i + 1), r,
150
                   &d->pam_regions[i+1]);
131 151
    }
132 152
    smram = d->dev.config[I440FX_SMRAM];
133 153
    if ((d->smm_enabled && (smram & 0x08)) || (smram & 0x40)) {
134
        cpu_register_physical_memory(0xa0000, 0x20000, 0xa0000);
154
        if (!d->smram_enabled) {
155
            memory_region_del_subregion(d->system_memory, &d->smram_region);
156
            d->smram_enabled = true;
157
        }
135 158
    } else {
136
        for(addr = 0xa0000; addr < 0xc0000; addr += 4096) {
137
            cpu_register_physical_memory(addr, 4096,
138
                                         d->isa_page_descs[(addr - 0xa0000) >> 12]);
159
        if (d->smram_enabled) {
160
            memory_region_add_subregion_overlap(d->system_memory, 0xa0000,
161
                                                &d->smram_region, 1);
162
            d->smram_enabled = false;
139 163
        }
140 164
    }
141 165
}
......
152 176
}
153 177

  
154 178

  
155
/* XXX: suppress when better memory API. We make the assumption that
156
   no device (in particular the VGA) changes the memory mappings in
157
   the 0xa0000-0x100000 range */
158
void i440fx_init_memory_mappings(PCII440FXState *d)
159
{
160
    int i;
161
    for(i = 0; i < 96; i++) {
162
        d->isa_page_descs[i] = cpu_get_physical_page_desc(0xa0000 + i * 0x1000);
163
    }
164
}
165

  
166 179
static void i440fx_write_config(PCIDevice *dev,
167 180
                                uint32_t address, uint32_t val, int len)
168 181
{
......
244 257
                                  qemu_irq *pic,
245 258
                                  MemoryRegion *address_space_mem,
246 259
                                  MemoryRegion *address_space_io,
247
                                  ram_addr_t ram_size)
260
                                  ram_addr_t ram_size,
261
                                  target_phys_addr_t pci_hole_start,
262
                                  target_phys_addr_t pci_hole_size,
263
                                  target_phys_addr_t pci_hole64_start,
264
                                  target_phys_addr_t pci_hole64_size,
265
                                  MemoryRegion *pci_address_space,
266
                                  MemoryRegion *ram_memory)
248 267
{
249 268
    DeviceState *dev;
250 269
    PCIBus *b;
251 270
    PCIDevice *d;
252 271
    I440FXState *s;
253 272
    PIIX3State *piix3;
273
    PCII440FXState *f;
254 274

  
255 275
    dev = qdev_create(NULL, "i440FX-pcihost");
256 276
    s = FROM_SYSBUS(I440FXState, sysbus_from_qdev(dev));
257 277
    s->address_space = address_space_mem;
258
    b = pci_bus_new(&s->busdev.qdev, NULL, s->address_space,
278
    b = pci_bus_new(&s->busdev.qdev, NULL, pci_address_space,
259 279
                    address_space_io, 0);
260 280
    s->bus = b;
261 281
    qdev_init_nofail(dev);
262 282

  
263 283
    d = pci_create_simple(b, 0, device_name);
264 284
    *pi440fx_state = DO_UPCAST(PCII440FXState, dev, d);
285
    f = *pi440fx_state;
286
    f->system_memory = address_space_mem;
287
    f->pci_address_space = pci_address_space;
288
    f->ram_memory = ram_memory;
289
    memory_region_init_alias(&f->pci_hole, "pci-hole", f->pci_address_space,
290
                             pci_hole_start, pci_hole_size);
291
    memory_region_add_subregion(f->system_memory, pci_hole_start, &f->pci_hole);
292
    memory_region_init_alias(&f->pci_hole_64bit, "pci-hole64",
293
                             f->pci_address_space,
294
                             pci_hole64_start, pci_hole64_size);
295
    if (pci_hole64_size) {
296
        memory_region_add_subregion(f->system_memory, pci_hole64_start,
297
                                    &f->pci_hole_64bit);
298
    }
299
    memory_region_init_alias(&f->smram_region, "smram-region",
300
                             f->pci_address_space, 0xa0000, 0x20000);
301
    f->smram_enabled = true;
265 302

  
266 303
    /* Xen supports additional interrupt routes from the PCI devices to
267 304
     * the IOAPIC: the four pins of each PCI device on the bus are also
......
289 326
        ram_size = 255;
290 327
    (*pi440fx_state)->dev.config[0x57]=ram_size;
291 328

  
329
    i440fx_update_memory_mappings(f);
330

  
292 331
    return b;
293 332
}
294 333

  
......
296 335
                    qemu_irq *pic,
297 336
                    MemoryRegion *address_space_mem,
298 337
                    MemoryRegion *address_space_io,
299
                    ram_addr_t ram_size)
338
                    ram_addr_t ram_size,
339
                    target_phys_addr_t pci_hole_start,
340
                    target_phys_addr_t pci_hole_size,
341
                    target_phys_addr_t pci_hole64_start,
342
                    target_phys_addr_t pci_hole64_size,
343
                    MemoryRegion *pci_memory, MemoryRegion *ram_memory)
344

  
300 345
{
301 346
    PCIBus *b;
302 347

  
303 348
    b = i440fx_common_init("i440FX", pi440fx_state, piix3_devfn, pic,
304
                           address_space_mem, address_space_io, ram_size);
349
                           address_space_mem, address_space_io, ram_size,
350
                           pci_hole_start, pci_hole_size,
351
                           pci_hole64_size, pci_hole64_size,
352
                           pci_memory, ram_memory);
305 353
    return b;
306 354
}
307 355

  

Also available in: Unified diff