Commit 13eb76e091a302dff848b0001a64d1b571450ccc

Authored by bellard
1 parent 3cf1e035

virtual memory access for gdbstub


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@581 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 3 changed files with 152 additions and 49 deletions
cpu-all.h
... ... @@ -473,6 +473,11 @@ int cpu_breakpoint_insert(CPUState *env, uint32_t pc);
473 473 int cpu_breakpoint_remove(CPUState *env, uint32_t pc);
474 474 void cpu_single_step(CPUState *env, int enabled);
475 475  
  476 +/* Return the physical page corresponding to a virtual one. Use it
  477 + only for debugging because no protection checks are done. Return -1
  478 + if no page found. */
  479 +target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr);
  480 +
476 481 #define CPU_LOG_ALL 1
477 482 void cpu_set_log(int log_flags);
478 483 void cpu_set_log_filename(const char *filename);
... ... @@ -515,6 +520,11 @@ int cpu_register_io_memory(int io_index,
515 520 CPUReadMemoryFunc **mem_read,
516 521 CPUWriteMemoryFunc **mem_write);
517 522  
  523 +void cpu_physical_memory_rw(CPUState *env, uint8_t *buf, target_ulong addr,
  524 + int len, int is_write);
  525 +int cpu_memory_rw_debug(CPUState *env,
  526 + uint8_t *buf, target_ulong addr, int len, int is_write);
  527 +
518 528 /* gdb stub API */
519 529 extern int gdbstub_fd;
520 530 CPUState *cpu_gdbstub_get_env(void *opaque);
... ...
... ... @@ -1561,6 +1561,144 @@ int cpu_register_io_memory(int io_index,
1561 1561 return io_index << IO_MEM_SHIFT;
1562 1562 }
1563 1563  
  1564 +/* physical memory access (slow version, mainly for debug) */
  1565 +#if defined(CONFIG_USER_ONLY)
  1566 +void cpu_physical_memory_rw(CPUState *env, uint8_t *buf, target_ulong addr,
  1567 + int len, int is_write)
  1568 +{
  1569 + int l, flags;
  1570 + target_ulong page;
  1571 +
  1572 + while (len > 0) {
  1573 + page = addr & TARGET_PAGE_MASK;
  1574 + l = (page + TARGET_PAGE_SIZE) - addr;
  1575 + if (l > len)
  1576 + l = len;
  1577 + flags = page_get_flags(page);
  1578 + if (!(flags & PAGE_VALID))
  1579 + return;
  1580 + if (is_write) {
  1581 + if (!(flags & PAGE_WRITE))
  1582 + return;
  1583 + memcpy((uint8_t *)addr, buf, len);
  1584 + } else {
  1585 + if (!(flags & PAGE_READ))
  1586 + return;
  1587 + memcpy(buf, (uint8_t *)addr, len);
  1588 + }
  1589 + len -= l;
  1590 + buf += l;
  1591 + addr += l;
  1592 + }
  1593 +}
  1594 +#else
  1595 +void cpu_physical_memory_rw(CPUState *env, uint8_t *buf, target_ulong addr,
  1596 + int len, int is_write)
  1597 +{
  1598 + int l, io_index;
  1599 + uint8_t *ptr;
  1600 + uint32_t val;
  1601 + target_ulong page, pd;
  1602 + PageDesc *p;
  1603 +
  1604 + while (len > 0) {
  1605 + page = addr & TARGET_PAGE_MASK;
  1606 + l = (page + TARGET_PAGE_SIZE) - addr;
  1607 + if (l > len)
  1608 + l = len;
  1609 + p = page_find(page >> TARGET_PAGE_BITS);
  1610 + if (!p) {
  1611 + pd = IO_MEM_UNASSIGNED;
  1612 + } else {
  1613 + pd = p->phys_offset;
  1614 + }
  1615 +
  1616 + if (is_write) {
  1617 + if ((pd & ~TARGET_PAGE_MASK) != 0) {
  1618 + io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
  1619 + if (l >= 4 && ((addr & 3) == 0)) {
  1620 + /* 32 bit read access */
  1621 + val = ldl_raw(buf);
  1622 + io_mem_write[io_index][2](addr, val);
  1623 + l = 4;
  1624 + } else if (l >= 2 && ((addr & 1) == 0)) {
  1625 + /* 16 bit read access */
  1626 + val = lduw_raw(buf);
  1627 + io_mem_write[io_index][1](addr, val);
  1628 + l = 2;
  1629 + } else {
  1630 + /* 8 bit access */
  1631 + val = ldub_raw(buf);
  1632 + io_mem_write[io_index][0](addr, val);
  1633 + l = 1;
  1634 + }
  1635 + } else {
  1636 + /* RAM case */
  1637 + ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
  1638 + (addr & ~TARGET_PAGE_MASK);
  1639 + memcpy(ptr, buf, l);
  1640 + }
  1641 + } else {
  1642 + if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM &&
  1643 + (pd & ~TARGET_PAGE_MASK) != IO_MEM_CODE) {
  1644 + /* I/O case */
  1645 + io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
  1646 + if (l >= 4 && ((addr & 3) == 0)) {
  1647 + /* 32 bit read access */
  1648 + val = io_mem_read[io_index][2](addr);
  1649 + stl_raw(buf, val);
  1650 + l = 4;
  1651 + } else if (l >= 2 && ((addr & 1) == 0)) {
  1652 + /* 16 bit read access */
  1653 + val = io_mem_read[io_index][1](addr);
  1654 + stw_raw(buf, val);
  1655 + l = 2;
  1656 + } else {
  1657 + /* 8 bit access */
  1658 + val = io_mem_read[io_index][0](addr);
  1659 + stb_raw(buf, val);
  1660 + l = 1;
  1661 + }
  1662 + } else {
  1663 + /* RAM case */
  1664 + ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
  1665 + (addr & ~TARGET_PAGE_MASK);
  1666 + memcpy(buf, ptr, l);
  1667 + }
  1668 + }
  1669 + len -= l;
  1670 + buf += l;
  1671 + addr += l;
  1672 + }
  1673 +}
  1674 +#endif
  1675 +
  1676 +/* virtual memory access for debug */
  1677 +int cpu_memory_rw_debug(CPUState *env,
  1678 + uint8_t *buf, target_ulong addr, int len, int is_write)
  1679 +{
  1680 + int l;
  1681 + target_ulong page, phys_addr;
  1682 +
  1683 + while (len > 0) {
  1684 + page = addr & TARGET_PAGE_MASK;
  1685 + phys_addr = cpu_get_phys_page_debug(env, page);
  1686 + /* if no physical page mapped, return an error */
  1687 + if (phys_addr == -1)
  1688 + return -1;
  1689 + l = (page + TARGET_PAGE_SIZE) - addr;
  1690 + if (l > len)
  1691 + l = len;
  1692 + cpu_physical_memory_rw(env, buf,
  1693 + phys_addr + (addr & ~TARGET_PAGE_MASK), l,
  1694 + is_write);
  1695 + len -= l;
  1696 + buf += l;
  1697 + addr += l;
  1698 + }
  1699 + return 0;
  1700 +}
  1701 +
