Commit 5bfb56b264d18be57f16c519464fc1919db44372

Authored by blueswir1
1 parent 65f9ee8d

Implement sparc64_[gs]et_context


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3334 c046a42c-6fe2-441c-8c8c-71466251a162
linux-user/main.c
@@ -634,6 +634,14 @@ void cpu_loop (CPUSPARCState *env) @@ -634,6 +634,14 @@ void cpu_loop (CPUSPARCState *env)
634 queue_signal(info.si_signo, &info); 634 queue_signal(info.si_signo, &info);
635 } 635 }
636 break; 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 #endif 645 #endif
638 case EXCP_INTERRUPT: 646 case EXCP_INTERRUPT:
639 /* just indicate that signals should be handled asap */ 647 /* just indicate that signals should be handled asap */
linux-user/qemu.h
@@ -160,6 +160,9 @@ void save_v86_state(CPUX86State *env); @@ -160,6 +160,9 @@ void save_v86_state(CPUX86State *env);
160 void handle_vm86_trap(CPUX86State *env, int trapno); 160 void handle_vm86_trap(CPUX86State *env, int trapno);
161 void handle_vm86_fault(CPUX86State *env); 161 void handle_vm86_fault(CPUX86State *env);
162 int do_vm86(CPUX86State *env, long subfunction, target_ulong v86_addr); 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 #endif 166 #endif
164 167
165 /* mmap.c */ 168 /* mmap.c */
linux-user/signal.c
@@ -1443,6 +1443,9 @@ struct target_rt_signal_frame { @@ -1443,6 +1443,9 @@ struct target_rt_signal_frame {
1443 #define UREG_I0 0 1443 #define UREG_I0 0
1444 #define UREG_I1 1 1444 #define UREG_I1 1
1445 #define UREG_I2 2 1445 #define UREG_I2 2
  1446 +#define UREG_I3 3
  1447 +#define UREG_I4 4
  1448 +#define UREG_I5 5
1446 #define UREG_I6 6 1449 #define UREG_I6 6
1447 #define UREG_I7 7 1450 #define UREG_I7 7
1448 #define UREG_L0 8 1451 #define UREG_L0 8
@@ -1704,6 +1707,239 @@ long do_rt_sigreturn(CPUState *env) @@ -1704,6 +1707,239 @@ long do_rt_sigreturn(CPUState *env)
1704 return -ENOSYS; 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 #elif defined(TARGET_MIPS64) 1943 #elif defined(TARGET_MIPS64)
1708 1944
1709 # warning signal handling not implemented 1945 # warning signal handling not implemented