* [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* Re: [Qemu-devel] [PATCH] sparc64 support TSB related MMU registers
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>
2009-04-26 19:24 ` Igor Kovalenko
0 siblings, 2 replies; 6+ messages in thread
From: Blue Swirl @ 2009-04-24 17:42 UTC (permalink / raw)
To: Igor Kovalenko; +Cc: qemu-devel
On 4/24/09, Igor Kovalenko <igor.v.kovalenko@gmail.com> wrote:
> 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.
Nice, though I didn't notice any visible improvement in my tests.
About the patch, there are a few problems:
- it breaks Sparc32
- commented out code is ugly
- if and else should be on the same line as '{' or '}'
- long lines should be wrapped
- in the line:
+ return (((tag_access_register & 0x1fff)<<48)|(tag_access_register >> 22));
there should be white space between ) and << and 48.
> (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)
Similar very obscure problem was fixed with PPC (r481), the bug was
with the PCI nodes.
^ permalink raw reply [flat|nested] 6+ messages in thread[parent not found: <b2fa41d60904242246x6b1b7177ifb973c41a3c051fb@mail.gmail.com>]
* Re: [Qemu-devel] [PATCH] sparc64 support TSB related MMU registers
2009-04-24 17:42 ` Blue Swirl
[not found] ` <b2fa41d60904242246x6b1b7177ifb973c41a3c051fb@mail.gmail.com>
@ 2009-04-26 19:24 ` Igor Kovalenko
2009-04-27 16:51 ` Blue Swirl
1 sibling, 1 reply; 6+ messages in thread
From: Igor Kovalenko @ 2009-04-26 19:24 UTC (permalink / raw)
To: Blue Swirl; +Cc: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 1699 bytes --]
On Fri, Apr 24, 2009 at 9:42 PM, Blue Swirl <blauwirbel@gmail.com> wrote:
> On 4/24/09, Igor Kovalenko <igor.v.kovalenko@gmail.com> wrote:
>> 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.
>
> Nice, though I didn't notice any visible improvement in my tests.
Here is the missing part in qemu-sparc64-mmu-pagesize.patch
This fixes TLB match code to respect page size, otherwise 4M page
mappings may be not found.
Also this corrects a typo in get_physical_address_code which uses a
register from DMMU instead of IMMU.
Please apply.
get_physical_address_data/code probably needs some code reuse refactoring.
>> (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)
>
> Similar very obscure problem was fixed with PPC (r481), the bug was
> with the PCI nodes.
Here (r484) on sparc64 it hangs in the same place.
--
Kind regards,
Igor V. Kovalenko
[-- Attachment #2: qemu-sparc64-mmu-pagesize.patch --]
[-- Type: application/octet-stream, Size: 2329 bytes --]
Index: qemu-trunk/target-sparc/helper.c
===================================================================
--- qemu-trunk.orig/target-sparc/helper.c
+++ qemu-trunk/target-sparc/helper.c
@@ -404,7 +404,7 @@ static int get_physical_address_data(CPU
}
// ctx match, vaddr match, valid?
if (env->dmmuregs[1] == (env->dtlb_tag[i] & 0x1fff) &&
- (address & mask) == (env->dtlb_tag[i] & ~0x1fffULL) &&
+ (address & mask) == (env->dtlb_tag[i] & mask) &&
(env->dtlb_tte[i] & 0x8000000000000000ULL)) {
// access ok?
if (((env->dtlb_tte[i] & 0x4) && is_user) ||
@@ -420,8 +420,8 @@ static int get_physical_address_data(CPU
#endif
return 1;
}
- *physical = (env->dtlb_tte[i] & mask & 0x1fffffff000ULL) +
- (address & ~mask & 0x1fffffff000ULL);
+ *physical = ((env->dtlb_tte[i] & mask) | (address & ~mask)) &
+ 0x1ffffffe000ULL;
*prot = PAGE_READ;
if (env->dtlb_tte[i] & 0x2)
*prot |= PAGE_WRITE;
@@ -467,7 +467,7 @@ static int get_physical_address_code(CPU
}
// ctx match, vaddr match, valid?
if (env->dmmuregs[1] == (env->itlb_tag[i] & 0x1fff) &&
- (address & mask) == (env->itlb_tag[i] & ~0x1fffULL) &&
+ (address & mask) == (env->itlb_tag[i] & mask) &&
(env->itlb_tte[i] & 0x8000000000000000ULL)) {
// access ok?
if ((env->itlb_tte[i] & 0x4) && is_user) {
@@ -481,8 +481,8 @@ static int get_physical_address_code(CPU
#endif
return 1;
}
- *physical = (env->itlb_tte[i] & mask & 0x1fffffff000ULL) +
- (address & ~mask & 0x1fffffff000ULL);
+ *physical = ((env->itlb_tte[i] & mask) | (address & ~mask)) &
+ 0x1ffffffe000ULL;
*prot = PAGE_EXEC;
return 0;
}
@@ -490,7 +490,7 @@ static int get_physical_address_code(CPU
#ifdef DEBUG_MMU
printf("TMISS at 0x%" PRIx64 "\n", address);
#endif
- env->immuregs[6] = (address & ~0x1fffULL) | (env->dmmuregs[1] & 0x1fff);
+ env->immuregs[6] = (address & ~0x1fffULL) | (env->immuregs[1] & 0x1fff);
env->exception_index = TT_TMISS;
return 1;
}
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [Qemu-devel] [PATCH] sparc64 support TSB related MMU registers
2009-04-26 19:24 ` Igor Kovalenko
@ 2009-04-27 16:51 ` Blue Swirl
0 siblings, 0 replies; 6+ messages in thread
From: Blue Swirl @ 2009-04-27 16:51 UTC (permalink / raw)
To: Igor Kovalenko; +Cc: qemu-devel
On 4/26/09, Igor Kovalenko <igor.v.kovalenko@gmail.com> wrote:
> On Fri, Apr 24, 2009 at 9:42 PM, Blue Swirl <blauwirbel@gmail.com> wrote:
>
> > On 4/24/09, Igor Kovalenko <igor.v.kovalenko@gmail.com> wrote:
> >> 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.
> >
> > Nice, though I didn't notice any visible improvement in my tests.
>
>
> Here is the missing part in qemu-sparc64-mmu-pagesize.patch
> This fixes TLB match code to respect page size, otherwise 4M page
> mappings may be not found.
> Also this corrects a typo in get_physical_address_code which uses a
> register from DMMU instead of IMMU.
>
> Please apply.
Looks OK. Please resubmit with only the commit changelog material and
a Sign-off. I'm still learning git (with qgit), I don't know how to
trim the commit message yet. Or maybe that is not the "git way"?
> get_physical_address_data/code probably needs some code reuse refactoring.
True.
^ 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).