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