Revision e1833e1f target-ppc/helper.c

b/target-ppc/helper.c
44 44
    int exception, error_code;
45 45

  
46 46
    if (rw == 2) {
47
        exception = EXCP_ISI;
47
        exception = POWERPC_EXCP_ISI;
48 48
        error_code = 0;
49 49
    } else {
50
        exception = EXCP_DSI;
50
        exception = POWERPC_EXCP_DSI;
51 51
        error_code = 0;
52 52
        if (rw)
53 53
            error_code |= 0x02000000;
......
1128 1128
                ctx->prot |= PAGE_WRITE;
1129 1129
            }
1130 1130
        }
1131
        break;
1131 1132
    case POWERPC_MMU_BOOKE:
1132 1133
        ctx->prot |= PAGE_WRITE;
1133 1134
        break;
......
1250 1251
            cpu_dump_state(env, logfile, fprintf, 0);
1251 1252
#endif
1252 1253
        if (access_type == ACCESS_CODE) {
1253
            exception = EXCP_ISI;
1254
            exception = POWERPC_EXCP_ISI;
1254 1255
            switch (ret) {
1255 1256
            case -1:
1256 1257
                /* No matches in page tables or TLB */
1257 1258
                switch (env->mmu_model) {
1258 1259
                case POWERPC_MMU_SOFT_6xx:
1259
                    exception = EXCP_I_TLBMISS;
1260
                    exception = POWERPC_EXCP_IFTLB;
1260 1261
                    env->spr[SPR_IMISS] = address;
1261 1262
                    env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem;
1262 1263
                    error_code = 1 << 18;
1263 1264
                    goto tlb_miss;
1264 1265
                case POWERPC_MMU_SOFT_4xx:
1265 1266
                case POWERPC_MMU_SOFT_4xx_Z:
1266
                    exception = EXCP_40x_ITLBMISS;
1267
                    exception = POWERPC_EXCP_ITLB;
1267 1268
                    error_code = 0;
1268 1269
                    env->spr[SPR_40x_DEAR] = address;
1269 1270
                    env->spr[SPR_40x_ESR] = 0x00000000;
......
1315 1316
                /* No code fetch is allowed in direct-store areas */
1316 1317
                error_code = 0x10000000;
1317 1318
                break;
1319
#if defined(TARGET_PPC64)
1318 1320
            case -5:
1319 1321
                /* No match in segment table */
1320
                exception = EXCP_ISEG;
1322
                exception = POWERPC_EXCP_ISEG;
1321 1323
                error_code = 0;
1322 1324
                break;
1325
#endif
1323 1326
            }
1324 1327
        } else {
1325
            exception = EXCP_DSI;
1328
            exception = POWERPC_EXCP_DSI;
1326 1329
            switch (ret) {
1327 1330
            case -1:
1328 1331
                /* No matches in page tables or TLB */
1329 1332
                switch (env->mmu_model) {
1330 1333
                case POWERPC_MMU_SOFT_6xx:
1331 1334
                    if (rw == 1) {
1332
                        exception = EXCP_DS_TLBMISS;
1335
                        exception = POWERPC_EXCP_DSTLB;
1333 1336
                        error_code = 1 << 16;
1334 1337
                    } else {
1335
                        exception = EXCP_DL_TLBMISS;
1338
                        exception = POWERPC_EXCP_DLTLB;
1336 1339
                        error_code = 0;
1337 1340
                    }
1338 1341
                    env->spr[SPR_DMISS] = address;
......
1345 1348
                    goto out;
1346 1349
                case POWERPC_MMU_SOFT_4xx:
1347 1350
                case POWERPC_MMU_SOFT_4xx_Z:
1348
                    exception = EXCP_40x_DTLBMISS;
1351
                    exception = POWERPC_EXCP_DTLB;
1349 1352
                    error_code = 0;
1350 1353
                    env->spr[SPR_40x_DEAR] = address;
1351 1354
                    if (rw)
......
1396 1399
                switch (access_type) {
1397 1400
                case ACCESS_FLOAT:
1398 1401
                    /* Floating point load/store */
1399
                    exception = EXCP_ALIGN;
1400
                    error_code = EXCP_ALIGN_FP;
1402
                    exception = POWERPC_EXCP_ALIGN;
1403
                    error_code = POWERPC_EXCP_ALIGN_FP;
1401 1404
                    break;
1402 1405
                case ACCESS_RES:
1403 1406
                    /* lwarx, ldarx or srwcx. */
......
1409 1412
                    break;
1410 1413
                default:
1411 1414
                    printf("DSI: invalid exception (%d)\n", ret);
1412
                    exception = EXCP_PROGRAM;
1413
                    error_code = EXCP_INVAL | EXCP_INVAL_INVAL;
1415
                    exception = POWERPC_EXCP_PROGRAM;
1416
                    error_code = POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL;
1414 1417
                    break;
1415 1418
                }
1416 1419
                break;
1420
#if defined(TARGET_PPC64)
1417 1421
            case -5:
1418 1422
                /* No match in segment table */
1419
                exception = EXCP_DSEG;
1423
                exception = POWERPC_EXCP_DSEG;
1420 1424
                error_code = 0;
1421 1425
                break;
1426
#endif
1422 1427
            }
1423
            if (exception == EXCP_DSI && rw == 1)
1428
            if (exception == POWERPC_EXCP_DSI && rw == 1)
1424 1429
                error_code |= 0x02000000;
1425 1430
            /* Store fault address */
1426 1431
            env->spr[SPR_DAR] = address;
......
1830 1835
#if defined (CONFIG_USER_ONLY)
1831 1836
void do_interrupt (CPUState *env)
1832 1837
{
1833
    env->exception_index = -1;
1838
    env->exception_index = POWERPC_EXCP_NONE;
1839
    env->error_code = 0;
1834 1840
}
1835 1841

  
1836 1842
void ppc_hw_interrupt (CPUState *env)
1837 1843
{
1838
    env->exception_index = -1;
1844
    env->exception_index = POWERPC_EXCP_NONE;
1845
    env->error_code = 0;
1839 1846
}
1840 1847
#else /* defined (CONFIG_USER_ONLY) */
1841 1848
static void dump_syscall (CPUState *env)
......
1846 1853
            env->gpr[5], env->gpr[6], env->nip);
1847 1854
}
1848 1855

  
1849
void do_interrupt (CPUState *env)
1856
/* Note that this function should be greatly optimized
1857
 * when called with a constant excp, from ppc_hw_interrupt
1858
 */
1859
static always_inline void powerpc_excp (CPUState *env,
1860
                                        int excp_model, int excp)
1850 1861
{
1851
    target_ulong msr, *srr_0, *srr_1, *asrr_0, *asrr_1;
1852
    int excp, idx;
1862
    target_ulong msr, vector;
1863
    int srr0, srr1, asrr0, asrr1;
1853 1864

  
1854
    excp = env->exception_index;
1855
    msr = do_load_msr(env);
1856
    /* The default is to use SRR0 & SRR1 to save the exception context */
1857
    srr_0 = &env->spr[SPR_SRR0];
1858
    srr_1 = &env->spr[SPR_SRR1];
1859
    asrr_0 = NULL;
1860
    asrr_1 = NULL;
1861
#if defined (DEBUG_EXCEPTIONS)
1862
    if ((excp == EXCP_PROGRAM || excp == EXCP_DSI) && msr_pr == 1) {
1863
        if (loglevel != 0) {
1864
            fprintf(logfile,
1865
                    "Raise exception at 0x" ADDRX " => 0x%08x (%02x)\n",
1866
                    env->nip, excp, env->error_code);
1867
            cpu_dump_state(env, logfile, fprintf, 0);
1868
        }
1869
    }
1870
#endif
1871 1865
    if (loglevel & CPU_LOG_INT) {
1872 1866
        fprintf(logfile, "Raise exception at 0x" ADDRX " => 0x%08x (%02x)\n",
1873 1867
                env->nip, excp, env->error_code);
1874 1868
    }
1875
    msr_pow = 0;
1876
    idx = -1;
1877
    /* Generate informations in save/restore registers */
1869
    msr = do_load_msr(env);
1870
    srr0 = SPR_SRR0;
1871
    srr1 = SPR_SRR1;
1872
    asrr0 = -1;
1873
    asrr1 = -1;
1874
    msr &= ~((target_ulong)0x783F0000);
1878 1875
    switch (excp) {
1879
    /* Generic PowerPC exceptions */
1880
    case EXCP_RESET: /* 0x0100 */
1881
        switch (env->excp_model) {
1876
    case POWERPC_EXCP_NONE:
1877
        /* Should never happen */
1878
        return;
1879
    case POWERPC_EXCP_CRITICAL:    /* Critical input                         */
1880
        msr_ri = 0; /* XXX: check this */
1881
        switch (excp_model) {
1882 1882
        case POWERPC_EXCP_40x:
1883
            srr_0 = &env->spr[SPR_40x_SRR2];
1884
            srr_1 = &env->spr[SPR_40x_SRR3];
1883
            srr0 = SPR_40x_SRR2;
1884
            srr1 = SPR_40x_SRR3;
1885 1885
            break;
1886 1886
        case POWERPC_EXCP_BOOKE:
1887
            idx = 0;
1888
            srr_0 = &env->spr[SPR_BOOKE_CSRR0];
1889
            srr_1 = &env->spr[SPR_BOOKE_CSRR1];
1887
            srr0 = SPR_BOOKE_CSRR0;
1888
            srr1 = SPR_BOOKE_CSRR1;
1890 1889
            break;
1891
        default:
1892
            if (msr_ip)
1893
                excp += 0xFFC00;
1894
            excp |= 0xFFC00000;
1890
        case POWERPC_EXCP_G2:
1895 1891
            break;
1892
        default:
1893
            goto excp_invalid;
1896 1894
        }
1897 1895
        goto store_next;
1898
    case EXCP_MACHINE_CHECK: /* 0x0200 */
1899
        switch (env->excp_model) {
1896
    case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */
1897
        if (msr_me == 0) {
1898
            /* Machine check exception is not enabled */
1899
            /* XXX: we may just stop the processor here, to allow debugging */
1900
            excp = POWERPC_EXCP_RESET;
1901
            goto excp_reset;
1902
        }
1903
        msr_ri = 0;
1904
        msr_me = 0;
1905
#if defined(TARGET_PPC64H)
1906
        msr_hv = 1;
1907
#endif
1908
        /* XXX: should also have something loaded in DAR / DSISR */
1909
        switch (excp_model) {
1900 1910
        case POWERPC_EXCP_40x:
1901
            srr_0 = &env->spr[SPR_40x_SRR2];
1902
            srr_1 = &env->spr[SPR_40x_SRR3];
1911
            srr0 = SPR_40x_SRR2;
1912
            srr1 = SPR_40x_SRR3;
1903 1913
            break;
1904 1914
        case POWERPC_EXCP_BOOKE:
1905
            idx = 1;
1906
            srr_0 = &env->spr[SPR_BOOKE_MCSRR0];
1907
            srr_1 = &env->spr[SPR_BOOKE_MCSRR1];
1908
            asrr_0 = &env->spr[SPR_BOOKE_CSRR0];
1909
            asrr_1 = &env->spr[SPR_BOOKE_CSRR1];
1910
            msr_ce = 0;
1915
            srr0 = SPR_BOOKE_MCSRR0;
1916
            srr1 = SPR_BOOKE_MCSRR1;
1917
            asrr0 = SPR_BOOKE_CSRR0;
1918
            asrr1 = SPR_BOOKE_CSRR1;
1911 1919
            break;
1912 1920
        default:
1913 1921
            break;
1914 1922
        }
1915
        msr_me = 0;
1916
        break;
1917
    case EXCP_DSI: /* 0x0300 */
1918
        /* Store exception cause */
1919
        /* data location address has been stored
1920
         * when the fault has been detected
1921
         */
1922
        idx = 2;
1923
        msr &= ~0xFFFF0000;
1923
        goto store_next;
1924
    case POWERPC_EXCP_DSI:       /* Data storage exception                   */
1924 1925
#if defined (DEBUG_EXCEPTIONS)
1925 1926
        if (loglevel != 0) {
1926 1927
            fprintf(logfile, "DSI exception: DSISR=0x" ADDRX" DAR=0x" ADDRX
1927 1928
                    "\n", env->spr[SPR_DSISR], env->spr[SPR_DAR]);
1928 1929
        }
1929 1930
#endif
1931
        msr_ri = 0;
1932
#if defined(TARGET_PPC64H)
1933
        if (lpes1 == 0)
1934
            msr_hv = 1;
1935
#endif
1930 1936
        goto store_next;
1931
    case EXCP_ISI: /* 0x0400 */
1932
        /* Store exception cause */
1933
        idx = 3;
1934
        msr &= ~0xFFFF0000;
1935
        msr |= env->error_code;
1937
    case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
1936 1938
#if defined (DEBUG_EXCEPTIONS)
1937 1939
        if (loglevel != 0) {
1938 1940
            fprintf(logfile, "ISI exception: msr=0x" ADDRX ", nip=0x" ADDRX
1939 1941
                    "\n", msr, env->nip);
1940 1942
        }
1941 1943
#endif
1944
        msr_ri = 0;
1945
#if defined(TARGET_PPC64H)
1946
        if (lpes1 == 0)
1947
            msr_hv = 1;
1948
#endif
1949
        msr |= env->error_code;
1942 1950
        goto store_next;
1943
    case EXCP_EXTERNAL: /* 0x0500 */
1944
        idx = 4;
1951
    case POWERPC_EXCP_EXTERNAL:  /* External input                           */
1952
        msr_ri = 0;
1953
#if defined(TARGET_PPC64H)
1954
        if (lpes0 == 1)
1955
            msr_hv = 1;
1956
#endif
1945 1957
        goto store_next;
1946
    case EXCP_ALIGN: /* 0x0600 */
1947
        if (likely(env->excp_model != POWERPC_EXCP_601)) {
1948
            /* Store exception cause */
1949
            idx = 5;
1950
            /* Get rS/rD and rA from faulting opcode */
1951
            env->spr[SPR_DSISR] |=
1952
                (ldl_code((env->nip - 4)) & 0x03FF0000) >> 16;
1953
            /* data location address has been stored
1954
             * when the fault has been detected
1955
             */
1956
        } else {
1957
            /* IO error exception on PowerPC 601 */
1958
            /* XXX: TODO */
1959
            cpu_abort(env,
1960
                      "601 IO error exception is not implemented yet !\n");
1961
        }
1958
    case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
1959
        msr_ri = 0;
1960
#if defined(TARGET_PPC64H)
1961
        if (lpes1 == 0)
1962
            msr_hv = 1;
1963
#endif
1964
        /* XXX: this is false */
1965
        /* Get rS/rD and rA from faulting opcode */
1966
        env->spr[SPR_DSISR] |= (ldl_code((env->nip - 4)) & 0x03FF0000) >> 16;
1962 1967
        goto store_current;
1963
    case EXCP_PROGRAM: /* 0x0700 */
1964
        idx = 6;
1965
        msr &= ~0xFFFF0000;
1968
    case POWERPC_EXCP_PROGRAM:   /* Program exception                        */
1966 1969
        switch (env->error_code & ~0xF) {
1967
        case EXCP_FP:
1968
            if (msr_fe0 == 0 && msr_fe1 == 0) {
1970
        case POWERPC_EXCP_FP:
1971
            if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
1969 1972
#if defined (DEBUG_EXCEPTIONS)
1970 1973
                if (loglevel != 0) {
1971 1974
                    fprintf(logfile, "Ignore floating point exception\n");
......
1973 1976
#endif
1974 1977
                return;
1975 1978
            }
1979
            msr_ri = 0;
1980
#if defined(TARGET_PPC64H)
1981
            if (lpes1 == 0)
1982
                msr_hv = 1;
1983
#endif
1976 1984
            msr |= 0x00100000;
1977 1985
            /* Set FX */
1978 1986
            env->fpscr[7] |= 0x8;
......
1980 1988
            if ((((env->fpscr[7] & 0x3) << 3) | (env->fpscr[6] >> 1)) &
1981 1989
                ((env->fpscr[1] << 1) | (env->fpscr[0] >> 3)))
1982 1990
                env->fpscr[7] |= 0x4;
1991
            if (msr_fe0 != msr_fe1) {
1992
                msr |= 0x00010000;
1993
                goto store_current;
1994
            }
1983 1995
            break;
1984
        case EXCP_INVAL:
1996
        case POWERPC_EXCP_INVAL:
1985 1997
#if defined (DEBUG_EXCEPTIONS)
1986 1998
            if (loglevel != 0) {
1987 1999
                fprintf(logfile, "Invalid instruction at 0x" ADDRX "\n",
1988 2000
                        env->nip);
1989 2001
            }
1990 2002
#endif
2003
            msr_ri = 0;
2004
#if defined(TARGET_PPC64H)
2005
            if (lpes1 == 0)
2006
                msr_hv = 1;
2007
#endif
1991 2008
            msr |= 0x00080000;
1992 2009
            break;
1993
        case EXCP_PRIV:
2010
        case POWERPC_EXCP_PRIV:
2011
            msr_ri = 0;
2012
#if defined(TARGET_PPC64H)
2013
            if (lpes1 == 0)
2014
                msr_hv = 1;
2015
#endif
1994 2016
            msr |= 0x00040000;
1995 2017
            break;
1996
        case EXCP_TRAP:
1997
            idx = 15;
2018
        case POWERPC_EXCP_TRAP:
2019
            msr_ri = 0;
2020
#if defined(TARGET_PPC64H)
2021
            if (lpes1 == 0)
2022
                msr_hv = 1;
2023
#endif
1998 2024
            msr |= 0x00020000;
1999 2025
            break;
2000 2026
        default:
2001 2027
            /* Should never occur */
2028
            cpu_abort(env, "Invalid program exception %d. Aborting\n",
2029
                      env->error_code);
2002 2030
            break;
2003 2031
        }
2004
        msr |= 0x00010000;
2005
        goto store_current;
2006
    case EXCP_NO_FP: /* 0x0800 */
2007
        idx = 7;
2008
        msr &= ~0xFFFF0000;
2009
        goto store_current;
2010
    case EXCP_DECR:
2011 2032
        goto store_next;
2012
    case EXCP_SYSCALL: /* 0x0C00 */
2013
        idx = 8;
2033
    case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
2034
        msr_ri = 0;
2035
#if defined(TARGET_PPC64H)
2036
        if (lpes1 == 0)
2037
            msr_hv = 1;
2038
#endif
2039
        goto store_current;
2040
    case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
2014 2041
        /* NOTE: this is a temporary hack to support graphics OSI
2015 2042
           calls from the MOL driver */
2043
        /* XXX: To be removed */
2016 2044
        if (env->gpr[3] == 0x113724fa && env->gpr[4] == 0x77810f9b &&
2017 2045
            env->osi_call) {
2018 2046
            if (env->osi_call(env) != 0)
......
2021 2049
        if (loglevel & CPU_LOG_INT) {
2022 2050
            dump_syscall(env);
2023 2051
        }
2052
        msr_ri = 0;
2053
#if defined(TARGET_PPC64H)
2054
        if (lev == 1 || (lpes0 == 0 && lpes1 == 0))
2055
            msr_hv = 1;
2056
#endif
2057
        goto store_next;
2058
    case POWERPC_EXCP_APU:       /* Auxiliary processor unavailable          */
2059
        msr_ri = 0;
2060
        goto store_current;
2061
    case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
2062
        msr_ri = 0;
2063
#if defined(TARGET_PPC64H)
2064
        if (lpes1 == 0)
2065
            msr_hv = 1;
2066
#endif
2067
        goto store_next;
2068
    case POWERPC_EXCP_FIT:       /* Fixed-interval timer interrupt           */
2069
        /* FIT on 4xx */
2070
#if defined (DEBUG_EXCEPTIONS)
2071
        if (loglevel != 0)
2072
            fprintf(logfile, "FIT exception\n");
2073
#endif
2074
        msr_ri = 0; /* XXX: check this */
2024 2075
        goto store_next;
2025
    case EXCP_TRACE: /* 0x0D00 */
2076
    case POWERPC_EXCP_WDT:       /* Watchdog timer interrupt                 */
2077
#if defined (DEBUG_EXCEPTIONS)
2078
        if (loglevel != 0)
2079
            fprintf(logfile, "WDT exception\n");
2080
#endif
2081
        switch (excp_model) {
2082
        case POWERPC_EXCP_BOOKE:
2083
            srr0 = SPR_BOOKE_CSRR0;
2084
            srr1 = SPR_BOOKE_CSRR1;
2085
            break;
2086
        default:
2087
            break;
2088
        }
2089
        msr_ri = 0; /* XXX: check this */
2026 2090
        goto store_next;
2027
    case EXCP_PERF: /* 0x0F00 */
2091
    case POWERPC_EXCP_DTLB:      /* Data TLB error                           */
2092
        msr_ri = 0; /* XXX: check this */
2093
        goto store_next;
2094
    case POWERPC_EXCP_ITLB:      /* Instruction TLB error                    */
2095
        msr_ri = 0; /* XXX: check this */
2096
        goto store_next;
2097
    case POWERPC_EXCP_DEBUG:     /* Debug interrupt                          */
2098
        switch (excp_model) {
2099
        case POWERPC_EXCP_BOOKE:
2100
            srr0 = SPR_BOOKE_DSRR0;
2101
            srr1 = SPR_BOOKE_DSRR1;
2102
            asrr0 = SPR_BOOKE_CSRR0;
2103
            asrr1 = SPR_BOOKE_CSRR1;
2104
            break;
2105
        default:
2106
            break;
2107
        }
2028 2108
        /* XXX: TODO */
2029
        cpu_abort(env,
2030
                  "Performance counter exception is not implemented yet !\n");
2109
        cpu_abort(env, "Debug exception is not implemented yet !\n");
2031 2110
        goto store_next;
2032
    /* 32 bits PowerPC specific exceptions */
2033
    case EXCP_FP_ASSIST: /* 0x0E00 */
2111
#if defined(TARGET_PPCEMB)
2112
    case POWERPC_EXCP_SPEU:      /* SPE/embedded floating-point unavailable  */
2113
        msr_ri = 0; /* XXX: check this */
2114
        goto store_current;
2115
    case POWERPC_EXCP_EFPDI:     /* Embedded floating-point data interrupt   */
2034 2116
        /* XXX: TODO */
2035
        cpu_abort(env, "Floating point assist exception "
2117
        cpu_abort(env, "Embedded floating point data exception "
2036 2118
                  "is not implemented yet !\n");
2037 2119
        goto store_next;
2038
    /* 64 bits PowerPC exceptions */
2039
    case EXCP_DSEG: /* 0x0380 */
2120
    case POWERPC_EXCP_EFPRI:     /* Embedded floating-point round interrupt  */
2040 2121
        /* XXX: TODO */
2041
        cpu_abort(env, "Data segment exception is not implemented yet !\n");
2122
        cpu_abort(env, "Embedded floating point round exception "
2123
                  "is not implemented yet !\n");
2042 2124
        goto store_next;
2043
    case EXCP_ISEG: /* 0x0480 */
2125
    case POWERPC_EXCP_EPERFM:    /* Embedded performance monitor interrupt   */
2126
        msr_ri = 0;
2044 2127
        /* XXX: TODO */
2045 2128
        cpu_abort(env,
2046
                  "Instruction segment exception is not implemented yet !\n");
2129
                  "Performance counter exception is not implemented yet !\n");
2047 2130
        goto store_next;
2048
    case EXCP_HDECR: /* 0x0980 */
2131
    case POWERPC_EXCP_DOORI:     /* Embedded doorbell interrupt              */
2049 2132
        /* XXX: TODO */
2050
        cpu_abort(env, "Hypervisor decrementer exception is not implemented "
2051
                  "yet !\n");
2133
        cpu_abort(env,
2134
                  "Embedded doorbell interrupt is not implemented yet !\n");
2052 2135
        goto store_next;
2053
    /* Implementation specific exceptions */
2054
    case 0x0A00:
2055
        switch (env->excp_model) {
2056
        case POWERPC_EXCP_G2:
2057
            /* Critical interrupt on G2 */
2058
            /* XXX: TODO */
2059
            cpu_abort(env, "G2 critical interrupt is not implemented yet !\n");
2060
            goto store_next;
2061
        default:
2062
            cpu_abort(env, "Invalid exception 0x0A00 !\n");
2136
    case POWERPC_EXCP_DOORCI:    /* Embedded doorbell critical interrupt     */
2137
        switch (excp_model) {
2138
        case POWERPC_EXCP_BOOKE:
2139
            srr0 = SPR_BOOKE_CSRR0;
2140
            srr1 = SPR_BOOKE_CSRR1;
2063 2141
            break;
2064
        }
2065
        return;
2066
    case 0x0F20:
2067
        idx = 9;
2068
        switch (env->excp_model) {
2069
        case POWERPC_EXCP_40x:
2070
            /* APU unavailable on 405 */
2071
            /* XXX: TODO */
2072
            cpu_abort(env,
2073
                      "APU unavailable exception is not implemented yet !\n");
2074
            goto store_next;
2075
        case POWERPC_EXCP_74xx:
2076
            /* Altivec unavailable */
2077
            /* XXX: TODO */
2078
            cpu_abort(env, "Altivec unavailable exception "
2079
                      "is not implemented yet !\n");
2080
            goto store_next;
2081 2142
        default:
2082
            cpu_abort(env, "Invalid exception 0x0F20 !\n");
2083 2143
            break;
2084 2144
        }
2085
        return;
2086
    case 0x1000:
2087
        idx = 10;
2088
        switch (env->excp_model) {
2089
        case POWERPC_EXCP_40x:
2090
            /* PIT on 4xx */
2091
            msr &= ~0xFFFF0000;
2145
        /* XXX: TODO */
2146
        cpu_abort(env, "Embedded doorbell critical interrupt "
2147
                  "is not implemented yet !\n");
2148
        goto store_next;
2149
#endif /* defined(TARGET_PPCEMB) */
2150
    case POWERPC_EXCP_RESET:     /* System reset exception                   */
2151
        msr_ri = 0;
2152
#if defined(TARGET_PPC64H)
2153
        msr_hv = 1;
2154
#endif
2155
    excp_reset:
2156
        goto store_next;
2157
#if defined(TARGET_PPC64)
2158
    case POWERPC_EXCP_DSEG:      /* Data segment exception                   */
2159
        msr_ri = 0;
2160
#if defined(TARGET_PPC64H)
2161
        if (lpes1 == 0)
2162
            msr_hv = 1;
2163
#endif
2164
        /* XXX: TODO */
2165
        cpu_abort(env, "Data segment exception is not implemented yet !\n");
2166
        goto store_next;
2167
    case POWERPC_EXCP_ISEG:      /* Instruction segment exception            */
2168
        msr_ri = 0;
2169
#if defined(TARGET_PPC64H)
2170
        if (lpes1 == 0)
2171
            msr_hv = 1;
2172
#endif
2173
        /* XXX: TODO */
2174
        cpu_abort(env,
2175
                  "Instruction segment exception is not implemented yet !\n");
2176
        goto store_next;
2177
#endif /* defined(TARGET_PPC64) */
2178
#if defined(TARGET_PPC64H)
2179
    case POWERPC_EXCP_HDECR:     /* Hypervisor decrementer exception         */
2180
        srr0 = SPR_HSRR0;
2181
        srr1 = SPR_HSSR1;
2182
        msr_hv = 1;
2183
        goto store_next;
2184
#endif
2185
    case POWERPC_EXCP_TRACE:     /* Trace exception                          */
2186
        msr_ri = 0;
2187
#if defined(TARGET_PPC64H)
2188
        if (lpes1 == 0)
2189
            msr_hv = 1;
2190
#endif
2191
        goto store_next;
2192
#if defined(TARGET_PPC64H)
2193
    case POWERPC_EXCP_HDSI:      /* Hypervisor data storage exception        */
2194
        srr0 = SPR_HSRR0;
2195
        srr1 = SPR_HSSR1;
2196
        msr_hv = 1;
2197
        goto store_next;
2198
    case POWERPC_EXCP_HISI:      /* Hypervisor instruction storage exception */
2199
        srr0 = SPR_HSRR0;
2200
        srr1 = SPR_HSSR1;
2201
        msr_hv = 1;
2202
        /* XXX: TODO */
2203
        cpu_abort(env, "Hypervisor instruction storage exception "
2204
                  "is not implemented yet !\n");
2205
        goto store_next;
2206
    case POWERPC_EXCP_HDSEG:     /* Hypervisor data segment exception        */
2207
        srr0 = SPR_HSRR0;
2208
        srr1 = SPR_HSSR1;
2209
        msr_hv = 1;
2210
        goto store_next;
2211
    case POWERPC_EXCP_HISEG:     /* Hypervisor instruction segment exception */
2212
        srr0 = SPR_HSRR0;
2213
        srr1 = SPR_HSSR1;
2214
        msr_hv = 1;
2215
        goto store_next;
2216
#endif /* defined(TARGET_PPC64H) */
2217
    case POWERPC_EXCP_VPU:       /* Vector unavailable exception             */
2218
        msr_ri = 0;
2219
#if defined(TARGET_PPC64H)
2220
        if (lpes1 == 0)
2221
            msr_hv = 1;
2222
#endif
2223
        goto store_current;
2224
    case POWERPC_EXCP_PIT:       /* Programmable interval timer interrupt    */
2092 2225
#if defined (DEBUG_EXCEPTIONS)
2093
            if (loglevel != 0)
2094
                fprintf(logfile, "PIT exception\n");
2226
        if (loglevel != 0)
2227
            fprintf(logfile, "PIT exception\n");
2228
#endif
2229
        msr_ri = 0; /* XXX: check this */
2230
        goto store_next;
2231
    case POWERPC_EXCP_IO:        /* IO error exception                       */
2232
        /* XXX: TODO */
2233
        cpu_abort(env, "601 IO error exception is not implemented yet !\n");
2234
        goto store_next;
2235
    case POWERPC_EXCP_RUNM:      /* Run mode exception                       */
2236
        /* XXX: TODO */
2237
        cpu_abort(env, "601 run mode exception is not implemented yet !\n");
2238
        goto store_next;
2239
    case POWERPC_EXCP_EMUL:      /* Emulation trap exception                 */
2240
        /* XXX: TODO */
2241
        cpu_abort(env, "602 emulation trap exception "
2242
                  "is not implemented yet !\n");
2243
        goto store_next;
2244
    case POWERPC_EXCP_IFTLB:     /* Instruction fetch TLB error              */
2245
        msr_ri = 0; /* XXX: check this */
2246
#if defined(TARGET_PPC64H) /* XXX: check this */
2247
        if (lpes1 == 0)
2248
            msr_hv = 1;
2095 2249
#endif
2096
            goto store_next;
2250
        switch (excp_model) {
2097 2251
        case POWERPC_EXCP_602:
2098 2252
        case POWERPC_EXCP_603:
2099 2253
        case POWERPC_EXCP_603E:
2100 2254
        case POWERPC_EXCP_G2:
2101
            /* ITLBMISS on 602/603 */
2102
            goto store_gprs;
2255
            goto tlb_miss_tgpr;
2103 2256
        case POWERPC_EXCP_7x5:
2104
            /* ITLBMISS on 745/755 */
2105 2257
            goto tlb_miss;
2106 2258
        default:
2107
            cpu_abort(env, "Invalid exception 0x1000 !\n");
2108
            break;
2109
        }
2110
        return;
2111
    case 0x1010:
2112
        idx = 11;
2113
        switch (env->excp_model) {
2114
        case POWERPC_EXCP_40x:
2115
            /* FIT on 4xx */
2116
            msr &= ~0xFFFF0000;
2117
#if defined (DEBUG_EXCEPTIONS)
2118
            if (loglevel != 0)
2119
                fprintf(logfile, "FIT exception\n");
2120
#endif
2121
            goto store_next;
2122
        default:
2123
            cpu_abort(env, "Invalid exception 0x1010 !\n");
2259
            cpu_abort(env, "Invalid instruction TLB miss exception\n");
2124 2260
            break;
2125 2261
        }
2126
        return;
2127
    case 0x1020:
2128
        idx = 12;
2129
        switch (env->excp_model) {
2130
        case POWERPC_EXCP_40x:
2131
            /* Watchdog on 4xx */
2132
            msr &= ~0xFFFF0000;
2133
#if defined (DEBUG_EXCEPTIONS)
2134
            if (loglevel != 0)
2135
                fprintf(logfile, "WDT exception\n");
2262
        break;
2263
    case POWERPC_EXCP_DLTLB:     /* Data load TLB miss                       */
2264
        msr_ri = 0; /* XXX: check this */
2265
#if defined(TARGET_PPC64H) /* XXX: check this */
2266
        if (lpes1 == 0)
2267
            msr_hv = 1;
2136 2268
#endif
2137
            goto store_next;
2138
        case POWERPC_EXCP_BOOKE:
2139
            srr_0 = &env->spr[SPR_BOOKE_CSRR0];
2140
            srr_1 = &env->spr[SPR_BOOKE_CSRR1];
2141
            break;
2142
        default:
2143
            cpu_abort(env, "Invalid exception 0x1020 !\n");
2144
            break;
2145
        }
2146
        return;
2147
    case 0x1100:
2148
        idx = 13;
2149
        switch (env->excp_model) {
2150
        case POWERPC_EXCP_40x:
2151
            /* DTLBMISS on 4xx */
2152
            msr &= ~0xFFFF0000;
2153
            goto store_next;
2269
        switch (excp_model) {
2154 2270
        case POWERPC_EXCP_602:
2155 2271
        case POWERPC_EXCP_603:
2156 2272
        case POWERPC_EXCP_603E:
2157 2273
        case POWERPC_EXCP_G2:
2158
            /* DLTLBMISS on 602/603 */
2159
            goto store_gprs;
2274
            goto tlb_miss_tgpr;
2160 2275
        case POWERPC_EXCP_7x5:
2161
            /* DLTLBMISS on 745/755 */
2162 2276
            goto tlb_miss;
2163 2277
        default:
2164
            cpu_abort(env, "Invalid exception 0x1100 !\n");
2278
            cpu_abort(env, "Invalid data load TLB miss exception\n");
2165 2279
            break;
2166 2280
        }
2167
        return;
2168
    case 0x1200:
2169
        idx = 14;
2170
        switch (env->excp_model) {
2171
        case POWERPC_EXCP_40x:
2172
            /* ITLBMISS on 4xx */
2173
            msr &= ~0xFFFF0000;
2174
            goto store_next;
2281
        break;
2282
    case POWERPC_EXCP_DSTLB:     /* Data store TLB miss                      */
2283
        msr_ri = 0; /* XXX: check this */
2284
#if defined(TARGET_PPC64H) /* XXX: check this */
2285
        if (lpes1 == 0)
2286
            msr_hv = 1;
2287
#endif
2288
        switch (excp_model) {
2175 2289
        case POWERPC_EXCP_602:
2176 2290
        case POWERPC_EXCP_603:
2177 2291
        case POWERPC_EXCP_603E:
2178 2292
        case POWERPC_EXCP_G2:
2179
            /* DSTLBMISS on 602/603 */
2180
        store_gprs:
2293
        tlb_miss_tgpr:
2181 2294
            /* Swap temporary saved registers with GPRs */
2182 2295
            swap_gpr_tgpr(env);
2183 2296
            msr_tgpr = 1;
2297
            goto tlb_miss;
2298
        case POWERPC_EXCP_7x5:
2299
        tlb_miss:
2184 2300
#if defined (DEBUG_SOFTWARE_TLB)
2185 2301
            if (loglevel != 0) {
2186 2302
                const unsigned char *es;
......
2207 2323
                        env->error_code);
2208 2324
            }
2209 2325
#endif
2210
            goto tlb_miss;
2211
        case POWERPC_EXCP_7x5:
2212
            /* DSTLBMISS on 745/755 */
2213
        tlb_miss:
2214
            msr &= ~0xF83F0000;
2215 2326
            msr |= env->crf[0] << 28;
2216 2327
            msr |= env->error_code; /* key, D/I, S/L bits */
2217 2328
            /* Set way using a LRU mechanism */
2218 2329
            msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17;
2219
            goto store_next;
2220
        default:
2221
            cpu_abort(env, "Invalid exception 0x1200 !\n");
2222
            break;
2223
        }
2224
        return;
2225
    case 0x1300:
2226
        switch (env->excp_model) {
2227
        case POWERPC_EXCP_601:
2228
        case POWERPC_EXCP_602:
2229
        case POWERPC_EXCP_603:
2230
        case POWERPC_EXCP_603E:
2231
        case POWERPC_EXCP_G2:
2232
        case POWERPC_EXCP_604:
2233
        case POWERPC_EXCP_7x0:
2234
        case POWERPC_EXCP_7x5:
2235
            /* IABR on 6xx/7xx */
2236
            /* XXX: TODO */
2237
            cpu_abort(env, "IABR exception is not implemented yet !\n");
2238
            goto store_next;
2239
        default:
2240
            cpu_abort(env, "Invalid exception 0x1300 !\n");
2241
            break;
2242
        }
2243
        return;
2244
    case 0x1400:
2245
        switch (env->excp_model) {
2246
        case POWERPC_EXCP_601:
2247
        case POWERPC_EXCP_602:
2248
        case POWERPC_EXCP_603:
2249
        case POWERPC_EXCP_603E:
2250
        case POWERPC_EXCP_G2:
2251
        case POWERPC_EXCP_604:
2252
        case POWERPC_EXCP_7x0:
2253
        case POWERPC_EXCP_7x5:
2254
            /* SMI on 6xx/7xx */
2255
            /* XXX: TODO */
2256
            cpu_abort(env, "SMI exception is not implemented yet !\n");
2257
            goto store_next;
2258
        default:
2259
            cpu_abort(env, "Invalid exception 0x1400 !\n");
2260
            break;
2261
        }
2262
        return;
2263
    case 0x1500:
2264
        switch (env->excp_model) {
2265
        case POWERPC_EXCP_602:
2266
            /* Watchdog on 602 */
2267
            /* XXX: TODO */
2268
            cpu_abort(env,
2269
                      "602 watchdog exception is not implemented yet !\n");
2270
            goto store_next;
2271
        case POWERPC_EXCP_970:
2272
            /* Soft patch exception on 970 */
2273
            /* XXX: TODO */
2274
            cpu_abort(env,
2275
                      "970 soft-patch exception is not implemented yet !\n");
2276
            goto store_next;
2277
        case POWERPC_EXCP_74xx:
2278
            /* VPU assist on 74xx */
2279
            /* XXX: TODO */
2280
            cpu_abort(env, "VPU assist exception is not implemented yet !\n");
2281
            goto store_next;
2282
        default:
2283
            cpu_abort(env, "Invalid exception 0x1500 !\n");
2284
            break;
2285
        }
2286
        return;
2287
    case 0x1600:
2288
        switch (env->excp_model) {
2289
        case POWERPC_EXCP_602:
2290
            /* Emulation trap on 602 */
2291
            /* XXX: TODO */
2292
            cpu_abort(env, "602 emulation trap exception "
2293
                      "is not implemented yet !\n");
2294
            goto store_next;
2295
        case POWERPC_EXCP_970:
2296
            /* Maintenance exception on 970 */
2297
            /* XXX: TODO */
2298
            cpu_abort(env,
2299
                      "970 maintenance exception is not implemented yet !\n");
2300
            goto store_next;
2301
        default:
2302
            cpu_abort(env, "Invalid exception 0x1600 !\n");
2303
            break;
2304
        }
2305
        return;
2306
    case 0x1700:
2307
        switch (env->excp_model) {
2308
        case POWERPC_EXCP_7x0:
2309
        case POWERPC_EXCP_7x5:
2310
            /* Thermal management interrupt on G3 */
2311
            /* XXX: TODO */
2312
            cpu_abort(env, "G3 thermal management exception "
2313
                      "is not implemented yet !\n");
2314
            goto store_next;
2315
        case POWERPC_EXCP_970:
2316
            /* VPU assist on 970 */
2317
            /* XXX: TODO */
2318
            cpu_abort(env,
2319
                      "970 VPU assist exception is not implemented yet !\n");
2320
            goto store_next;
2321
        default:
2322
            cpu_abort(env, "Invalid exception 0x1700 !\n");
2323
            break;
2324
        }
2325
        return;
2326
    case 0x1800:
2327
        switch (env->excp_model) {
2328
        case POWERPC_EXCP_970:
2329
            /* Thermal exception on 970 */
2330
            /* XXX: TODO */
2331
            cpu_abort(env, "970 thermal management exception "
2332
                      "is not implemented yet !\n");
2333
            goto store_next;
2334
        default:
2335
            cpu_abort(env, "Invalid exception 0x1800 !\n");
2336
            break;
2337
        }
2338
        return;
2339
    case 0x2000:
2340
        switch (env->excp_model) {
2341
        case POWERPC_EXCP_40x:
2342
            /* DEBUG on 4xx */
2343
            /* XXX: TODO */
2344
            cpu_abort(env, "40x debug exception is not implemented yet !\n");
2345
            goto store_next;
2346
        case POWERPC_EXCP_601:
2347
            /* Run mode exception on 601 */
2348
            /* XXX: TODO */
2349
            cpu_abort(env,
2350
                      "601 run mode exception is not implemented yet !\n");
2351
            goto store_next;
2352
        case POWERPC_EXCP_BOOKE:
2353
            srr_0 = &env->spr[SPR_BOOKE_CSRR0];
2354
            srr_1 = &env->spr[SPR_BOOKE_CSRR1];
2355 2330
            break;
2356 2331
        default:
2357
            cpu_abort(env, "Invalid exception 0x1800 !\n");
2332
            cpu_abort(env, "Invalid data store TLB miss exception\n");
2358 2333
            break;
2359 2334
        }
2360
        return;
2361
    /* Other exceptions */
2362
    /* Qemu internal exceptions:
2363
     * we should never come here with those values: abort execution
2364
     */
2335
        goto store_next;
2336
    case POWERPC_EXCP_FPA:       /* Floating-point assist exception          */
2337
        /* XXX: TODO */
2338
        cpu_abort(env, "Floating point assist exception "
2339
                  "is not implemented yet !\n");
2340
        goto store_next;
2341
    case POWERPC_EXCP_IABR:      /* Instruction address breakpoint           */
2342
        /* XXX: TODO */
2343
        cpu_abort(env, "IABR exception is not implemented yet !\n");
2344
        goto store_next;
2345
    case POWERPC_EXCP_SMI:       /* System management interrupt              */
2346
        /* XXX: TODO */
2347
        cpu_abort(env, "SMI exception is not implemented yet !\n");
2348
        goto store_next;
2349
    case POWERPC_EXCP_THERM:     /* Thermal interrupt                        */
2350
        /* XXX: TODO */
2351
        cpu_abort(env, "Thermal management exception "
2352
                  "is not implemented yet !\n");
2353
        goto store_next;
2354
    case POWERPC_EXCP_PERFM:     /* Embedded performance monitor interrupt   */
2355
        msr_ri = 0;
2356
#if defined(TARGET_PPC64H)
2357
        if (lpes1 == 0)
2358
            msr_hv = 1;
2359
#endif
2360
        /* XXX: TODO */
2361
        cpu_abort(env,
2362
                  "Performance counter exception is not implemented yet !\n");
2363
        goto store_next;
2364
    case POWERPC_EXCP_VPUA:      /* Vector assist exception                  */
2365
        /* XXX: TODO */
2366
        cpu_abort(env, "VPU assist exception is not implemented yet !\n");
2367
        goto store_next;
2368
    case POWERPC_EXCP_SOFTP:     /* Soft patch exception                     */
2369
        /* XXX: TODO */
2370
        cpu_abort(env,
2371
                  "970 soft-patch exception is not implemented yet !\n");
2372
        goto store_next;
2373
    case POWERPC_EXCP_MAINT:     /* Maintenance exception                    */
2374
        /* XXX: TODO */
2375
        cpu_abort(env,
2376
                  "970 maintenance exception is not implemented yet !\n");
2377
        goto store_next;
2365 2378
    default:
2366
        cpu_abort(env, "Invalid exception: code %d (%04x)\n", excp, excp);
2367
        return;
2379
    excp_invalid:
2380
        cpu_abort(env, "Invalid PowerPC exception %d. Aborting\n", excp);
2381
        break;
2368 2382
    store_current:
2369 2383
        /* save current instruction location */
2370
        *srr_0 = env->nip - 4;
2384
        env->spr[srr0] = env->nip - 4;
2371 2385
        break;
2372 2386
    store_next:
2373 2387
        /* save next instruction location */
2374
        *srr_0 = env->nip;
2388
        env->spr[srr0] = env->nip;
2375 2389
        break;
2376 2390
    }
2377
    /* Save msr */
2378
    *srr_1 = msr;
2379
    if (asrr_0 != NULL)
2380
        *asrr_0 = *srr_0;
2381
    if (asrr_1 != NULL)
2382
        *asrr_1 = *srr_1;
2391
    /* Save MSR */
2392
    env->spr[srr1] = msr;
2393
    /* If any alternate SRR register are defined, duplicate saved values */
2394
    if (asrr0 != -1)
2395
        env->spr[asrr0] = env->spr[srr0];
2396
    if (asrr1 != -1)
2397
        env->spr[asrr1] = env->spr[srr1];
2383 2398
    /* If we disactivated any translation, flush TLBs */
2384
    if (msr_ir || msr_dr) {
2399
    if (msr_ir || msr_dr)
2385 2400
        tlb_flush(env, 1);
2386
    }
2387 2401
    /* reload MSR with correct bits */
2388 2402
    msr_ee = 0;
2389 2403
    msr_pr = 0;
......
2394 2408
    msr_fe1 = 0;
2395 2409
    msr_ir = 0;
2396 2410
    msr_dr = 0;
2397
    msr_ri = 0;
2411
#if 0 /* Fix this: not on all targets */
2412
    msr_pmm = 0;
2413
#endif
2398 2414
    msr_le = msr_ile;
2399
    if (env->excp_model == POWERPC_EXCP_BOOKE) {
2400
        msr_cm = msr_icm;
2401
        if (idx == -1 || (idx >= 16 && idx < 32)) {
2402
            cpu_abort(env, "Invalid exception index for excp %d %08x idx %d\n",
2403
                      excp, excp, idx);
2404
        }
2415
    do_compute_hflags(env);
2416
    /* Jump to handler */
2417
    vector = env->excp_vectors[excp];
2418
    if (vector == (target_ulong)-1) {
2419
        cpu_abort(env, "Raised an exception without defined vector %d\n",
2420
                  excp);
2421
    }
2422
    vector |= env->excp_prefix;
2405 2423
#if defined(TARGET_PPC64)
2406
        if (msr_cm)
2407
            env->nip = (uint64_t)env->spr[SPR_BOOKE_IVPR];
2408
        else
2409
#endif
2410
            env->nip = (uint32_t)env->spr[SPR_BOOKE_IVPR];
2411
        if (idx < 16)
2412
            env->nip |= env->spr[SPR_BOOKE_IVOR0 + idx];
2413
        else if (idx < 38)
2414
            env->nip |= env->spr[SPR_BOOKE_IVOR32 + idx - 32];
2424
    if (excp_model == POWERPC_EXCP_BOOKE) {
2425
        msr_cm = msr_icm;
2426
        if (!msr_cm)
2427
            vector = (uint32_t)vector;
2415 2428
    } else {
2416 2429
        msr_sf = msr_isf;
2417
        env->nip = excp;
2430
        if (!msr_sf)
2431
            vector = (uint32_t)vector;
2418 2432
    }
2419
    do_compute_hflags(env);
2420
    /* Jump to handler */
2421
    env->exception_index = EXCP_NONE;
2433
#endif
2434
    env->nip = vector;
2435
    /* Reset exception state */
2436
    env->exception_index = POWERPC_EXCP_NONE;
2437
    env->error_code = 0;
2422 2438
}
2423 2439

  
2424
void ppc_hw_interrupt (CPUPPCState *env)
2440
void do_interrupt (CPUState *env)
2425 2441
{
2426
    int raised = 0;
2442
    powerpc_excp(env, env->excp_model, env->exception_index);
2443
}
2427 2444

  
2445
void ppc_hw_interrupt (CPUPPCState *env)
2446
{
2428 2447
#if 1
2429 2448
    if (loglevel & CPU_LOG_INT) {
2430 2449
        fprintf(logfile, "%s: %p pending %08x req %08x me %d ee %d\n",
......
2432 2451
                env->interrupt_request, msr_me, msr_ee);
2433 2452
    }
2434 2453
#endif
2435
    /* Raise it */
2454
    /* External reset */
2436 2455
    if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) {
2437
        /* External reset / critical input */
2438
        /* XXX: critical input should be handled another way.
2439
         *      This code is not correct !
2440
         */
2441
        env->exception_index = EXCP_RESET;
2442 2456
        env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET);
2443
        raised = 1;
2444
    }
2445
    if (raised == 0 && msr_me != 0) {
2446
        /* Machine check exception */
2447
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_MCK)) {
2448
            env->exception_index = EXCP_MACHINE_CHECK;
2449
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_MCK);
2450
            raised = 1;
2451
        }
2457
        powerpc_excp(env, env->excp_model, POWERPC_EXCP_RESET);
2458
        return;
2459
    }
2460
    /* Machine check exception */
2461
    if (env->pending_interrupts & (1 << PPC_INTERRUPT_MCK)) {
2462
        env->pending_interrupts &= ~(1 << PPC_INTERRUPT_MCK);
2463
        powerpc_excp(env, env->excp_model, POWERPC_EXCP_MCHECK);
2464
        return;
2452 2465
    }
2453
    if (raised == 0 && msr_ee != 0) {
2454
#if defined(TARGET_PPC64H) /* PowerPC 64 with hypervisor mode support */
2466
#if 0 /* TODO */
2467
    /* External debug exception */
2468
    if (env->pending_interrupts & (1 << PPC_INTERRUPT_DEBUG)) {
2469
        env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DEBUG);
2470
        powerpc_excp(env, env->excp_model, POWERPC_EXCP_DEBUG);
2471
        return;
2472
    }
2473
#endif
2474
#if defined(TARGET_PPC64H)
2475
    if ((msr_ee != 0 || msr_hv == 0 || msr_pr == 1) & hdice != 0) {
2455 2476
        /* Hypervisor decrementer exception */
2456 2477
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) {
2457
            env->exception_index = EXCP_HDECR;
2458 2478
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR);
2459
            raised = 1;
2460
        } else
2479
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_HDECR);
2480
            return;
2481
        }
2482
    }
2483
#endif
2484
    if (msr_ce != 0) {
2485
        /* External critical interrupt */
2486
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_CEXT)) {
2487
            /* Taking a critical external interrupt does not clear the external
2488
             * critical interrupt status
2489
             */
2490
#if 0
2491
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CEXT);
2461 2492
#endif
2493
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_CRITICAL);
2494
            return;
