qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] sparc64 support TSB related MMU registers
@ 2009-04-23 22:56 Igor Kovalenko
  2009-04-24 17:42 ` Blue Swirl
  0 siblings, 1 reply; 6+ messages in thread
From: Igor Kovalenko @ 2009-04-23 22:56 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 881 bytes --]

Hi!

This change allows reading ultrasparc I/D MMU TSB tag target register
and TSB pointer register (8k and 64k).
Linux kernel uses TSB for memory management, and with this change it
now can use early allocation routines.

I'm testing with linux-2.6.29.1 minimalistic sparc64 uniprocessor
build, now kernel is able to start build device tree.
Without the change kernel was not able to handle D-MMU miss while
creating first device tree node.
Currently it stops shortly after building device tree, trying to find
out path to console.

(PS with openbios instance-to-path method fails in client interface
call, in the same way
it fails without loading kernel when I try invoking get-instance-path
on stdin handle from command prompt.
there fmove invokes memmove() with size argument looking like some
pointer which leads to unhandled D-MMU fault)

-- 
Kind regards,
Igor V. Kovalenko

[-- Attachment #2: qemu-sparc64-tsb-asi.patch --]
[-- Type: application/octet-stream, Size: 4584 bytes --]

Index: target-sparc/op_helper.c
===================================================================
--- target-sparc/op_helper.c	(revision 7235)
+++ target-sparc/op_helper.c	(working copy)
@@ -39,6 +39,55 @@
 #endif
 #endif
 
+// Calculates TSB pointer value for fault page size 8k or 64k
+static uint64_t ultrasparc_tsb_pointer_value(uint64_t tsb_register, uint64_t tag_access_register, int page_size)
+{
+
+    uint64_t tsb_base = tsb_register & ~0x1fffULL;
+    int tsb_split = (env->dmmuregs[5] & 0x1000ULL)?1:0;
+    int tsb_size  = env->dmmuregs[5] & 0xf;
+
+    //uint64_t tag_access_context = tag_access_register & 0x1fffULL;
+    uint64_t tag_access_va = tag_access_register & ~0x1fffULL;
+
+    // now reorder bits
+    uint64_t tsb_base_mask = ~0x1fffULL;
+    uint64_t va = tag_access_va;
+
+    // move va bits to correct position
+    if (page_size == 8*1024) {
+        // VA<21+N:13> 0000
+        va >>= 9;
+    } else if (page_size == 64*1024) {
+        // VA<24+N:16> 0000
+        va >>= 12;
+    }
+
+    if (tsb_size)
+        tsb_base_mask <<= tsb_size;
+
+    // calculate tsb_base mask and adjust va if split is in use
+    if (tsb_split) {
+    //For a split TSB (TSB register split field=1):
+        if (page_size == 8*1024) {
+            //8K_POINTER = TSB_Base<63:14+N> 0 VA<21+N:13> 0000
+            va &= ~(1ULL << (13 + tsb_size));
+        } else if (page_size == 64*1024) {
+            //64K_POINTER = TSB_Base<63:14+N> 1 VA<24+N:16> 0000
+            va |= (1ULL << (13 + tsb_size));
+        }
+        tsb_base_mask <<= 1;
+    }
+
+    return ((tsb_base & tsb_base_mask) | (va & ~tsb_base_mask)) & ~0xfULL;
+}
+
+// Calculates tag target register value by reordering bits in tag access register
+static uint64_t ultrasparc_tag_target_value(uint64_t tag_access_register)
+{
+    return (((tag_access_register & 0x1fff)<<48)|(tag_access_register >> 22));
+}
+
 static inline void address_mask(CPUState *env1, target_ulong *addr)
 {
 #ifdef TARGET_SPARC64
@@ -1652,13 +1701,32 @@
         {
             int reg = (addr >> 3) & 0xf;
 
-            ret = env->immuregs[reg];
+            if (reg == 0)
+            {
+                // I-TSB Tag Target register
+                ret = ultrasparc_tag_target_value(env->immuregs[6]);
+            }
+            else
+            {
+                ret = env->immuregs[reg];
+            }
+
             break;
         }
     case 0x51: // I-MMU 8k TSB pointer
+        {
+            // env->immuregs[5] holds I-MMU TSB register value
+            // env->immuregs[6] holds I-MMU Tag Access register value
+            ret = ultrasparc_tsb_pointer_value(env->immuregs[5], env->immuregs[6], 8*1024);
+            break;
+        }
     case 0x52: // I-MMU 64k TSB pointer
-        // XXX
-        break;
+        {
+            // env->immuregs[5] holds I-MMU TSB register value
+            // env->immuregs[6] holds I-MMU Tag Access register value
+            ret = ultrasparc_tsb_pointer_value(env->immuregs[5], env->immuregs[6], 64*1024);
+            break;
+        }
     case 0x55: // I-MMU data access
         {
             int reg = (addr >> 3) & 0x3f;
@@ -1677,9 +1745,31 @@
         {
             int reg = (addr >> 3) & 0xf;
 
-            ret = env->dmmuregs[reg];
+            if (reg == 0)
+            {
+                // D-TSB Tag Target register
+                ret = ultrasparc_tag_target_value(env->dmmuregs[6]);
+            }
+            else
+            {
+                ret = env->dmmuregs[reg];
+            }
             break;
         }
+    case 0x59: // D-MMU 8k TSB pointer
+        {
+            // env->dmmuregs[5] holds D-MMU TSB register value
+            // env->dmmuregs[6] holds D-MMU Tag Access register value
+            ret = ultrasparc_tsb_pointer_value(env->dmmuregs[5], env->dmmuregs[6], 8*1024);
+            break;
+        }
+    case 0x5a: // D-MMU 64k TSB pointer
+        {
+            // env->dmmuregs[5] holds D-MMU TSB register value
+            // env->dmmuregs[6] holds D-MMU Tag Access register value
+            ret = ultrasparc_tsb_pointer_value(env->dmmuregs[5], env->dmmuregs[6], 64*1024);
+            break;
+        }
     case 0x5d: // D-MMU data access
         {
             int reg = (addr >> 3) & 0x3f;
@@ -1707,8 +1797,6 @@
     case 0x76: // E-cache tag
     case 0x7e: // E-cache tag
         break;
-    case 0x59: // D-MMU 8k TSB pointer
-    case 0x5a: // D-MMU 64k TSB pointer
     case 0x5b: // D-MMU data pointer
     case 0x48: // Interrupt dispatch, RO
     case 0x49: // Interrupt data receive

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2009-04-27 16:51 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-04-23 22:56 [Qemu-devel] [PATCH] sparc64 support TSB related MMU registers Igor Kovalenko
2009-04-24 17:42 ` Blue Swirl
     [not found]   ` <b2fa41d60904242246x6b1b7177ifb973c41a3c051fb@mail.gmail.com>
     [not found]     ` <f43fc5580904242358k74df8bf9lc0b72c92e58a38bf@mail.gmail.com>
     [not found]       ` <b2fa41d60904250010m52db6db4id08b5729276faf62@mail.gmail.com>
     [not found]         ` <b2fa41d60904250714m3eb68cfay45ed84ff78892855@mail.gmail.com>
2009-04-25 14:17           ` Igor Kovalenko
2009-04-25 15:27             ` Blue Swirl
2009-04-26 19:24   ` Igor Kovalenko
2009-04-27 16:51     ` Blue Swirl

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).