All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/7] PPC64 Linux bringup patches v2
@ 2009-03-05 14:14 Alexander Graf
  2009-03-05 14:14 ` [Qemu-devel] [PATCH 1/7] PPC64: Implement slbmte Alexander Graf
  0 siblings, 1 reply; 16+ messages in thread
From: Alexander Graf @ 2009-03-05 14:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: blauwirbel

After spending even more time trying to get qemu-system-ppc64 to run Linux, I
get up to the pretty penguin on the screen now ;-).

I am aware that this patchset is not 100% accurate and perfect for emulation,
but I think that it can't get worse than it is now.

This patchset enhances MMU support to work with large pages, implement tlbiel,
and fixes random issues I ran into while getting closer to the kernel running
userspace code :).

Keep in mind that this also requires an OpenBIOS update, as the current code
is not aware that it gets run in 64 bit mode.

Also, I am now stuck at a kernel panic in the pmz initialization, because the
Device Tree doesn't contain proper interrupt line propagation. I am seriously
lost there and it would be awesome if someone with more OpenFirmware knowledge
could step in here.

Alexander Graf (7):
  PPC64: Implement slbmte
  PPC64: Implement large pages
  PPC64: Implment tlbiel
  Activate uninorth AGP bridge
  PPC64: Nop some SPRs on 970fx
  PPC64: Enable 64bit mode on interrupts
  PPC64: Don't fault at lwsync

 hw/unin_pci.c               |   27 +++------
 target-ppc/cpu.h            |    4 +-
 target-ppc/helper.c         |  141 +++++++++++++++++++++++++++++--------------
 target-ppc/op_helper.c      |    6 +-
 target-ppc/translate.c      |   41 +++++++++++-
 target-ppc/translate_init.c |   12 ++++
 6 files changed, 160 insertions(+), 71 deletions(-)

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

* [Qemu-devel] [PATCH 1/7] PPC64: Implement slbmte
  2009-03-05 14:14 [Qemu-devel] [PATCH 0/7] PPC64 Linux bringup patches v2 Alexander Graf
@ 2009-03-05 14:14 ` Alexander Graf
  2009-03-05 14:14   ` [Qemu-devel] [PATCH 2/7] PPC64: Implement large pages Alexander Graf
  0 siblings, 1 reply; 16+ messages in thread
From: Alexander Graf @ 2009-03-05 14:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: blauwirbel, Alexander Graf

In order to modify SLB entries on recent PPC64 machines, the slbmte
instruction is used.

This patch implements the slbmte instruction and makes the "bridge"
mode code use the slb set functions, so we can move the SLB into
the CPU struct later.

This is required for Linux to run on PPC64.

Signed-off-by: Alexander Graf <alex@csgraf.de>
---
 target-ppc/cpu.h       |    3 +-
 target-ppc/helper.c    |   57 ++++++++++++++++++++++++++++++++++++-----------
 target-ppc/op_helper.c |    6 +++-
 target-ppc/translate.c |   23 ++++++++++++++++---
 4 files changed, 68 insertions(+), 21 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index bdc3cf9..f53be5a 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -714,7 +714,8 @@ void ppc_store_sdr1 (CPUPPCState *env, target_ulong value);
 #if defined(TARGET_PPC64)
 void ppc_store_asr (CPUPPCState *env, target_ulong value);
 target_ulong ppc_load_slb (CPUPPCState *env, int slb_nr);
-void ppc_store_slb (CPUPPCState *env, int slb_nr, target_ulong rs);
+target_ulong ppc_load_sr (CPUPPCState *env, int sr_nr);
+void ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs);
 #endif /* defined(TARGET_PPC64) */
 void ppc_store_sr (CPUPPCState *env, int srnum, target_ulong value);
 #endif /* !defined(CONFIG_USER_ONLY) */
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index e02dcb0..9461daf 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -821,27 +821,34 @@ target_ulong ppc_load_slb (CPUPPCState *env, int slb_nr)
     return rt;
 }
 
-void ppc_store_slb (CPUPPCState *env, int slb_nr, target_ulong rs)
+void ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs)
 {
     target_phys_addr_t sr_base;
     uint64_t tmp64;
     uint32_t tmp;
 
+    uint64_t vsid;
+    uint64_t esid;
+    int flags, valid, slb_nr;
+
+    vsid = rs >> 12;
+    flags = ((rs >> 8) & 0xf);
+
+    esid = rb >> 28;
+    valid = (rb & (1 << 27));
+    slb_nr = rb & 0xfff;
+
+    tmp64 = (esid << 28) | valid | (vsid >> 24);
+    tmp = (vsid << 8) | (flags << 3);
+
+    /* Write SLB entry to memory */
     sr_base = env->spr[SPR_ASR];
     sr_base += 12 * slb_nr;
-    /* Copy Rs bits 37:63 to SLB 62:88 */
-    tmp = rs << 8;
-    tmp64 = (rs >> 24) & 0x7;
-    /* Copy Rs bits 33:36 to SLB 89:92 */
-    tmp |= ((rs >> 27) & 0xF) << 4;
-    /* Set the valid bit */
-    tmp64 |= 1 << 27;
-    /* Set ESID */
-    tmp64 |= (uint32_t)slb_nr << 28;
-    LOG_SLB("%s: %d " ADDRX " => " PADDRX " %016" PRIx64
+
+    LOG_SLB("%s: %d " ADDRX " - " ADDRX " => " PADDRX " %016" PRIx64
                 " %08" PRIx32 "\n", __func__,
-                slb_nr, rs, sr_base, tmp64, tmp);
-    /* Write SLB entry to memory */
+                slb_nr, rb, rs, sr_base, tmp64, tmp);
+
     stq_phys(sr_base, tmp64);
     stl_phys(sr_base + 8, tmp);
 }
@@ -1945,11 +1952,33 @@ void ppc_store_sdr1 (CPUPPCState *env, target_ulong value)
     }
 }
 
+target_ulong ppc_load_sr (CPUPPCState *env, int slb_nr)
+{
+    // XXX
+    return 0;
+}
+
 void ppc_store_sr (CPUPPCState *env, int srnum, target_ulong value)
 {
     LOG_MMU("%s: reg=%d " ADDRX " " ADDRX "\n",
                 __func__, srnum, value, env->sr[srnum]);
-    if (env->sr[srnum] != value) {
+    if (env->mmu_model & POWERPC_MMU_64) {
+        uint64_t rb = 0, rs = 0;
+
+        /* ESID = srnum */
+        rb |= ((uint32_t)srnum & 0xf) << 28;
+        /* Set the valid bit */
+        rb |= 1 << 27;
+        /* Index = ESID */
+        rb |= (uint32_t)srnum;
+
+        /* VSID = VSID */
+        rs |= (value & 0xfffffff) << 12;
+        /* flags = flags */
+        rs |= ((value >> 27) & 0xf) << 9;
+
+        ppc_store_slb(env, rb, rs);
+    } else if (env->sr[srnum] != value) {
         env->sr[srnum] = value;
 #if !defined(FLUSH_ALL_TLBS) && 0
         {
diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
index 3afd217..527f8de 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/op_helper.c
@@ -3752,6 +3752,8 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 /* Segment registers load and store */
 target_ulong helper_load_sr (target_ulong sr_num)
 {
+    if (env->mmu_model & POWERPC_MMU_64)
+        return ppc_load_sr(env, sr_num);
     return env->sr[sr_num];
 }
 
@@ -3767,9 +3769,9 @@ target_ulong helper_load_slb (target_ulong slb_nr)
     return ppc_load_slb(env, slb_nr);
 }
 
-void helper_store_slb (target_ulong slb_nr, target_ulong rs)
+void helper_store_slb (target_ulong rb, target_ulong rs)
 {
-    ppc_store_slb(env, slb_nr, rs);
+    ppc_store_slb(env, rb, rs);
 }
 
 void helper_slbia (void)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 489ba09..f48ab20 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -4296,7 +4296,7 @@ GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B)
         return;
     }
     t0 = tcg_const_tl(SR(ctx->opcode));
-    gen_helper_load_slb(cpu_gpr[rD(ctx->opcode)], t0);
+    gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], t0);
     tcg_temp_free(t0);
 #endif
 }
@@ -4316,7 +4316,7 @@ GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
     t0 = tcg_temp_new();
     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
     tcg_gen_andi_tl(t0, t0, 0xF);
-    gen_helper_load_slb(cpu_gpr[rD(ctx->opcode)], t0);
+    gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], t0);
     tcg_temp_free(t0);
 #endif
 }
@@ -4333,7 +4333,7 @@ GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B)
         return;
     }
     t0 = tcg_const_tl(SR(ctx->opcode));
-    gen_helper_store_slb(t0, cpu_gpr[rS(ctx->opcode)]);
+    gen_helper_store_sr(t0, cpu_gpr[rS(ctx->opcode)]);
     tcg_temp_free(t0);
 #endif
 }
@@ -4353,10 +4353,25 @@ GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
     t0 = tcg_temp_new();
     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
     tcg_gen_andi_tl(t0, t0, 0xF);
-    gen_helper_store_slb(t0, cpu_gpr[rS(ctx->opcode)]);
+    gen_helper_store_sr(t0, cpu_gpr[rS(ctx->opcode)]);
     tcg_temp_free(t0);
 #endif
 }
+
+/* slbmte */
+GEN_HANDLER2(slbmte, "slbmte", 0x1F, 0x12, 0x0C, 0x00000000, PPC_SEGMENT_64B)
+{
+#if defined(CONFIG_USER_ONLY)
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+#else
+    if (unlikely(!ctx->mem_idx)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+        return;
+    }
+    gen_helper_store_slb(cpu_gpr[rB(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
+#endif
+}
+
 #endif /* defined(TARGET_PPC64) */
 
 /***                      Lookaside buffer management                      ***/
-- 
1.6.0.2

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

* [Qemu-devel] [PATCH 2/7] PPC64: Implement large pages
  2009-03-05 14:14 ` [Qemu-devel] [PATCH 1/7] PPC64: Implement slbmte Alexander Graf
