Revision 5bfb56b2

b/linux-user/main.c
634 634
                queue_signal(info.si_signo, &info);
635 635
            }
636 636
            break;
637
        case 0x16e:
638
            flush_windows(env);
639
            sparc64_get_context(env);
640
            break;
641
        case 0x16f:
642
            flush_windows(env);
643
            sparc64_set_context(env);
644
            break;
637 645
#endif
638 646
        case EXCP_INTERRUPT:
639 647
            /* just indicate that signals should be handled asap */
b/linux-user/qemu.h
160 160
void handle_vm86_trap(CPUX86State *env, int trapno);
161 161
void handle_vm86_fault(CPUX86State *env);
162 162
int do_vm86(CPUX86State *env, long subfunction, target_ulong v86_addr);
163
#elif defined(TARGET_SPARC64)
164
void sparc64_set_context(CPUSPARCState *env);
165
void sparc64_get_context(CPUSPARCState *env);
163 166
#endif
164 167

  
165 168
/* mmap.c */
b/linux-user/signal.c
1443 1443
#define UREG_I0        0
1444 1444
#define UREG_I1        1
1445 1445
#define UREG_I2        2
1446
#define UREG_I3        3
1447
#define UREG_I4        4
1448
#define UREG_I5        5
1446 1449
#define UREG_I6        6
1447 1450
#define UREG_I7        7
1448 1451
#define UREG_L0	       8
......
1704 1707
    return -ENOSYS;
