From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1JkzBE-0005ZV-VS for qemu-devel@nongnu.org; Sun, 13 Apr 2008 06:11:25 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1JkzBD-0005Wn-2L for qemu-devel@nongnu.org; Sun, 13 Apr 2008 06:11:24 -0400 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1JkzBC-0005WK-MM for qemu-devel@nongnu.org; Sun, 13 Apr 2008 06:11:22 -0400 Received: from fmmailgate02.web.de ([217.72.192.227]) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1JkzBC-000414-6f for qemu-devel@nongnu.org; Sun, 13 Apr 2008 06:11:22 -0400 Received: from smtp06.web.de (fmsmtp06.dlan.cinetic.de [172.20.5.172]) by fmmailgate02.web.de (Postfix) with ESMTP id C2CC0D8AC79F for ; Sun, 13 Apr 2008 12:11:21 +0200 (CEST) Received: from [88.65.41.105] (helo=[192.168.1.198]) by smtp06.web.de with asmtp (TLSv1:AES256-SHA:256) (WEB.DE 4.109 #226) id 1JkzBB-0000rY-00 for qemu-devel@nongnu.org; Sun, 13 Apr 2008 12:11:21 +0200 Message-ID: <4801DC49.9090302@web.de> Date: Sun, 13 Apr 2008 12:11:21 +0200 From: Jan Kiszka MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 7bit Sender: jan.kiszka@web.de Subject: [Qemu-devel] [RFC][PATCH 3/4] cfi02: Optimize consecutive write accesses Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org The MusicPal emulation supports, of course, also updating the virtual flash (online or via the emergency procedure [1]). But this procedure turned out to take ages even on high-end hosts. Running oprofile on QEMU revealed the bottleneck: before and after each write access, the cfi02 emulation switches the access mode of the flash between read/write and read-only. For this purpose, cpu_register_physical_memory() is invoked which is a fairly heavy-weighted function, surely not written to be called in a tight loop. Therefore, this patch optimizes the chip un-/locking by invoking cpu_register_physical_memory() lazily: the chip memory remains read/writable as long as no read access takes place. Flash update algorithms like the one of the MusicPal will now be able to write larger chunks without the overhead of access mode changes (e.g. the MusicPal writes one sector and only then verifies its content). On the MusicPal, this speeds up firmware updates significantly. I never ran it without optimization, it would have taken hours, but now it is done within a few minutes on a Core 2. [1] http://www.mydssd.de/musicpal/doku.php?id=my_musicpal:firmware Signed-off-by: Jan Kiszka --- hw/pflash_cfi02.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) Index: b/hw/pflash_cfi02.c =================================================================== --- a/hw/pflash_cfi02.c +++ b/hw/pflash_cfi02.c @@ -70,6 +70,7 @@ struct pflash_t { QEMUTimer *timer; ram_addr_t off; int fl_mem; + int rom_mode; void *storage; }; @@ -80,6 +81,7 @@ static void pflash_register_memory(pflas if (rom_mode) phys_offset |= pfl->off | IO_MEM_ROMD; + pfl->rom_mode = rom_mode; for (i = 0; i < pfl->mappings; i++) cpu_register_physical_memory(pfl->base + i * pfl->chip_len, @@ -110,7 +112,13 @@ static uint32_t pflash_read (pflash_t *p DPRINTF("%s: offset " TARGET_FMT_lx "\n", __func__, offset); ret = -1; - offset -= pfl->base; + if (pfl->rom_mode) { + offset -= (uint32_t)(long)pfl->storage; + /* Lazy reset of to ROMD mode */ + if (pfl->wcycle == 0) + pflash_register_memory(pfl, 1); + } else + offset -= pfl->base; offset &= pfl->chip_len - 1; boff = offset & 0xFF; if (pfl->width == 2) @@ -224,8 +232,6 @@ static void pflash_write (pflash_t *pfl, uint8_t *p; uint8_t cmd; - /* WARNING: when the memory area is in ROMD mode, the offset is a - ram offset, not a physical address */ cmd = value; if (pfl->cmd != 0xA0 && cmd == 0xF0) { #if 0 @@ -236,7 +242,9 @@ static void pflash_write (pflash_t *pfl, } DPRINTF("%s: offset " TARGET_FMT_lx " %08x %d %d\n", __func__, offset, value, width, pfl->wcycle); - if (pfl->wcycle == 0) + /* WARNING: when the memory area is in ROMD mode, the offset is a + ram offset, not a physical address */ + if (pfl->rom_mode) offset -= (uint32_t)(long)pfl->storage; else offset -= pfl->base; @@ -251,8 +259,9 @@ static void pflash_write (pflash_t *pfl, boff = boff >> 2; switch (pfl->wcycle) { case 0: - /* Set the device in I/O access mode */ - pflash_register_memory(pfl, 0); + /* Set the device in I/O access mode if required */ + if (pfl->rom_mode) + pflash_register_memory(pfl, 0); /* We're in read mode */ check_unlock0: if (boff == 0x55 && cmd == 0x98) { @@ -439,7 +448,6 @@ static void pflash_write (pflash_t *pfl, /* Reset flash */ reset_flash: - pflash_register_memory(pfl, 1); pfl->bypass = 0; pfl->wcycle = 0; pfl->cmd = 0;