@ 2009-03-05 14:14   ` Alexander Graf
  2009-03-05 14:14     ` [Qemu-devel] [PATCH 3/7] PPC64: Implment tlbiel Alexander Graf
  0 siblings, 1 reply; 16+ messages in thread
From: Alexander Graf @ 2009-03-05 14:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: blauwirbel, Alexander Graf

The current SLB/PTE code does not support large pages, which are
required by Linux, as it boots up with the kernel regions up as large.

This patch implements large page support, so we can run Linux.

Signed-off-by: Alexander Graf <alex@csgraf.de>
---
 target-ppc/cpu.h    |    1 +
 target-ppc/helper.c |   78 +++++++++++++++++++++++++++++++-------------------
 2 files changed, 49 insertions(+), 30 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index f53be5a..c88f81b 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -675,6 +675,7 @@ struct CPUPPCState {
 typedef struct mmu_ctx_t mmu_ctx_t;
 struct mmu_ctx_t {
     target_phys_addr_t raddr;      /* Real address              */
+    target_phys_addr_t eaddr;      /* Effective address         */
     int prot;                      /* Protection bits           */
     target_phys_addr_t pg_addr[2]; /* PTE tables base addresses */
     target_ulong ptem;             /* Virtual segment ID | API  */
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index 9461daf..0fa87dc 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -582,7 +582,8 @@ static always_inline int get_bat (CPUState *env, mmu_ctx_t *ctx,
 
 /* PTE table lookup */
 static always_inline int _find_pte (mmu_ctx_t *ctx, int is_64b, int h,
-                                    int rw, int type)
+                                    int rw, int type,
+                                    int target_page_bits)
 {
     target_ulong base, pte0, pte1;
     int i, good = -1;
@@ -594,7 +595,14 @@ static always_inline int _find_pte (mmu_ctx_t *ctx, int is_64b, int h,
 #if defined(TARGET_PPC64)
         if (is_64b) {
             pte0 = ldq_phys(base + (i * 16));
-            pte1 =  ldq_phys(base + (i * 16) + 8);
+            pte1 = ldq_phys(base + (i * 16) + 8);
+
+            /* We have a TLB that saves 4K pages, so let's
+             * split a huge page to 4k chunks */
+            if (target_page_bits != TARGET_PAGE_BITS)
+                pte1 |= (ctx->eaddr & (( 1 << target_page_bits ) - 1))
+                        & TARGET_PAGE_MASK;
+
             r = pte64_check(ctx, pte0, pte1, h, rw, type);
             LOG_MMU("Load pte from " ADDRX " => " ADDRX " " ADDRX
                         " %d %d %d " ADDRX "\n",
@@ -658,27 +666,30 @@ static always_inline int _find_pte (mmu_ctx_t *ctx, int is_64b, int h,
     return ret;
 }
 
-static always_inline int find_pte32 (mmu_ctx_t *ctx, int h, int rw, int type)
+static always_inline int find_pte32 (mmu_ctx_t *ctx, int h, int rw,
+                                     int type, int target_page_bits)
 {
-    return _find_pte(ctx, 0, h, rw, type);
+    return _find_pte(ctx, 0, h, rw, type, target_page_bits);
 }
 
 #if defined(TARGET_PPC64)
-static always_inline int find_pte64 (mmu_ctx_t *ctx, int h, int rw, int type)
+static always_inline int find_pte64 (mmu_ctx_t *ctx, int h, int rw,
+                                     int type, int target_page_bits)
 {
-    return _find_pte(ctx, 1, h, rw, type);
+    return _find_pte(ctx, 1, h, rw, type, target_page_bits);
 }
 #endif
 
 static always_inline int find_pte (CPUState *env, mmu_ctx_t *ctx,
-                                   int h, int rw, int type)
+                                   int h, int rw, int type,
+                                   int target_page_bits)
 {
 #if defined(TARGET_PPC64)
     if (env->mmu_model & POWERPC_MMU_64)
-        return find_pte64(ctx, h, rw, type);
+        return find_pte64(ctx, h, rw, type, target_page_bits);
 #endif
 
-    return find_pte32(ctx, h, rw, type);
+    return find_pte32(ctx, h, rw, type, target_page_bits);
 }
 
 #if defined(TARGET_PPC64)
@@ -694,7 +705,8 @@ static always_inline void slb_invalidate (uint64_t *slb64)
 
 static always_inline int slb_lookup (CPUPPCState *env, target_ulong eaddr,
                                      target_ulong *vsid,
-                                     target_ulong *page_mask, int *attr)
+                                     target_ulong *page_mask, int *attr,
+                                     int *target_page_bits)
 {
     target_phys_addr_t sr_base;
     target_ulong mask;
@@ -714,19 +726,16 @@ static always_inline int slb_lookup (CPUPPCState *env, target_ulong eaddr,
                     PRIx32 "\n", __func__, n, sr_base, tmp64, tmp);
         if (slb_is_valid(tmp64)) {
             /* SLB entry is valid */
-            switch (tmp64 & 0x0000000006000000ULL) {
-            case 0x0000000000000000ULL:
-                /* 256 MB segment */
-                mask = 0xFFFFFFFFF0000000ULL;
-                break;
-            case 0x0000000002000000ULL:
-                /* 1 TB segment */
+            if (tmp & 0x8) {
+                /* 1 TB Segment */
                 mask = 0xFFFF000000000000ULL;
-                break;
-            case 0x0000000004000000ULL:
-            case 0x0000000006000000ULL:
-                /* Reserved => segment is invalid */
-                continue;
+                if (target_page_bits)
+                    *target_page_bits = 24; // XXX 16M pages?
+            } else {
+                /* 256MB Segment */
+                mask = 0xFFFFFFFFF0000000ULL;
+                if (target_page_bits)
+                    *target_page_bits = TARGET_PAGE_BITS;
             }
             if ((eaddr & mask) == (tmp64 & mask)) {
                 /* SLB match */
@@ -777,7 +786,7 @@ void ppc_slb_invalidate_one (CPUPPCState *env, uint64_t T0)
     int attr;
     int n;
 
-    n = slb_lookup(env, T0, &vsid, &page_mask, &attr);
+    n = slb_lookup(env, T0, &vsid, &page_mask, &attr, NULL);
     if (n >= 0) {
         sr_base = env->spr[SPR_ASR];
         sr_base += 12 * n;
@@ -871,20 +880,22 @@ static always_inline int get_segment (CPUState *env, mmu_ctx_t *ctx,
 #if defined(TARGET_PPC64)
     int attr;
 #endif
-    int ds, vsid_sh, sdr_sh, pr;
+    int ds, vsid_sh, sdr_sh, pr, target_page_bits;
     int ret, ret2;
 
     pr = msr_pr;
 #if defined(TARGET_PPC64)
     if (env->mmu_model & POWERPC_MMU_64) {
         LOG_MMU("Check SLBs\n");
-        ret = slb_lookup(env, eaddr, &vsid, &page_mask, &attr);
+        ret = slb_lookup(env, eaddr, &vsid, &page_mask, &attr,
+                         &target_page_bits);
         if (ret < 0)
             return ret;
         ctx->key = ((attr & 0x40) && (pr != 0)) ||
             ((attr & 0x80) && (pr == 0)) ? 1 : 0;
         ds = 0;
-        ctx->nx = attr & 0x20 ? 1 : 0;
+        ctx->nx = attr & 0x10 ? 1 : 0;
+        ctx->eaddr = eaddr;
         vsid_mask = 0x00003FFFFFFFFF80ULL;
         vsid_sh = 7;
         sdr_sh = 18;
@@ -903,6 +914,7 @@ static always_inline int get_segment (CPUState *env, mmu_ctx_t *ctx,
         vsid_sh = 6;
         sdr_sh = 16;
         sdr_mask = 0xFFC0;
+        target_page_bits = TARGET_PAGE_BITS;
         LOG_MMU("Check segment v=" ADDRX " %d " ADDRX
                     " nip=" ADDRX " lr=" ADDRX " ir=%d dr=%d pr=%d %d t=%d\n",
                     eaddr, (int)(eaddr >> 28), sr, env->nip,
@@ -918,7 +930,7 @@ static always_inline int get_segment (CPUState *env, mmu_ctx_t *ctx,
             /* Page address translation */
             /* Primary table address */
             sdr = env->sdr1;
-            pgidx = (eaddr & page_mask) >> TARGET_PAGE_BITS;
+            pgidx = (eaddr & page_mask) >> target_page_bits;
 #if defined(TARGET_PPC64)
             if (env->mmu_model & POWERPC_MMU_64) {
                 htab_mask = 0x0FFFFFFF >> (28 - (sdr & 0x1F));
@@ -944,7 +956,12 @@ static always_inline int get_segment (CPUState *env, mmu_ctx_t *ctx,
 #if defined(TARGET_PPC64)
             if (env->mmu_model & POWERPC_MMU_64) {
                 /* Only 5 bits of the page index are used in the AVPN */
-                ctx->ptem = (vsid << 12) | ((pgidx >> 4) & 0x0F80);
+                if (target_page_bits > 23) {
+                    ctx->ptem = (vsid << 12) |
+                                ((pgidx << (target_page_bits - 16)) & 0xF80);
+                } else {
+                    ctx->ptem = (vsid << 12) | ((pgidx >> 4) & 0x0F80);
+                }
             } else
 #endif
             {
@@ -962,7 +979,7 @@ static always_inline int get_segment (CPUState *env, mmu_ctx_t *ctx,
                             " pg_addr=" PADDRX "\n",
                             sdr, vsid, pgidx, hash, ctx->pg_addr[0]);
                 /* Primary table lookup */
-                ret = find_pte(env, ctx, 0, rw, type);
+                ret = find_pte(env, ctx, 0, rw, type, target_page_bits);
                 if (ret < 0) {
                     /* Secondary table lookup */
                     if (eaddr != 0xEFFFFFFF)
@@ -970,7 +987,8 @@ static always_inline int get_segment (CPUState *env, mmu_ctx_t *ctx,
                                 "api=" ADDRX " hash=" PADDRX
                                 " pg_addr=" PADDRX "\n",
                                 sdr, vsid, pgidx, hash, ctx->pg_addr[1]);
-                    ret2 = find_pte(env, ctx, 1, rw, type);
+                    ret2 = find_pte(env, ctx, 1, rw, type,
+                                    target_page_bits);
                     if (ret2 != -1)
                         ret = ret2;
                 }
-- 
1.6.0.2

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

* [Qemu-devel] [PATCH 3/7] PPC64: Implment tlbiel
  2009-03-05 14:14   ` [Qemu-devel] [PATCH 2/7] PPC64: Implement large pages Alexander Graf
@ 2009-03-05 14:14     ` Alexander Graf
  2009-03-05 14:14       ` [Qemu-devel] [PATCH 4/7] Activate uninorth AGP bridge Alexander Graf
  0 siblings, 1 reply; 16+ messages in thread
From: Alexander Graf @ 2009-03-05 14:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: blauwirbel, Alexander Graf

Linux uses tlbiel to flush TLB entries in PPC64 mode. This special TLB
flush opcode only flushes an entry for the CPU it runs on, not across
all CPUs in the system.

Signed-off-by: Alexander Graf <alex@csgraf.de>
---
 target-ppc/translate.c |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index f48ab20..b5de33b 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -4390,6 +4390,20 @@ GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA)
 #endif
 }
 
+/* tlbiel */
+GEN_HANDLER(tlbiel, 0x1F, 0x12, 0x08, 0x03FF0001, PPC_MEM_TLBIE)
+{
+#if defined(CONFIG_USER_ONLY)
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+#else
+    if (unlikely(!ctx->mem_idx)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
+    gen_helper_tlbie(cpu_gpr[rB(ctx->opcode)]);
+#endif
+}
+
 /* tlbie */
 GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE)
 {
-- 
1.6.0.2

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

* [Qemu-devel] [PATCH 4/7] Activate uninorth AGP bridge
  2009-03-05 14:14     ` [Qemu-devel] [PATCH 3/7] PPC64: Implment tlbiel Alexander Graf
@ 2009-03-05 14:14       ` Alexander Graf
  2009-03-05 14:14         ` [Qemu-devel] [PATCH 5/7] PPC64: Nop some SPRs on 970fx Alexander Graf
  0 siblings, 1 reply; 16+ messages in thread
From: Alexander Graf @ 2009-03-05 14:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: blauwirbel, Alexander Graf

Linux tries to poke the AGP bridge port and is pretty sad when it can't,
so let's activate the old code again and throw out the bit modifications,
as we don't really do anything with the values anyways.

Signed-off-by: Alexander Graf <alex@csgraf.de>
---
 hw/unin_pci.c |   27 ++++++++-------------------
 1 files changed, 8 insertions(+), 19 deletions(-)

diff --git a/hw/unin_pci.c b/hw/unin_pci.c
index 949e63f..c734f1c 100644
--- a/hw/unin_pci.c
+++ b/hw/unin_pci.c
@@ -92,17 +92,12 @@ static CPUReadMemoryFunc *pci_unin_main_read[] = {
     &pci_host_data_readl,
 };
 
-#if 0
-
 static void pci_unin_config_writel (void *opaque, target_phys_addr_t addr,
                                     uint32_t val)
 {
     UNINState *s = opaque;
 
-#ifdef TARGET_WORDS_BIGENDIAN
-    val = bswap32(val);
-#endif
-    s->config_reg = 0x80000000 | (val & ~0x00000001);
+    s->config_reg = val;
 }
 
 static uint32_t pci_unin_config_readl (void *opaque,
@@ -111,12 +106,7 @@ static uint32_t pci_unin_config_readl (void *opaque,
     UNINState *s = opaque;
     uint32_t val;
 
-    val = (s->config_reg | 0x00000001) & ~0x80000000;
-#ifdef TARGET_WORDS_BIGENDIAN
-    val = bswap32(val);
-#endif
-
-    return val;
+    return s->config_reg;
 }
 
 static CPUWriteMemoryFunc *pci_unin_config_write[] = {
@@ -131,6 +121,7 @@ static CPUReadMemoryFunc *pci_unin_config_read[] = {
     &pci_unin_config_readl,
 };
 
+#if 0
 static CPUWriteMemoryFunc *pci_unin_write[] = {
     &pci_host_pci_writeb,
     &pci_host_pci_writew,
@@ -233,18 +224,17 @@ PCIBus *pci_pmac_init(qemu_irq *pic)
     d->config[0x27] = 0x7F;
     // d->config[0x34] = 0xdc // capabilities_pointer
 #endif
-#if 0 // XXX: not needed for now
+
     /* Uninorth AGP bus */
-    s = &pci_bridge[1];
     pci_mem_config = cpu_register_io_memory(0, pci_unin_config_read,
                                             pci_unin_config_write, s);
-    pci_mem_data = cpu_register_io_memory(0, pci_unin_read,
-                                          pci_unin_write, s);
+    pci_mem_data = cpu_register_io_memory(0, pci_unin_main_read,
+                                          pci_unin_main_write, s);
     cpu_register_physical_memory(0xf0800000, 0x1000, pci_mem_config);
     cpu_register_physical_memory(0xf0c00000, 0x1000, pci_mem_data);
 
-    d = pci_register_device("Uni-north AGP", sizeof(PCIDevice), 0, 11 << 3,
-                            NULL, NULL);
+    d = pci_register_device(s->bus, "Uni-north AGP", sizeof(PCIDevice),
+                            11 << 3, NULL, NULL);
     pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_APPLE);
     pci_config_set_device_id(d->config, PCI_DEVICE_ID_APPLE_UNI_N_AGP);
     d->config[0x08] = 0x00; // revision
@@ -253,7 +243,6 @@ PCIBus *pci_pmac_init(qemu_irq *pic)
     d->config[0x0D] = 0x10; // latency_timer
     d->config[0x0E] = 0x00; // header_type
     //    d->config[0x34] = 0x80; // capabilities_pointer
-#endif
 
 #if 0 // XXX: not needed for now
     /* Uninorth internal bus */
-- 
1.6.0.2

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

* [Qemu-devel] [PATCH 5/7] PPC64: Nop some SPRs on 970fx
  2009-03-05 14:14       ` [Qemu-devel] [PATCH 4/7] Activate uninorth AGP bridge Alexander Graf
@ 2009-03-05 14:14         ` Alexander Graf
  2009-03-05 14:14           ` [Qemu-devel] [PATCH 6/7] PPC64: Enable 64bit mode on interrupts Alexander Graf
  0 siblings, 1 reply; 16+ messages in thread
From: Alexander Graf @ 2009-03-05 14:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: blauwirbel, Alexander Graf

Linux tries to access some SPRs on PPC64 boot. Let's just ignore those
for the 970fx for now to make it happy.

Signed-off-by: Alexander Graf <alex@csgraf.de>
---
 target-ppc/translate_init.c |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 6b7ab98..815a0c5 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -6043,6 +6043,18 @@ static void init_proc_970FX (CPUPPCState *env)
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_hior, &spr_write_hior,
                  0x00000000);
+    spr_register(env, SPR_CTRL, "SPR_CTRL",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_UCTRL, "SPR_UCTRL",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_VRSAVE, "SPR_VRSAVE",
+                 &spr_read_generic, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
 #if !defined(CONFIG_USER_ONLY)
     env->slb_nr = 32;
 #endif
-- 
1.6.0.2

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

* [Qemu-devel] [PATCH 6/7] PPC64: Enable 64bit mode on interrupts
  2009-03-05 14:14         ` [Qemu-devel] [PATCH 5/7] PPC64: Nop some SPRs on 970fx Alexander Graf
@ 2009-03-05 14:14           ` Alexander Graf
  2009-03-05 14:14             ` [Qemu-devel] [PATCH 7/7] PPC64: Don't fault at lwsync Alexander Graf
  0 siblings, 1 reply; 16+ messages in thread
From: Alexander Graf @ 2009-03-05 14:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: blauwirbel, Alexander Graf

Real 970s enable MSR_SF on all interrupts. The current code didn't do
this until now, so let's activate it!

Signed-off-by: Alexander Graf <alex@csgraf.de>
---
 target-ppc/helper.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index 0fa87dc..7fe3f8f 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -2607,7 +2607,7 @@ static always_inline void powerpc_excp (CPUState *env,
             new_msr |= (target_ulong)1 << MSR_CM;
         }
     } else {
-        if (!msr_isf) {
+        if (!msr_isf && !(env->mmu_model & POWERPC_MMU_64)) {
             new_msr &= ~((target_ulong)1 << MSR_SF);
             vector = (uint32_t)vector;
         } else {
@@ -2788,6 +2788,10 @@ void cpu_ppc_reset (void *opaque)
         ppc_tlb_invalidate_all(env);
 #endif
     env->msr = msr & env->msr_mask;
+#if defined(TARGET_PPC64)
+    if (env->mmu_model & POWERPC_MMU_64)
+        env->msr |= (1ULL << MSR_SF);
+#endif
     hreg_compute_hflags(env);
     env->reserve = (target_ulong)-1ULL;
     /* Be sure no exception or interrupt is pending */
-- 
1.6.0.2

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

* [Qemu-devel] [PATCH 7/7] PPC64: Don't fault at lwsync
  2009-03-05 14:14           ` [Qemu-devel] [PATCH 6/7] PPC64: Enable 64bit mode on interrupts Alexander Graf
@ 2009-03-05 14:14             ` Alexander Graf
  2009-03-05 15:07               ` Paul Brook
  2009-03-05 16:44               ` Paul Brook
  0 siblings, 2 replies; 16+ messages in thread
From: Alexander Graf @ 2009-03-05 14:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: blauwirbel, Alexander Graf

Right now we can throw a fault on lwsync, even though the fault is
actually caused by the instruction after lwsync.

I haven't found the magic that messed this up, but for now we can
just end the TB on lwsync, forcing the next command to issue faults
itself.

If anyone knows how to really fix this, please step forward and do
so. This only makes things work at all for me :-).

Signed-off-by: Alexander Graf <alex@csgraf.de>
---
 target-ppc/translate.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index b5de33b..c994ad7 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -3289,6 +3289,10 @@ GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B)
 /* sync */
 GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x039FF801, PPC_MEM_SYNC)
 {
+    // XXX without stopping here a page fault thinks it happens
+    //     in the sync, which is obviously wrong. Let's just keep
+    //     a sync as one TB as long as we don't do real SMP.
+    gen_stop_exception(ctx);
 }
 
 /* wait */
-- 
1.6.0.2

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

* Re: [Qemu-devel] [PATCH 7/7] PPC64: Don't fault at lwsync
  2009-03-05 14:14             ` [Qemu-devel] [PATCH 7/7] PPC64: Don't fault at lwsync Alexander Graf
@ 2009-03-05 15:07               ` Paul Brook
  2009-03-05 15:57                 ` Alexander Graf
  2009-03-05 16:44               ` Paul Brook
  1 sibling, 1 reply; 16+ messages in thread
From: Paul Brook @ 2009-03-05 15:07 UTC (permalink / raw)
  To: qemu-devel; +Cc: blauwirbel, Alexander Graf, Alexander Graf

On Thursday 05 March 2009, Alexander Graf wrote:
> Right now we can throw a fault on lwsync, even though the fault is
> actually caused by the instruction after lwsync.
>
> I haven't found the magic that messed this up, but for now we can
> just end the TB on lwsync, forcing the next command to issue faults
> itself.
>
> If anyone knows how to really fix this, please step forward and do
> so. This only makes things work at all for me :-).

Where is the subsequent fault coming from? I suspect the real bug is nothing 
to do with lwsync, and the subsequent fault is actually just corrupting the 
CPU state. As discussed recently this is the same bug SPARC has with its 
unassigned access handlers.

Paul

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

* Re: [Qemu-devel] [PATCH 7/7] PPC64: Don't fault at lwsync
  2009-03-05 15:07               ` Paul Brook
@ 2009-03-05 15:57                 ` Alexander Graf
  2009-03-05 16:09                   ` Alexander Graf
  0 siblings, 1 reply; 16+ messages in thread
From: Alexander Graf @ 2009-03-05 15:57 UTC (permalink / raw)
  To: Paul Brook; +Cc: blauwirbel, Alexander Graf, qemu-devel

Paul Brook wrote:
> On Thursday 05 March 2009, Alexander Graf wrote:
>   
>> Right now we can throw a fault on lwsync, even though the fault is
>> actually caused by the instruction after lwsync.
>>
>> I haven't found the magic that messed this up, but for now we can
>> just end the TB on lwsync, forcing the next command to issue faults
>> itself.
>>
>> If anyone knows how to really fix this, please step forward and do
>> so. This only makes things work at all for me :-).
>>     
>
> Where is the subsequent fault coming from? I suspect the real bug is nothing 
> to do with lwsync, and the subsequent fault is actually just corrupting the 
> CPU state. As discussed recently this is the same bug SPARC has with its 
> unassigned access handlers.
>
> Paul
>   

Without the patch I get:

Unable to handle kernel paging request for data at address 0x00000000
Faulting instruction address: 0xc0000000000ba524
Oops: Kernel access of bad area, sig: 11 [#1]
SMP NR_CPUS=1024 NUMA PowerMac
Modules linked in:
Supported: Yes
NIP: c0000000000ba524 LR: c000000000775a0c CTR: c0000000007759e8
REGS: c0000000061afb10 TRAP: 0300   Not tainted  (2.6.27.7-9-ppc64)
MSR: 8000000000009032 <EE,ME,IR,DR>  CR: 84000044  XER: 20000000
DAR: 0000000000000000, DSISR: 0000000040000000
TASK = c00000000619d560[1] 'swapper' THREAD: c0000000061ac000 CPU: 0
GPR00: ffffffffffffffff c0000000061afd90 c0000000009bbce8 0000000000000000
GPR04: 0000000000000000 0000000000000000 0000000000000000 c000000000a82c80
GPR08: 0000000000000613 c00000000619d560 c0000000070704c0 c0000000061ac000
GPR12: 0000000088000044 c000000000a82c80 0000000000051b63 0000000000051a41
GPR16: 0000000000051b5b 000000000004003c 0000000000053958 000000000005345e
GPR20: 0000000000052fd4 0000000000063dc8 0000000000063db4 00000000fff0245c
GPR24: 4000000002110000 c0000000007932f8 c000000000b077a8 0000000000000000
GPR28: c0000000009621f0 c0000000007b01c8 c000000000938f18 c0000000007afce0
NIP [c0000000000ba524] .cmpxchg_futex_value_locked+0x38/0x78
LR [c000000000775a0c] .futex_init+0x24/0xac
Call Trace:
[c0000000061afd90] [c0000000007759c0] .init_tstats_procfs+0x2c/0x54
(unreliable)
[c0000000061afe10] [c00000000000944c] .do_one_initcall+0x78/0x194
[c0000000061aff00] [c000000000750440] .kernel_init+0xd0/0x148
[c0000000061aff90] [c00000000002ad84] .kernel_thread+0x4c/0x68
Instruction dump:
39290001 912b0014 7c8407b4 7ca507b4 e92d01b0 e8090520 7fa30040 419d0038
e92d01b0 e8090520 2ba00003 409d0028 <7c2004ac> 7c001828 7c002000 40c20010
---[ end trace 561bb236c800851f ]---
note: swapper[1] exited with preempt_count 1
swapper used greatest stack depth: 9296 bytes left
Kernel panic - not syncing: Attempted to kill init!


Which is this translation block:

NIP c0000000000ba524   LR c000000000775a0c CTR c0000000007759e8 XER 20000000
MSR 8000000000009032 HID0 0000000060000000  HF 8000000000000000 idx 1
TB 00000000 d8b159bb DECR 0007c417
GPR00 ffffffffffffffff c0000000061afd90 c0000000009bbce8 0000000000000000
GPR04 0000000000000000 0000000000000000 0000000000000000 c000000000a82c80
GPR08 0000000000000613 c00000000619d560 c0000000070704c0 c0000000061ac000
GPR12 0000000088000044 c000000000a82c80 0000000000051b63 0000000000051a41
GPR16 0000000000051b5b 000000000004003c 0000000000053958 000000000005345e
GPR20 0000000000052fd4 0000000000063dc8 0000000000063db4 00000000fff0245c
GPR24 4000000002110000 c0000000007932f8 c000000000b077a8 0000000000000000
GPR28 c0000000009621f0 c0000000007b01c8 c000000000938f18 c0000000007afce0
CR 84000044  [ L  G  -  -  -  -  G  G  ]             RES ffffffffffffffff
FPR00 0000000000000000 0000000000000000 0000000000000000 0000000000000000
FPR04 0000000000000000 0000000000000000 0000000000000000 0000000000000000
FPR08 0000000000000000 0000000000000000 0000000000000000 0000000000000000
FPR12 0000000000000000 0000000000000000 0000000000000000 0000000000000000
FPR16 0000000000000000 0000000000000000 0000000000000000 0000000000000000
FPR20 0000000000000000 0000000000000000 0000000000000000 0000000000000000
FPR24 0000000000000000 0000000000000000 0000000000000000 0000000000000000
FPR28 0000000000000000 0000000000000000 0000000000000000 0000000000000000
FPSCR 00000000
SRR0 c000000000774950 SRR1 8000000000009032 SDR1 0000000007c00003
IN:
0xc0000000000ba524:  lwsync
0xc0000000000ba528:  lwarx   r0,0,r3
0xc0000000000ba52c:  cmpw    r0,r4
0xc0000000000ba530:  bne-    0xc0000000000ba540


And I seriously have trouble understanding how a data storage exception
could happen on the lwsync opcode. It looks like R3 became 0 from the
guest's point of view after lwsync though - hum.

Alex

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

* Re: [Qemu-devel] [PATCH 7/7] PPC64: Don't fault at lwsync
  2009-03-05 15:57                 ` Alexander Graf
@ 2009-03-05 16:09                   ` Alexander Graf
  2009-03-05 16:29                     ` Paul Brook
  0 siblings, 1 reply; 16+ messages in thread
From: Alexander Graf @ 2009-03-05 16:09 UTC (permalink / raw)
  To: qemu-devel; +Cc: blauwirbel, Alexander Graf, Paul Brook

Alexander Graf wrote:
> Paul Brook wrote:
>   
>> On Thursday 05 March 2009, Alexander Graf wrote:
>>   
>>     
>>> Right now we can throw a fault on lwsync, even though the fault is
>>> actually caused by the instruction after lwsync.
>>>
>>> I haven't found the magic that messed this up, but for now we can
>>> just end the TB on lwsync, forcing the next command to issue faults
>>> itself.
>>>
>>> If anyone knows how to really fix this, please step forward and do
>>> so. This only makes things work at all for me :-).
>>>     
>>>       
>> Where is the subsequent fault coming from? I suspect the real bug is nothing 
>> to do with lwsync, and the subsequent fault is actually just corrupting the 
>> CPU state. As discussed recently this is the same bug SPARC has with its 
>> unassigned access handlers.
>>
>> Paul
>>   
>>     
>
> Without the patch I get:
>
> Unable to handle kernel paging request for data at address 0x00000000
> Faulting instruction address: 0xc0000000000ba524
> Oops: Kernel access of bad area, sig: 11 [#1]
> SMP NR_CPUS=1024 NUMA PowerMac
> Modules linked in:
> Supported: Yes
> NIP: c0000000000ba524 LR: c000000000775a0c CTR: c0000000007759e8
> REGS: c0000000061afb10 TRAP: 0300   Not tainted  (2.6.27.7-9-ppc64)
> MSR: 8000000000009032 <EE,ME,IR,DR>  CR: 84000044  XER: 20000000
> DAR: 0000000000000000, DSISR: 0000000040000000
> TASK = c00000000619d560[1] 'swapper' THREAD: c0000000061ac000 CPU: 0
> GPR00: ffffffffffffffff c0000000061afd90 c0000000009bbce8 0000000000000000
> GPR04: 0000000000000000 0000000000000000 0000000000000000 c000000000a82c80
> GPR08: 0000000000000613 c00000000619d560 c0000000070704c0 c0000000061ac000
> GPR12: 0000000088000044 c000000000a82c80 0000000000051b63 0000000000051a41
> GPR16: 0000000000051b5b 000000000004003c 0000000000053958 000000000005345e
> GPR20: 0000000000052fd4 0000000000063dc8 0000000000063db4 00000000fff0245c
> GPR24: 4000000002110000 c0000000007932f8 c000000000b077a8 0000000000000000
> GPR28: c0000000009621f0 c0000000007b01c8 c000000000938f18 c0000000007afce0
> NIP [c0000000000ba524] .cmpxchg_futex_value_locked+0x38/0x78
> LR [c000000000775a0c] .futex_init+0x24/0xac
> Call Trace:
> [c0000000061afd90] [c0000000007759c0] .init_tstats_procfs+0x2c/0x54
> (unreliable)
> [c0000000061afe10] [c00000000000944c] .do_one_initcall+0x78/0x194
> [c0000000061aff00] [c000000000750440] .kernel_init+0xd0/0x148
> [c0000000061aff90] [c00000000002ad84] .kernel_thread+0x4c/0x68
> Instruction dump:
> 39290001 912b0014 7c8407b4 7ca507b4 e92d01b0 e8090520 7fa30040 419d0038
> e92d01b0 e8090520 2ba00003 409d0028 <7c2004ac> 7c001828 7c002000 40c20010
> ---[ end trace 561bb236c800851f ]---
> note: swapper[1] exited with preempt_count 1
> swapper used greatest stack depth: 9296 bytes left
> Kernel panic - not syncing: Attempted to kill init!
>
>
> Which is this translation block:
>
> NIP c0000000000ba524   LR c000000000775a0c CTR c0000000007759e8 XER 20000000
> MSR 8000000000009032 HID0 0000000060000000  HF 8000000000000000 idx 1
> TB 00000000 d8b159bb DECR 0007c417
> GPR00 ffffffffffffffff c0000000061afd90 c0000000009bbce8 0000000000000000
> GPR04 0000000000000000 0000000000000000 0000000000000000 c000000000a82c80
> GPR08 0000000000000613 c00000000619d560 c0000000070704c0 c0000000061ac000
> GPR12 0000000088000044 c000000000a82c80 0000000000051b63 0000000000051a41
> GPR16 0000000000051b5b 000000000004003c 0000000000053958 000000000005345e
> GPR20 0000000000052fd4 0000000000063dc8 0000000000063db4 00000000fff0245c
> GPR24 4000000002110000 c0000000007932f8 c000000000b077a8 0000000000000000
> GPR28 c0000000009621f0 c0000000007b01c8 c000000000938f18 c0000000007afce0
> CR 84000044  [ L  G  -  -  -  -  G  G  ]             RES ffffffffffffffff
> FPR00 0000000000000000 0000000000000000 0000000000000000 0000000000000000
> FPR04 0000000000000000 0000000000000000 0000000000000000 0000000000000000
> FPR08 0000000000000000 0000000000000000 0000000000000000 0000000000000000
> FPR12 0000000000000000 0000000000000000 0000000000000000 0000000000000000
> FPR16 0000000000000000 0000000000000000 0000000000000000 0000000000000000
> FPR20 0000000000000000 0000000000000000 0000000000000000 0000000000000000
> FPR24 0000000000000000 0000000000000000 0000000000000000 0000000000000000
> FPR28 0000000000000000 0000000000000000 0000000000000000 0000000000000000
> FPSCR 00000000
> SRR0 c000000000774950 SRR1 8000000000009032 SDR1 0000000007c00003
> IN:
> 0xc0000000000ba524:  lwsync
> 0xc0000000000ba528:  lwarx   r0,0,r3
> 0xc0000000000ba52c:  cmpw    r0,r4
> 0xc0000000000ba530:  bne-    0xc0000000000ba540
>
>
> And I seriously have trouble understanding how a data storage exception
> could happen on the lwsync opcode. It looks like R3 became 0 from the
> guest's point of view after lwsync though - hum.
>   

Ah I remember that one now :-). The futex_init function tests if cmpxchg
works with NULL values and that's why R3 is 0. It's actually _supposed_
to fault here. But something gets messed up when the fault happens on
IP=lwsync instead of IP=lwarx and I haven't really researched into why.

Alex

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

* Re: [Qemu-devel] [PATCH 7/7] PPC64: Don't fault at lwsync
  2009-03-05 16:09                   ` Alexander Graf
@ 2009-03-05 16:29                     ` Paul Brook
  0 siblings, 0 replies; 16+ messages in thread
From: Paul Brook @ 2009-03-05 16:29 UTC (permalink / raw)
  To: Alexander Graf; +Cc: blauwirbel, Alexander Graf, qemu-devel

> > 0xc0000000000ba524:  lwsync
> > 0xc0000000000ba528:  lwarx   r0,0,r3
> > 0xc0000000000ba52c:  cmpw    r0,r4
> > 0xc0000000000ba530:  bne-    0xc0000000000ba540
> >
> >
> > And I seriously have trouble understanding how a data storage exception
> > could happen on the lwsync opcode. It looks like R3 became 0 from the
> > guest's point of view after lwsync though - hum.
>
> Ah I remember that one now :-). The futex_init function tests if cmpxchg
> works with NULL values and that's why R3 is 0. It's actually _supposed_
> to fault here. But something gets messed up when the fault happens on
> IP=lwsync instead of IP=lwarx and I haven't really researched into why.

That's what you need to fix then :-)

I'm pretty sure that terminating the TB after the lwsync is not the correct 
solution, and is just hiding the real bug.

Paul

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

* Re: [Qemu-devel] [PATCH 7/7] PPC64: Don't fault at lwsync
  2009-03-05 14:14             ` [Qemu-devel] [PATCH 7/7] PPC64: Don't fault at lwsync Alexander Graf
  2009-03-05 15:07               ` Paul Brook
@ 2009-03-05 16:44               ` Paul Brook
  2009-03-05 19:42                 ` Daniel Jacobowitz
  2009-03-05 21:21                 ` Alexander Graf
  1 sibling, 2 replies; 16+ messages in thread
From: Paul Brook @ 2009-03-05 16:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: blauwirbel, Alexander Graf, Alexander Graf

> If anyone knows how to really fix this, please step forward and do
> so. This only makes things work at all for me :-).

I bet lwsync being a nop is a clue.

When an MMU exception occurs, qemu figures out the guest location from the 
location of the MMU access in guest code (see cpu_restore_state). My guess is 
that this breaks when two guest instructions have the same location. I'm not 
entirely sure what the correct fix is, or where the bug lies 
(cpu_restore_state,  gen_intermediate_code_pc, or tcg_gen_code_search_pc) but 
hopefully this will point you in the right direction.

One thing to try (to confirm this theory) is make lwsync do domething (write 
to a dummy register or call a helper function) and see if the problem goes 
away.

Paul

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

* Re: [Qemu-devel] [PATCH 7/7] PPC64: Don't fault at lwsync
  2009-03-05 16:44               ` Paul Brook
@ 2009-03-05 19:42                 ` Daniel Jacobowitz
  2009-03-06  0:53                   ` Paul Brook
  2009-03-05 21:21                 ` Alexander Graf
  1 sibling, 1 reply; 16+ messages in thread
From: Daniel Jacobowitz @ 2009-03-05 19:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: blauwirbel, Alexander Graf, Alexander Graf

On Thu, Mar 05, 2009 at 04:44:30PM +0000, Paul Brook wrote:
> When an MMU exception occurs, qemu figures out the guest location from the 
> location of the MMU access in guest code (see cpu_restore_state). My guess is 
> that this breaks when two guest instructions have the same location. I'm not 
> entirely sure what the correct fix is, or where the bug lies 
> (cpu_restore_state,  gen_intermediate_code_pc, or tcg_gen_code_search_pc) but 
> hopefully this will point you in the right direction.

Automatically pick the second instruction, on the principle that an
instruction with no opcodes is unlikely to trigger a synchronous
fault?

-- 
Daniel Jacobowitz
CodeSourcery

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

* Re: [Qemu-devel] [PATCH 7/7] PPC64: Don't fault at lwsync
  2009-03-05 16:44               ` Paul Brook
  2009-03-05 19:42                 ` Daniel Jacobowitz
@ 2009-03-05 21:21                 ` Alexander Graf
  1 sibling, 0 replies; 16+ messages in thread
From: Alexander Graf @ 2009-03-05 21:21 UTC (permalink / raw)
  To: Paul Brook; +Cc: blauwirbel, qemu-devel, Alexander Graf

Paul Brook wrote:
>> If anyone knows how to really fix this, please step forward and do
>> so. This only makes things work at all for me :-).
>>     
>
> I bet lwsync being a nop is a clue.
>
> When an MMU exception occurs, qemu figures out the guest location from the 
> location of the MMU access in guest code (see cpu_restore_state). My guess is 
> that this breaks when two guest instructions have the same location. I'm not 
> entirely sure what the correct fix is, or where the bug lies 
> (cpu_restore_state,  gen_intermediate_code_pc, or tcg_gen_code_search_pc) but 
> hopefully this will point you in the right direction.
>
> One thing to try (to confirm this theory) is make lwsync do domething (write 
> to a dummy register or call a helper function) and see if the problem goes 
> away.
>   

Yep, that's the root cause. I just put in a movi to a temp var and that
works as well. Mind to fix it? I'm actually only fixing the qemu ppc64
parts to debug kvm inside and am slowly running out of time to work on
the kvm part of things ;).

I'll also send a new patch series tomorrow - userspace works now and I
can boot an openSUSE 11.1 DVD up to the installer prompt, though
keyboard and serial ports don't work (but that's an OpenBIOS issue).

Alex

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

* Re: [Qemu-devel] [PATCH 7/7] PPC64: Don't fault at lwsync
  2009-03-05 19:42                 ` Daniel Jacobowitz
@ 2009-03-06  0:53                   ` Paul Brook
  0 siblings, 0 replies; 16+ messages in thread
From: Paul Brook @ 2009-03-06  0:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: blauwirbel, Alexander Graf, Alexander Graf

On Thursday 05 March 2009, Daniel Jacobowitz wrote:
> On Thu, Mar 05, 2009 at 04:44:30PM +0000, Paul Brook wrote:
> > When an MMU exception occurs, qemu figures out the guest location from
> > the location of the MMU access in guest code (see cpu_restore_state). My
> > guess is that this breaks when two guest instructions have the same
> > location. I'm not entirely sure what the correct fix is, or where the bug
> > lies
> > (cpu_restore_state,  gen_intermediate_code_pc, or tcg_gen_code_search_pc)
> > but hopefully this will point you in the right direction.
>
> Automatically pick the second instruction, on the principle that an
> instruction with no opcodes is unlikely to trigger a synchronous
> fault?

Yes, that sounds like the right fix.

Paul

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

end of thread, other threads:[~2009-03-06  0:53 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-03-05 14:14 [Qemu-devel] [PATCH 0/7] PPC64 Linux bringup patches v2 Alexander Graf
2009-03-05 14:14 ` [Qemu-devel] [PATCH 1/7] PPC64: Implement slbmte Alexander Graf
2009-03-05 14:14   ` [Qemu-devel] [PATCH 2/7] PPC64: Implement large pages Alexander Graf
2009-03-05 14:14     ` [Qemu-devel] [PATCH 3/7] PPC64: Implment tlbiel Alexander Graf
2009-03-05 14:14       ` [Qemu-devel] [PATCH 4/7] Activate uninorth AGP bridge Alexander Graf
2009-03-05 14:14         ` [Qemu-devel] [PATCH 5/7] PPC64: Nop some SPRs on 970fx Alexander Graf
2009-03-05 14:14           ` [Qemu-devel] [PATCH 6/7] PPC64: Enable 64bit mode on interrupts Alexander Graf
2009-03-05 14:14             ` [Qemu-devel] [PATCH 7/7] PPC64: Don't fault at lwsync Alexander Graf
2009-03-05 15:07               ` Paul Brook
2009-03-05 15:57                 ` Alexander Graf
2009-03-05 16:09                   ` Alexander Graf
2009-03-05 16:29                     ` Paul Brook
2009-03-05 16:44               ` Paul Brook
2009-03-05 19:42                 ` Daniel Jacobowitz
2009-03-06  0:53                   ` Paul Brook
2009-03-05 21:21                 ` Alexander Graf

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.