~ubuntu-branches/ubuntu/trusty/qemu/trusty

« back to all changes in this revision

Viewing changes to tcg/arm/tcg-target.c

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn
  • Date: 2013-10-22 22:47:07 UTC
  • mfrom: (1.8.3) (10.1.42 sid)
  • Revision ID: package-import@ubuntu.com-20131022224707-1lya34fw3k3f24tv
Tags: 1.6.0+dfsg-2ubuntu1
* Merge 1.6.0~rc0+dfsg-2exp from debian experimental.  Remaining changes:
  - debian/control
    * update maintainer
    * remove libiscsi, usb-redir, vde, vnc-jpeg, and libssh2-1-dev
      from build-deps
    * enable rbd
    * add qemu-system and qemu-common B/R to qemu-keymaps
    * add D:udev, R:qemu, R:qemu-common and B:qemu-common to
      qemu-system-common
    * qemu-system-arm, qemu-system-ppc, qemu-system-sparc:
      - add qemu-kvm to Provides
      - add qemu-common, qemu-kvm, kvm to B/R
      - remove openbios-sparc from qemu-system-sparc D
      - drop openbios-ppc and openhackware Depends to Suggests (for now)
    * qemu-system-x86:
      - add qemu-common to Breaks/Replaces.
      - add cpu-checker to Recommends.
    * qemu-user: add B/R:qemu-kvm
    * qemu-kvm:
      - add armhf armel powerpc sparc to Architecture
      - C/R/P: qemu-kvm-spice
    * add qemu-common package
    * drop qemu-slof which is not packaged in ubuntu
  - add qemu-system-common.links for tap ifup/down scripts and OVMF link.
  - qemu-system-x86.links:
    * remove pxe rom links which are in kvm-ipxe
    * add symlink for kvm.1 manpage
  - debian/rules
    * add kvm-spice symlink to qemu-kvm
    * call dh_installmodules for qemu-system-x86
    * update dh_installinit to install upstart script
    * run dh_installman (Closes: #709241) (cherrypicked from 1.5.0+dfsg-2)
  - Add qemu-utils.links for kvm-* symlinks.
  - Add qemu-system-x86.qemu-kvm.upstart and .default
  - Add qemu-system-x86.modprobe to set nesting=1
  - Add qemu-system-common.preinst to add kvm group
  - qemu-system-common.postinst: remove bad group acl if there, then have
    udev relabel /dev/kvm.
  - New linaro patches from qemu-linaro rebasing branch
  - Dropped patches:
    * xen-simplify-xen_enabled.patch
    * sparc-linux-user-fix-missing-symbols-in-.rel-.rela.plt-sections.patch
    * main_loop-do-not-set-nonblocking-if-xen_enabled.patch
    * xen_machine_pv-do-not-create-a-dummy-CPU-in-machine-.patch
    * virtio-rng-fix-crash
  - Kept patches:
    * expose_vms_qemu64cpu.patch - updated
    * linaro arm patches from qemu-linaro rebasing branch
  - New patches:
    * fix-pci-add: change CONFIG variable in ifdef to make sure that
      pci_add is defined.
* Add linaro patches
* Add experimental mach-virt patches for arm virtualization.
* qemu-system-common.install: add debian/tmp/usr/lib to install the
  qemu-bridge-helper

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 * THE SOFTWARE.
23
23
 */
24
24
 
25
 
#if defined(__ARM_ARCH_7__) ||  \
26
 
    defined(__ARM_ARCH_7A__) || \
27
 
    defined(__ARM_ARCH_7EM__) || \
28
 
    defined(__ARM_ARCH_7M__) || \
29
 
    defined(__ARM_ARCH_7R__)
30
 
#define USE_ARMV7_INSTRUCTIONS
31
 
#endif
32
 
 
33
 
#if defined(USE_ARMV7_INSTRUCTIONS) || \
34
 
    defined(__ARM_ARCH_6J__) || \
35
 
    defined(__ARM_ARCH_6K__) || \
36
 
    defined(__ARM_ARCH_6T2__) || \
37
 
    defined(__ARM_ARCH_6Z__) || \
38
 
    defined(__ARM_ARCH_6ZK__)
39
 
#define USE_ARMV6_INSTRUCTIONS
40
 
#endif
41
 
 
42
 
#if defined(USE_ARMV6_INSTRUCTIONS) || \
43
 
    defined(__ARM_ARCH_5T__) || \
44
 
    defined(__ARM_ARCH_5TE__) || \
45
 
    defined(__ARM_ARCH_5TEJ__)
46
 
#define USE_ARMV5_INSTRUCTIONS
47
 
#endif
48
 
 
49
 
#ifdef USE_ARMV5_INSTRUCTIONS
50
 
static const int use_armv5_instructions = 1;
51
 
#else
52
 
static const int use_armv5_instructions = 0;
53
 
#endif
54
 
#undef USE_ARMV5_INSTRUCTIONS
55
 
 
56
 
#ifdef USE_ARMV6_INSTRUCTIONS
57
 
static const int use_armv6_instructions = 1;
58
 
#else
59
 
static const int use_armv6_instructions = 0;
60
 
#endif
61
 
#undef USE_ARMV6_INSTRUCTIONS
62
 
 
63
 
#ifdef USE_ARMV7_INSTRUCTIONS
64
 
static const int use_armv7_instructions = 1;
65
 
#else
66
 
static const int use_armv7_instructions = 0;
67
 
#endif
68
 
#undef USE_ARMV7_INSTRUCTIONS
 
25
/* The __ARM_ARCH define is provided by gcc 4.8.  Construct it otherwise.  */
 
26
#ifndef __ARM_ARCH
 
27
# if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
 
28
     || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
 
29
     || defined(__ARM_ARCH_7EM__)
 
30
#  define __ARM_ARCH 7
 
31
# elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
 
32
       || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) \
 
