[oe-commits] Khem Raj : qemu_0.12.5.bb: Backport patches from upstream to fix qemu for SH4

git version control git at git.openembedded.org
Mon Jan 10 00:06:11 UTC 2011


Module: openembedded.git
Branch: master
Commit: 6d58ac4a1cb250c513a73066c77ab1cea7763b14
URL:    http://gitweb.openembedded.net/?p=openembedded.git&a=commit;h=6d58ac4a1cb250c513a73066c77ab1cea7763b14

Author: Khem Raj <raj.khem at gmail.com>
Date:   Sun Jan  9 16:02:15 2011 -0800

qemu_0.12.5.bb: Backport patches from upstream to fix qemu for SH4

* Now we can boot SH4 qemu again with these patches and gcc 4.5 compiled
  kernel/root file system

Signed-off-by: Khem Raj <raj.khem at gmail.com>

---

 .../qemu/qemu-0.12.5/qemu-sh4-improve-tlb.patch    |  120 ++++++++++++++++++++
 .../qemu/qemu-0.12.5/qemu-sh4-mmapped-ITLB.patch   |   70 ++++++++++++
 recipes/qemu/qemu_0.12.5.bb                        |    4 +-
 3 files changed, 193 insertions(+), 1 deletions(-)

diff --git a/recipes/qemu/qemu-0.12.5/qemu-sh4-improve-tlb.patch b/recipes/qemu/qemu-0.12.5/qemu-sh4-improve-tlb.patch
new file mode 100644
index 0000000..0742bb0
--- /dev/null
+++ b/recipes/qemu/qemu-0.12.5/qemu-sh4-improve-tlb.patch
@@ -0,0 +1,120 @@
+From 829a49274f6741c0f3d3a2ba4698baf381a7e264 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Sun, 09 Jan 2011 22:53:45 +0000
+Subject: target-sh4: improve TLB
+
+SH4 is using 16-bit instructions which means most of the constants are
+loaded through a constant pool at the end of the subroutine. The same
+memory page is therefore accessed in exec and read mode.
+
+With the current implementation, a QEMU TLB entry is set to read or
+read/write mode after an UTLB search and to exec mode after an ITLB
+search, which causes a lot of TLB exceptions to switch from read or
+read/write to exec and vice versa.
+
+This patch optimizes that by already setting the QEMU TLB entry in read
+or read/write mode when an UTLB entry is copied into ITLB (during an
+ITLB miss). This improve the emulation speed by about 14%.
+
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+---
+Index: qemu-0.12.5/target-sh4/helper.c
+===================================================================
+--- qemu-0.12.5.orig/target-sh4/helper.c	2011-01-09 15:41:39.000000000 -0800
++++ qemu-0.12.5/target-sh4/helper.c	2011-01-09 15:54:43.808656002 -0800
+@@ -295,36 +295,41 @@
+     env->mmucr = (env->mmucr & 0xffff03ff) | (urc << 10);
+ }
+ 
+-/* Find itlb entry - update itlb from utlb if necessary and asked for
++/* Copy and utlb entry into itlb
++   Return entry
++*/
++static int copy_utlb_entry_itlb(CPUState *env, int utlb)
++{
++    int itlb;
++
++    tlb_t * ientry;
++   itlb = itlb_replacement(env);
++    ientry = &env->itlb[itlb];
++    if (ientry->v) {
++        tlb_flush_page(env, ientry->vpn << 10);
++    }
++    *ientry = env->utlb[utlb];
++    update_itlb_use(env, itlb);
++    return itlb;
++}
++
++/* Find itlb entry
+    Return entry, MMU_ITLB_MISS, MMU_ITLB_MULTIPLE or MMU_DTLB_MULTIPLE
+    Update the itlb from utlb if update is not 0
+ */
+ static int find_itlb_entry(CPUState * env, target_ulong address,
+-                           int use_asid, int update)
++                           int use_asid)
+ {
+-    int e, n;
++    int e;
+ 
+     e = find_tlb_entry(env, address, env->itlb, ITLB_SIZE, use_asid);
+-    if (e == MMU_DTLB_MULTIPLE)
++    if (e == MMU_DTLB_MULTIPLE) {
+ 	e = MMU_ITLB_MULTIPLE;
+-    else if (e == MMU_DTLB_MISS && update) {
+-	e = find_tlb_entry(env, address, env->utlb, UTLB_SIZE, use_asid);
+-	if (e >= 0) {
+-	    tlb_t * ientry;
+-	    n = itlb_replacement(env);
+-	    ientry = &env->itlb[n];
+-	    if (ientry->v) {
+-		if (!same_tlb_entry_exists(env->utlb, UTLB_SIZE, ientry))
+-		    tlb_flush_page(env, ientry->vpn << 10);
+-	    }
+-	    *ientry = env->utlb[e];
+-	    e = n;
+-	} else if (e == MMU_DTLB_MISS)
+-	    e = MMU_ITLB_MISS;
+-    } else if (e == MMU_DTLB_MISS)
++    } else if (e == MMU_DTLB_MISS) {
+ 	e = MMU_ITLB_MISS;
+-    if (e >= 0)
++    } else if (e >= 0) {
+ 	update_itlb_use(env, e);
++    }
+     return e;
+ }
+ 
+@@ -356,13 +361,31 @@
+     use_asid = (env->mmucr & MMUCR_SV) == 0 || (env->sr & SR_MD) == 0;
+ 
+     if (rw == 2) {
+-	n = find_itlb_entry(env, address, use_asid, 1);
++	n = find_itlb_entry(env, address, use_asid);
+ 	if (n >= 0) {
+ 	    matching = &env->itlb[n];
+ 	    if (!(env->sr & SR_MD) && !(matching->pr & 2))
+ 		n = MMU_ITLB_VIOLATION;
+ 	    else
+-		*prot = PAGE_READ;
++		*prot = PAGE_EXEC;
++        } else {
++            n = find_utlb_entry(env, address, use_asid);
++            if (n >= 0) {
++                n = copy_utlb_entry_itlb(env, n);
++                matching = &env->itlb[n];
++                if (!(env->sr & SR_MD) && !(matching->pr & 2)) {
++                      n = MMU_ITLB_VIOLATION;
++                } else {
++                    *prot = PAGE_READ | PAGE_EXEC;
++                    if ((matching->pr & 1) && matching->d) {
++                        *prot |= PAGE_WRITE;
++                    }
++                }
++            } else if (n == MMU_DTLB_MULTIPLE) {
++                n = MMU_ITLB_MULTIPLE;
++            } else if (n == MMU_DTLB_MISS) {
++                n = MMU_ITLB_MISS;
++            }
+ 	}
+     } else {
+ 	n = find_utlb_entry(env, address, use_asid);
diff --git a/recipes/qemu/qemu-0.12.5/qemu-sh4-mmapped-ITLB.patch b/recipes/qemu/qemu-0.12.5/qemu-sh4-mmapped-ITLB.patch
new file mode 100644
index 0000000..4fb5452
--- /dev/null
+++ b/recipes/qemu/qemu-0.12.5/qemu-sh4-mmapped-ITLB.patch
@@ -0,0 +1,70 @@
+From c0f809c46aa271f29a9e6268cdeda1f21301a8ef Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Sun, 09 Jan 2011 22:53:45 +0000
+Subject: target-sh4: implement writes to mmaped ITLB
+
+Some Linux kernels seems to implement ITLB/UTLB flushing through by
+writing all TLB entries through the memory mapped interface instead
+of writing one to MMUCR.TI.
+
+Implement memory mapped ITLB write interface so that such kernels can
+boot. This fixes https://bugs.launchpad.net/bugs/700774 .
+
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+---
+Index: qemu-0.12.5/hw/sh7750.c
+===================================================================
+--- qemu-0.12.5.orig/hw/sh7750.c	2010-07-22 05:39:04.000000000 -0700
++++ qemu-0.12.5/hw/sh7750.c	2011-01-09 15:41:39.148656001 -0800
+@@ -670,6 +670,8 @@
+         /* do nothing */
+ 	break;
+     case MM_ITLB_ADDR:
++        cpu_sh4_write_mmaped_itlb_addr(s->cpu, addr, mem_value);
++        break;
+     case MM_ITLB_DATA:
+         /* XXXXX */
+         assert(0);
+Index: qemu-0.12.5/target-sh4/cpu.h
+===================================================================
+--- qemu-0.12.5.orig/target-sh4/cpu.h	2011-01-09 14:04:50.708656002 -0800
++++ qemu-0.12.5/target-sh4/cpu.h	2011-01-09 15:41:39.168656001 -0800
+@@ -167,6 +167,8 @@
+ 
+ void sh4_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
+ void cpu_sh4_invalidate_tlb(CPUSH4State *s);
++void cpu_sh4_write_mmaped_itlb_addr(CPUSH4State *s, target_phys_addr_t addr,
++				    uint32_t mem_value);
+ void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr,
+ 				    uint32_t mem_value);
+ 
+Index: qemu-0.12.5/target-sh4/helper.c
+===================================================================
+--- qemu-0.12.5.orig/target-sh4/helper.c	2011-01-09 14:04:50.708656002 -0800
++++ qemu-0.12.5/target-sh4/helper.c	2011-01-09 15:41:39.178656001 -0800
+@@ -561,6 +561,25 @@
+     tlb_flush(s, 1);
+ }
+ 
++void cpu_sh4_write_mmaped_itlb_addr(CPUSH4State *s, target_phys_addr_t addr,
++				    uint32_t mem_value)
++{
++    uint32_t vpn = (mem_value & 0xfffffc00) >> 10;
++    uint8_t v = (uint8_t)((mem_value & 0x00000100) >> 8);
++    uint8_t asid = (uint8_t)(mem_value & 0x000000ff);
++
++    int index = (addr & 0x00003f00) >> 8;
++    tlb_t * entry = &s->itlb[index];
++    if (entry->v) {
++        /* Overwriting valid entry in itlb. */
++        target_ulong address = entry->vpn << 10;
++        tlb_flush_page(s, address);
++    }
++    entry->asid = asid;
++    entry->vpn = vpn;
++    entry->v = v;
++}
++
+ void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr,
+ 				    uint32_t mem_value)
+ {
diff --git a/recipes/qemu/qemu_0.12.5.bb b/recipes/qemu/qemu_0.12.5.bb
index a8d67f1..d88d834 100644
--- a/recipes/qemu/qemu_0.12.5.bb
+++ b/recipes/qemu/qemu_0.12.5.bb
@@ -1,7 +1,7 @@
 LICENSE = "GPL"
 DEPENDS = "zlib ncurses gnutls"
 
-PR = "r1"
+PR = "r2"
 
 SRC_URI = "\
     http://download.savannah.gnu.org/releases/qemu/qemu-${PV}.tar.gz \
@@ -16,6 +16,8 @@ SRC_URI = "\
     file://fix_baum_c_compilation.patch \
     file://fallback.to.safe.mmap_min_addr.patch \
     file://linux-user-fix-running-programs-with-iwmmxt.patch \
+    file://qemu-sh4-mmapped-ITLB.patch \
+    file://qemu-sh4-improve-tlb.patch \
     "
 
 SRC_URI[md5sum] = "1d02ee0a04dfae2894340273372c1de4"





More information about the Openembedded-commits mailing list