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,6 +473,11 @@ int cpu_breakpoint_insert(CPUState *env, uint32_t pc);
473 int cpu_breakpoint_remove(CPUState *env, uint32_t pc); 473 int cpu_breakpoint_remove(CPUState *env, uint32_t pc);
474 void cpu_single_step(CPUState *env, int enabled); 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 #define CPU_LOG_ALL 1 481 #define CPU_LOG_ALL 1
477 void cpu_set_log(int log_flags); 482 void cpu_set_log(int log_flags);
478 void cpu_set_log_filename(const char *filename); 483 void cpu_set_log_filename(const char *filename);
@@ -515,6 +520,11 @@ int cpu_register_io_memory(int io_index, @@ -515,6 +520,11 @@ int cpu_register_io_memory(int io_index,
515 CPUReadMemoryFunc **mem_read, 520 CPUReadMemoryFunc **mem_read,
516 CPUWriteMemoryFunc **mem_write); 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 /* gdb stub API */ 528 /* gdb stub API */
519 extern int gdbstub_fd; 529 extern int gdbstub_fd;
520 CPUState *cpu_gdbstub_get_env(void *opaque); 530 CPUState *cpu_gdbstub_get_env(void *opaque);
@@ -1561,6 +1561,144 @@ int cpu_register_io_memory(int io_index, @@ -1561,6 +1561,144 @@ int cpu_register_io_memory(int io_index,
1561 return io_index << IO_MEM_SHIFT; 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 #if !defined(CONFIG_USER_ONLY) 1702 #if !defined(CONFIG_USER_ONLY)
1565 1703
1566 #define MMUSUFFIX _cmmu 1704 #define MMUSUFFIX _cmmu
gdbstub.c
@@ -248,53 +248,6 @@ static int put_packet(char *buf) @@ -248,53 +248,6 @@ static int put_packet(char *buf)
248 return 0; 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 #if defined(TARGET_I386) 251 #if defined(TARGET_I386)
299 252
300 static void to_le32(uint8_t *p, int v) 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,16 +467,18 @@ int cpu_gdbstub(void *opaque, int (*main_loop)(void *opaque), int port)
514 put_packet("OK"); 467 put_packet("OK");
515 break; 468 break;
516 case 'm': 469 case 'm':
  470 + env = cpu_gdbstub_get_env(opaque);
517 addr = strtoul(p, (char **)&p, 16); 471 addr = strtoul(p, (char **)&p, 16);
518 if (*p == ',') 472 if (*p == ',')
519 p++; 473 p++;
520 len = strtoul(p, NULL, 16); 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 memset(mem_buf, 0, len); 476 memset(mem_buf, 0, len);
523 memtohex(buf, mem_buf, len); 477 memtohex(buf, mem_buf, len);
524 put_packet(buf); 478 put_packet(buf);
525 break; 479 break;
526 case 'M': 480 case 'M':
  481 + env = cpu_gdbstub_get_env(opaque);
527 addr = strtoul(p, (char **)&p, 16); 482 addr = strtoul(p, (char **)&p, 16);
528 if (*p == ',') 483 if (*p == ',')
529 p++; 484 p++;
@@ -531,7 +486,7 @@ int cpu_gdbstub(void *opaque, int (*main_loop)(void *opaque), int port) @@ -531,7 +486,7 @@ int cpu_gdbstub(void *opaque, int (*main_loop)(void *opaque), int port)
531 if (*p == ',') 486 if (*p == ',')
532 p++; 487 p++;
533 hextomem(mem_buf, p, len); 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 put_packet("ENN"); 490 put_packet("ENN");
536 else 491 else
537 put_packet("OK"); 492 put_packet("OK");