2495
        }
2496
    }
2497
    if (msr_ee != 0) {
2498
        /* Watchdog timer on embedded PowerPC */
2499
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_WDT)) {
2500
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_WDT);
2501
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_WDT);
2502
            return;
2503
        }
2504
#if defined(TARGET_PPCEMB)
2505
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_CDOORBELL)) {
2506
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CDOORBELL);
2507
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_DOORCI);
2508
            return;
2509
        }
2510
#endif
2511
#if defined(TARGET_PPCEMB)
2512
        /* External interrupt */
2513
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) {
2514
            /* Taking an external interrupt does not clear the external
2515
             * interrupt status
2516
             */
2517
#if 0
2518
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_EXT);
2519
#endif
2520
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_EXTERNAL);
2521
            return;
2522
        }
2523
#endif
2524
        /* Fixed interval timer on embedded PowerPC */
2525
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) {
2526
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT);
2527
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_FIT);
2528
            return;
2529
        }
2530
        /* Programmable interval timer on embedded PowerPC */
2531
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_PIT)) {
2532
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PIT);
2533
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_PIT);
2534
            return;
2535
        }
2462 2536
        /* Decrementer exception */
2463 2537
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_DECR)) {
2464
            env->exception_index = EXCP_DECR;
2465 2538
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DECR);
2466
            raised = 1;
