Commit a8490473 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20150528' into staging



A set of patches add support for vector registers on s390x.
Notable: Floating point registers and vector registers overlap,
so extra care is needed so that we end up with a consistent state
in all cases.

# gpg: Signature made Thu May 28 09:37:27 2015 BST using RSA key ID C6F02FAF
# gpg: Good signature from "Cornelia Huck <huckc@linux.vnet.ibm.com>"
# gpg:                 aka "Cornelia Huck <cornelia.huck@de.ibm.com>"

* remotes/cohuck/tags/s390x-20150528:
  s390x: Enable vector processing capability
  s390x: Migrate vector registers
  s390x: Add vector registers to ELF dump
  linux/elf.h update
  s390x: Add vector registers to HMP output
  s390x: gdb updates for vector registers
  gdb-xml: Include XML for s390 vector registers
  s390x: Store Additional Status SIGP order
  s390x: Vector Register IOCTLs
  s390x: Common access to floating point registers

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents bc3004f0 46ca6b3b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -5292,7 +5292,7 @@ case "$target_name" in
    echo "TARGET_ABI32=y" >> $config_target_mak
  ;;
  s390x)
    gdb_xml_files="s390x-core64.xml s390-acr.xml s390-fpr.xml"
    gdb_xml_files="s390x-core64.xml s390-acr.xml s390-fpr.xml s390-vx.xml"
  ;;
  tricore)
  ;;

gdb-xml/s390-vx.xml

0 → 100644
+59 −0
Original line number Diff line number Diff line
<?xml version="1.0"?>
<!-- Copyright (C) 2010-2014 Free Software Foundation, Inc.

     Copying and distribution of this file, with or without modification,
     are permitted in any medium without royalty provided the copyright
     notice and this notice are preserved.  -->

<!DOCTYPE feature SYSTEM "gdb-target.dtd">
<feature name="org.gnu.gdb.s390.vx">
  <vector id="v4f" type="ieee_single" count="4"/>
  <vector id="v2d" type="ieee_double" count="2"/>
  <vector id="v16i8" type="int8" count="16"/>
  <vector id="v8i16" type="int16" count="8"/>
  <vector id="v4i32" type="int32" count="4"/>
  <vector id="v2i64" type="int64" count="2"/>
  <union id="vec128">
    <field name="v4_float" type="v4f"/>
    <field name="v2_double" type="v2d"/>
    <field name="v16_int8" type="v16i8"/>
    <field name="v8_int16" type="v8i16"/>
    <field name="v4_int32" type="v4i32"/>
    <field name="v2_int64" type="v2i64"/>
    <field name="uint128" type="uint128"/>
  </union>

  <reg name="v0l" bitsize="64" type="uint64"/>
  <reg name="v1l" bitsize="64" type="uint64"/>
  <reg name="v2l" bitsize="64" type="uint64"/>
  <reg name="v3l" bitsize="64" type="uint64"/>
  <reg name="v4l" bitsize="64" type="uint64"/>
  <reg name="v5l" bitsize="64" type="uint64"/>
  <reg name="v6l" bitsize="64" type="uint64"/>
  <reg name="v7l" bitsize="64" type="uint64"/>
  <reg name="v8l" bitsize="64" type="uint64"/>
  <reg name="v9l" bitsize="64" type="uint64"/>
  <reg name="v10l" bitsize="64" type="uint64"/>
  <reg name="v11l" bitsize="64" type="uint64"/>
  <reg name="v12l" bitsize="64" type="uint64"/>
  <reg name="v13l" bitsize="64" type="uint64"/>
  <reg name="v14l" bitsize="64" type="uint64"/>
  <reg name="v15l" bitsize="64" type="uint64"/>

  <reg name="v16" bitsize="128" type="vec128"/>
  <reg name="v17" bitsize="128" type="vec128"/>
  <reg name="v18" bitsize="128" type="vec128"/>
  <reg name="v19" bitsize="128" type="vec128"/>
  <reg name="v20" bitsize="128" type="vec128"/>
  <reg name="v21" bitsize="128" type="vec128"/>
  <reg name="v22" bitsize="128" type="vec128"/>
  <reg name="v23" bitsize="128" type="vec128"/>
  <reg name="v24" bitsize="128" type="vec128"/>
  <reg name="v25" bitsize="128" type="vec128"/>
  <reg name="v26" bitsize="128" type="vec128"/>
  <reg name="v27" bitsize="128" type="vec128"/>
  <reg name="v28" bitsize="128" type="vec128"/>
  <reg name="v29" bitsize="128" type="vec128"/>
  <reg name="v30" bitsize="128" type="vec128"/>
  <reg name="v31" bitsize="128" type="vec128"/>
