Commit 2a1086d91c19cc058f74fb2913e05f262f37cdc7

Authored by ths
1 parent 924edcae

More PCI mapping/remapping for Gallileo.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2972 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 2 changed files with 321 additions and 32 deletions
hw/gt64xxx.c
... ... @@ -222,34 +222,217 @@ typedef target_phys_addr_t pci_addr_t;
222 222 #define GT_PCI0_HICMASK (0xca4 >> 2)
223 223 #define GT_PCI1_SERR1MASK (0xca8 >> 2)
224 224  
  225 +#define PCI_MAPPING_ENTRY(regname) \
  226 + target_phys_addr_t regname ##_start; \
  227 + target_phys_addr_t regname ##_length; \
  228 + int regname ##_handle
  229 +
  230 +#define PCI_REMAPPING_ENTRY(regname) \
  231 + target_phys_addr_t regname ##_start; \
  232 + target_phys_addr_t regname ##_length; \
  233 + target_phys_addr_t regname ##_offset; \
  234 + int regname ##_handle
225 235  
226 236 typedef PCIHostState GT64120PCIState;
227 237  
228 238 typedef struct GT64120State {
229 239 GT64120PCIState *pci;
230 240 uint32_t regs[GT_REGS];
231   - target_phys_addr_t PCI0IO_start;
232   - target_phys_addr_t PCI0IO_length;
  241 + PCI_MAPPING_ENTRY(SCS10);
  242 + PCI_REMAPPING_ENTRY(SCS10AR);
  243 + PCI_MAPPING_ENTRY(SCS32);
  244 + PCI_REMAPPING_ENTRY(SCS32AR);
  245 + PCI_MAPPING_ENTRY(CS20);
  246 + PCI_REMAPPING_ENTRY(CS20R);
  247 + PCI_MAPPING_ENTRY(CS3BOOT);
  248 + PCI_REMAPPING_ENTRY(CS3BOOTR);
  249 + PCI_MAPPING_ENTRY(PCI0IO);
  250 + PCI_REMAPPING_ENTRY(PCI0IOREMAP);
  251 + PCI_MAPPING_ENTRY(PCI0M0);
  252 + PCI_REMAPPING_ENTRY(PCI0M0REMAP);
  253 + PCI_MAPPING_ENTRY(PCI0M1);
  254 + PCI_REMAPPING_ENTRY(PCI0M1REMAP);
  255 + PCI_MAPPING_ENTRY(PCI1IO);
  256 + PCI_REMAPPING_ENTRY(PCI1IOREMAP);
  257 + PCI_MAPPING_ENTRY(PCI1M0);
  258 + PCI_REMAPPING_ENTRY(PCI1M0REMAP);
  259 + PCI_MAPPING_ENTRY(PCI1M1);
  260 + PCI_REMAPPING_ENTRY(PCI1M1REMAP);
  261 + PCI_MAPPING_ENTRY(ISD);
233 262 } GT64120State;
234 263  
235   -static void gt64120_pci_mapping(GT64120State *s)
  264 +/* Adjust range to avoid touching space which isn't mappable via PCI */
  265 +/* XXX: Hardcoded values for Malta: 0x1e000000 - 0x1f100000
  266 + 0x1fc00000 - 0x1fd00000 */
  267 +static void check_reserved_space (target_phys_addr_t *start,
  268 + target_phys_addr_t *length)
