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 | 1360 | static uint32_t ohci_mem_read(void *ptr, target_phys_addr_t addr) |
1361 | 1361 | { |
1362 | 1362 | OHCIState *ohci = ptr; |
1363 | + uint32_t retval; | |
1363 | 1364 | |
1364 | 1365 | /* Only aligned reads are allowed on OHCI */ |
1365 | 1366 | if (addr & 3) { |
1366 | 1367 | fprintf(stderr, "usb-ohci: Mis-aligned read\n"); |
1367 | 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 | 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 | 1484 | static void ohci_mem_write(void *ptr, target_phys_addr_t addr, uint32_t val) |
1457 | 1485 | { |
1458 | 1486 | OHCIState *ohci = ptr; |
1459 | 1487 | |
1488 | +#ifdef TARGET_WORDS_BIGENDIAN | |
1489 | + val = bswap32(val); | |
1490 | +#endif | |
1491 | + | |
1460 | 1492 | /* Only aligned reads are allowed on OHCI */ |
1461 | 1493 | if (addr & 3) { |
1462 | 1494 | fprintf(stderr, "usb-ohci: Mis-aligned write\n"); | ... | ... |