33
       || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__)
 
34
#  define __ARM_ARCH 6
 
35
# elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5E__) \
 
36
       || defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5TE__) \
 
37
       || defined(__ARM_ARCH_5TEJ__)
 
38
#  define __ARM_ARCH 5
 
39
# else
 
40
#  define __ARM_ARCH 4
 
41
# endif
 
42
#endif
 
43
 
 
44
static int arm_arch = __ARM_ARCH;
 
45
 
 
46
#if defined(__ARM_ARCH_5T__) \
 
47
    || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5TEJ__)
 
48
# define use_armv5t_instructions 1
 
49
#else
 
50
# define use_armv5t_instructions use_armv6_instructions
 
51
#endif
 
52
 
 
53
#define use_armv6_instructions  (__ARM_ARCH >= 6 || arm_arch >= 6)
 
54
#define use_armv7_instructions  (__ARM_ARCH >= 7 || arm_arch >= 7)
 
55
 
 
56
#ifndef use_idiv_instructions
 
57
bool use_idiv_instructions;
 
58
#endif
 
59
#ifdef CONFIG_GETAUXVAL
 
60
# include <sys/auxv.h>
 
61
#endif
69
62
 
70
63
#ifndef NDEBUG
71
64
static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
1023
1016
    if (val - 8 < 0x02000000 && val - 8 >= -0x02000000) {
1024
1017
        if (addr & 1) {
1025
1018
            /* Use BLX if the target is in Thumb mode */
1026
 
            if (!use_armv5_instructions) {
 
1019
            if (!use_armv5t_instructions) {
1027
1020
                tcg_abort();
1028
1021
            }
1029
1022
            tcg_out_blx_imm(s, val);
1042
1035
 
1043
1036
static inline void tcg_out_callr(TCGContext *s, int cond, int arg)
1044
1037
{
1045
 
    if (use_armv5_instructions) {
 
1038
    if (use_armv5t_instructions) {
1046
1039
        tcg_out_blx(s, cond, arg);
1047
1040
    } else {
1048
1041
        tcg_out_dat_reg(s, cond, ARITH_MOV, TCG_REG_R14, 0,
1926
1919
    case INDEX_op_divu_i32:
1927
1920
        tcg_out_udiv(s, COND_AL, args[0], args[1], args[2]);
1928
1921
        break;
1929
 
    case INDEX_op_rem_i32:
1930
 
        tcg_out_sdiv(s, COND_AL, TCG_REG_TMP, args[1], args[2]);
1931
 
        tcg_out_mul32(s, COND_AL, TCG_REG_TMP, TCG_REG_TMP, args[2]);
1932
 
        tcg_out_dat_reg(s, COND_AL, ARITH_SUB, args[0], args[1], TCG_REG_TMP,
1933
 
                        SHIFT_IMM_LSL(0));
1934
 
        break;
1935
 
    case INDEX_op_remu_i32:
1936
 
        tcg_out_udiv(s, COND_AL, TCG_REG_TMP, args[1], args[2]);
1937
 
        tcg_out_mul32(s, COND_AL, TCG_REG_TMP, TCG_REG_TMP, args[2]);
1938
 
        tcg_out_dat_reg(s, COND_AL, ARITH_SUB, args[0], args[1], TCG_REG_TMP,
1939
 
                        SHIFT_IMM_LSL(0));
1940
 
        break;
1941
1922
 
1942
1923
    default:
1943
1924
        tcg_abort();
2041
2022
 
2042
2023
    { INDEX_op_deposit_i32, { "r", "0", "rZ" } },
2043
2024
 
2044
 
#if TCG_TARGET_HAS_div_i32
2045
2025
    { INDEX_op_div_i32, { "r", "r", "r" } },
2046
 
    { INDEX_op_rem_i32, { "r", "r", "r" } },
2047
2026
    { INDEX_op_divu_i32, { "r", "r", "r" } },
2048
 
    { INDEX_op_remu_i32, { "r", "r", "r" } },
2049
 
#endif
2050
2027
 
2051
2028
    { -1 },
2052
2029
};
2053
2030
 
2054
2031
static void tcg_target_init(TCGContext *s)
2055
2032
{
2056
 
#if !defined(CONFIG_USER_ONLY)
2057
 
    /* fail safe */
2058
 
    if ((1 << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry))
2059
 
        tcg_abort();
2060
 
#endif
 
2033
#if defined(CONFIG_GETAUXVAL)
 
2034
    /* Only probe for the platform and capabilities if we havn't already
 
2035
       determined maximum values at compile time.  */
 
2036
# if !defined(use_idiv_instructions)
 
2037
    {
 
2038
        unsigned long hwcap = getauxval(AT_HWCAP);
 
2039
        use_idiv_instructions = (hwcap & HWCAP_ARM_IDIVA) != 0;
 
2040
    }
 
2041
# endif
 
2042
    if (__ARM_ARCH < 7) {
 
2043
        const char *pl = (const char *)getauxval(AT_PLATFORM);
 
2044
        if (pl != NULL && pl[0] == 'v' && pl[1] >= '4' && pl[1] <= '9') {
 
2045
            arm_arch = pl[1] - '0';
 
2046
        }
 
2047
    }
 
2048
#endif /* GETAUXVAL */
2061
2049
 
2062
2050
    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff);
2063
2051
    tcg_regset_set32(tcg_target_call_clobber_regs, 0,
2100
2088
    tcg_out_movi32(s, COND_AL, ret, arg);
2101
2089
}
2102
2090
 
 
2091
/* Compute frame size via macros, to share between tcg_target_qemu_prologue
 
2092
   and tcg_register_jit.  */
 
2093
 
 
2094
#define PUSH_SIZE  ((11 - 4 + 1 + 1) * sizeof(tcg_target_long))
 
2095
 
 
2096
#define FRAME_SIZE \
 
2097
    ((PUSH_SIZE \
 
2098
      + TCG_STATIC_CALL_ARGS_SIZE \
 
2099
      + CPU_TEMP_BUF_NLONGS * sizeof(long) \
 
2100
      + TCG_TARGET_STACK_ALIGN - 1) \
 
2101
     & -TCG_TARGET_STACK_ALIGN)
 
2102
 
2103
2103
static void tcg_target_qemu_prologue(TCGContext *s)
2104
2104
{
2105
 
    int frame_size;
 
2105
    int stack_addend;
2106
2106
 
2107
2107
    /* Calling convention requires us to save r4-r11 and lr.  */
2108
2108
    /* stmdb sp!, { r4 - r11, lr } */
2109
2109
    tcg_out32(s, (COND_AL << 28) | 0x092d4ff0);
2110
2110
 
2111
 
    /* Allocate the local stack frame.  */
2112
 
    frame_size = TCG_STATIC_CALL_ARGS_SIZE;
2113
 
    frame_size += CPU_TEMP_BUF_NLONGS * sizeof(long);
2114
 
    /* We saved an odd number of registers above; keep an 8 aligned stack.  */
2115
 
    frame_size = ((frame_size + TCG_TARGET_STACK_ALIGN - 1)
2116
 
                  & -TCG_TARGET_STACK_ALIGN) + 4;
 
2111
    /* Reserve callee argument and tcg temp space.  */
 
2112
    stack_addend = FRAME_SIZE - PUSH_SIZE;
2117
2113
 
2118
2114
    tcg_out_dat_rI(s, COND_AL, ARITH_SUB, TCG_REG_CALL_STACK,
2119
 
                   TCG_REG_CALL_STACK, frame_size, 1);
 
2115
                   TCG_REG_CALL_STACK, stack_addend, 1);
2120
2116
    tcg_set_frame(s, TCG_REG_CALL_STACK, TCG_STATIC_CALL_ARGS_SIZE,
2121
2117
                  CPU_TEMP_BUF_NLONGS * sizeof(long));
2122
2118
 
2127
2123
 
2128
2124
    /* Epilogue.  We branch here via tb_ret_addr.  */
2129
2125
    tcg_out_dat_rI(s, COND_AL, ARITH_ADD, TCG_REG_CALL_STACK,
2130
 
                   TCG_REG_CALL_STACK, frame_size, 1);
 
2126
                   TCG_REG_CALL_STACK, stack_addend, 1);
2131
2127
 
2132
2128
    /* ldmia sp!, { r4 - r11, pc } */
2133
2129
    tcg_out32(s, (COND_AL << 28) | 0x08bd8ff0);
2134
2130
}
 
2131
 
 
2132
typedef struct {
 
2133
    DebugFrameCIE cie;
 
2134
    DebugFrameFDEHeader fde;
 
2135
    uint8_t fde_def_cfa[4];
 
2136
    uint8_t fde_reg_ofs[18];
 
2137
} DebugFrame;
 
2138
 
 
2139
#define ELF_HOST_MACHINE EM_ARM
 
2140
 
 
2141
/* We're expecting a 2 byte uleb128 encoded value.  */
 
2142
QEMU_BUILD_BUG_ON(FRAME_SIZE >= (1 << 14));
 
2143
 
 
2144
static DebugFrame debug_frame = {
 
2145
    .cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
 
2146
    .cie.id = -1,
 
2147
    .cie.version = 1,
 
2148
    .cie.code_align = 1,
 
2149
    .cie.data_align = 0x7c,             /* sleb128 -4 */
 
2150
    .cie.return_column = 14,
 
2151
 
 
2152
    /* Total FDE size does not include the "len" member.  */
 
2153
    .fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, fde.cie_offset),
 
2154
 
 
2155
    .fde_def_cfa = {
 
2156
        12, 13,                         /* DW_CFA_def_cfa sp, ... */
 
2157
        (FRAME_SIZE & 0x7f) | 0x80,     /* ... uleb128 FRAME_SIZE */
 
2158
        (FRAME_SIZE >> 7)
 
2159
    },
 
2160
    .fde_reg_ofs = {
 
2161
        /* The following must match the stmdb in the prologue.  */
 
2162
        0x8e, 1,                        /* DW_CFA_offset, lr, -4 */
 
2163
        0x8b, 2,                        /* DW_CFA_offset, r11, -8 */
 
2164
        0x8a, 3,                        /* DW_CFA_offset, r10, -12 */
 
2165
        0x89, 4,                        /* DW_CFA_offset, r9, -16 */
 
2166
        0x88, 5,                        /* DW_CFA_offset, r8, -20 */
 
2167
        0x87, 6,                        /* DW_CFA_offset, r7, -24 */
 
2168
        0x86, 7,                        /* DW_CFA_offset, r6, -28 */
 
2169
        0x85, 8,                        /* DW_CFA_offset, r5, -32 */
 
2170
        0x84, 9,                        /* DW_CFA_offset, r4, -36 */
 
2171
    }
 
2172
};
 
2173
 
 
2174
void tcg_register_jit(void *buf, size_t buf_size)
 
2175
{
 
2176
    debug_frame.fde.func_start = (tcg_target_long) buf;
 
2177
    debug_frame.fde.func_len = buf_size;
 
2178
 
 
2179
    tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
 
2180
}