236 269 {
237   - /* Update IO mapping */
238   - if ((s->regs[GT_PCI0IOLD] & 0x7f) <= s->regs[GT_PCI0IOHD])
239   - {
240   - /* Unmap old IO address */
241   - if (s->PCI0IO_length)
242   - {
243   - cpu_register_physical_memory(s->PCI0IO_start, s->PCI0IO_length, IO_MEM_UNASSIGNED);
244   - }
245   - /* Map new IO address */
246   - s->PCI0IO_start = s->regs[GT_PCI0IOLD] << 21;
247   - s->PCI0IO_length = ((s->regs[GT_PCI0IOHD] + 1) - (s->regs[GT_PCI0IOLD] & 0x7f)) << 21;
248   - isa_mem_base = s->PCI0IO_start;
249   - isa_mmio_init(s->PCI0IO_start, s->PCI0IO_length);
250   - }
  270 + target_phys_addr_t begin = *start;
  271 + target_phys_addr_t end = *start + *length;
  272 +
  273 + if (end >= 0x1e000000LL && end < 0x1f100000LL)
  274 + end = 0x1e000000LL;
  275 + if (begin >= 0x1e000000LL && begin < 0x1f100000LL)
  276 + begin = 0x1f100000LL;
  277 + if (end >= 0x1fc00000LL && end < 0x1fd00000LL)
  278 + end = 0x1fc00000LL;
  279 + if (begin >= 0x1fc00000LL && begin < 0x1fd00000LL)
  280 + begin = 0x1fd00000LL;
  281 + /* XXX: This is broken when a reserved range splits the requested range */
  282 + if (end >= 0x1f100000LL && begin < 0x1e000000LL)
  283 + end = 0x1e000000LL;
  284 + if (end >= 0x1fd00000LL && begin < 0x1fc00000LL)
  285 + end = 0x1fc00000LL;
  286 +
  287 + *start = begin;
  288 + *length = end - begin;
  289 +}
  290 +
  291 +/* XXX: cpu_register_physical_memory isn't really suited for dynamic mappings
  292 + since it doesn't layer several mappings over the same address range.
  293 + This should keep track of mappings as set of 2 MB pages / 20 mappings. */
  294 +
  295 +#define BUILD_UPDATE_PCI_MAPPING(reg, remap) \
  296 +static void gt64120_## reg ##_mapping(GT64120State *s) \
  297 +{ \
  298 + target_phys_addr_t start = s->regs[GT_## reg ##LD] << 21; \
  299 + target_phys_addr_t length = ((s->regs[GT_## reg ##HD] + 1) - \
  300 + (s->regs[GT_## reg ##LD] & 0x7f)) << 21; \
  301 + \
  302 + /* Unmap old address */ \
  303 + if (s->remap ##_length) \
  304 + cpu_register_physical_memory(s->remap ##_start, \
  305 + s->remap ##_length, \
  306 + IO_MEM_UNASSIGNED); \
  307 + s->remap ##_length = 0; \
  308 + if (s->reg ##_length) \
  309 + cpu_register_physical_memory(s->reg ##_start, \
  310 + s->reg ##_length, \
  311 + IO_MEM_UNASSIGNED); \
  312 + \
  313 + if ((s->regs[GT_## reg ##LD] & 0x7f) <= s->regs[GT_## reg ##HD]) \
  314 + { \
  315 + check_reserved_space(&start, &length); \
  316 + /* Map new address */ \
  317 +dprintf("PCI " # reg ": %x@%x -> %x@%x, %x\n", s->reg ##_length, s->reg ##_start, length, start, s->reg ##_handle); \
  318 + s->reg ##_start = start; \
  319 + s->reg ##_length = length; \
  320 + cpu_register_physical_memory(s->reg ##_start, \
  321 + s->reg ##_length, \
  322 + s->reg ##_handle); \
  323 + } else \
  324 +dprintf("PCI " # reg ": %x@%x disabled, %x\n", s->reg ##_length, s->reg ##_start, s->reg ##_handle); \
  325 +} \
  326 + \
  327 +static void gt64120_## remap ##_mapping(GT64120State *s) \
  328 +{ \
  329 + /* XXX: range calculation is broken */ \
  330 + target_phys_addr_t start = (s->reg ## _start & ~(0x7ff << 21)) | \
  331 + (s->regs[GT_## remap] << 21); \
  332 + target_phys_addr_t length = s->reg ##_length; \
  333 + \
  334 + if (s->remap ##_length) \
  335 + cpu_register_physical_memory(s->remap ##_start, \
  336 + s->remap ##_length, \
  337 + IO_MEM_UNASSIGNED); \
  338 + check_reserved_space(&start, &length); \
  339 + s->remap ##_start = start; \
  340 + s->remap ##_length = length; \
  341 + s->remap ##_offset = s->reg ##_start - start; \
  342 +dprintf("PCI " # remap ": %x@%x +> %x@%x, %x\n", s->reg ##_length, s->reg ##_start, length, start, s->remap ##_handle); \
  343 + cpu_register_physical_memory(s->remap ##_start, \
  344 + s->remap ##_length, \
  345 + s->remap ##_handle); \
  346 +}
  347 +
  348 +BUILD_UPDATE_PCI_MAPPING(SCS10, SCS10AR)
  349 +BUILD_UPDATE_PCI_MAPPING(SCS32, SCS32AR)
  350 +BUILD_UPDATE_PCI_MAPPING(CS20, CS20R)
  351 +BUILD_UPDATE_PCI_MAPPING(CS3BOOT, CS3BOOTR)
  352 +BUILD_UPDATE_PCI_MAPPING(PCI0IO, PCI0IOREMAP)
  353 +BUILD_UPDATE_PCI_MAPPING(PCI0M0, PCI0M0REMAP)
  354 +BUILD_UPDATE_PCI_MAPPING(PCI0M1, PCI0M1REMAP)
  355 +BUILD_UPDATE_PCI_MAPPING(PCI1IO, PCI1IOREMAP)
  356 +BUILD_UPDATE_PCI_MAPPING(PCI1M0, PCI1M0REMAP)
  357 +BUILD_UPDATE_PCI_MAPPING(PCI1M1, PCI1M1REMAP)
  358 +
  359 +static void gt64120_isd_mapping(GT64120State *s)
  360 +{
  361 + if (s->ISD_length)
  362 + cpu_register_physical_memory(s->ISD_start, s->ISD_length,
  363 + IO_MEM_UNASSIGNED);
  364 +dprintf("PCI ISD: %x@%x -> %x@%x, %x\n", s->ISD_length, s->ISD_start, 0x1000, s->regs[GT_ISD] << 21, s->ISD_handle);
  365 + s->ISD_start = s->regs[GT_ISD] << 21;
  366 + s->ISD_length = 0x1000;
  367 + cpu_register_physical_memory(s->ISD_start, s->ISD_length, s->ISD_handle);
  368 +}
  369 +
  370 +static void gt64120_mmio_writeb (void *opaque, target_phys_addr_t addr,
  371 + uint32_t val)
  372 +{
  373 + cpu_outb(NULL, addr & 0xffff, val);
  374 +}
  375 +
  376 +static void gt64120_mmio_writew (void *opaque, target_phys_addr_t addr,
  377 + uint32_t val)
  378 +{
  379 +#ifdef TARGET_WORDS_BIGENDIAN
  380 + val = bswap16(val);
  381 +#endif
  382 + cpu_outw(NULL, addr & 0xffff, val);
  383 +}
  384 +
  385 +static void gt64120_mmio_writel (void *opaque, target_phys_addr_t addr,
  386 + uint32_t val)
  387 +{
  388 +#ifdef TARGET_WORDS_BIGENDIAN
  389 + val = bswap32(val);
  390 +#endif
  391 + cpu_outl(NULL, addr & 0xffff, val);
  392 +}
  393 +
  394 +static uint32_t gt64120_mmio_readb (void *opaque, target_phys_addr_t addr)
  395 +{
  396 + uint32_t val;
  397 +
  398 + val = cpu_inb(NULL, addr & 0xffff);
  399 + return val;
251 400 }
252 401  
  402 +static uint32_t gt64120_mmio_readw (void *opaque, target_phys_addr_t addr)
  403 +{
  404 + uint32_t val;
  405 +
  406 + val = cpu_inw(NULL, addr & 0xffff);
  407 +#ifdef TARGET_WORDS_BIGENDIAN
  408 + val = bswap16(val);
  409 +#endif
  410 + return val;
  411 +}
  412 +
  413 +static uint32_t gt64120_mmio_readl (void *opaque, target_phys_addr_t addr)
  414 +{
  415 + uint32_t val;
  416 +
  417 + val = cpu_inl(NULL, addr & 0xffff);
  418 +#ifdef TARGET_WORDS_BIGENDIAN
  419 + val = bswap32(val);
  420 +#endif
  421 + return val;
  422 +}
  423 +
  424 +static CPUWriteMemoryFunc *gt64120_mmio_write[] = {
  425 + &gt64120_mmio_writeb,
  426 + &gt64120_mmio_writew,
  427 + &gt64120_mmio_writel,
  428 +};
  429 +
  430 +static CPUReadMemoryFunc *gt64120_mmio_read[] = {
  431 + &gt64120_mmio_readb,
  432 + &gt64120_mmio_readw,
  433 + &gt64120_mmio_readl,
  434 +};
  435 +
253 436 static void gt64120_writel (void *opaque, target_phys_addr_t addr,
254 437 uint32_t val)
255 438 {
... ... @@ -272,53 +455,142 @@ static void gt64120_writel (void *opaque, target_phys_addr_t addr,
272 455 break;
273 456  
274 457 /* CPU Address Decode */
  458 + case GT_SCS10LD:
  459 + s->regs[GT_SCS10LD] = val & 0x00007fff;
  460 + s->regs[GT_SCS10AR] = val & 0x000007ff;
  461 + gt64120_SCS10_mapping(s);
  462 + break;
  463 + case GT_SCS32LD:
  464 + s->regs[GT_SCS32LD] = val & 0x00007fff;
  465 + s->regs[GT_SCS32AR] = val & 0x000007ff;
  466 +//
  467 +// gt64120_SCS32_mapping(s);
  468 + break;
  469 + case GT_CS20LD:
  470 + s->regs[GT_CS20LD] = val & 0x00007fff;
  471 + s->regs[GT_CS20R] = val & 0x000007ff;
  472 + gt64120_CS20_mapping(s);
  473 + break;
  474 + case GT_CS3BOOTLD:
  475 + s->regs[GT_CS3BOOTLD] = val & 0x00007fff;
  476 + s->regs[GT_CS3BOOTR] = val & 0x000007ff;
  477 + gt64120_CS3BOOT_mapping(s);
  478 + break;
  479 + case GT_SCS10HD:
  480 + s->regs[saddr] = val & 0x0000007f;
  481 + gt64120_SCS10_mapping(s);
  482 + break;
  483 + case GT_SCS32HD:
  484 + s->regs[saddr] = val & 0x0000007f;
  485 +//
  486 +// gt64120_SCS32_mapping(s);
  487 + break;
  488 + case GT_CS20HD:
  489 + s->regs[saddr] = val & 0x0000007f;
  490 + gt64120_CS20_mapping(s);
  491 + break;
  492 + case GT_CS3BOOTHD:
  493 + s->regs[saddr] = val & 0x0000007f;
  494 + gt64120_CS3BOOT_mapping(s);
  495 + break;
275 496 case GT_PCI0IOLD:
276 497 s->regs[GT_PCI0IOLD] = val & 0x00007fff;
277 498 s->regs[GT_PCI0IOREMAP] = val & 0x000007ff;
278   - gt64120_pci_mapping(s);
  499 + gt64120_PCI0IO_mapping(s);
279 500 break;
280 501 case GT_PCI0M0LD:
281 502 s->regs[GT_PCI0M0LD] = val & 0x00007fff;
282 503 s->regs[GT_PCI0M0REMAP] = val & 0x000007ff;
283   - gt64120_pci_mapping(s);
  504 + gt64120_PCI0M0_mapping(s);
284 505 break;
285 506 case GT_PCI0M1LD:
286 507 s->regs[GT_PCI0M1LD] = val & 0x00007fff;
287 508 s->regs[GT_PCI0M1REMAP] = val & 0x000007ff;
288   - gt64120_pci_mapping(s);
  509 + gt64120_PCI0M1_mapping(s);
289 510 break;
290 511 case GT_PCI1IOLD:
291 512 s->regs[GT_PCI1IOLD] = val & 0x00007fff;
292 513 s->regs[GT_PCI1IOREMAP] = val & 0x000007ff;
293   - gt64120_pci_mapping(s);
  514 + gt64120_PCI1IO_mapping(s);
294 515 break;
295 516 case GT_PCI1M0LD:
296 517 s->regs[GT_PCI1M0LD] = val & 0x00007fff;
297 518 s->regs[GT_PCI1M0REMAP] = val & 0x000007ff;
298   - gt64120_pci_mapping(s);
  519 + gt64120_PCI1M1_mapping(s);
299 520 break;
300 521 case GT_PCI1M1LD:
301 522 s->regs[GT_PCI1M1LD] = val & 0x00007fff;
302 523 s->regs[GT_PCI1M1REMAP] = val & 0x000007ff;
303   - gt64120_pci_mapping(s);
  524 + gt64120_PCI1M1_mapping(s);
304 525 break;
305 526 case GT_PCI0IOHD:
  527 + s->regs[saddr] = val & 0x0000007f;
  528 + gt64120_PCI0IO_mapping(s);
  529 + break;
306 530 case GT_PCI0M0HD:
  531 + s->regs[saddr] = val & 0x0000007f;
  532 + gt64120_PCI0M0_mapping(s);
  533 + break;
307 534 case GT_PCI0M1HD:
  535 + s->regs[saddr] = val & 0x0000007f;
  536 + gt64120_PCI0M1_mapping(s);
  537 + break;
308 538 case GT_PCI1IOHD:
  539 + s->regs[saddr] = val & 0x0000007f;
  540 + gt64120_PCI1IO_mapping(s);
  541 + break;
309 542 case GT_PCI1M0HD:
  543 + s->regs[saddr] = val & 0x0000007f;
  544 + gt64120_PCI1M0_mapping(s);
  545 + break;
310 546 case GT_PCI1M1HD:
311 547 s->regs[saddr] = val & 0x0000007f;
312   - gt64120_pci_mapping(s);
  548 + gt64120_PCI1M1_mapping(s);
  549 + break;
  550 + case GT_ISD:
  551 + s->regs[saddr] = val & 0x00007fff;
  552 + gt64120_isd_mapping(s);
  553 + break;
  554 +
  555 + case GT_SCS10AR:
  556 + s->regs[saddr] = val & 0x000007ff;
  557 + gt64120_SCS10AR_mapping(s);
  558 + break;
  559 + case GT_SCS32AR:
  560 + s->regs[saddr] = val & 0x000007ff;
  561 + gt64120_SCS32AR_mapping(s);
  562 + break;
  563 + case GT_CS20R:
  564 + s->regs[saddr] = val & 0x000007ff;
  565 + gt64120_CS20R_mapping(s);
  566 + break;
  567 + case GT_CS3BOOTR:
  568 + s->regs[saddr] = val & 0x000007ff;
  569 + gt64120_CS3BOOTR_mapping(s);
313 570 break;
314 571 case GT_PCI0IOREMAP:
  572 + s->regs[saddr] = val & 0x000007ff;
  573 + gt64120_PCI0IOREMAP_mapping(s);
  574 + break;
315 575 case GT_PCI0M0REMAP:
  576 + s->regs[saddr] = val & 0x000007ff;
  577 + gt64120_PCI0M0REMAP_mapping(s);
  578 + break;
316 579 case GT_PCI0M1REMAP:
  580 + s->regs[saddr] = val & 0x000007ff;
  581 + gt64120_PCI0M1REMAP_mapping(s);
  582 + break;
317 583 case GT_PCI1IOREMAP:
  584 + s->regs[saddr] = val & 0x000007ff;
  585 + gt64120_PCI1IOREMAP_mapping(s);
  586 + break;
318 587 case GT_PCI1M0REMAP:
  588 + s->regs[saddr] = val & 0x000007ff;
  589 + gt64120_PCI1M0REMAP_mapping(s);
  590 + break;
319 591 case GT_PCI1M1REMAP:
320 592 s->regs[saddr] = val & 0x000007ff;
321   - gt64120_pci_mapping(s);
  593 + gt64120_PCI1M1REMAP_mapping(s);
322 594 break;
323 595  
324 596 /* CPU Error Report */
... ... @@ -1026,7 +1298,17 @@ void gt64120_reset(void *opaque)
1026 1298  
1027 1299 /* Interrupt registers are all zeroed at reset */
1028 1300  
1029   - gt64120_pci_mapping(s);
  1301 + gt64120_isd_mapping(s);
  1302 + gt64120_SCS10_mapping(s);
  1303 +// gt64120_SCS32_mapping(s);
  1304 + gt64120_CS20_mapping(s);
  1305 + gt64120_CS3BOOT_mapping(s);
  1306 + gt64120_PCI0IO_mapping(s);
  1307 + gt64120_PCI0M0_mapping(s);
  1308 + gt64120_PCI0M1_mapping(s);
  1309 + gt64120_PCI1IO_mapping(s);
  1310 + gt64120_PCI1M0_mapping(s);
  1311 + gt64120_PCI1M1_mapping(s);
1030 1312 }
1031 1313  
1032 1314 static uint32_t gt64120_read_config(PCIDevice *d, uint32_t address, int len)
... ... @@ -1070,18 +1352,16 @@ PCIBus *pci_gt64120_init(qemu_irq *pic)
1070 1352 {
1071 1353 GT64120State *s;
1072 1354 PCIDevice *d;
1073   - int gt64120;
1074 1355  
1075 1356 s = qemu_mallocz(sizeof(GT64120State));
1076 1357 s->pci = qemu_mallocz(sizeof(GT64120PCIState));
1077   - gt64120_reset(s);
1078   -
1079 1358 s->pci->bus = pci_register_bus(pci_gt64120_set_irq, pci_gt64120_map_irq,
1080 1359 pic, 144, 4);
1081 1360  
1082   - gt64120 = cpu_register_io_memory(0, gt64120_read,
1083   - gt64120_write, s);
1084   - cpu_register_physical_memory(0x1be00000LL, 0x1000, gt64120);
  1361 + s->ISD_handle = cpu_register_io_memory(0, gt64120_read, gt64120_write, s);
  1362 + s->PCI0IO_handle = cpu_register_io_memory(0, gt64120_mmio_read,
  1363 + gt64120_mmio_write, s);
  1364 + gt64120_reset(s);
1085 1365  
1086 1366 d = pci_register_device(s->pci->bus, "GT64120 PCI Bus", sizeof(PCIDevice),
1087 1367 0, gt64120_read_config, gt64120_write_config);
... ...
hw/mips_malta.c
... ... @@ -543,6 +543,15 @@ static void write_bootloader (CPUState *env, unsigned long bios_offset, int64_t
543 543 stl_raw(p++, 0x34e70000 | (env->ram_size & 0xffff)); /* ori a3, a3, low(env->ram_size) */
544 544  
545 545 /* Load BAR registers as done by YAMON */
  546 + stl_raw(p++, 0x3c09b400); /* lui t1, 0xb400 */
  547 +
  548 +#ifdef TARGET_WORDS_BIGENDIAN
  549 + stl_raw(p++, 0x3c08df00); /* lui t0, 0xdf00 */
  550 +#else
  551 + stl_raw(p++, 0x340800df); /* ori t0, r0, 0x00df */
  552 +#endif
  553 + stl_raw(p++, 0xad280068); /* sw t0, 0x0068(t1) */
  554 +
546 555 stl_raw(p++, 0x3c09bbe0); /* lui t1, 0xbbe0 */
547 556  
548 557 #ifdef TARGET_WORDS_BIGENDIAN
... ...