1705 1708
}
1706 1709

  
1710
#ifdef TARGET_SPARC64
1711
#define MC_TSTATE 0
1712
#define MC_PC 1
1713
#define MC_NPC 2
1714
#define MC_Y 3
1715
#define MC_G1 4
1716
#define MC_G2 5
1717
#define MC_G3 6
1718
#define MC_G4 7
1719
#define MC_G5 8
1720
#define MC_G6 9
1721
#define MC_G7 10
1722
#define MC_O0 11
1723
#define MC_O1 12
1724
#define MC_O2 13
1725
#define MC_O3 14
1726
#define MC_O4 15
1727
#define MC_O5 16
1728
#define MC_O6 17
1729
#define MC_O7 18
1730
#define MC_NGREG 19
1731

  
1732
typedef target_ulong target_mc_greg_t;
1733
typedef target_mc_greg_t target_mc_gregset_t[MC_NGREG];
1734

  
1735
struct target_mc_fq {
1736
    target_ulong *mcfq_addr;
1737
    uint32_t mcfq_insn;
1738
};
1739

  
1740
struct target_mc_fpu {
1741
    union {
1742
        uint32_t sregs[32];
1743
        uint64_t dregs[32];
1744
        //uint128_t qregs[16];
1745
    } mcfpu_fregs;
1746
    target_ulong mcfpu_fsr;
1747
    target_ulong mcfpu_fprs;
1748
    target_ulong mcfpu_gsr;
1749
    struct target_mc_fq *mcfpu_fq;
1750
    unsigned char mcfpu_qcnt;
1751
    unsigned char mcfpu_qentsz;
1752
    unsigned char mcfpu_enab;
1753
};
1754
typedef struct target_mc_fpu target_mc_fpu_t;
1755

  
1756
typedef struct {
1757
    target_mc_gregset_t mc_gregs;
1758
    target_mc_greg_t mc_fp;
1759
    target_mc_greg_t mc_i7;
1760
    target_mc_fpu_t mc_fpregs;
1761
} target_mcontext_t;
1762

  
1763
struct target_ucontext {
1764
    struct target_ucontext *uc_link;
1765
    target_ulong uc_flags;
1766
    target_sigset_t uc_sigmask;
1767
    target_mcontext_t uc_mcontext;
1768
};
1769

  
1770
/* A V9 register window */
1771
struct target_reg_window {
1772
    target_ulong locals[8];
1773
    target_ulong ins[8];
1774
};
1775

  
1776
#define TARGET_STACK_BIAS 2047
1777

  
1778
/* {set, get}context() needed for 64-bit SparcLinux userland. */
1779
void sparc64_set_context(CPUSPARCState *env)
1780
{
1781
    struct target_ucontext *ucp = (struct target_ucontext *)
1782
        env->regwptr[UREG_I0];
1783
    target_mc_gregset_t *grp;
1784
    target_ulong pc, npc, tstate;
1785
    target_ulong fp, i7;
1786
    unsigned char fenab;
1787
    int err;
1788
    unsigned int i;
1789
    target_ulong *src, *dst;
1790

  
1791
    grp  = &ucp->uc_mcontext.mc_gregs;
1792
    err  = get_user(pc, &((*grp)[MC_PC]));
1793
    err |= get_user(npc, &((*grp)[MC_NPC]));
1794
    if (err || ((pc | npc) & 3))
1795
        goto do_sigsegv;
1796
    if (env->regwptr[UREG_I1]) {
1797
        target_sigset_t target_set;
1798
        sigset_t set;
1799

  
1800
        if (TARGET_NSIG_WORDS == 1) {
1801
            if (get_user(target_set.sig[0], &ucp->uc_sigmask.sig[0]))
1802
                goto do_sigsegv;
1803
        } else {
1804
            src = &ucp->uc_sigmask;
1805
            dst = &target_set;
1806
            for (i = 0; i < sizeof(target_sigset_t) / sizeof(target_ulong);
1807
                 i++, dst++, src++)
1808
                err |= get_user(dst, src);
1809
            if (err)
1810
                goto do_sigsegv;
1811
        }
1812
        target_to_host_sigset_internal(&set, &target_set);
1813
        sigprocmask(SIG_SETMASK, &set, NULL);
1814
    }
1815
    env->pc = pc;
1816
    env->npc = npc;
1817
    err |= get_user(env->y, &((*grp)[MC_Y]));
1818
    err |= get_user(tstate, &((*grp)[MC_TSTATE]));
1819
    env->asi = (tstate >> 24) & 0xff;
1820
    PUT_CCR(env, tstate >> 32);
1821
    PUT_CWP64(env, tstate & 0x1f);
1822
    err |= get_user(env->gregs[1], (&(*grp)[MC_G1]));
1823
    err |= get_user(env->gregs[2], (&(*grp)[MC_G2]));
1824
    err |= get_user(env->gregs[3], (&(*grp)[MC_G3]));
1825
    err |= get_user(env->gregs[4], (&(*grp)[MC_G4]));
1826
    err |= get_user(env->gregs[5], (&(*grp)[MC_G5]));
1827
    err |= get_user(env->gregs[6], (&(*grp)[MC_G6]));
1828
    err |= get_user(env->gregs[7], (&(*grp)[MC_G7]));
1829
    err |= get_user(env->regwptr[UREG_I0], (&(*grp)[MC_O0]));
1830
    err |= get_user(env->regwptr[UREG_I1], (&(*grp)[MC_O1]));
1831
    err |= get_user(env->regwptr[UREG_I2], (&(*grp)[MC_O2]));
1832
    err |= get_user(env->regwptr[UREG_I3], (&(*grp)[MC_O3]));
1833
    err |= get_user(env->regwptr[UREG_I4], (&(*grp)[MC_O4]));
1834
    err |= get_user(env->regwptr[UREG_I5], (&(*grp)[MC_O5]));
1835
    err |= get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6]));
1836
    err |= get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7]));
1837

  
1838
    err |= get_user(fp, &(ucp->uc_mcontext.mc_fp));
1839
    err |= get_user(i7, &(ucp->uc_mcontext.mc_i7));
1840
    err |= put_user(fp,
1841
                    (&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[6])));
1842
    err |= put_user(i7,
1843
                    (&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[7])));
1844

  
1845
    err |= get_user(fenab, &(ucp->uc_mcontext.mc_fpregs.mcfpu_enab));
1846
    err |= get_user(env->fprs, &(ucp->uc_mcontext.mc_fpregs.mcfpu_fprs));
1847
    src = &(ucp->uc_mcontext.mc_fpregs.mcfpu_fregs);
1848
    dst = &env->fpr;
1849
    for (i = 0; i < 64; i++, dst++, src++)
1850
        err |= get_user(dst, src);
1851
    err |= get_user(env->fsr,
1852
                    &(ucp->uc_mcontext.mc_fpregs.mcfpu_fsr));
1853
    err |= get_user(env->gsr,
1854
                    &(ucp->uc_mcontext.mc_fpregs.mcfpu_gsr));
