qemu-ppc
[Top][All Lists]
Advanced

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

Re: [Qemu-ppc] Booting AIX on qemu-system-ppc, kernel not started succes


From: Alexander Graf
Subject: Re: [Qemu-ppc] Booting AIX on qemu-system-ppc, kernel not started successfully
Date: Fri, 24 Feb 2012 15:05:23 +0100

On 24.02.2012, at 14:46, Liang Guo wrote:

> On Fri, Feb 24, 2012 at 2:00 AM, Alexander Graf <address@hidden> wrote:
>> Ugh. Now you did exactly what you shouldn't do. You posted a >300kb file on
>> a mailing list :(. That's why I pointed you to pastebin earlier.... Please
>> don't post such a large attachment to mailing lists.
> Sorry,  I will not send large attached to maillist, thanks for you mention.
> 
>> 
>> With the following patch to current upstream SLOF (on github) you can check
>> for missing device tree entries:
>> 
>> diff --git a/slof/fs/client.fs b/slof/fs/client.fs
>> index 7ffd506..610a4c1 100644
>> --- a/slof/fs/client.fs
>> +++ b/slof/fs/client.fs
>> @@ -13,7 +13,7 @@
>> 
>>  \ Client interface.
>> 
>> -0 VALUE debug-client-interface?
>> +1 VALUE debug-client-interface?
>> 
>>  \ First, the machinery.
>> 
>> @@ -125,7 +125,11 @@ ALSO client-voc DEFINITIONS
>>  ;
>> 
>>  : getprop ( phandle zstr buf len -- len' )
>> ->r>r zcount rot get-property
>> +>r>r zcount
>> +   debug-client-interface? IF
>> +      ." ci: getprop " 2dup type cr
>> +   THEN
>> +  rot get-property
>>   0= IF r>  swap dup r>  min swap>r move r>
>>   ELSE r>  r>  2drop -1 THEN ;
>> 
>> 
>> 
>> It's not complete though, Thomas has a more complete version in his queue.
>> 
>> With this, we were able to identify a few shortcomings in the QEMU code,
>> most notably:
>> 
>> diff --git a/hw/spapr.c b/hw/spapr.c
>> index dffb6a2..8b49576 100644
>> --- a/hw/spapr.c
>> +++ b/hw/spapr.c
>> @@ -315,9 +315,13 @@ static void *spapr_create_fdt_skel(const char
>> *cpu_model,
>>         _FDT((fdt_property_string(fdt, "device_type", "cpu")));
>> 
>>         _FDT((fdt_property_cell(fdt, "cpu-version", env->spr[SPR_PVR])));
>> -        _FDT((fdt_property_cell(fdt, "dcache-block-size",
>> +        _FDT((fdt_property_cell(fdt, "d-cache-block-size",
>>                                 env->dcache_line_size)));
>> -        _FDT((fdt_property_cell(fdt, "icache-block-size",
>> +        _FDT((fdt_property_cell(fdt, "d-cache-size",
>> +                                env->dcache_line_size)));
>> +        _FDT((fdt_property_cell(fdt, "i-cache-block-size",
>> +                                env->icache_line_size)));
>> +        _FDT((fdt_property_cell(fdt, "i-cache-size",
>>                                 env->icache_line_size)));
>>         _FDT((fdt_property_cell(fdt, "timebase-frequency", tbfreq)));
>>         _FDT((fdt_property_cell(fdt, "clock-frequency", cpufreq)));
>> diff --git a/hw/spapr_rtas.c b/hw/spapr_rtas.c
>> index c0723b3..c02962b 100644
>> --- a/hw/spapr_rtas.c
>> +++ b/hw/spapr_rtas.c
>> @@ -187,6 +187,14 @@ static void rtas_start_cpu(sPAPREnvironment *spapr,
>>     rtas_st(rets, 0, -3);
>>  }
>> 
>> +static void rtas_freeze_time_base(sPAPREnvironment *spapr,
>> +                                  uint32_t token, uint32_t nargs,
>> +                                  target_ulong args,
>> +                                  uint32_t nret, target_ulong rets)
>> +{
>> +    rtas_st(rets, 0, 0);
>> +}
>> +
>>  static struct rtas_call {
>>     const char *name;
>>     spapr_rtas_fn fn;
>> @@ -297,6 +305,7 @@ static void core_rtas_register_types(void)
>>     spapr_rtas_register("query-cpu-stopped-state",
>>                         rtas_query_cpu_stopped_state);
>>     spapr_rtas_register("start-cpu", rtas_start_cpu);
>> +    spapr_rtas_register("freeze-time-base", rtas_freeze_time_base);
>>  }
>> 
>>  type_init(core_rtas_register_types)
>> 
>> 
>> However, AIX still doesn't boot. It does however get past the point where
>> you saw it failing, looping at address 00000000003b32b0 for me now. I'm out
>> of time to look at this though, so good luck with it!
>> 
> With the patch applied, different aix version shows different behavor.

Yeah, I got things a bit further now. The real problem that was left after this 
one change was an unimplemented hcall - H_SET_SPRG0. Now AIX fails in turning 
on its MMU:

 NIP 000000000000038c   LR 00000000001f9454 CTR 0000000000000000 XER 
000000002000
 SRR0 00000000002b1090  SRR1 8000000000001032    PVR 0000000000390202 VRSAVE 000

So we're somewhere in the "SLB entry not found for data" trap. SLB looks like 
this:

(qemu) info tlb 
SLB     ESID                    VSID
0       0x0000000008000000      0x0000000002002400
21      0xf1000815b8000000      0x000000001315b400
22      0xf201800018000000      0x0001800010001500
23      0xf1000f0008000000      0x000000000f000400
24      0xf1000f2e58000000      0x000000000a2e5400

which looks very odd to me. And yes, there is no SLB entry for the ESID that 
NIP is on during the exception - which happened with MSR_IR set. I'm slightly 
confused why we're getting a data fault really.


$ ./ppc64-softmmu/qemu-system-ppc64 -M pseries -nographic -cdrom CDlatest.iso 
-m 1G  -cpu 970

Very incomplete and hacky patch follows:

diff --git a/exec.c b/exec.c
index b81677a..7edff5b 100644
--- a/exec.c
+++ b/exec.c
@@ -217,7 +217,7 @@ static MemoryRegion io_mem_watch;
 #ifdef WIN32
 static const char *logfilename = "qemu.log";
 #else
-static const char *logfilename = "/tmp/qemu.log";
+static const char *logfilename = "/dev/shm/qemu.log";
 #endif
 FILE *logfile;
 int loglevel;
@@ -2689,8 +2689,8 @@ static void *file_ram_alloc(RAMBlock *block,
     }
 
     if (kvm_enabled() && !kvm_has_sync_mmu()) {
-        fprintf(stderr, "host lacks kvm mmu notifiers, -mem-path 
unsupported\n");
-        return NULL;
+//        fprintf(stderr, "host lacks kvm mmu notifiers, -mem-path 
unsupported\n");
+//        return NULL;
     }
 
     if (asprintf(&filename, "%s/qemu_back_mem.XXXXXX", path) == -1) {
diff --git a/hw/spapr.c b/hw/spapr.c
index dffb6a2..a96fe4c 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -315,13 +315,24 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
         _FDT((fdt_property_string(fdt, "device_type", "cpu")));
 
         _FDT((fdt_property_cell(fdt, "cpu-version", env->spr[SPR_PVR])));
-        _FDT((fdt_property_cell(fdt, "dcache-block-size",
+        _FDT((fdt_property_cell(fdt, "d-cache-block-size",
                                 env->dcache_line_size)));
-        _FDT((fdt_property_cell(fdt, "icache-block-size",
+        _FDT((fdt_property_cell(fdt, "d-cache-line-size",
+                                env->dcache_line_size)));
+        _FDT((fdt_property_cell(fdt, "d-cache-size", 0x8000)));
+        _FDT((fdt_property_cell(fdt, "i-cache-block-size",
+                                env->icache_line_size)));
+        _FDT((fdt_property_cell(fdt, "i-cache-line-size",
                                 env->icache_line_size)));
+        _FDT((fdt_property_cell(fdt, "i-cache-size", 0x10000)));
+        _FDT((fdt_property_cell(fdt, "l2-cache", 0x2000)));
+        _FDT((fdt_property_cell(fdt, "reservation-granule-size", 0x80)));
+        _FDT((fdt_property_cell(fdt, "tlb-size", 0x400)));
+        _FDT((fdt_property_cell(fdt, "tlb-sets", 0x100)));
         _FDT((fdt_property_cell(fdt, "timebase-frequency", tbfreq)));
         _FDT((fdt_property_cell(fdt, "clock-frequency", cpufreq)));
         _FDT((fdt_property_cell(fdt, "ibm,slb-size", env->slb_nr)));
+        _FDT((fdt_property_cell(fdt, "slb-size", env->slb_nr)));
         _FDT((fdt_property(fdt, "ibm,pft-size",
                            pft_size_prop, sizeof(pft_size_prop))));
         _FDT((fdt_property_string(fdt, "status", "okay")));
diff --git a/hw/spapr_hcall.c b/hw/spapr_hcall.c
index 6ac7384..ab4dc5b 100644
--- a/hw/spapr_hcall.c
+++ b/hw/spapr_hcall.c
@@ -174,6 +174,31 @@ static target_ulong h_enter(CPUState *env, 
sPAPREnvironment *spapr,
     return H_SUCCESS;
 }
 
+static target_ulong h_read(CPUState *env, sPAPREnvironment *spapr,
+                            target_ulong opcode, target_ulong *args)
+{
+    target_ulong flags = args[0];
+    target_ulong pte_index = args[1];
+    int i, n = 2;
+    uint8_t *hpte;
+
+    if (flags & H_READ_4) {
+        pte_index &= ~0x3UL;
+        n = 8;
+    }
+
+    if ((pte_index * HASH_PTE_SIZE_64) & ~env->htab_mask) {
+        return H_PARAMETER;
+    }
+
+    hpte = env->external_htab + (pte_index * HASH_PTE_SIZE_64);
+    for(i = 0; i < n; i++) {
+        args[i] = ldq_p(hpte + (i * 8));
+    }
+
+    return H_SUCCESS;
+}
+
 enum {
     REMOVE_SUCCESS = 0,
     REMOVE_NOT_FOUND = 1,
@@ -356,6 +381,15 @@ static target_ulong h_protect(CPUState *env, 
sPAPREnvironment *spapr,
     return H_SUCCESS;
 }
 
+static target_ulong h_set_sprg0(CPUState *env, sPAPREnvironment *spapr,
+                                target_ulong opcode, target_ulong *args)
+{
+    // XXX kvm sync
+    //cpu_synchronize_state(env);
+    env->spr[SPR_SPRG0] = args[0];
+    return H_SUCCESS;
+}
+
 static target_ulong h_set_dabr(CPUState *env, sPAPREnvironment *spapr,
                                target_ulong opcode, target_ulong *args)
 {
@@ -363,6 +397,34 @@ static target_ulong h_set_dabr(CPUState *env, 
sPAPREnvironment *spapr,
     return H_HARDWARE;
 }
 
+static target_ulong h_page_init(CPUState *env, sPAPREnvironment *spapr,
+                               target_ulong opcode, target_ulong *args)
+{
+    target_ulong flags = args[0];
+    target_ulong dest = args[1];
+    target_ulong source = args[2];
+    int i;
+
+    if (flags & ~(H_ZERO_PAGE | H_COPY_PAGE)) {
+        fprintf(stderr, "PAPR: page init with unknown flags: %x\n", 
(int)flags);
+    }
+
+    if (source & ~TARGET_PAGE_MASK) {
+        return H_PARAMETER;
+    }
+
+    for (i = 0; i < TARGET_PAGE_SIZE; i += 8) {
+        if (flags & H_COPY_PAGE) {
+            /* copy mode */
+            stq_phys(dest + i, ldq_phys(source + i));
+        } else if (flags & H_ZERO_PAGE) {
+            stq_phys(dest + i, 0);
+        }
+    }
+
+    return H_SUCCESS;
+}
+
 #define FLAGS_REGISTER_VPA         0x0000200000000000ULL
 #define FLAGS_REGISTER_DTL         0x0000400000000000ULL
 #define FLAGS_REGISTER_SLBSHADOW   0x0000600000000000ULL
@@ -669,6 +731,7 @@ target_ulong spapr_hypercall(CPUState *env, target_ulong 
opcode,
     }
 
     hcall_dprintf("Unimplemented hcall 0x" TARGET_FMT_lx "\n", opcode);
+printf("Unimplemented hcall 0x" TARGET_FMT_lx "\n", opcode);
     return H_FUNCTION;
 }
 
@@ -676,15 +739,22 @@ static void hypercall_register_types(void)
 {
     /* hcall-pft */
     spapr_register_hypercall(H_ENTER, h_enter);
+    spapr_register_hypercall(H_READ, h_read);
     spapr_register_hypercall(H_REMOVE, h_remove);
     spapr_register_hypercall(H_PROTECT, h_protect);
 
     /* hcall-bulk */
     spapr_register_hypercall(H_BULK_REMOVE, h_bulk_remove);
 
+    /* hcall-sprg0 */
+    spapr_register_hypercall(H_SET_SPRG0, h_set_sprg0);
+
     /* hcall-dabr */
     spapr_register_hypercall(H_SET_DABR, h_set_dabr);
 
+    /* hcall-page-init */
+    spapr_register_hypercall(H_PAGE_INIT, h_page_init);
+
     /* hcall-splpar */
     spapr_register_hypercall(H_REGISTER_VPA, h_register_vpa);
     spapr_register_hypercall(H_CEDE, h_cede);
diff --git a/hw/spapr_rtas.c b/hw/spapr_rtas.c
index c0723b3..7122be3 100644
--- a/hw/spapr_rtas.c
+++ b/hw/spapr_rtas.c
@@ -187,6 +187,14 @@ static void rtas_start_cpu(sPAPREnvironment *spapr,
     rtas_st(rets, 0, -3);
 }
 
+static void rtas_nop_ok(sPAPREnvironment *spapr,
+                        uint32_t token, uint32_t nargs,
+                        target_ulong args,
+                        uint32_t nret, target_ulong rets)
+{
+    rtas_st(rets, 0, 0);
+}
+
 static struct rtas_call {
     const char *name;
     spapr_rtas_fn fn;
@@ -218,6 +226,7 @@ target_ulong spapr_rtas_call(sPAPREnvironment *spapr,
     }
 
     hcall_dprintf("Unknown RTAS token 0x%x\n", token);
+printf("Unknown RTAS token 0x%x\n", token);
     rtas_st(rets, 0, -3);
     return H_PARAMETER;
 }
@@ -297,6 +306,34 @@ static void core_rtas_register_types(void)
     spapr_rtas_register("query-cpu-stopped-state",
                         rtas_query_cpu_stopped_state);
     spapr_rtas_register("start-cpu", rtas_start_cpu);
+
+    spapr_rtas_register("assume-power-management", rtas_nop_ok);
+    spapr_rtas_register("cache-control", rtas_nop_ok);
+    spapr_rtas_register("check-exception", rtas_nop_ok);
+    spapr_rtas_register("event-scan", rtas_nop_ok);
+    spapr_rtas_register("exti2c", rtas_nop_ok);
+    spapr_rtas_register("freeze-time-base", rtas_nop_ok);
+    spapr_rtas_register("get-power-level", rtas_nop_ok);
+    spapr_rtas_register("get-sensor-state", rtas_nop_ok);
+    spapr_rtas_register("hibernate", rtas_nop_ok);
+    spapr_rtas_register("last-error", rtas_nop_ok);
+    spapr_rtas_register("nvram-fetch", rtas_nop_ok);
+    spapr_rtas_register("nvram-store", rtas_nop_ok);
+    spapr_rtas_register("os-term", rtas_nop_ok);
+    spapr_rtas_register("read-pci-config", rtas_nop_ok);
+    spapr_rtas_register("reboot", rtas_nop_ok);
+    spapr_rtas_register("refresh-firmware-parameters", rtas_nop_ok);
+    spapr_rtas_register("relinquish-power-management", rtas_nop_ok);
+    spapr_rtas_register("restart-rtas", rtas_nop_ok);
+    spapr_rtas_register("set-indicator", rtas_nop_ok);
+    spapr_rtas_register("set-power-level", rtas_nop_ok);
+    spapr_rtas_register("set-time-for-power-on", rtas_nop_ok);
+    spapr_rtas_register("set-time-of-day", rtas_nop_ok);
+    spapr_rtas_register("stop-self", rtas_nop_ok);
+    spapr_rtas_register("suspend", rtas_nop_ok);
+    spapr_rtas_register("thaw-time-base", rtas_nop_ok);
+    spapr_rtas_register("update-flash", rtas_nop_ok);
+    spapr_rtas_register("write-pci-config", rtas_nop_ok);
 }
 
 type_init(core_rtas_register_types)
diff --git a/pc-bios/slof.bin b/pc-bios/slof.bin
index 8554f54..0a0b7c6 100644
Binary files a/pc-bios/slof.bin and b/pc-bios/slof.bin differ
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index ac753f3..2ee05c4 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1310,6 +1310,7 @@ static inline void cpu_clone_regs(CPUState *env, 
target_ulong newsp)
 #define SPR_MPC_CMPH          (0x09B)
 #define SPR_MPC_LCTRL1        (0x09C)
 #define SPR_MPC_LCTRL2        (0x09D)
+#define SPR_UAMOR             (0x09D)
 #define SPR_MPC_ICTRL         (0x09E)
 #define SPR_MPC_BAR           (0x09F)
 #define SPR_VRSAVE            (0x100)
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 6253076..049c4e9 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -6247,6 +6247,46 @@ static void init_proc_970 (CPUPPCState *env)
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
                  0x00000000);
+    /* XXX : not implemented */
+    spr_register(env, SPR_AMR, "AMR",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    /* XXX : not implemented */
+    spr_register(env, SPR_ASR, "ASR",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    /* XXX : not implemented */
+    spr_register(env, SPR_CTRL, "CTRL",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    /* XXX : not implemented */
+    spr_register(env, SPR_UCTRL, "UCTRL",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    /* XXX : not implemented */
+    spr_register(env, SPR_USPRG0, "USPRG0",
+                 &spr_read_generic, &spr_write_generic,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    /* XXX : not implemented */
+    spr_register(env, SPR_USPRG1, "USPRG1",
+                 &spr_read_generic, &spr_write_generic,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    /* XXX : not implemented */
+    spr_register(env, SPR_USPRG2, "USPRG2",
+                 &spr_read_generic, &spr_write_generic,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    /* XXX : not implemented */
+    spr_register(env, SPR_USPRG3, "USPRG3",
+                 &spr_read_generic, &spr_write_generic,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
     /* Memory management */
     /* XXX: not correct */
     gen_low_BATs(env);




reply via email to

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