Revision 83469015 hw/pci.c
b/hw/pci.c | ||
---|---|---|
1291 | 1291 |
return s; |
1292 | 1292 |
} |
1293 | 1293 |
|
1294 |
/* Ultrasparc APB PCI host */ |
|
1295 |
static void pci_apb_config_writel (void *opaque, target_phys_addr_t addr, |
|
1296 |
uint32_t val) |
|
1297 |
{ |
|
1298 |
PCIBus *s = opaque; |
|
1299 |
int i; |
|
1300 |
|
|
1301 |
for (i = 11; i < 32; i++) { |
|
1302 |
if ((val & (1 << i)) != 0) |
|
1303 |
break; |
|
1304 |
} |
|
1305 |
s->config_reg = 0x80000000 | (1 << 16) | (val & 0x7FC) | (i << 11); |
|
1306 |
} |
|
1307 |
|
|
1308 |
static uint32_t pci_apb_config_readl (void *opaque, |
|
1309 |
target_phys_addr_t addr) |
|
1310 |
{ |
|
1311 |
PCIBus *s = opaque; |
|
1312 |
uint32_t val; |
|
1313 |
int devfn; |
|
1314 |
|
|
1315 |
devfn = (s->config_reg >> 8) & 0xFF; |
|
1316 |
val = (1 << (devfn >> 3)) | ((devfn & 0x07) << 8) | (s->config_reg & 0xFC); |
|
1317 |
return val; |
|
1318 |
} |
|
1319 |
|
|
1320 |
static CPUWriteMemoryFunc *pci_apb_config_write[] = { |
|
1321 |
&pci_apb_config_writel, |
|
1322 |
&pci_apb_config_writel, |
|
1323 |
&pci_apb_config_writel, |
|
1324 |
}; |
|
1325 |
|
|
1326 |
static CPUReadMemoryFunc *pci_apb_config_read[] = { |
|
1327 |
&pci_apb_config_readl, |
|
1328 |
&pci_apb_config_readl, |
|
1329 |
&pci_apb_config_readl, |
|
1330 |
}; |
|
1331 |
|
|
1332 |
static void apb_config_writel (void *opaque, target_phys_addr_t addr, |
|
1333 |
uint32_t val) |
|
1334 |
{ |
|
1335 |
//PCIBus *s = opaque; |
|
1336 |
|
|
1337 |
switch (addr & 0x3f) { |
|
1338 |
case 0x00: // Control/Status |
|
1339 |
case 0x10: // AFSR |
|
1340 |
case 0x18: // AFAR |
|
1341 |
case 0x20: // Diagnostic |
|
1342 |
case 0x28: // Target address space |
|
1343 |
// XXX |
|
1344 |
default: |
|
1345 |
break; |
|
1346 |
} |
|
1347 |
} |
|
1348 |
|
|
1349 |
static uint32_t apb_config_readl (void *opaque, |
|
1350 |
target_phys_addr_t addr) |
|
1351 |
{ |
|
1352 |
//PCIBus *s = opaque; |
|
1353 |
uint32_t val; |
|
1354 |
|
|
1355 |
switch (addr & 0x3f) { |
|
1356 |
case 0x00: // Control/Status |
|
1357 |
case 0x10: // AFSR |
|
1358 |
case 0x18: // AFAR |
|
1359 |
case 0x20: // Diagnostic |
|
1360 |
case 0x28: // Target address space |
|
1361 |
// XXX |
|
1362 |
default: |
|
1363 |
val = 0; |
|
1364 |
break; |
|
1365 |
} |
|
1366 |
return val; |
|
1367 |
} |
|
1368 |
|
|
1369 |
static CPUWriteMemoryFunc *apb_config_write[] = { |
|
1370 |
&apb_config_writel, |
|
1371 |
&apb_config_writel, |
|
1372 |
&apb_config_writel, |
|
1373 |
}; |
|
1374 |
|
|
1375 |
static CPUReadMemoryFunc *apb_config_read[] = { |
|
1376 |
&apb_config_readl, |
|
1377 |
&apb_config_readl, |
|
1378 |
&apb_config_readl, |
|
1379 |
}; |
|
1380 |
|
|
1381 |
static void pci_apb_writeb (void *opaque, target_phys_addr_t addr, |
|
1382 |
uint32_t val) |
|
1383 |
{ |
|
1384 |
PCIBus *s = opaque; |
|
1385 |
|
|
1386 |
pci_data_write(s, addr & 7, val, 1); |
|
1387 |
} |
|
1388 |
|
|
1389 |
static void pci_apb_writew (void *opaque, target_phys_addr_t addr, |
|
1390 |
uint32_t val) |
|
1391 |
{ |
|
1392 |
PCIBus *s = opaque; |
|
1393 |
|
|
1394 |
pci_data_write(s, addr & 7, val, 2); |
|
1395 |
} |
|
1396 |
|
|
1397 |
static void pci_apb_writel (void *opaque, target_phys_addr_t addr, |
|
1398 |
uint32_t val) |
|
1399 |
{ |
|
1400 |
PCIBus *s = opaque; |
|
1401 |
|
|
1402 |
pci_data_write(s, addr & 7, val, 4); |
|
1403 |
} |
|
1404 |
|
|
1405 |
static uint32_t pci_apb_readb (void *opaque, target_phys_addr_t addr) |
|
1406 |
{ |
|
1407 |
PCIBus *s = opaque; |
|
1408 |
uint32_t val; |
|
1409 |
|
|
1410 |
val = pci_data_read(s, addr & 7, 1); |
|
1411 |
return val; |
|
1412 |
} |
|
1413 |
|
|
1414 |
static uint32_t pci_apb_readw (void *opaque, target_phys_addr_t addr) |
|
1415 |
{ |
|
1416 |
PCIBus *s = opaque; |
|
1417 |
uint32_t val; |
|
1418 |
|
|
1419 |
val = pci_data_read(s, addr & 7, 2); |
|
1420 |
return val; |
|
1421 |
} |
|
1422 |
|
|
1423 |
static uint32_t pci_apb_readl (void *opaque, target_phys_addr_t addr) |
|
1424 |
{ |
|
1425 |
PCIBus *s = opaque; |
|
1426 |
uint32_t val; |
|
1427 |
|
|
1428 |
val = pci_data_read(s, addr, 4); |
|
1429 |
return val; |
|
1430 |
} |
|
1431 |
|
|
1432 |
static CPUWriteMemoryFunc *pci_apb_write[] = { |
|
1433 |
&pci_apb_writeb, |
|
1434 |
&pci_apb_writew, |
|
1435 |
&pci_apb_writel, |
|
1436 |
}; |
|
1437 |
|
|
1438 |
static CPUReadMemoryFunc *pci_apb_read[] = { |
|
1439 |
&pci_apb_readb, |
|
1440 |
&pci_apb_readw, |
|
1441 |
&pci_apb_readl, |
|
1442 |
}; |
|
1443 |
|
|
1444 |
static void pci_apb_iowriteb (void *opaque, target_phys_addr_t addr, |
|
1445 |
uint32_t val) |
|
1446 |
{ |
|
1447 |
cpu_outb(NULL, addr & 0xffff, val); |
|
1448 |
} |
|
1449 |
|
|
1450 |
static void pci_apb_iowritew (void *opaque, target_phys_addr_t addr, |
|
1451 |
uint32_t val) |
|
1452 |
{ |
|
1453 |
cpu_outw(NULL, addr & 0xffff, val); |
|
1454 |
} |
|
1455 |
|
|
1456 |
static void pci_apb_iowritel (void *opaque, target_phys_addr_t addr, |
|
1457 |
uint32_t val) |
|
1458 |
{ |
|
1459 |
cpu_outl(NULL, addr & 0xffff, val); |
|
1460 |
} |
|
1461 |
|
|
1462 |
static uint32_t pci_apb_ioreadb (void *opaque, target_phys_addr_t addr) |
|
1463 |
{ |
|
1464 |
uint32_t val; |
|
1465 |
|
|
1466 |
val = cpu_inb(NULL, addr & 0xffff); |
|
1467 |
return val; |
|
1468 |
} |
|
1469 |
|
|
1470 |
static uint32_t pci_apb_ioreadw (void *opaque, target_phys_addr_t addr) |
|
1471 |
{ |
|
1472 |
uint32_t val; |
|
1473 |
|
|
1474 |
val = cpu_inw(NULL, addr & 0xffff); |
|
1475 |
return val; |
|
1476 |
} |
|
1477 |
|
|
1478 |
static uint32_t pci_apb_ioreadl (void *opaque, target_phys_addr_t addr) |
|
1479 |
{ |
|
1480 |
uint32_t val; |
|
1481 |
|
|
1482 |
val = cpu_inl(NULL, addr & 0xffff); |
|
1483 |
return val; |
|
1484 |
} |
|
1485 |
|
|
1486 |
static CPUWriteMemoryFunc *pci_apb_iowrite[] = { |
|
1487 |
&pci_apb_iowriteb, |
|
1488 |
&pci_apb_iowritew, |
|
1489 |
&pci_apb_iowritel, |
|
1490 |
}; |
|
1491 |
|
|
1492 |
static CPUReadMemoryFunc *pci_apb_ioread[] = { |
|
1493 |
&pci_apb_ioreadb, |
|
1494 |
&pci_apb_ioreadw, |
|
1495 |
&pci_apb_ioreadl, |
|
1496 |
}; |
|
1497 |
|
|
1498 |
PCIBus *pci_apb_init(target_ulong special_base, target_ulong mem_base) |
|
1499 |
{ |
|
1500 |
PCIBus *s; |
|
1501 |
PCIDevice *d; |
|
1502 |
int pci_mem_config, pci_mem_data, apb_config, pci_ioport; |
|
1503 |
|
|
1504 |
/* Ultrasparc APB main bus */ |
|
1505 |
s = pci_register_bus(); |
|
1506 |
s->set_irq = pci_set_irq_simple; |
|
1507 |
|
|
1508 |
pci_mem_config = cpu_register_io_memory(0, pci_apb_config_read, |
|
1509 |
pci_apb_config_write, s); |
|
1510 |
apb_config = cpu_register_io_memory(0, apb_config_read, |
|
1511 |
apb_config_write, s); |
|
1512 |
pci_mem_data = cpu_register_io_memory(0, pci_apb_read, |
|
1513 |
pci_apb_write, s); |
|
1514 |
pci_ioport = cpu_register_io_memory(0, pci_apb_ioread, |
|
1515 |
pci_apb_iowrite, s); |
|
1516 |
|
|
1517 |
cpu_register_physical_memory(special_base + 0x2000ULL, 0x40, apb_config); |
|
1518 |
cpu_register_physical_memory(special_base + 0x1000000ULL, 0x10, pci_mem_config); |
|
1519 |
cpu_register_physical_memory(special_base + 0x2000000ULL, 0x10000, pci_ioport); |
|
1520 |
cpu_register_physical_memory(mem_base, 0x10000000, pci_mem_data); // XXX size should be 4G-prom |
|
1521 |
|
|
1522 |
d = pci_register_device(s, "Advanced PCI Bus", sizeof(PCIDevice), |
|
1523 |
-1, NULL, NULL); |
|
1524 |
d->config[0x00] = 0x8e; // vendor_id : Sun |
|
1525 |
d->config[0x01] = 0x10; |
|
1526 |
d->config[0x02] = 0x00; // device_id |
|
1527 |
d->config[0x03] = 0xa0; |
|
1528 |
d->config[0x04] = 0x06; // command = bus master, pci mem |
|
1529 |
d->config[0x05] = 0x00; |
|
1530 |
d->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error |
|
1531 |
d->config[0x07] = 0x03; // status = medium devsel |
|
1532 |
d->config[0x08] = 0x00; // revision |
|
1533 |
d->config[0x09] = 0x00; // programming i/f |
|
1534 |
d->config[0x0A] = 0x00; // class_sub = pci host |
|
1535 |
d->config[0x0B] = 0x06; // class_base = PCI_bridge |
|
1536 |
d->config[0x0D] = 0x10; // latency_timer |
|
1537 |
d->config[0x0E] = 0x00; // header_type |
|
1538 |
return s; |
|
1539 |
} |
|
1540 |
|
|
1294 | 1541 |
/***********************************************************/ |
1295 | 1542 |
/* generic PCI irq support */ |
1296 | 1543 |
|
Also available in: Unified diff