qemu-ppc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-ppc] Qemu pSeries AIX ADB boot


From: Michael Sabino
Subject: Re: [Qemu-ppc] Qemu pSeries AIX ADB boot
Date: Wed, 13 Jun 2012 15:52:05 -0500

The below applies to booting with -M pseries and -cpu POWER7.
I found something unusual about qemu behavior on x64 vs. i386 hosts. Qemu with the exception handling code disabled appears to behave differently on different host archs. I mentioned where I got before with exception handling code disabled, which was some obscure low level function vm_disclaim_com(), which is something invoked from 0x95BE5C in main() of the AIX kernel code... now the exception handling is different, so I am at:

KDB(0)> f
pvthread+000500 STACK:
[00738680]logwrite+000040 (FFFFF00000000000, 0000000000000002,
   0000000000000028, 0000000000100000, FFFFF00000002000, 0000000000002000 [??])
[00738EB8]loginit+000518 (??)
[0073A6EC]logopen+00020C (??, ??, ??)
[0073F200]pmount+000C40 (??, ??, ??)
[007F9808]jfs_rootinit+000208 ()
[007C84E0]vfsinit+000100 ()
[007C8330]lfsinit+0001B0 ()
[0095BE5C]main+00015C ()
[00459438].start1+0000B8 ()

It appears to be trying to mount the CD-ROM as a JFS root.


compare this with the function above main in the i386 version of qemu:
[003627F8]etrc_init+000178 ()

which is located much earlier.

The relevant portion of the log, showing the opcodes on a 64-bit host that result in a program exception. Some of these might be chained together though
---------
Starting kernel
h_get_ppp might not be right yet

Opcode: 7ca01fa7

Opcode: 7ce10124

Opcode: 7c010124

Opcode: 7d810124

Opcode: 7ce10124

Opcode: 7d810124

Opcode: 7c2003e4

Opcode: e0c30000

Opcode: e0c30000

Opcode: e0c30000
SLB shadow: 0x2624800
Opcode: 7c601fa7

Opcode: 7d810124
LED{814}
LED{A20}
Data Storage Interrupt - PROC
.logwrite+000040        sth    r5,FFE(r7)          r5=0000000000000028,FFE(r7)=FFFFF00000002FFE
---------
In addition to these exception-related architectural differences, there seems to be several errors in ./hw/spapr_hcall.c where %llu is used for printing a long long int, which doesn't compile, since it referencing a variable of type target_ulong (Architecture-dependent). Not sure what the best way is to fix this.


So far I've made the following changes to spapr_hcall.c for a 64-bit architecture.
----------------------------------
--- ../base/agraf/hw/spapr_hcall.c 2012-06-06 11:13:42.000000000 -0500
+++ ../alternate/agraf/hw/spapr_hcall.c 2012-06-13 15:34:01.905089409 -0500
@@ -428,11 +428,11 @@
     }
 
     if ((flags & H_COPY_PAGE) && (source & ~TARGET_PAGE_MASK)) {
-        fprintf(stderr, "PAPR: page init with unaligned source: %llx\n", source);
+        fprintf(stderr, "PAPR: page init with unaligned source: %lx\n", source);
         return H_PARAMETER;
     }
     if (dest & ~TARGET_PAGE_MASK) {
-        fprintf(stderr, "PAPR: page init with unaligned dest: %llx\n", dest);
+        fprintf(stderr, "PAPR: page init with unaligned dest: %lx\n", dest);
         return H_PARAMETER;
     }
 
