Revision a0a8793e hw/gt64xxx.c
b/hw/gt64xxx.c | ||
---|---|---|
225 | 225 |
|
226 | 226 |
typedef PCIHostState GT64120PCIState; |
227 | 227 |
|
228 |
#define PCI_MAPPING_ENTRY(regname) \ |
|
229 |
target_phys_addr_t regname ##_start; \ |
|
230 |
target_phys_addr_t regname ##_length; \ |
|
231 |
int regname ##_handle |
|
232 |
|
|
228 | 233 |
typedef struct GT64120State { |
229 | 234 |
GT64120PCIState *pci; |
230 | 235 |
uint32_t regs[GT_REGS]; |
231 |
target_phys_addr_t PCI0IO_start;
|
|
232 |
target_phys_addr_t PCI0IO_length;
|
|
236 |
PCI_MAPPING_ENTRY(PCI0IO);
|
|
237 |
PCI_MAPPING_ENTRY(ISD);
|
|
233 | 238 |
} GT64120State; |
234 | 239 |
|
240 |
/* Adjust range to avoid touching space which isn't mappable via PCI */ |
|
241 |
/* XXX: Hardcoded values for Malta: 0x1e000000 - 0x1f100000 |
|
242 |
0x1fc00000 - 0x1fd00000 */ |
|
243 |
static void check_reserved_space (target_phys_addr_t *start, |
|
244 |
target_phys_addr_t *length) |
|
245 |
{ |
|
246 |
target_phys_addr_t begin = *start; |
|
247 |
target_phys_addr_t end = *start + *length; |
|
248 |
|
|
249 |
if (end >= 0x1e000000LL && end < 0x1f100000LL) |
|
250 |
end = 0x1e000000LL; |
|
251 |
if (begin >= 0x1e000000LL && begin < 0x1f100000LL) |
|
252 |
begin = 0x1f100000LL; |
|
253 |
if (end >= 0x1fc00000LL && end < 0x1fd00000LL) |
|
254 |
end = 0x1fc00000LL; |
|
255 |
if (begin >= 0x1fc00000LL && begin < 0x1fd00000LL) |
|
256 |
begin = 0x1fd00000LL; |
|
257 |
/* XXX: This is broken when a reserved range splits the requested range */ |
|
258 |
if (end >= 0x1f100000LL && begin < 0x1e000000LL) |
|
259 |
end = 0x1e000000LL; |
|
260 |
if (end >= 0x1fd00000LL && begin < 0x1fc00000LL) |
|
261 |
end = 0x1fc00000LL; |
|
262 |
|
|
263 |
*start = begin; |
|
264 |
*length = end - begin; |
|
265 |
} |
|
266 |
|
|
267 |
static void gt64120_isd_mapping(GT64120State *s) |
|
268 |
{ |
|
269 |
target_phys_addr_t start = s->regs[GT_ISD] << 21; |
|
270 |
target_phys_addr_t length = 0x1000; |
|
271 |
|
|
272 |
if (s->ISD_length) |
|
273 |
cpu_register_physical_memory(s->ISD_start, s->ISD_length, |
|
274 |
IO_MEM_UNASSIGNED); |
|
275 |
check_reserved_space(&start, &length); |
|
276 |
length = 0x1000; |
|
277 |
/* Map new address */ |
|
278 |
dprintf("ISD: %x@%x -> %x@%x, %x\n", s->ISD_length, s->ISD_start, |
|
279 |
length, start, s->ISD_handle); |
|
280 |
s->ISD_start = start; |
|
281 |
s->ISD_length = length; |
|
282 |
cpu_register_physical_memory(s->ISD_start, s->ISD_length, s->ISD_handle); |
|
283 |
} |
|
284 |
|
|
235 | 285 |
static void gt64120_pci_mapping(GT64120State *s) |
236 | 286 |
{ |
237 | 287 |
/* Update IO mapping */ |
... | ... | |
311 | 361 |
s->regs[saddr] = val & 0x0000007f; |
312 | 362 |
gt64120_pci_mapping(s); |
313 | 363 |
break; |
364 |
case GT_ISD: |
|
365 |
s->regs[saddr] = val & 0x00007fff; |
|
366 |
gt64120_isd_mapping(s); |
|
367 |
break; |
|
368 |
|
|
314 | 369 |
case GT_PCI0IOREMAP: |
315 | 370 |
case GT_PCI0M0REMAP: |
316 | 371 |
case GT_PCI0M1REMAP: |
... | ... | |
1026 | 1081 |
|
1027 | 1082 |
/* Interrupt registers are all zeroed at reset */ |
1028 | 1083 |
|
1084 |
gt64120_isd_mapping(s); |
|
1029 | 1085 |
gt64120_pci_mapping(s); |
1030 | 1086 |
} |
1031 | 1087 |
|
... | ... | |
1070 | 1126 |
{ |
1071 | 1127 |
GT64120State *s; |
1072 | 1128 |
PCIDevice *d; |
1073 |
int gt64120; |
|
1074 | 1129 |
|
1075 | 1130 |
s = qemu_mallocz(sizeof(GT64120State)); |
1076 | 1131 |
s->pci = qemu_mallocz(sizeof(GT64120PCIState)); |
1077 |
gt64120_reset(s); |
|
1078 | 1132 |
|
1079 | 1133 |
s->pci->bus = pci_register_bus(pci_gt64120_set_irq, pci_gt64120_map_irq, |
1080 | 1134 |
pic, 144, 4); |
1081 |
|
|
1082 |
gt64120 = cpu_register_io_memory(0, gt64120_read, |
|
1083 |
gt64120_write, s); |
|
1084 |
cpu_register_physical_memory(0x1be00000LL, 0x1000, gt64120); |
|
1085 |
|
|
1135 |
s->ISD_handle = cpu_register_io_memory(0, gt64120_read, gt64120_write, s); |
|
1086 | 1136 |
d = pci_register_device(s->pci->bus, "GT64120 PCI Bus", sizeof(PCIDevice), |
1087 | 1137 |
0, gt64120_read_config, gt64120_write_config); |
1088 | 1138 |
|
1089 | 1139 |
/* FIXME: Malta specific hw assumptions ahead */ |
1090 | 1140 |
|
1091 |
d->config[0x00] = 0xab; // vendor_id
|
|
1141 |
d->config[0x00] = 0xab; /* vendor_id */
|
|
1092 | 1142 |
d->config[0x01] = 0x11; |
1093 |
d->config[0x02] = 0x20; // device_id
|
|
1143 |
d->config[0x02] = 0x20; /* device_id */
|
|
1094 | 1144 |
d->config[0x03] = 0x46; |
1095 | 1145 |
|
1096 | 1146 |
d->config[0x04] = 0x00; |
... | ... | |
1113 | 1163 |
d->config[0x27] = 0x14; |
1114 | 1164 |
d->config[0x3D] = 0x01; |
1115 | 1165 |
|
1166 |
gt64120_reset(s); |
|
1167 |
|
|
1116 | 1168 |
register_savevm("GT64120 PCI Bus", 0, 1, gt64120_save, gt64120_load, d); |
1117 | 1169 |
|
1118 | 1170 |
return s->pci->bus; |
Also available in: Unified diff