Commit c9baa30f authored by Richard Henderson's avatar Richard Henderson
Browse files

tcg-s390: Use qemu_getauxval in query_facilities



No need to set up a SIGILL signal handler for detection anymore.

Remove a ton of sanity checks that must be true, given that we're
requiring a 64-bit build (the note about 31-bit KVM is satisfied
by configuring with TCI).

Signed-off-by: default avatarRichard Henderson <rth@twiddle.net>
parent 41d9ea80
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -479,6 +479,20 @@ typedef struct {
#define HWCAP_SPARC_V9		16
#define HWCAP_SPARC_ULTRA3	32

/* Bits present in AT_HWCAP for s390.  */

#define HWCAP_S390_ESAN3        1
#define HWCAP_S390_ZARCH        2
#define HWCAP_S390_STFLE        4
#define HWCAP_S390_MSA          8
#define HWCAP_S390_LDISP        16
#define HWCAP_S390_EIMM         32
#define HWCAP_S390_DFP          64
#define HWCAP_S390_HPAGE        128
#define HWCAP_S390_ETF3EH       256
#define HWCAP_S390_HIGH_GPRS    512
#define HWCAP_S390_TE           1024

/*
 * 68k ELF relocation types
 */
+12 −83
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@
#error "unsupported code generation mode"
#endif

#include "elf.h"

/* ??? The translation blocks produced by TCG are generally small enough to
   be entirely reachable with a 16-bit displacement.  Leaving the option for
   a 32-bit displacement here Just In Case.  */
@@ -2233,91 +2235,18 @@ static void sigill_handler(int sig)

static void query_facilities(void)
{
    struct sigaction sa_old, sa_new;
    unsigned long hwcap = qemu_getauxval(AT_HWCAP);

    /* Is STORE FACILITY LIST EXTENDED available?  Honestly, I believe this
       is present on all 64-bit systems, but let's check for it anyway.  */
    if (hwcap & HWCAP_S390_STFLE) {
        register int r0 __asm__("0");
        register void *r1 __asm__("1");
    int fail;

    memset(&sa_new, 0, sizeof(sa_new));
    sa_new.sa_handler = sigill_handler;
    sigaction(SIGILL, &sa_new, &sa_old);

    /* First, try STORE FACILITY LIST EXTENDED.  If this is present, then
       we need not do any more probing.  Unfortunately, this itself is an
       extension and the original STORE FACILITY LIST instruction is
       kernel-only, storing its results at absolute address 200.  */
        /* stfle 0(%r1) */
        r1 = &facilities;
        asm volatile(".word 0xb2b0,0x1000"
                     : "=r"(r0) : "0"(0), "r"(r1) : "memory", "cc");

    if (got_sigill) {
        /* STORE FACILITY EXTENDED is not available.  Probe for one of each
           kind of instruction that we're interested in.  */
        /* ??? Possibly some of these are in practice never present unless
           the store-facility-extended facility is also present.  But since
           that isn't documented it's just better to probe for each.  */

        /* Test for z/Architecture.  Required even in 31-bit mode.  */
        got_sigill = 0;
        /* agr %r0,%r0 */
        asm volatile(".word 0xb908,0x0000" : "=r"(r0) : : "cc");
        if (!got_sigill) {
            facilities |= FACILITY_ZARCH_ACTIVE;
        }

        /* Test for long displacement.  */
        got_sigill = 0;
        /* ly %r0,0(%r1) */
        r1 = &facilities;
        asm volatile(".word 0xe300,0x1000,0x0058"
                     : "=r"(r0) : "r"(r1) : "cc");
        if (!got_sigill) {
            facilities |= FACILITY_LONG_DISP;
        }

        /* Test for extended immediates.  */
        got_sigill = 0;
        /* afi %r0,0 */
        asm volatile(".word 0xc209,0x0000,0x0000" : : : "cc");
        if (!got_sigill) {
            facilities |= FACILITY_EXT_IMM;
        }

        /* Test for general-instructions-extension.  */
        got_sigill = 0;
        /* msfi %r0,1 */
        asm volatile(".word 0xc201,0x0000,0x0001");
        if (!got_sigill) {
            facilities |= FACILITY_GEN_INST_EXT;
        }
    }

    sigaction(SIGILL, &sa_old, NULL);

    /* The translator currently uses these extensions unconditionally.
       Pruning this back to the base ESA/390 architecture doesn't seem
       worthwhile, since even the KVM target requires z/Arch.  */
    fail = 0;
    if ((facilities & FACILITY_ZARCH_ACTIVE) == 0) {
        fprintf(stderr, "TCG: z/Arch facility is required.\n");
        fprintf(stderr, "TCG: Boot with a 64-bit enabled kernel.\n");
        fail = 1;
    }
    if ((facilities & FACILITY_LONG_DISP) == 0) {
        fprintf(stderr, "TCG: long-displacement facility is required.\n");
        fail = 1;
    }

    /* So far there's just enough support for 31-bit mode to let the
       compile succeed.  This is good enough to run QEMU with KVM.  */
    if (sizeof(void *) != 8) {
        fprintf(stderr, "TCG: 31-bit mode is not supported.\n");
        fail = 1;
    }

    if (fail) {
        exit(-1);
    }
}