@@ -512,7 +512,7 @@
 {
     uint32_t size;
 
-printf("SLB shadow: 0x%llx", addr);
+printf("SLB shadow: 0x%lx", addr);
     if (addr == 0) {
         hcall_dprintf("Can't cope with SLB shadow at logical 0\n");
         return H_HARDWARE;
@@ -711,10 +711,33 @@
                               target_ulong opcode, target_ulong *args)
 {
     printf("\nh_get_ppp might not be right yet\n");
-    env->gpr[4] = 100;
-    env->gpr[5] = 10;
-    env->gpr[6] = 0xffff;
-    env->gpr[7] = 0x1;
+    env->gpr[4] = 100; // Processor capacity percentage
+    env->gpr[5] = 0; // Unallocated processor capacity percentage
+
+    int group_num  = 1; // Group number
+    int pool_num = 1; // Pool number
+
+    target_ulong r6_bitmask = ((group_num & 0xffff) << 2*8) + ((pool_num & 0xffff)); // bitmask for r6
+    env->gpr[6] = r6_bitmask;
+
+    bool capped = 1; // Capped
+    int weight = 128; // Capacity weight
+    int unallocated_weight = 0; // // Unallocated Variable Processor Capacity Weight
+    int active_procs_in_pool = 1; // Active processors in Physical Processor Pool
+    int active_system_procs = 1; // Processors active on platform
+
+    target_ulong r7_bitmask1 = (((target_ulong)capped & 0x01) << 6*8) + (((target_ulong)weight & 0xff) << 5*8) + (((target_ulong)unallocated_weight & 0xff) << 4*8);
+    target_ulong r7_bitmask2 = ((active_procs_in_pool & 0xffff) << 2*8) + (active_system_procs & (0xffff));
+    env->gpr[7] = r7_bitmask2 + r7_bitmask1;
+
+    int phys_platform_procs = 1; // Physical platform procs allocated to virtualization
+    int max_proc_cap_avail = 100; // Max procs capacity % available to the partitions pool.
+    int entitled_proc_cap_avail = 100; // Entitled procs capacity % available to the partitions pool
+
+    target_ulong r8_bitmask1 = ((target_ulong)phys_platform_procs << 6*8);
+    target_ulong r8_bitmask2 =  ((max_proc_cap_avail & 0xffffff) << 3*8) + ((entitled_proc_cap_avail & 0xffffff));
+
+    env->gpr[8] = r8_bitmask1 + r8_bitmask2;
     return H_SUCCESS;
 }


address@hidden:~/base$ diff -Naur ../base/agraf/target-ppc/translate.c ../alternate/agraf/target-ppc/translate.c
--- ../base/agraf/target-ppc/translate.c 2012-06-06 11:13:42.000000000 -0500
+++ ../alternate/agraf/target-ppc/translate.c 2012-06-13 15:39:59.601168003 -0500
@@ -309,7 +309,9 @@
 
 static inline void gen_inval_exception(DisasContext *ctx, uint32_t error)
 {
-    gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL | error);
+      printf("\nOpcode before exception: %x\n", ctx->opcode);
+//      gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL | error);
+
 }
 
 /* Stop translation */

-------------------------------
address@hidden:~/base$ vim ../alternate/agraf/target-ppc/address@hidden:~/base$ diff -Naur ../base/agraf/target-ppc/translate_init.c ../alternate/agraf/target-ppc/translate_init.c
--- ../base/agraf/target-ppc/translate_init.c 2012-06-06 11:13:42.000000000 -0500
+++ ../alternate/agraf/target-ppc/translate_init.c 2012-06-13 15:41:59.175759849 -0500
@@ -6639,6 +6639,71 @@
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
                  0x00000000);
+
+    spr_register(env, 280, "NEW1",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, 1023, "NEW2",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, 795, "NEW3",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, 798, "NEW4",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, 787, "NEW5",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, 788, "NEW6",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, 789, "NEW7",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, 790, "NEW8",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, 791, "NEW9",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, 792, "NEW10",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, 793, "NEW11",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, 794, "NEW12",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, 780, "NEW13",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, 781, "NEW14",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, 786, "NEW15",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, 799, "NEW16",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
     /* Memory management */
     /* XXX: not correct */
     gen_low_BATs(env);
@@ -6721,6 +6786,72 @@
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
                  0x00000000);