1564 1702 #if !defined(CONFIG_USER_ONLY)
1565 1703  
1566 1704 #define MMUSUFFIX _cmmu
... ...
gdbstub.c
... ... @@ -248,53 +248,6 @@ static int put_packet(char *buf)
248 248 return 0;
249 249 }
250 250  
251   -/* better than nothing for SOFTMMU : we use physical addresses */
252   -#if !defined(CONFIG_USER_ONLY)
253   -static int memory_rw(uint8_t *buf, uint32_t addr, int len, int is_write)
254   -{
255   - uint8_t *ptr;
256   -
257   - if (addr >= phys_ram_size ||
258   - ((int64_t)addr + len > phys_ram_size))
259   - return -1;
260   - ptr = phys_ram_base + addr;
261   - if (is_write)
262   - memcpy(ptr, buf, len);
263   - else
264   - memcpy(buf, ptr, len);
265   - return 0;
266   -}
267   -#else
268   -static int memory_rw(uint8_t *buf, uint32_t addr, int len, int is_write)
269   -{
270   - int l, flags;
271   - uint32_t page;
272   -
273   - while (len > 0) {
274   - page = addr & TARGET_PAGE_MASK;
275   - l = (page + TARGET_PAGE_SIZE) - addr;
276   - if (l > len)
277   - l = len;
278   - flags = page_get_flags(page);
279   - if (!(flags & PAGE_VALID))
280   - return -1;
281   - if (is_write) {
282   - if (!(flags & PAGE_WRITE))
283   - return -1;
284   - memcpy((uint8_t *)addr, buf, l);
285   - } else {
286   - if (!(flags & PAGE_READ))
287   - return -1;
288   - memcpy(buf, (uint8_t *)addr, l);
289   - }
290   - len -= l;
291   - buf += l;
292   - addr += l;
293   - }
294   - return 0;
295   -}
296   -#endif
297   -
298 251 #if defined(TARGET_I386)
299 252  
300 253 static void to_le32(uint8_t *p, int v)
... ... @@ -514,16 +467,18 @@ int cpu_gdbstub(void *opaque, int (*main_loop)(void *opaque), int port)
514 467 put_packet("OK");
515 468 break;
516 469 case 'm':
  470 + env = cpu_gdbstub_get_env(opaque);
517 471 addr = strtoul(p, (char **)&p, 16);
518 472 if (*p == ',')
519 473 p++;
520 474 len = strtoul(p, NULL, 16);
521   - if (memory_rw(mem_buf, addr, len, 0) != 0)
  475 + if (cpu_memory_rw_debug(env, mem_buf, addr, len, 0) != 0)
522 476 memset(mem_buf, 0, len);
523 477 memtohex(buf, mem_buf, len);
524 478 put_packet(buf);
525 479 break;
526 480 case 'M':
  481 + env = cpu_gdbstub_get_env(opaque);
527 482 addr = strtoul(p, (char **)&p, 16);
528 483 if (*p == ',')
529 484 p++;
... ... @@ -531,7 +486,7 @@ int cpu_gdbstub(void *opaque, int (*main_loop)(void *opaque), int port)
531 486 if (*p == ',')
532 487 p++;
533 488 hextomem(mem_buf, p, len);
534   - if (memory_rw(mem_buf, addr, len, 1) != 0)
  489 + if (cpu_memory_rw_debug(env, mem_buf, addr, len, 1) != 0)
535 490 put_packet("ENN");
536 491 else
537 492 put_packet("OK");
... ...