Revision 2a1086d9 hw/gt64xxx.c

b/hw/gt64xxx.c
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 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 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 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);

Also available in: Unified diff