qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 02/13] Implement cpu_physical_memory_zero()


From: Anthony Liguori
Subject: Re: [Qemu-devel] [PATCH 02/13] Implement cpu_physical_memory_zero()
Date: Mon, 14 May 2012 19:42:00 -0500
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:11.0) Gecko/20120329 Thunderbird/11.0.1

On 05/09/2012 11:48 PM, Benjamin Herrenschmidt wrote:
From: David Gibson<address@hidden>

This patch adds cpu_physical_memory_zero() function.  This is equivalent to
calling cpu_physical_memory_write() with a buffer full of zeroes, but
avoids actually allocating such a buffer along the way.

Signed-off-by: David Gibson<address@hidden>
Signed-off-by: Benjamin Herrenschmidt<address@hidden>
---
  cpu-common.h |    1 +
  exec.c       |   53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
  2 files changed, 54 insertions(+)

diff --git a/cpu-common.h b/cpu-common.h
index dca5175..146429c 100644
--- a/cpu-common.h
+++ b/cpu-common.h
@@ -53,6 +53,7 @@ void qemu_ram_set_idstr(ram_addr_t addr, const char *name, 
DeviceState *dev);

  void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
                              int len, int is_write);
+void cpu_physical_memory_zero(target_phys_addr_t addr, int len);
  static inline void cpu_physical_memory_read(target_phys_addr_t addr,
                                              void *buf, int len)
  {
diff --git a/exec.c b/exec.c
index 0607c9b..8511496 100644
--- a/exec.c
+++ b/exec.c
@@ -3581,6 +3581,59 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, 
uint8_t *buf,
      }
  }

+void cpu_physical_memory_zero(target_phys_addr_t addr, int len)
+{

I'd think a memset() like interface would be better but...

We should definitely implement this function in terms of cpu_physical_memory_write instead of open coding the logic again.

Regards,

Anthony Liguori

+    int l;
+    uint8_t *ptr;
+    target_phys_addr_t page;
+    MemoryRegionSection *section;
+
+    while (len>  0) {
+        page = addr&  TARGET_PAGE_MASK;
+        l = (page + TARGET_PAGE_SIZE) - addr;
+        if (l>  len)
+            l = len;
+        section = phys_page_find(page>>  TARGET_PAGE_BITS);
+
+        if (!memory_region_is_ram(section->mr)) {
+            target_phys_addr_t addr1;
+            addr1 = memory_region_section_addr(section, addr);
+            /* XXX: could force cpu_single_env to NULL to avoid
+               potential bugs */
+            if (l>= 4&&  ((addr1&  3) == 0)) {
+                /* 32 bit write access */
+                io_mem_write(section->mr, addr1, 0, 4);
+                l = 4;
+            } else if (l>= 2&&  ((addr1&  1) == 0)) {
+                /* 16 bit write access */
+                io_mem_write(section->mr, addr1, 0, 2);
+                l = 2;
+            } else {
+                /* 8 bit write access */
+                io_mem_write(section->mr, addr1, 0, 1);
+                l = 1;
+            }
+        } else if (!section->readonly) {
+            ram_addr_t addr1;
+            addr1 = memory_region_get_ram_addr(section->mr)
+                + memory_region_section_addr(section, addr);
+            /* RAM case */
+            ptr = qemu_get_ram_ptr(addr1);
+            memset(ptr, 0, l);
+            if (!cpu_physical_memory_is_dirty(addr1)) {
+                /* invalidate code */
+                tb_invalidate_phys_page_range(addr1, addr1 + l, 0);
+                /* set dirty bit */
+                cpu_physical_memory_set_dirty_flags(
+                    addr1, (0xff&  ~CODE_DIRTY_FLAG));
+            }
+            qemu_put_ram_ptr(ptr);
+        }
+        len -= l;
+        addr += l;
+    }
+}
+
  /* used for ROM loading : can write in RAM and ROM */
  void cpu_physical_memory_write_rom(target_phys_addr_t addr,
                                     const uint8_t *buf, int len)




reply via email to

[Prev in Thread] Current Thread [Next in Thread]