Commit 54585ffec7b378b187679d9a374b70f9e6720dd5
1 parent
4c54e875
OMAP STI/XTI console.
Add a dummy serial to receive the output from STI console (OMAP debugging/emulation interface). Add some more OMAP UART dummy registers. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4331 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
217 additions
and
0 deletions
hw/omap.h
| ... | ... | @@ -330,6 +330,7 @@ void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, int iomemtype, |
| 330 | 330 | /* |
| 331 | 331 | * OMAP-24xx common IRQ numbers |
| 332 | 332 | */ |
| 333 | +# define OMAP_INT_24XX_STI 4 | |
| 333 | 334 | # define OMAP_INT_24XX_SYS_NIRQ 7 |
| 334 | 335 | # define OMAP_INT_24XX_L3_IRQ 10 |
| 335 | 336 | # define OMAP_INT_24XX_PRCM_MPU_IRQ 11 | ... | ... |
hw/omap1.c
| ... | ... | @@ -1987,6 +1987,8 @@ struct omap_uart_s { |
| 1987 | 1987 | uint8_t syscontrol; |
| 1988 | 1988 | uint8_t wkup; |
| 1989 | 1989 | uint8_t cfps; |
| 1990 | + uint8_t mdr[2]; | |
| 1991 | + uint8_t scr; | |
| 1990 | 1992 | }; |
| 1991 | 1993 | |
| 1992 | 1994 | void omap_uart_reset(struct omap_uart_s *s) |
| ... | ... | @@ -2015,6 +2017,14 @@ static uint32_t omap_uart_read(void *opaque, target_phys_addr_t addr) |
| 2015 | 2017 | int offset = addr - s->base; |
| 2016 | 2018 | |
| 2017 | 2019 | switch (offset) { |
| 2020 | + case 0x20: /* MDR1 */ | |
| 2021 | + return s->mdr[0]; | |
| 2022 | + case 0x24: /* MDR2 */ | |
| 2023 | + return s->mdr[1]; | |
| 2024 | + case 0x40: /* SCR */ | |
| 2025 | + return s->scr; | |
| 2026 | + case 0x44: /* SSR */ | |
| 2027 | + return 0x0; | |
| 2018 | 2028 | case 0x48: /* EBLR */ |
| 2019 | 2029 | return s->eblr; |
| 2020 | 2030 | case 0x50: /* MVR */ |
| ... | ... | @@ -2040,9 +2050,19 @@ static void omap_uart_write(void *opaque, target_phys_addr_t addr, |
| 2040 | 2050 | int offset = addr - s->base; |
| 2041 | 2051 | |
| 2042 | 2052 | switch (offset) { |
| 2053 | + case 0x20: /* MDR1 */ | |
| 2054 | + s->mdr[0] = value & 0x7f; | |
| 2055 | + break; | |
| 2056 | + case 0x24: /* MDR2 */ | |
| 2057 | + s->mdr[1] = value & 0xff; | |
| 2058 | + break; | |
| 2059 | + case 0x40: /* SCR */ | |
| 2060 | + s->scr = value & 0xff; | |
| 2061 | + break; | |
| 2043 | 2062 | case 0x48: /* EBLR */ |
| 2044 | 2063 | s->eblr = value & 0xff; |
| 2045 | 2064 | break; |
| 2065 | + case 0x44: /* SSR */ | |
| 2046 | 2066 | case 0x50: /* MVR */ |
| 2047 | 2067 | case 0x58: /* SYSS */ |
| 2048 | 2068 | OMAP_RO_REG(addr); | ... | ... |
hw/omap2.c
| ... | ... | @@ -1419,6 +1419,196 @@ void omap_mcspi_attach(struct omap_mcspi_s *s, |
| 1419 | 1419 | s->ch[chipselect].opaque = opaque; |
| 1420 | 1420 | } |
| 1421 | 1421 | |
| 1422 | +/* STI/XTI (emulation interface) console - reverse engineered only */ | |
| 1423 | +struct omap_sti_s { | |
| 1424 | + target_phys_addr_t base; | |
| 1425 | + target_phys_addr_t channel_base; | |
| 1426 | + qemu_irq irq; | |
| 1427 | + CharDriverState *chr; | |
| 1428 | + | |
| 1429 | + uint32_t sysconfig; | |
| 1430 | + uint32_t systest; | |
| 1431 | + uint32_t irqst; | |
| 1432 | + uint32_t irqen; | |
| 1433 | + uint32_t clkcontrol; | |
| 1434 | + uint32_t serial_config; | |
| 1435 | +}; | |
| 1436 | + | |
| 1437 | +#define STI_TRACE_CONSOLE_CHANNEL 239 | |
| 1438 | +#define STI_TRACE_CONTROL_CHANNEL 253 | |
| 1439 | + | |
| 1440 | +static inline void omap_sti_interrupt_update(struct omap_sti_s *s) | |
| 1441 | +{ | |
| 1442 | + qemu_set_irq(s->irq, s->irqst & s->irqen); | |
| 1443 | +} | |
| 1444 | + | |
| 1445 | +static void omap_sti_reset(struct omap_sti_s *s) | |
| 1446 | +{ | |
| 1447 | + s->sysconfig = 0; | |
| 1448 | + s->irqst = 0; | |
| 1449 | + s->irqen = 0; | |
| 1450 | + s->clkcontrol = 0; | |
| 1451 | + s->serial_config = 0; | |
| 1452 | + | |
| 1453 | + omap_sti_interrupt_update(s); | |
| 1454 | +} | |
| 1455 | + | |
| 1456 | +static uint32_t omap_sti_read(void *opaque, target_phys_addr_t addr) | |
| 1457 | +{ | |
| 1458 | + struct omap_sti_s *s = (struct omap_sti_s *) opaque; | |
| 1459 | + int offset = addr - s->base; | |
| 1460 | + | |
| 1461 | + switch (offset) { | |
| 1462 | + case 0x00: /* STI_REVISION */ | |
| 1463 | + return 0x10; | |
| 1464 | + | |
| 1465 | + case 0x10: /* STI_SYSCONFIG */ | |
| 1466 | + return s->sysconfig; | |
| 1467 | + | |
| 1468 | + case 0x14: /* STI_SYSSTATUS / STI_RX_STATUS / XTI_SYSSTATUS */ | |
| 1469 | + return 0x00; | |
| 1470 | + | |
| 1471 | + case 0x18: /* STI_IRQSTATUS */ | |
| 1472 | + return s->irqst; | |
| 1473 | + | |
| 1474 | + case 0x1c: /* STI_IRQSETEN / STI_IRQCLREN */ | |
| 1475 | + return s->irqen; | |
| 1476 | + | |
| 1477 | + case 0x24: /* STI_ER / STI_DR / XTI_TRACESELECT */ | |
| 1478 | + case 0x28: /* STI_RX_DR / XTI_RXDATA */ | |
| 1479 | + break; | |
| 1480 | + | |
| 1481 | + case 0x2c: /* STI_CLK_CTRL / XTI_SCLKCRTL */ | |
| 1482 | + return s->clkcontrol; | |
| 1483 | + | |
| 1484 | + case 0x30: /* STI_SERIAL_CFG / XTI_SCONFIG */ | |
| 1485 | + return s->serial_config; | |
| 1486 | + } | |
| 1487 | + | |
| 1488 | + OMAP_BAD_REG(addr); | |
| 1489 | + return 0; | |
| 1490 | +} | |
| 1491 | + | |
| 1492 | +static void omap_sti_write(void *opaque, target_phys_addr_t addr, | |
| 1493 | + uint32_t value) | |
| 1494 | +{ | |
| 1495 | + struct omap_sti_s *s = (struct omap_sti_s *) opaque; | |
| 1496 | + int offset = addr - s->base; | |
| 1497 | + | |
| 1498 | + switch (offset) { | |
| 1499 | + case 0x00: /* STI_REVISION */ | |
| 1500 | + case 0x14: /* STI_SYSSTATUS / STI_RX_STATUS / XTI_SYSSTATUS */ | |
| 1501 | + OMAP_RO_REG(addr); | |
| 1502 | + return; | |
| 1503 | + | |
| 1504 | + case 0x10: /* STI_SYSCONFIG */ | |
| 1505 | + if (value & (1 << 1)) /* SOFTRESET */ | |
| 1506 | + omap_sti_reset(s); | |
| 1507 | + s->sysconfig = value & 0xfe; | |
| 1508 | + break; | |
| 1509 | + | |
| 1510 | + case 0x18: /* STI_IRQSTATUS */ | |
| 1511 | + s->irqst &= ~value; | |
| 1512 | + omap_sti_interrupt_update(s); | |
| 1513 | + break; | |
| 1514 | + | |
| 1515 | + case 0x1c: /* STI_IRQSETEN / STI_IRQCLREN */ | |
| 1516 | + s->irqen = value & 0xffff; | |
| 1517 | + omap_sti_interrupt_update(s); | |
| 1518 | + break; | |
| 1519 | + | |
| 1520 | + case 0x2c: /* STI_CLK_CTRL / XTI_SCLKCRTL */ | |
| 1521 | + s->clkcontrol = value & 0xff; | |
| 1522 | + break; | |
| 1523 | + | |
| 1524 | + case 0x30: /* STI_SERIAL_CFG / XTI_SCONFIG */ | |
| 1525 | + s->serial_config = value & 0xff; | |
| 1526 | + break; | |
| 1527 | + | |
| 1528 | + case 0x24: /* STI_ER / STI_DR / XTI_TRACESELECT */ | |
| 1529 | + case 0x28: /* STI_RX_DR / XTI_RXDATA */ | |
| 1530 | + default: | |
| 1531 | + OMAP_BAD_REG(addr); | |
| 1532 | + return; | |
| 1533 | + } | |
| 1534 | +} | |
| 1535 | + | |
| 1536 | +static CPUReadMemoryFunc *omap_sti_readfn[] = { | |
| 1537 | + omap_badwidth_read32, | |
| 1538 | + omap_badwidth_read32, | |
| 1539 | + omap_sti_read, | |
| 1540 | +}; | |
| 1541 | + | |
| 1542 | +static CPUWriteMemoryFunc *omap_sti_writefn[] = { | |
| 1543 | + omap_badwidth_write32, | |
| 1544 | + omap_badwidth_write32, | |
| 1545 | + omap_sti_write, | |
| 1546 | +}; | |
| 1547 | + | |
| 1548 | +static uint32_t omap_sti_fifo_read(void *opaque, target_phys_addr_t addr) | |
| 1549 | +{ | |
| 1550 | + OMAP_BAD_REG(addr); | |
| 1551 | + return 0; | |
| 1552 | +} | |
| 1553 | + | |
| 1554 | +static void omap_sti_fifo_write(void *opaque, target_phys_addr_t addr, | |
| 1555 | + uint32_t value) | |
| 1556 | +{ | |
| 1557 | + struct omap_sti_s *s = (struct omap_sti_s *) opaque; | |
| 1558 | + int offset = addr - s->channel_base; | |
| 1559 | + int ch = offset >> 6; | |
| 1560 | + uint8_t byte = value; | |
| 1561 | + | |
| 1562 | + if (ch == STI_TRACE_CONTROL_CHANNEL) { | |
| 1563 | + /* Flush channel <i>value</i>. */ | |
| 1564 | + qemu_chr_write(s->chr, "\r", 1); | |
| 1565 | + } else if (ch == STI_TRACE_CONSOLE_CHANNEL || 1) { | |
| 1566 | + if (value == 0xc0 || value == 0xc3) { | |
| 1567 | + /* Open channel <i>ch</i>. */ | |
| 1568 | + } else if (value == 0x00) | |
| 1569 | + qemu_chr_write(s->chr, "\n", 1); | |
| 1570 | + else | |
| 1571 | + qemu_chr_write(s->chr, &byte, 1); | |
| 1572 | + } | |
| 1573 | +} | |
| 1574 | + | |
| 1575 | +static CPUReadMemoryFunc *omap_sti_fifo_readfn[] = { | |
| 1576 | + omap_sti_fifo_read, | |
| 1577 | + omap_badwidth_read8, | |
| 1578 | + omap_badwidth_read8, | |
| 1579 | +}; | |
| 1580 | + | |
| 1581 | +static CPUWriteMemoryFunc *omap_sti_fifo_writefn[] = { | |
| 1582 | + omap_sti_fifo_write, | |
| 1583 | + omap_badwidth_write8, | |
| 1584 | + omap_badwidth_write8, | |
| 1585 | +}; | |
| 1586 | + | |
| 1587 | +struct omap_sti_s *omap_sti_init(struct omap_target_agent_s *ta, | |
| 1588 | + target_phys_addr_t channel_base, qemu_irq irq, omap_clk clk, | |
| 1589 | + CharDriverState *chr) | |
| 1590 | +{ | |
| 1591 | + int iomemtype; | |
| 1592 | + struct omap_sti_s *s = (struct omap_sti_s *) | |
| 1593 | + qemu_mallocz(sizeof(struct omap_sti_s)); | |
| 1594 | + | |
| 1595 | + s->irq = irq; | |
| 1596 | + omap_sti_reset(s); | |
| 1597 | + | |
| 1598 | + s->chr = chr ?: qemu_chr_open("null"); | |
| 1599 | + | |
| 1600 | + iomemtype = cpu_register_io_memory(0, omap_sti_readfn, | |
| 1601 | + omap_sti_writefn, s); | |
| 1602 | + s->base = omap_l4_attach(ta, 0, iomemtype); | |
| 1603 | + | |
| 1604 | + iomemtype = cpu_register_io_memory(0, omap_sti_fifo_readfn, | |
| 1605 | + omap_sti_fifo_writefn, s); | |
| 1606 | + s->channel_base = channel_base; | |
| 1607 | + cpu_register_physical_memory(s->channel_base, 0x10000, iomemtype); | |
| 1608 | + | |
| 1609 | + return s; | |
| 1610 | +} | |
| 1611 | + | |
| 1422 | 1612 | /* L4 Interconnect */ |
| 1423 | 1613 | struct omap_target_agent_s { |
| 1424 | 1614 | struct omap_l4_s *bus; |
| ... | ... | @@ -3674,6 +3864,11 @@ struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size, |
| 3674 | 3864 | omap_findclk(s, "dss_l3_iclk"), |
| 3675 | 3865 | omap_findclk(s, "dss_l4_iclk")); |
| 3676 | 3866 | |
| 3867 | + omap_sti_init(omap_l4ta(s->l4, 18), 0x54000000, | |
| 3868 | + s->irq[0][OMAP_INT_24XX_STI], omap_findclk(s, "emul_ck"), | |
| 3869 | + serial_hds[0] && serial_hds[1] && serial_hds[2] ? | |
| 3870 | + serial_hds[3] : 0); | |
| 3871 | + | |
| 3677 | 3872 | /* All register mappings (includin those not currenlty implemented): |
| 3678 | 3873 | * SystemControlMod 48000000 - 48000fff |
| 3679 | 3874 | * SystemControlL4 48001000 - 48001fff |
| ... | ... | @@ -3803,6 +3998,7 @@ struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size, |
| 3803 | 3998 | * HDQ/1-wire Mod 480b2000 - 480b2fff |
| 3804 | 3999 | * HDQ/1-wire L4 480b3000 - 480b3fff |
| 3805 | 4000 | * MPU interrupt 480fe000 - 480fefff |
| 4001 | + * STI channel base 54000000 - 5400ffff | |
| 3806 | 4002 | * IVA RAM 5c000000 - 5c01ffff |
| 3807 | 4003 | * IVA ROM 5c020000 - 5c027fff |
| 3808 | 4004 | * IMG_BUF_A 5c040000 - 5c040fff | ... | ... |