2467
        /* Programmable interval timer on embedded PowerPC */
2468
        } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_PIT)) {
2469
            env->exception_index = EXCP_40x_PIT;
2470
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PIT);
2471
            raised = 1;
2472
        /* Fixed interval timer on embedded PowerPC */
2473
        } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) {
2474
            env->exception_index = EXCP_40x_FIT;
2475
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT);
2476
            raised = 1;
2477
        /* Watchdog timer on embedded PowerPC */
2478
        } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_WDT)) {
2479
            env->exception_index = EXCP_40x_WATCHDOG;
2480
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_WDT);
2481
            raised = 1;
2539
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_DECR);
2540
            return;
2541
        }
2542
#if !defined(TARGET_PPCEMB)
2482 2543
        /* External interrupt */
2483
        } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) {
2484
            env->exception_index = EXCP_EXTERNAL;
2544
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) {
2485 2545
            /* Taking an external interrupt does not clear the external
2486 2546
             * interrupt status
2487 2547
             */
2488 2548
#if 0
2489 2549
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_EXT);
2490 2550
#endif
2491
            raised = 1;
2492
#if 0 // TODO
2493
        /* Thermal interrupt */
2494
        } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_THERM)) {
2495
            env->exception_index = EXCP_970_THRM;
2496
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_THERM);
2497
            raised = 1;
