qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] Port QEMU to MIPS


From: Lb peace
Subject: [Qemu-devel] Port QEMU to MIPS
Date: Thu, 19 Jun 2014 20:28:45 +0800

We port coremu to mips host(loongson).We put this project on:https://sourceforge.net/projects/coremuformips
1)use ll/sc in mips to replace "lock:" in x86
2)fix some errors.
It now can run debian or windows but you may find it a little slow.
we will improve this project:
1)to make it run faster
2)improve hard drive's operation.(Maybe we can add locks on hard driver's read/write)
3)merge new qemu's version.We devlelop this project in 2011,so the qemu version was 0.13.5 derived from coremu 0.1.2.
4)port to arm or other risc host.We only have Loongson 2F box (and it broke on 2012 Jan. so  we can not debug some errors  ). We get a mainboard of loongson 3A now.:)
Thanks for coremu project & QEMU project.

  只在 coremu_mips/coremu 存在:bin
diff -r coremu-0.1.2/coremu/configure coremu_mips/coremu/configure
114,117c114,117
< config_feature ${crosscode} COREMU_CMC_SUPPORT
< config_feature ${usecachesim} COREMU_CACHESIM_MODE
< config_feature ${usedebug} COREMU_DEBUG_MODE
< config_feature ${lockdetect} COREMU_LOCK_DETECT
---
> config_feature() ${crosscode} COREMU_CMC_SUPPORT
> config_feature() ${usecachesim} COREMU_CACHESIM_MODE
> config_feature() ${usedebug} COREMU_DEBUG_MODE
> config_feature() ${lockdetect} COREMU_LOCK_DETECT
只在 coremu_mips/coremu 存在:coremu.mk
diff -r coremu-0.1.2/coremu/incl/atomic-template.h coremu_mips/coremu/incl/atomic-template.h
8a9,10
> #  define DATA_SIZE (1ULL<<32)
> #  define DATA_MASK (~(DATA_SIZE-1))
11a14,15
> #  define DATA_SIZE (1ULL<<16)
> #  define DATA_MASK (~(DATA_SIZE-1))
14a19,20
> #  define DATA_SIZE (1ULL<<8)
> #  define DATA_MASK (~(DATA_SIZE-1))
18a25
20,24c27,31
<     asm volatile(
<         LOCK_PREFIX "inc"coremu_str(SUFFIX)" %0"
<         : "+m"(*p)
<         :
<         : "cc");
---
>     DATA_TYPE old, new;
>     do {
>         old = new = *p;
>         new = (DATA_TYPE)(new + 1);
>     } while(old != coremu_glue(CAS,SUFFIX)(p, old, new));
28,33c35
<     asm volatile(
<         LOCK_PREFIX "dec"coremu_str(SUFFIX)" %0"
<         : "+m"(*p)
<         :
<         : "cc");
< }
---
>     DATA_TYPE old, new;
35,41c37,40
< static __inline__ void coremu_glue(atomic_add, SUFFIX)(DATA_TYPE* addr,
<         DATA_TYPE val) {
<     asm volatile(
<         LOCK_PREFIX "add"coremu_str(SUFFIX)" %1, %0"
<         : "+m"(*addr)
<         : "a"(val)
<         : "cc");
---
>     do {
>         old = new = *p;
>         new = (DATA_TYPE)(new - 1);
>     } while(old != coremu_glue(CAS,SUFFIX)(p, old, new));
44,46c43
< /* swap the value VAL and *p.
<  * Return the value swapped out from memory. */
< static inline DATA_TYPE coremu_glue(atomic_exchange, SUFFIX)(
---
> static __inline__ DATA_TYPE coremu_glue(atomic_exchange, SUFFIX)(
49,68c46
<     DATA_TYPE out;
<     __asm __volatile(
<             "lock; xchg"coremu_str(SUFFIX)" %1,%2 \n\t"
<             : "=a" (out), "+m" (*p)
<             : "a" (val)
<             );
<     return out;
< }
< /* Return previous value in addr. So if the return value is the same as oldval,
<  * swap occured. */
< static __inline__ DATA_TYPE coremu_glue(atomic_compare_exchange, SUFFIX)(DATA_TYPE *addr,
<         DATA_TYPE oldval, DATA_TYPE newval) {
<     asm volatile(
<         LOCK_PREFIX "cmpxchg"coremu_str(SUFFIX)" %2, %1"
<         : "+a"(oldval), "+m"(*addr)
<         : "q"(newval)
<         : "cc");
<     return oldval;
< }
---
>     DATA_TYPE old, new;
70,76c48,65
< static __inline__ void coremu_glue(atomic_and, SUFFIX)(DATA_TYPE *addr,
<         DATA_TYPE mask) {
<     asm volatile(
<         LOCK_PREFIX "and"coremu_str(SUFFIX)" %1, %0"
<         : "+m"(*addr)
<         : "r"(mask)
<         : "cc");
---
>     if(!((uint32_t)p&0x3))
>     {
>         do {
>             old = new = *p;
>             new = val;
>         } while (old != coremu_glue(CAS,SUFFIX)(p, old, new));
>         return (DATA_TYPE)old;
>     }
>     else
>     {
>         DATA_TYPE *ap = (DATA_TYPE *)((uint32_t)p & ~0x3);
>         int offset = (uint32_t)p & 0x3;
>         do {
>             old = new = *ap;
>             *(DATA_TYPE *)((char *)&new + offset) = val;
>         } while(old != coremu_glue(CAS,SUFFIX)(ap, old, new));
>         return *(DATA_TYPE *)((char *)&old + offset);
>     }
78,85c67,83
< static __inline__ void coremu_glue(atomic_or, SUFFIX)(DATA_TYPE *addr,
<         DATA_TYPE mask) {
<     asm volatile(
<         LOCK_PREFIX "or"coremu_str(SUFFIX)" %1, %0"
<         : "+m"(*addr)
<         : "r"(mask)
<         : "cc");
---
> static __inline__  DATA_TYPE coremu_glue(atomic_compare_exchange, SUFFIX)(DATA_TYPE *addr,
>         DATA_TYPE oldval, DATA_TYPE newval) {
>    uint32_t  old, new;
>     if(!((uint32_t)addr&0x3))
>     {
>         old = coremu_glue(CAS,SUFFIX)((DATA_TYPE *)addr, oldval, newval);
>         return (DATA_TYPE)old;
>     }
>    else
>     {   
>         uint32_t *ap = (uint32_t *)((uint32_t)addr & ~0x3);
>         int offset = (uint32_t)addr & 0x3;
>         old = new = *ap;
>         *(DATA_TYPE *)((char *)&new + offset) = newval;
>         old = CASl(ap, old, new);
>         return *(DATA_TYPE *)((char *)&old + offset);
>     }
88,97d85
< static __inline__ DATA_TYPE coremu_glue(atomic_xadd, SUFFIX)(
<         DATA_TYPE* addr, DATA_TYPE val) {
<     asm volatile(
<         LOCK_PREFIX "xadd"coremu_str(SUFFIX)" %0, %1"
<         : "+a"(val), "+m"(*addr)
<         :
<         : "cc");
<     return val;
< }
100a89,90
> #undef DATA_SIZE
> #undef DATA_MASK
diff -r coremu-0.1.2/coremu/incl/coremu-atomic.h coremu_mips/coremu/incl/coremu-atomic.h
28a29,56
> /*-
>  * Copyright (c) 2013 Ed Schouten <address@hidden>
>  * All rights reserved.
>  *
>  * Copyright (c) 1998 Doug Rabson
>  * All rights reserved.
>  *
>  * Redistribution and use in source and binary forms, with or without
>  * modification, are permitted provided that the following conditions
>  * are met:
>  * 1. Redistributions of source code must retain the above copyright
>  *    notice, this list of conditions and the following disclaimer.
>  * 2. Redistributions in binary form must reproduce the above copyright
>  *    notice, this list of conditions and the following disclaimer in the
>  *    documentation and/or other materials provided with the distribution.
>  *
>  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
>  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
>  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
>  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
>  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
>  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
>  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
>  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
>  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
>  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
>  * SUCH DAMAGE.
>  */
37c65,77
< static __inline__ uint8_t bit_testandset(int *base, int off)
---
> /*
>  * Memory barriers.
>  *
>  * It turns out __sync_synchronize() does not emit any code when used
>  * with GCC 4.2. Implement our own version that does work reliably.
>  *
>  * Although __sync_lock_test_and_set() should only perform an acquire
>  * barrier, make it do a full barrier like the other functions. This
>  * should make <stdatomic.h>'s atomic_exchange_explicit() work reliably.
>  */
> static __inline__ void
> do_sync(void)
39c79,91
<     uint8_t readval = 0;
---
>         __asm volatile (
>                 ".set noreorder\n"
>                 "\tnop\n"
>                 "\tnop\n"
>                 "\tnop\n"
>                 "\tnop\n"
>                 "\tnop\n"
>                 "\tnop\n"
>                 "\tnop\n"
>                 "\tnop\n"
>                 ".set reorder\n"
>                 : : : "memory");
> }
41,47c93,105
<     /* CF <-- Bit(BitBase, BitOffset). */
<     __asm__ __volatile__ (
<            "lock; btsl %2,%0\n\t"
<             "setb %1\n\t"
<             : "=m" (*base),"=a" (readval)
<             : "Ir" (off)
<             : "cc");
---
> typedef union {
>         uint8_t         v8[4];
>         uint32_t        v32;
> } reg_t;
> /*
>  * Given a memory address pointing to an 8-bit or 16-bit integer, return
>  * the address of the 32-bit word containing it.
>  */
> static __inline__ uint32_t *
> round_to_word(void *ptr)
> {
49c107
<     return readval;
---
>         return ((uint32_t *)((intptr_t)ptr & ~3));
52c110,117
< static __inline__ uint8_t bit_testandreset(int *base, int off)
---
> /*
>  * Utility functions for loading and storing 8-bit and 16-bit integers
>  * in 32-bit words at an offset corresponding with the location of the
>  * atomic variable.
>  */
> static __inline__ void
> put_1(reg_t *r, const uint8_t *offset_ptr, uint8_t val)
54c119
<     uint8_t readval = 0;
---
>         size_t offset;
56,62c121,123
<     /* CF <-- Bit(BitBase, BitOffset). */
<     __asm__ __volatile__ (
<             "lock; btrl %2,%0\n\t"
<             "setb %1\n\t"
<             : "=m" (*base),"=a" (readval)
<             : "Ir" (off)
<             : "cc");
---
>         offset = (intptr_t)offset_ptr & 3;
>         r->v8[offset] = val;
> }
64c125,131
<     return readval;
---
> static __inline__ uint8_t
> get_1(const reg_t *r, const uint8_t *offset_ptr)
> {
>         size_t offset;
>         offset = (intptr_t)offset_ptr & 3;
>         return (r->v8[offset]);
67c134,135
< static __inline__ uint8_t bit_test(int *base, int off)
---
> static __inline__ void
> put_2(reg_t *r, const uint16_t *offset_ptr, uint16_t val)
69c137,147
<     uint8_t readval = 0;
---
>         size_t offset;
>         union {
>                 uint16_t in;
>                 uint8_t out[2];
>         } bytes;
>         offset = (intptr_t)offset_ptr & 3;
>         bytes.in = val;
>         r->v8[offset] = bytes.out[0];
>         r->v8[offset + 1] = bytes.out[1];
> }
71,77c149,162
<     /* CF <-- Bit(BitBase, BitOffset). */
<     __asm__ __volatile__ (
<             "lock; bt %2,%0\n\t"
<             "setb %1\n\t"
<             : "=m" (*base),"=a" (readval)
<             : "Ir" (off)
<             : "cc");
---
> static __inline__ uint16_t
> get_2(const reg_t *r, const uint16_t *offset_ptr)
> {
>         size_t offset;
>         union {
>                 uint8_t in[2];
>                 uint16_t out;
>         } bytes;
>         offset = (intptr_t)offset_ptr & 3;
>         bytes.in[0] = r->v8[offset];
>         bytes.in[1] = r->v8[offset + 1];
>         return (bytes.out);
> }
79c164,197
<     return readval;
---
> #define EMIT_VAL_COMPARE_AND_SWAP_N(N, uintN_t)                         \
> static __inline__ uintN_t                                                         \
> __sync_val_compare_and_swap_##N(uintN_t *mem, uintN_t expected,         \
>     uintN_t desired)                                                    \
> {                                                                       \
>         uint32_t *mem32;                                                \
>         reg_t expected32, desired32, posmask, old;                      \
>         uint32_t negmask, temp;                                         \
>                                                                         \
>         mem32 = round_to_word(mem);                                     \
>         expected32.v32 = 0x00000000;                                    \
>         put_##N(&expected32, mem, expected);                            \
>         desired32.v32 = 0x00000000;                                     \
>         put_##N(&desired32, mem, desired);                              \
>         posmask.v32 = 0x00000000;                                       \
>         put_##N(&posmask, mem, ~0);                                     \
>         negmask = ~posmask.v32;                                         \
>                                                                         \
>         do_sync();                                                      \
>         __asm volatile (                                                \
>                 "\t.set mips2\n"                                        \
>                 "1:"                                                    \
>                 "\tll   %0, %7\n"       /* Load old value. */           \
>                 "\tand  %2, %5, %0\n"   /* Isolate the old value. */    \
>                 "\tbne  %2, %3, 2f\n"   /* Compare to expected value. */\
>                 "\tand  %2, %6, %0\n"   /* Remove the old value. */     \
>                 "\tor   %2, %4\n"       /* Put in the new value. */     \
>                 "\tsc   %2, %1\n"       /* Attempt to store. */         \
>                 "\tbeqz %2, 1b\n"       /* Spin if failed. */           \
>                 "2:"                                                    \
>                 : "=&r" (old), "=m" (*mem32), "=&r" (temp)              \
>                 : "r" (expected32.v32), "r" (desired32.v32),            \
>                   "r" (posmask.v32), "r" (negmask), "m" (*mem32));      \
>         return (get_##N(&old, mem));                                    \
82,83c200,249
< // Is this the correct way to detect 64 system?
< #if (__LP64__== 1)
---
> EMIT_VAL_COMPARE_AND_SWAP_N(1, uint8_t)
> EMIT_VAL_COMPARE_AND_SWAP_N(2, uint16_t)
> static __inline__ uint32_t
> __sync_val_compare_and_swap_4(uint32_t *mem, uint32_t expected,
>     uint32_t desired)
> {
>         uint32_t old, temp;
>         do_sync();
>         __asm volatile (
>                 "\t.set mips2\n"
>                 "1:"
>                 "\tll   %0, %5\n"       /* Load old value. */
>                 "\tbne  %0, %3, 2f\n"   /* Compare to expected value. */
>                 "\tmove %2, %4\n"       /* Value to store. */
>                 "\tsc   %2, %1\n"       /* Attempt to store. */
>                 "\tbeqz %2, 1b\n"       /* Spin if failed. */
>                 "2:"
>                 : "=&r" (old), "=m" (*mem), "=&r" (temp)
>                 : "r" (expected), "r" (desired), "m" (*mem));
>         return (old);
> }
> #define EMIT_FETCH_AND_OP_4(name, op)                                   \
> static __inline__ uint32_t                                                                \
> __sync_##name##_4(uint32_t *mem, uint32_t val)                          \
> {                                                                       \
>         uint32_t old, temp;                                             \
>                                                                         \
>         do_sync();                                                      \
>         __asm volatile (                                                \
>                 "\t.set mips2\n"                                        \
>                 "1:"                                                    \
>                 "\tll   %0, %4\n"       /* Load old value. */           \
>                 "\t"op"\n"              /* Calculate new value. */      \
>                 "\tsc   %2, %1\n"       /* Attempt to store. */         \
>                 "\tbeqz %2, 1b\n"       /* Spin if failed. */           \
>                 : "=&r" (old), "=m" (*mem), "=&r" (temp)                \
>                 : "r" (val), "m" (*mem));                               \
>         return (old);                                                   \
> }
> EMIT_FETCH_AND_OP_4(lock_test_and_set, "move %2, %3")
> EMIT_FETCH_AND_OP_4(fetch_and_add, "addu %2, %0, %3")
> EMIT_FETCH_AND_OP_4(fetch_and_sub, "subu %2, %0, %3")
> #if defined(__mips__)
85,95c251,267
< atomic_compare_exchange16b(uint64_t *memp,
<                            uint64_t rax, uint64_t rdx,
<                            uint64_t rbx, uint64_t rcx)
< {
<     uint8_t z;
<     __asm __volatile__ ( "lock; cmpxchg16b %3\n\t"
<                          "setz %2\n\t"
<                          : "=a" (rax), "=d" (rdx), "=r" (z), "+m" (*memp)
<                          : "a" (rax), "d" (rdx), "b" (rbx), "c" (rcx)
<                          : "memory", "cc" );
<     return z;
---
> atomic_compare_exchange8b(uint64_t *memp,
>                            uint32_t eax, uint32_t edx,
>                            uint32_t ebx, uint32_t ecx)
> {
>     uint64_t edx_eax = ((uint64_t)edx << 32) | eax;
>     uint64_t ecx_ebx = ((uint64_t)ecx << 32) | ebx;
>     uint64_t ret;
>     __asm__ (
>             "       .set mips2              \n"
>             "1:     ll %0,%1                \n"
>             "       bne %0,%2,2f            \n"
>             "       move %0,%3              \n"
>             "2:     sc %0,%1                \n"
>             "       beq %0,$0,1b            \n"
>             : "=&r" (ret), "=m" (*memp)
>             : "Ir" (edx_eax), "Ir"(ecx_ebx));
>     return ret==edx_eax;
96a269,270
> #else
> #error unimplemented CPU support
99,102c273,279
< /* Memory Barriers: x86-64 ONLY now */
< #define mb()    asm volatile("mfence":::"memory")
< #define rmb()   asm volatile("lfence":::"memory")
< #define wmb()   asm volatile("sfence" ::: "memory")
---
> #if defined(__mips__)
>   #define mb    do_sync
>   #define rmb   do_sync
>   #define wmb   do_sync
> #else
> #error unimplemented CPU support
> #endif
111a289,342
> /*
> static inline uint64_t LL64(uint64_t *addr)
> {
uint64_t ret;
>        __asm__ (
>                 "      .set mips2               \n"
>                 "      lld %0,%1                \n"
>                 : "=&r" (ret), "=m" (*addr));
return ret;
> }
> static inline uint64_t SC64(uint64_t *addr,uint64_t val)
> {
>     __asm__ (
>                 "      .set mips2               \n"
>                 "      scd %0,%1                \n"
>                 : "=&r" (val), "=m" (*addr));
return val;
> }
> */
> static inline uint32_t CASl(uint32_t *p, uint32_t o, uint32_t n)
> {
>    return __sync_val_compare_and_swap_4(p, o, n);
> }
> static inline uint16_t CASw(uint16_t *p, uint16_t o, uint16_t n)
> {
>    return __sync_val_compare_and_swap_2(p, o, n);
> }
> static inline uint8_t CASb(uint8_t *p, uint8_t o, uint8_t n)
> {
>    return __sync_val_compare_and_swap_1(p, o, n);
> }
> static inline uint32_t LL32(uint32_t *addr)
> {
uint32_t ret;
>     __asm__ (
>                 "      .set mips2               \n"
>                 "      ll %0,%1                 \n"
>                 : "=&r" (ret), "=m" (*addr));
return ret;
> }
> static inline uint32_t SC32(uint32_t *addr,uint32_t val)
> {
>        __asm__ (
>                 "      .set mips2               \n"
>                 "      sc %0,%1                \n"
>                 : "=&r" (val), "=m" (*addr));
return val;
> }
121,138d351
< #if (__LP64__== 1)
< #define DATA_BITS 64
< #include "atomic-template.h"
< #endif
< static inline uint64_t atomic_xadd2(uint64_t *target)
< {
<     register uint64_t __result;
<     asm volatile (
<         "mov $2, %0\n"
<         "lock xaddq %0, %1\n"
<         : "=r" (__result), "+m" (*target)
<         :
<         : "cc", "memory"
<     );
<     return __result;
< }
只在 coremu_mips/coremu/incl 存在:coremu-feature.h
diff -r coremu-0.1.2/coremu/incl/coremu-spinlock.h coremu_mips/coremu/incl/coremu-spinlock.h
36c36
---
> //wh:copy from qemu-lock.h
39c39
<     int readval = 0;
---
>     int ret;
42,46c42,54
"lock; cmpxchgl %2, %0"
: "+m" (p->lock), "+a" (readval)
: "r" (1)
: "cc");
<     return readval;
---
>         "       .set push               \n"
>         "       .set noat               \n"
>         "       .set mips2              \n"
>         "1:     li      $1, 1           \n"
>         "       ll      %0, %1          \n"
>         "       sc      $1, %1          \n"
>         "       beqz    $1, 1b          \n"
>         "       .set pop                "
>         : "=r" (ret), "+R" (p->lock)
>         :
>         : "memory");
>     return ret;
diff -r coremu-0.1.2/coremu/incl/queue.h coremu_mips/coremu/incl/queue.h
65c65
<     uint64_t count;          /* higher order: unsigned integer */
---
>     uint32_t count;          /* higher order: unsigned integer */
76c76
<     int64_t count;           /* count the number of elements */
---
>     int32_t count;           /* count the number of elements */
101c101
<     uint64_t count;
---
>     uint32_t count;
diff -r coremu-0.1.2/coremu/main/lock-queue.c coremu_mips/coremu/main/lock-queue.c
87c87
<     atomic_incq(&Q->count);
---
>     __sync_fetch_and_add((uint32_t *) & Q->count,1);
103c103
<     atomic_decq(&Q->count);
---
>     __sync_fetch_and_sub((uint32_t *) & Q->count,1);
diff -r coremu-0.1.2/coremu/main/malloc-helper.c coremu_mips/coremu/main/malloc-helper.c
65c65
<     uint64_t res;
---
>     uint32_t res;
67,68c67,68
<     res = atomic_compare_exchangeq((uint64_t *)pp, (uint64_t)0, (uint64_t)p);
<     if (res != (uint64_t)NULL)
---
>     res = atomic_compare_exchangel((uint32_t *)pp, (uint32_t)0, (uint32_t)p);
>     if (res != (uint32_t)NULL)
diff -r coremu-0.1.2/coremu/main/ms-queue.c coremu_mips/coremu/main/ms-queue.c
56c56
< static inline uint64_t CAS(pointer_t *ptr, pointer_t old, pointer_t new);
---
> static inline uint32_t CAS(pointer_t *ptr, pointer_t old, pointer_t new);
85c85
< static inline uint64_t CAS(pointer_t *ptr, pointer_t old, pointer_t new)
---
> static inline uint32_t CAS(pointer_t *ptr, pointer_t old, pointer_t new)
87,98c87,95
<     volatile uint64_t rdx, rax;
<     volatile uint64_t rcx, rbx;
<     rax = (uint64_t) old.ptr;   /* lower  order 64 bits */
<     rdx = old.count;            /* higher order 64 bits */
<     rbx = (uint64_t) new.ptr;   /* lower  order 64 bits */
<     rcx = new.count;            /* higher order 64 bits */
<     assert(((uint64_t)ptr & 0xf) == 0);
<     return atomic_compare_exchange16b((uint64_t *)ptr, rax, rdx, rbx, rcx);
---
volatile uint32_t rdx,rax;
volatile uint32_t rcx,rbx;
rax=(uint32_t)old.ptr;
rdx=old.count;
rbx=(uint32_t)new.ptr;
rcx=new.count;
return atomic_compare_exchange8b((uint64_t *)ptr,rax,rdx,rbx,rcx);
165c162
<     atomic_incq((uint64_t *) & Q->count);
---
>     __sync_fetch_and_add((uint32_t *) & Q->count,1);
203c200
<     atomic_decq((uint64_t *) &Q->count);
---
>     __sync_fetch_and_sub((uint32_t *) & Q->count,1);
213c210
<     fprintf(stderr, ">>> print queue[%lu] <<<\n", Q->count);
---
>     fprintf(stderr, ">>> print queue[%d] <<<\n", Q->count);
diff -r coremu-0.1.2/coremu/main/utils.c coremu_mips/coremu/main/utils.c
31,37d30
< /* serializing instruction stream using CPUID.
<  * Example: cpuid(1, eax, ebx, ecx, edx); */
< #define cpuid(index, eax, ebx, ecx, edx) \
<     asm volatile ("cpuid"                                           \
<                   : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)  \
<                   : "0" (index))
79a73,81
> //wh:here we put a MIPS rdhwr 
> //copy from qemu-timer.h change the return type 
> #define MIPS_RDHWR(rd, value) {                         \
>         __asm__ __volatile__ (".set   push\n\t"         \
>                               ".set mips32r2\n\t"       \
>                               "rdhwr  %0, "rd"\n\t"     \
>                               ".set   pop"              \
>                               : "=r" (value));          \
>     }
82c84
< unsigned long read_host_tsc(void)
---
> uint64_t read_host_tsc(void)
84,87c86,94
<     unsigned a, d;
<     __asm __volatile("rdtsc":"=a"(a), "=d"(d));
<     return ((unsigned long)a) | (((unsigned long)d) << 32);
< }
---
>     uint32_t count;
>     static uint32_t cyc_per_count = 0;
>     if (!cyc_per_count) {
>         MIPS_RDHWR("$3", cyc_per_count);
>     }
>     MIPS_RDHWR("$2", count);
>     return (uint64_t)((int64_t)count * cyc_per_count);
88a96,98
> }
101,106d110
< }
< void coremu_serialize()
< {
<     uint32_t eax, ebx, ecx, edx;
<     cpuid(1, eax, ebx, ecx, edx);
diff -r coremu-0.1.2/coremu/main/utils.h coremu_mips/coremu/main/utils.h
66d65
< unsigned long read_host_tsc(void);
69d67
< void coremu_serialize(void);
72c70
---
> uint64_t read_host_tsc(void);//MIPS rdhwr
diff -r coremu-0.1.2/coremu/utils/module.mk coremu_mips/coremu/utils/module.mk
3,11c3
< programs  += $(bindir)/watch-test $(bindir)/watch-control $(bindir)/monitor
< $(bindir)/watch-test:  $(OBJDIR)/utils/watch-test.o
@mkdir -p $(@D)
$(call quiet-command, $(LD) -o $@ $^, "  LINK    $@")
< $(bindir)/watch-control: $(OBJDIR)/utils/watch-control.o
@mkdir -p $(@D)
$(call quiet-command, $(LD) -o $@ $^, "  LINK    $@")
---
> programs += $(bindir)/monitor
diff -r coremu-0.1.2/coremu/utils/profile-tool.c coremu_mips/coremu/utils/profile-tool.c
19,27d18
< void profile_tool(int command)
< {
<     /* Use 88 since wanwan was born in 1988 :) */
<     __asm__ __volatile__ ( "int $0x88"
<                            :
<                            : "a" (command)
<                            : "cc");
< }
diff -r coremu-0.1.2/coremu/utils/watch-client.h coremu_mips/coremu/utils/watch-client.h
39,77d38
< void inline cm_insert_watch_point(CMWatchID id, unsigned long addr, unsigned long len)
< {
<     __asm__ __volatile__( "int $0x86"
<                           :
<                           : "a"(WATCH_INSERT), "D"(id), "S"(addr), "d"(len)
<                           : "cc");
< }
< void inline cm_remove_watch_point(CMWatchID id, unsigned long addr, unsigned long len)
< {
<     __asm__ __volatile__( "int $0x86"
<                           :
<                           : "a"(WATCH_REMOVE), "D"(id), "S"(addr), "d"(len)
<                           : "cc");
< }
< void inline cm_start_watch(void)
< {
<     __asm__ __volatile__( "int $0x86"
<                           :
<                           : "a"(WATCH_START)
<                           : "cc");
< }
< void inline cm_stop_watch(void)
< {
<     __asm__ __volatile__( "int $0x86"
<                           :
<                           : "a"(WATCH_STOP)
<                           : "cc");
< }
< void inline cm_stop_all_watch(void)
< {
<     __asm__ __volatile__( "int $0x86"
<                           :
<                           : "a"(WATCH_STOP_ALL)
<                           : "cc");
< }
diff -r coremu-0.1.2/coremu/utils/watch-control.c coremu_mips/coremu/utils/watch-control.c
40,75d39
< int main(int argc, char *argv[])
< {
<     int c;
<     if(argc != 2)
<     {
<         printf("Usage: profile #command, -h for help info\n");
<         return 1;
<     }
<     while((c = getopt(argc, argv, "bseh")) != -1)
<     {
<         switch(c) {
<         case 'b':
<             cm_start_watch();
<             break;
<         case 'e':
<             cm_stop_watch();
<             break;
<         case 's':
<             cm_stop_all_watch();
<             break;
<         case 'h':
<             help_info();
<             break;
<         default :
<             printf("error option : %c\n", c);
<             help_info();
<         }
<     }
<     return 1;
< }
diff -r coremu-0.1.2/coremu/utils/watch-test.c coremu_mips/coremu/utils/watch-test.c
29,40d28
<     int var = 0;
<     cm_start_watch();
<     printf("&var : 0x%p\n", &var);
<     printf("Insert watch point\n");
<     cm_insert_watch_point(10, (unsigned long)&var, 100);
<     var = 1;
<     printf("after write : 0x%x\n", var);
<     printf("REMOVE watch point\n");
<     cm_remove_watch_point(10, (unsigned long)&var, 100);
<     var = 2;
<     printf("after write : 0x%x\n", var);
<     cm_stop_watch();
diff -r coremu-0.1.2/qemu/cm-features/memtrace.c coremu_mips/qemu/cm-features/memtrace.c
85,99d84
< void cm_memtrace_logging(uint64_t addr, int write)
< {
<     if (!memtrace_enable)
<         return;
<     CMLogbuf *buffer = memtrace_buf;
<     uint64_t* buf_ptr = ((uint64_t*)buffer->cur);
<     uint64_t cnt = atomic_xadd2(&global_mem_event_counter) | write;
<     buf_ptr[1] = (uint64_t)addr;
<     buf_ptr[0] = cnt;
<     buffer->cur += MEMTRACE_RECORD_SIZE;
<     if (buffer->cur == buffer->end){
<         cm_memtrace_buf_full();
<     }
< }
diff -r coremu-0.1.2/qemu/cm-features/watch.c coremu_mips/qemu/cm-features/watch.c
41a42
> #if 0 
457c458
---
> #endif
diff -r coremu-0.1.2/qemu/cm-init.c coremu_mips/qemu/cm-init.c
31d30
< #include <sys/mman.h>
40,42d38
< #include "cm-features/logbuffer.h"
< #include "cm-features/instrument.h"
< #include "cm-features/memtrace.h"
45c41
---
> //wh:we del some headers here
59c55
<     int flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT;
---
>     int flags = MAP_PRIVATE | MAP_ANONYMOUS;// MAP_32BIT is only supported on x86-64, for 64-bit programs.
diff -r coremu-0.1.2/qemu/cm-tbinval.c coremu_mips/qemu/cm-tbinval.c
32c32
< static uint16_t *cm_phys_tb_cnt;
---
> static uint32_t *cm_phys_tb_cnt;
37c37
<             ((ram_offset + size) >> TARGET_PAGE_BITS) * sizeof(uint16_t));
---
>             ((ram_offset + size) >> TARGET_PAGE_BITS) * sizeof(uint32_t));
39c39
<            (size >> TARGET_PAGE_BITS) * sizeof(uint16_t));
---
>            (size >> TARGET_PAGE_BITS) * sizeof(uint32_t));
44c44
<     atomic_incw(&cm_phys_tb_cnt[addr >> TARGET_PAGE_BITS]);
---
>     atomic_incl(&cm_phys_tb_cnt[addr >> TARGET_PAGE_BITS]);
49,50c49,51
<     assert(cm_phys_tb_cnt[addr >> TARGET_PAGE_BITS]);
<     atomic_decw(&cm_phys_tb_cnt[addr >> TARGET_PAGE_BITS]);
---
//wh:this assert may triggle some errors 
> //    assert(cm_phys_tb_cnt[addr >> TARGET_PAGE_BITS]);
>     atomic_decl(&cm_phys_tb_cnt[addr >> TARGET_PAGE_BITS]);
53c54
< uint16_t cm_phys_page_tb_p(ram_addr_t addr)
---
> uint32_t cm_phys_page_tb_p(ram_addr_t addr)
87d87
<     int cpu_idx = 0;
diff -r coremu-0.1.2/qemu/cm-tbinval.h coremu_mips/qemu/cm-tbinval.h
45c45
< uint16_t cm_phys_page_tb_p(ram_addr_t addr);
---
> uint32_t cm_phys_page_tb_p(ram_addr_t addr);
只在 coremu_mips/qemu 存在:coremu.mk
diff -r coremu-0.1.2/qemu/cutils.c coremu_mips/qemu/cutils.c
224c224,225
---
>     if(qiov->size<=0 || qiov->niov<=0 || qiov->nalloc<=0)
>         return;
diff -r coremu-0.1.2/qemu/exec.c coremu_mips/qemu/exec.c
1130c1130,1133
---
> #ifdef CONFIG_COREMU
>     if( tb==NULL )//wh:coremu may have some errors here
>         goto next; 
> #endif
1206a1210,1212
> #endif
> #ifdef CONFIG_COREMU
> next:
diff -r coremu-0.1.2/qemu/qemu-lock.h coremu_mips/qemu/qemu-lock.h
55c55,67
<     *p = SPIN_LOCK_UNLOCKED;
---
int ret;
__asm__ __volatile__(
"       .set push               \n"
>                 "       .set noat               \n"
>                 "       .set mips2              \n"
"atomic_block: ll %0,%1 \n"
" and %0,$0 \n"
" sc %0,%1 \n"
" beq %0,$0,atomic_block \n"
" .set pop \n"
:"=r"(ret),"+R" (*p)
:
: "memory");
diff -r coremu-0.1.2/qemu/target-i386/cm-atomic.c coremu_mips/qemu/target-i386/cm-atomic.c
341,366d340
<     uint64_t edx_eax, ecx_ebx, res;
<     int eflags;
<     unsigned long q_addr;
<     eflags = helper_cc_compute_all(CC_OP);
<     CM_GET_QEMU_ADDR(q_addr, a0);
<     edx_eax = (((uint64_t)EDX << 32) | (uint32_t)EAX);
<     ecx_ebx = (((uint64_t)ECX << 32) | (uint32_t)EBX);
<     res = atomic_compare_exchangeq((uint64_t *)q_addr, edx_eax, ecx_ebx);
<     mb();
<     if (res == edx_eax) {
<          eflags |= CC_Z;
<     } else {
<         EDX = (uint32_t)(res >> 32);
<         EAX = (uint32_t)res;
<         eflags &= ~CC_Z;
<     }
<     CC_SRC = eflags;
< }
< void helper_atomic_cmpxchg16b(target_ulong a0)
< {
374,376c348,350
<     uint64_t old_rax = *(uint64_t *)q_addr;
<     uint64_t old_rdx = *(uint64_t *)(q_addr + 8);
<     res = atomic_compare_exchange16b((uint64_t *)q_addr, EAX, EDX, EBX, ECX);
---
>     uint32_t old_EAX=*(uint32_t *)q_addr;
>     uint32_t old_EDX=*(uint32_t *)(q_addr+4);
>     res = atomic_compare_exchange8b((uint64_t *)q_addr, EAX, EDX, EBX, ECX);
380c354
<         eflags |= CC_Z;         /* swap success */
---
>          eflags |= CC_Z;
382,384c356,358
<         EDX = old_rdx;
<         EAX = old_rax;
<         eflags &= ~CC_Z;        /* read the old value ! */
---
>         EDX = old_EDX;
>         EAX = old_EAX;
>         eflags &= ~CC_Z;
diff -r coremu-0.1.2/qemu/target-i386/cm-helper.h coremu_mips/qemu/target-i386/cm-helper.h
41d40
< DEF_HELPER_1(atomic_cmpxchg16b, void, tl)
57d55
< DEF_HELPER_0(watch_server, void)
diff -r coremu-0.1.2/qemu/vl.c coremu_mips/qemu/vl.c
1327c1327
<         timeout = 1000;
---
>         timeout = 10;//wh: in order to make coremu gui's response quicker
只在 coremu_mips 存在:README

reply via email to

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