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,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");