+    spr_register(env, 280, "NEW1", 
+ SPR_NOACCESS, SPR_NOACCESS, 
+ &spr_read_generic, &spr_write_generic, 
+ 0x00000000);
+    spr_register(env, 157, "NEW2", 
+ SPR_NOACCESS, SPR_NOACCESS, 
+ &spr_read_generic, &spr_write_generic, 
+ 0x00000000);
+    spr_register(env, 31, "NEW3", 
+ SPR_NOACCESS, SPR_NOACCESS, 
+ &spr_read_generic, &spr_write_generic, 
+ 0x00000000);
+    spr_register(env, 48, "NEW4", 
+ SPR_NOACCESS, SPR_NOACCESS, 
+ &spr_read_generic, &spr_write_generic, 
+ 0x00000000);
+    spr_register(env, 795, "NEW5", 
+ SPR_NOACCESS, SPR_NOACCESS, 
+ &spr_read_generic, &spr_write_generic, 
+ 0x00000000);
+    spr_register(env, 798, "NEW6", 
+ SPR_NOACCESS, SPR_NOACCESS, 
+ &spr_read_generic, &spr_write_generic, 
+ 0x00000000);
+    spr_register(env, 787, "NEW7", 
+ SPR_NOACCESS, SPR_NOACCESS, 
+ &spr_read_generic, &spr_write_generic, 
+ 0x00000000);
+    spr_register(env, 788, "NEW8", 
+ SPR_NOACCESS, SPR_NOACCESS, 
+ &spr_read_generic, &spr_write_generic, 
+ 0x00000000);
+
+    spr_register(env, 1023, "NEW9",
+                SPR_NOACCESS, SPR_NOACCESS,
+                &spr_read_generic, &spr_write_generic,
+                0x00000000);
+    spr_register(env, 789, "NEW10",
+                SPR_NOACCESS, SPR_NOACCESS,
+                &spr_read_generic, &spr_write_generic,
+                0x00000000);
+    spr_register(env, 790, "NEW11",
+                SPR_NOACCESS, SPR_NOACCESS,
+                &spr_read_generic, &spr_write_generic,
+                0x00000000);
+    spr_register(env, 791, "NEW12",
+                SPR_NOACCESS, SPR_NOACCESS,
+                &spr_read_generic, &spr_write_generic,
+                0x00000000);
+    spr_register(env, 792, "NEW13",
+                SPR_NOACCESS, SPR_NOACCESS,
+                &spr_read_generic, &spr_write_generic,
+                0x00000000);
+    spr_register(env, 780, "NEW14",
+                SPR_NOACCESS, SPR_NOACCESS,
+                &spr_read_generic, &spr_write_generic,
+                0x00000000);
+    spr_register(env, 781, "NEW15",
+                SPR_NOACCESS, SPR_NOACCESS,
+                &spr_read_generic, &spr_write_generic,
+                0x00000000);
+    spr_register(env, 786, "NEW16",
+                SPR_NOACCESS, SPR_NOACCESS,
+                &spr_read_generic, &spr_write_generic,
+                0x00000000);
+
 #endif /* !CONFIG_USER_ONLY */
     /* Memory management */
     /* XXX : not implemented */
----------------------------------------
I really have nothing substantial yet. Just a series of hacks to make AIX get to trying to write to the log. Fixing the SPR's doesn't get you any further. It's mainly disabling/changing conditions of the exception handler.

I'm thinking some of these registers... a vector instruction was mentioned... probably in the end are important to the filesystem itself.

I know that filesystems these days can use some pretty advanced data structures.


Michael Sabino


On Tue, Jun 12, 2012 at 6:13 AM, Thomas Huth <address@hidden> wrote:
Am Mon, 11 Jun 2012 14:12:32 -0500
schrieb Michael Sabino <address@hidden>:

> Actually, the POWER7 code seems to get further than the 970 in this case
> with the exception handling code disabled.
>
> As far as the code with the exception handling code enabled -
> I added the spr's, but an invalid program exception seems to be being
> generated which doesn't relate to the writing/reading invalid SPR. I'm not
> sure what it's origin is quite yet. Any ideas for figuring this out?

I just attached a GDB and ran a boot until $pc < 0x1000 (to catch the
exceptions), and it seems to me like this is the culprit:

  0x5814a4:    stxvd2x vs0,r9,r1

That's a new instruction, introduced in PowerISA 2.06, and I guess QEMU
does not emulate it yet and thus generates that invalid program
exception.

 Thomas



reply via email to

[Prev in Thread] Current Thread [Next in Thread]