Commit 65e1d81b2912b7833f77578867998e3067e8c181
1 parent
470d86b7
USB OHCI: add support for big endian targets
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6368 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
115 additions
and
83 deletions
hw/usb-ohci.c
| @@ -1360,103 +1360,135 @@ static void ohci_port_set_status(OHCIState *ohci, int portnum, uint32_t val) | @@ -1360,103 +1360,135 @@ static void ohci_port_set_status(OHCIState *ohci, int portnum, uint32_t val) | ||
| 1360 | static uint32_t ohci_mem_read(void *ptr, target_phys_addr_t addr) | 1360 | static uint32_t ohci_mem_read(void *ptr, target_phys_addr_t addr) |
| 1361 | { | 1361 | { |
| 1362 | OHCIState *ohci = ptr; | 1362 | OHCIState *ohci = ptr; |
| 1363 | + uint32_t retval; | ||
| 1363 | 1364 | ||
| 1364 | /* Only aligned reads are allowed on OHCI */ | 1365 | /* Only aligned reads are allowed on OHCI */ |
| 1365 | if (addr & 3) { | 1366 | if (addr & 3) { |
| 1366 | fprintf(stderr, "usb-ohci: Mis-aligned read\n"); | 1367 | fprintf(stderr, "usb-ohci: Mis-aligned read\n"); |
| 1367 | return 0xffffffff; | 1368 | return 0xffffffff; |
| 1368 | - } | ||
| 1369 | - | ||
| 1370 | - if (addr >= 0x54 && addr < 0x54 + ohci->num_ports * 4) { | 1369 | + } else if (addr >= 0x54 && addr < 0x54 + ohci->num_ports * 4) { |
| 1371 | /* HcRhPortStatus */ | 1370 | /* HcRhPortStatus */ |
| 1372 | - return ohci->rhport[(addr - 0x54) >> 2].ctrl | OHCI_PORT_PPS; | 1371 | + retval = ohci->rhport[(addr - 0x54) >> 2].ctrl | OHCI_PORT_PPS; |
| 1372 | + } else { | ||
| 1373 | + switch (addr >> 2) { | ||
| 1374 | + case 0: /* HcRevision */ | ||
| 1375 | + retval = 0x10; | ||
| 1376 | + break; | ||
| 1377 | + | ||
| 1378 | + case 1: /* HcControl */ | ||
| 1379 | + retval = ohci->ctl; | ||
| 1380 | + break; | ||
| 1381 | + | ||
| 1382 | + case 2: /* HcCommandStatus */ | ||
| 1383 | + retval = ohci->status; | ||
| 1384 | + break; | ||
| 1385 | + | ||
| 1386 | + case 3: /* HcInterruptStatus */ | ||
| 1387 | + retval = ohci->intr_status; | ||
| 1388 | + break; | ||
| 1389 | + | ||
| 1390 | + case 4: /* HcInterruptEnable */ | ||
| 1391 | + case 5: /* HcInterruptDisable */ | ||
| 1392 | + retval = ohci->intr; | ||
| 1393 | + break; | ||
| 1394 | + | ||
| 1395 | + case 6: /* HcHCCA */ | ||
| 1396 | + retval = ohci->hcca; | ||
| 1397 | + break; | ||
| 1398 | + | ||
| 1399 | + case 7: /* HcPeriodCurrentED */ | ||
| 1400 | + retval = ohci->per_cur; | ||
| 1401 | + break; | ||
| 1402 | + | ||
| 1403 | + case 8: /* HcControlHeadED */ | ||
| 1404 | + retval = ohci->ctrl_head; | ||
| 1405 | + break; | ||
| 1406 | + | ||
| 1407 | + case 9: /* HcControlCurrentED */ | ||
| 1408 | + retval = ohci->ctrl_cur; | ||
| 1409 | + break; | ||
| 1410 | + | ||
| 1411 | + case 10: /* HcBulkHeadED */ | ||
| 1412 | + retval = ohci->bulk_head; | ||
| 1413 | + break; | ||
| 1414 | + | ||
| 1415 | + case 11: /* HcBulkCurrentED */ | ||
| 1416 | + retval = ohci->bulk_cur; | ||
| 1417 | + break; | ||
| 1418 | + | ||
| 1419 | + case 12: /* HcDoneHead */ | ||
| 1420 | + retval = ohci->done; | ||
| 1421 | + break; | ||
| 1422 | + | ||
| 1423 | + case 13: /* HcFmInterretval */ | ||
| 1424 | + retval = (ohci->fit << 31) | (ohci->fsmps << 16) | (ohci->fi); | ||
| 1425 | + break; | ||
| 1426 | + | ||
| 1427 | + case 14: /* HcFmRemaining */ | ||
| 1428 | + retval = ohci_get_frame_remaining(ohci); | ||
| 1429 | + break; | ||
| 1430 | + | ||
| 1431 | + case 15: /* HcFmNumber */ | ||
| 1432 | + retval = ohci->frame_number; | ||
| 1433 | + break; | ||
| 1434 | + | ||
| 1435 | + case 16: /* HcPeriodicStart */ | ||
| 1436 | + retval = ohci->pstart; | ||
| 1437 | + break; | ||
| 1438 | + | ||
| 1439 | + case 17: /* HcLSThreshold */ | ||
| 1440 | + retval = ohci->lst; | ||
| 1441 | + break; | ||
| 1442 | + | ||
| 1443 | + case 18: /* HcRhDescriptorA */ | ||
| 1444 | + retval = ohci->rhdesc_a; | ||
| 1445 | + break; | ||
| 1446 | + | ||
| 1447 | + case 19: /* HcRhDescriptorB */ | ||
| 1448 | + retval = ohci->rhdesc_b; | ||
| 1449 | + break; | ||
| 1450 | + | ||
| 1451 | + case 20: /* HcRhStatus */ | ||
| 1452 | + retval = ohci->rhstatus; | ||
| 1453 | + break; | ||
| 1454 | + | ||
| 1455 | + /* PXA27x specific registers */ | ||
| 1456 | + case 24: /* HcStatus */ | ||
| 1457 | + retval = ohci->hstatus & ohci->hmask; | ||
| 1458 | + break; | ||
| 1459 | + | ||
| 1460 | + case 25: /* HcHReset */ | ||
| 1461 | + retval = ohci->hreset; | ||
| 1462 | + break; | ||
| 1463 | + | ||
| 1464 | + case 26: /* HcHInterruptEnable */ | ||
| 1465 | + retval = ohci->hmask; | ||
| 1466 | + break; | ||
| 1467 | + | ||
| 1468 | + case 27: /* HcHInterruptTest */ | ||
| 1469 | + retval = ohci->htest; | ||
| 1470 | + break; | ||
| 1471 | + | ||
| 1472 | + default: | ||
| 1473 | + fprintf(stderr, "ohci_read: Bad offset %x\n", (int)addr); | ||
| 1474 | + retval = 0xffffffff; | ||
| 1475 | + } | ||
| 1373 | } | 1476 | } |
| 1374 | 1477 | ||
| 1375 | - switch (addr >> 2) { | ||
| 1376 | - case 0: /* HcRevision */ | ||
| 1377 | - return 0x10; | ||
| 1378 | - | ||
| 1379 | - case 1: /* HcControl */ | ||
| 1380 | - return ohci->ctl; | ||
| 1381 | - | ||
| 1382 | - case 2: /* HcCommandStatus */ | ||
| 1383 | - return ohci->status; | ||
| 1384 | - | ||
| 1385 | - case 3: /* HcInterruptStatus */ | ||
| 1386 | - return ohci->intr_status; | ||
| 1387 | - | ||
| 1388 | - case 4: /* HcInterruptEnable */ | ||
| 1389 | - case 5: /* HcInterruptDisable */ | ||
| 1390 | - return ohci->intr; | ||
| 1391 | - | ||
| 1392 | - case 6: /* HcHCCA */ | ||
| 1393 | - return ohci->hcca; | ||
| 1394 | - | ||
| 1395 | - case 7: /* HcPeriodCurrentED */ | ||
| 1396 | - return ohci->per_cur; | ||
| 1397 | - | ||
| 1398 | - case 8: /* HcControlHeadED */ | ||
| 1399 | - return ohci->ctrl_head; | ||
| 1400 | - | ||
| 1401 | - case 9: /* HcControlCurrentED */ | ||
| 1402 | - return ohci->ctrl_cur; | ||
| 1403 | - | ||
| 1404 | - case 10: /* HcBulkHeadED */ | ||
| 1405 | - return ohci->bulk_head; | ||
| 1406 | - | ||
| 1407 | - case 11: /* HcBulkCurrentED */ | ||
| 1408 | - return ohci->bulk_cur; | ||
| 1409 | - | ||
| 1410 | - case 12: /* HcDoneHead */ | ||
| 1411 | - return ohci->done; | ||
| 1412 | - | ||
| 1413 | - case 13: /* HcFmInterval */ | ||
| 1414 | - return (ohci->fit << 31) | (ohci->fsmps << 16) | (ohci->fi); | ||
| 1415 | - | ||
| 1416 | - case 14: /* HcFmRemaining */ | ||
| 1417 | - return ohci_get_frame_remaining(ohci); | ||
| 1418 | - | ||
| 1419 | - case 15: /* HcFmNumber */ | ||
| 1420 | - return ohci->frame_number; | ||
| 1421 | - | ||
| 1422 | - case 16: /* HcPeriodicStart */ | ||
| 1423 | - return ohci->pstart; | ||
| 1424 | - | ||
| 1425 | - case 17: /* HcLSThreshold */ | ||
| 1426 | - return ohci->lst; | ||
| 1427 | - | ||
| 1428 | - case 18: /* HcRhDescriptorA */ | ||
| 1429 | - return ohci->rhdesc_a; | ||
| 1430 | - | ||
| 1431 | - case 19: /* HcRhDescriptorB */ | ||
| 1432 | - return ohci->rhdesc_b; | ||
| 1433 | - | ||
| 1434 | - case 20: /* HcRhStatus */ | ||
| 1435 | - return ohci->rhstatus; | ||
| 1436 | - | ||
| 1437 | - /* PXA27x specific registers */ | ||
| 1438 | - case 24: /* HcStatus */ | ||
| 1439 | - return ohci->hstatus & ohci->hmask; | ||
| 1440 | - | ||
| 1441 | - case 25: /* HcHReset */ | ||
| 1442 | - return ohci->hreset; | ||
| 1443 | - | ||
| 1444 | - case 26: /* HcHInterruptEnable */ | ||
| 1445 | - return ohci->hmask; | ||
| 1446 | - | ||
| 1447 | - case 27: /* HcHInterruptTest */ | ||
| 1448 | - return ohci->htest; | ||
| 1449 | - | ||
| 1450 | - default: | ||
| 1451 | - fprintf(stderr, "ohci_read: Bad offset %x\n", (int)addr); | ||
| 1452 | - return 0xffffffff; | ||
| 1453 | - } | 1478 | +#ifdef TARGET_WORDS_BIGENDIAN |
| 1479 | + retval = bswap32(retval); | ||
| 1480 | +#endif | ||
| 1481 | + return retval; | ||
| 1454 | } | 1482 | } |
| 1455 | 1483 | ||
| 1456 | static void ohci_mem_write(void *ptr, target_phys_addr_t addr, uint32_t val) | 1484 | static void ohci_mem_write(void *ptr, target_phys_addr_t addr, uint32_t val) |
| 1457 | { | 1485 | { |
| 1458 | OHCIState *ohci = ptr; | 1486 | OHCIState *ohci = ptr; |
| 1459 | 1487 | ||
| 1488 | +#ifdef TARGET_WORDS_BIGENDIAN | ||
| 1489 | + val = bswap32(val); | ||
| 1490 | +#endif | ||
| 1491 | + | ||
| 1460 | /* Only aligned reads are allowed on OHCI */ | 1492 | /* Only aligned reads are allowed on OHCI */ |
| 1461 | if (addr & 3) { | 1493 | if (addr & 3) { |
| 1462 | fprintf(stderr, "usb-ohci: Mis-aligned write\n"); | 1494 | fprintf(stderr, "usb-ohci: Mis-aligned write\n"); |