[OpenBIOS] [commit] r1081 - trunk/openbios-devel/arch/ppc/qemu

repository service svn at openbios.org
Sun Jan 6 14:30:00 CET 2013


Author: agraf
Date: Sun Jan  6 14:29:59 2013
New Revision: 1081
URL: http://tracker.coreboot.org/trac/openbios/changeset/1081

Log:
PPC: Fix next slot eviction

This patch fixes next slot eviction in the MMU code when our HTAB is full.

The basic problem behind this is that the next slot id is stored in .bss which
is automatically resolved to an address that resides in a r/o area.

This is not an issue usually, because in virtual addressing mode OpenBIOS
swizzles accesses to the r/o ROM area to the r/w shadow in RAM. But since the
MMU code runs in real mode, this logic doesn't apply.

The solution is simple: Access the global variable using its shadowed address,
not the ROM address.

Based upon an original patch by

    Mark Cave-Ayland <mark.cave-ayland at ilande.co.uk>

Signed-off-by: Alexander Graf <agraf at suse.de>

Modified:
   trunk/openbios-devel/arch/ppc/qemu/ofmem.c

Modified: trunk/openbios-devel/arch/ppc/qemu/ofmem.c
==============================================================================
--- trunk/openbios-devel/arch/ppc/qemu/ofmem.c	Thu Dec 13 22:30:25 2012	(r1080)
+++ trunk/openbios-devel/arch/ppc/qemu/ofmem.c	Sun Jan  6 14:29:59 2013	(r1081)
@@ -311,10 +311,32 @@
     return phys;
 }
 
+/* Converts a global variable (from .data or .bss) into a pointer that
+   can be accessed from real mode */
+static void *
+global_ptr_real(void *p)
+{
+    return (void*)((uintptr_t)p - OF_CODE_START + get_rom_base());
+}
+
+/* Return the next slot to evict, in the range of [0..7] */
+static int
+next_evicted_slot(void)
+{
+    static int next_grab_slot;
+    int *next_grab_slot_va;
+    int r;
+
+    next_grab_slot_va = global_ptr_real(&next_grab_slot);
+    r = *next_grab_slot_va;
+    *next_grab_slot_va = (r + 1) % 8;
+
+    return r;
+}
+
 static void
 hash_page_64(unsigned long ea, phys_addr_t phys, ucell mode)
 {
-    static int next_grab_slot = 0;
     uint64_t vsid_mask, page_mask, pgidx, hash;
     uint64_t htab_mask, mask, avpn;
     unsigned long pgaddr;
@@ -349,10 +371,8 @@
             found = 1;
 
     /* out of slots, just evict one */
-    if (!found) {
-        i = next_grab_slot + 1;
-        next_grab_slot = (next_grab_slot + 1) % 8;
-    }
+    if (!found)
+        i = next_evicted_slot() + 1;
     i--;
     {
     mPTE_64_t p = {
@@ -381,7 +401,6 @@
 hash_page_32(unsigned long ea, phys_addr_t phys, ucell mode)
 {
 #ifndef __powerpc64__
-    static int next_grab_slot = 0;
     unsigned long *upte, cmp, hash1;
     int i, vsid, found;
     mPTE_t *pp;
@@ -407,10 +426,8 @@
             found = 1;
 
     /* out of slots, just evict one */
-    if (!found) {
-        i = next_grab_slot + 1;
-        next_grab_slot = (next_grab_slot + 1) % 8;
-    }
+    if (!found)
+        i = next_evicted_slot() + 1;
     i--;
     upte[i * 2] = cmp;
     upte[i * 2 + 1] = (phys & ~0xfff) | mode;



More information about the OpenBIOS mailing list