2551
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_EXTERNAL);
2552
            return;
2553
        }
2498 2554
#endif
2555
#if defined(TARGET_PPCEMB)
2556
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) {
2557
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL);
2558
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_DOORI);
2559
            return;
2499 2560
        }
2500
#if 0 // TODO
2501
    /* External debug exception */
2502
    } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_DEBUG)) {
2503
        env->exception_index = EXCP_xxx;
2504
        env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DEBUG);
2505
        raised = 1;
2506 2561
#endif
2507
    }
2508
    if (raised != 0) {
2509
        env->error_code = 0;
2510
        do_interrupt(env);
2562
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_PERFM)) {
2563
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PERFM);
2564
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_PERFM);
2565
            return;
2566
        }
2567
        /* Thermal interrupt */
2568
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_THERM)) {
2569
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_THERM);
2570
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_THERM);
2571
            return;
2572
        }
2511 2573
    }
2512 2574
}
2513 2575
#endif /* !CONFIG_USER_ONLY */
......
2572 2634
    env->reserve = -1;
2573 2635
    /* Be sure no exception or interrupt is pending */
2574 2636
    env->pending_interrupts = 0;
2575
    env->exception_index = EXCP_NONE;
2637
    env->exception_index = POWERPC_EXCP_NONE;
2638
    env->error_code = 0;
2576 2639
    /* Flush all TLBs */
2577 2640
    tlb_flush(env, 1);
2578 2641
}

Also available in: Unified diff