qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Igor Kovalenko <igor.v.kovalenko@gmail.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH] sparc64 support TSB related MMU registers
Date: Fri, 24 Apr 2009 02:56:51 +0400	[thread overview]
Message-ID: <b2fa41d60904231556r6523ef8agc3ffd8f1691931c9@mail.gmail.com> (raw)

[-- 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

             reply	other threads:[~2009-04-23 22:57 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-04-23 22:56 Igor Kovalenko [this message]
2009-04-24 17:42 ` [Qemu-devel] [PATCH] sparc64 support TSB related MMU registers 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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=b2fa41d60904231556r6523ef8agc3ffd8f1691931c9@mail.gmail.com \
    --to=igor.v.kovalenko@gmail.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).