</feature>
+2 −0
Original line number Diff line number Diff line
@@ -1456,6 +1456,8 @@ typedef struct elf64_shdr {
#define NT_TASKSTRUCT	4
#define NT_AUXV		6
#define NT_PRXFPREG     0x46e62b7f      /* copied from gdb5.1/include/elf/common.h */
#define NT_S390_VXRS_HIGH 0x30a         /* s390 vector registers 16-31 */
#define NT_S390_VXRS_LOW  0x309         /* s390 vector registers 0-15 (lower half) */
#define NT_S390_PREFIX  0x305           /* s390 prefix register */
#define NT_S390_CTRS    0x304           /* s390 control registers */
#define NT_S390_TODPREG 0x303           /* s390 TOD programmable register */
+2 −2
Original line number Diff line number Diff line
@@ -4098,7 +4098,7 @@ static void save_sigregs(CPUS390XState *env, target_sigregs *sregs)
     */
    //save_fp_regs(&current->thread.fp_regs); FIXME
    for (i = 0; i < 16; i++) {
        __put_user(env->fregs[i].ll, &sregs->fpregs.fprs[i]);
        __put_user(get_freg(env, i)->ll, &sregs->fpregs.fprs[i]);
    }
}

@@ -4239,7 +4239,7 @@ restore_sigregs(CPUS390XState *env, target_sigregs *sc)
        __get_user(env->aregs[i], &sc->regs.acrs[i]);
    }
    for (i = 0; i < 16; i++) {
        __get_user(env->fregs[i].ll, &sc->fpregs.fprs[i]);
        __get_user(get_freg(env, i)->ll, &sc->fpregs.fprs[i]);
    }

    return err;
+41 −1
Original line number Diff line number Diff line
@@ -44,6 +44,18 @@ struct S390xElfFpregsetStruct {

typedef struct S390xElfFpregsetStruct S390xElfFpregset;

struct S390xElfVregsLoStruct {
    uint64_t vregs[16];
} QEMU_PACKED;

typedef struct S390xElfVregsLoStruct S390xElfVregsLo;

struct S390xElfVregsHiStruct {
    uint64_t vregs[16][2];
} QEMU_PACKED;

typedef struct S390xElfVregsHiStruct S390xElfVregsHi;

typedef struct noteStruct {
    Elf64_Nhdr hdr;
    char name[5];
@@ -51,6 +63,8 @@ typedef struct noteStruct {
    union {
        S390xElfPrstatus prstatus;
        S390xElfFpregset fpregset;
        S390xElfVregsLo vregslo;
        S390xElfVregsHi vregshi;
        uint32_t prefix;
        uint64_t timer;
        uint64_t todcmp;
@@ -78,14 +92,38 @@ static void s390x_write_elf64_prstatus(Note *note, S390CPU *cpu)
static void s390x_write_elf64_fpregset(Note *note, S390CPU *cpu)
{
    int i;
    CPUS390XState *cs = &cpu->env;

    note->hdr.n_type = cpu_to_be32(NT_FPREGSET);
    note->contents.fpregset.fpc = cpu_to_be32(cpu->env.fpc);
    for (i = 0; i <= 15; i++) {
        note->contents.fpregset.fprs[i] = cpu_to_be64(cpu->env.fregs[i].ll);
        note->contents.fpregset.fprs[i] = cpu_to_be64(get_freg(cs, i)->ll);
    }
}

static void s390x_write_elf64_vregslo(Note *note, S390CPU *cpu)
{
    int i;

    note->hdr.n_type = cpu_to_be32(NT_S390_VXRS_LOW);
    for (i = 0; i <= 15; i++) {
        note->contents.vregslo.vregs[i] = cpu_to_be64(cpu->env.vregs[i][1].ll);
    }
}

static void s390x_write_elf64_vregshi(Note *note, S390CPU *cpu)
{
    int i;
    S390xElfVregsHi *temp_vregshi;

    temp_vregshi = &note->contents.vregshi;

    note->hdr.n_type = cpu_to_be32(NT_S390_VXRS_HIGH);
    for (i = 0; i <= 15; i++) {
        temp_vregshi->vregs[i][0] = cpu_to_be64(cpu->env.vregs[i + 16][0].ll);
        temp_vregshi->vregs[i][1] = cpu_to_be64(cpu->env.vregs[i + 16][1].ll);
    }
}

static void s390x_write_elf64_timer(Note *note, S390CPU *cpu)
{
@@ -134,6 +172,8 @@ static const struct NoteFuncDescStruct {
    {sizeof(((Note *)0)->contents.timer),    s390x_write_elf64_timer},
    {sizeof(((Note *)0)->contents.todcmp),   s390x_write_elf64_todcmp},
    {sizeof(((Note *)0)->contents.todpreg),  s390x_write_elf64_todpreg},
    {sizeof(((Note *)0)->contents.vregslo),  s390x_write_elf64_vregslo},
    {sizeof(((Note *)0)->contents.vregshi),  s390x_write_elf64_vregshi},
    { 0, NULL}
};

Loading