Commit 65e1d81b2912b7833f77578867998e3067e8c181

Authored by aurel32
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");
... ...