1855
    if (err)
1856
        goto do_sigsegv;
1857

  
1858
    return;
1859
 do_sigsegv:
1860
    force_sig(SIGSEGV);
1861
}
1862

  
1863
void sparc64_get_context(CPUSPARCState *env)
1864
{
1865
    struct target_ucontext *ucp = (struct target_ucontext *)
1866
        env->regwptr[UREG_I0];
1867
    target_mc_gregset_t *grp;
1868
    target_mcontext_t *mcp;
1869
    target_ulong fp, i7;
1870
    int err;
1871
    unsigned int i;
1872
    target_ulong *src, *dst;
1873
    target_sigset_t target_set;
1874
    sigset_t set;
1875

  
1876
    mcp = &ucp->uc_mcontext;
1877
    grp = &mcp->mc_gregs;
1878

  
1879
    /* Skip over the trap instruction, first. */
1880
    env->pc = env->npc;
1881
    env->npc += 4;
1882

  
1883
    err = 0;
1884

  
1885
    sigprocmask(0, NULL, &set);
1886
    host_to_target_sigset_internal(&target_set, &set);
1887
    if (TARGET_NSIG_WORDS == 1)
1888
        err |= put_user(target_set.sig[0],
1889
                        (target_ulong *)&ucp->uc_sigmask);
1890
    else {
1891
        src = &target_set;
1892
        dst = &ucp->uc_sigmask;
1893
        for (i = 0; i < sizeof(target_sigset_t) / sizeof(target_ulong);
1894
             i++, dst++, src++)
1895
            err |= put_user(src, dst);
1896
        if (err)
1897
            goto do_sigsegv;
1898
    }
1899

  
1900
    err |= put_user(env->tstate, &((*grp)[MC_TSTATE]));
1901
    err |= put_user(env->pc, &((*grp)[MC_PC]));
1902
    err |= put_user(env->npc, &((*grp)[MC_NPC]));
1903
    err |= put_user(env->y, &((*grp)[MC_Y]));
1904
    err |= put_user(env->gregs[1], &((*grp)[MC_G1]));
1905
    err |= put_user(env->gregs[2], &((*grp)[MC_G2]));
1906
    err |= put_user(env->gregs[3], &((*grp)[MC_G3]));
1907
    err |= put_user(env->gregs[4], &((*grp)[MC_G4]));
1908
    err |= put_user(env->gregs[5], &((*grp)[MC_G5]));
1909
    err |= put_user(env->gregs[6], &((*grp)[MC_G6]));
1910
    err |= put_user(env->gregs[7], &((*grp)[MC_G7]));
1911
    err |= put_user(env->regwptr[UREG_I0], &((*grp)[MC_O0]));
1912
    err |= put_user(env->regwptr[UREG_I1], &((*grp)[MC_O1]));
1913
    err |= put_user(env->regwptr[UREG_I2], &((*grp)[MC_O2]));
1914
    err |= put_user(env->regwptr[UREG_I3], &((*grp)[MC_O3]));
1915
    err |= put_user(env->regwptr[UREG_I4], &((*grp)[MC_O4]));
1916
    err |= put_user(env->regwptr[UREG_I5], &((*grp)[MC_O5]));
1917
    err |= put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]));
1918
    err |= put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]));
1919

  
1920
    err |= get_user(fp,
1921
                    (&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[6])));
1922
    err |= get_user(i7,
1923
                    (&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[7])));
1924
    err |= put_user(fp, &(mcp->mc_fp));
1925
    err |= put_user(i7, &(mcp->mc_i7));
1926

  
1927
    src = &env->fpr;
1928
    dst = &(ucp->uc_mcontext.mc_fpregs.mcfpu_fregs);
1929
    for (i = 0; i < 64; i++, dst++, src++)
1930
        err |= put_user(src, dst);
1931
    err |= put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr));
1932
    err |= put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr));
1933
    err |= put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs));
1934

  
1935
    if (err)
1936
        goto do_sigsegv;
1937

  
1938
    return;
1939
 do_sigsegv:
1940
    force_sig(SIGSEGV);
1941
}
1942
#endif
1707 1943
#elif defined(TARGET_MIPS64)
1708 1944

  
1709 1945
# warning signal handling not implemented

Also available in: Unified diff