symbian-qemu-0.9.1-12/qemu-symbian-svp/target-alpha/helper.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2  *  Alpha emulation cpu helpers for qemu.
       
     3  *
       
     4  *  Copyright (c) 2007 Jocelyn Mayer
       
     5  *
       
     6  * This library is free software; you can redistribute it and/or
       
     7  * modify it under the terms of the GNU Lesser General Public
       
     8  * License as published by the Free Software Foundation; either
       
     9  * version 2 of the License, or (at your option) any later version.
       
    10  *
       
    11  * This library is distributed in the hope that it will be useful,
       
    12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    14  * Lesser General Public License for more details.
       
    15  *
       
    16  * You should have received a copy of the GNU Lesser General Public
       
    17  * License along with this library; if not, write to the Free Software
       
    18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    19  */
       
    20 
       
    21 #include <stdint.h>
       
    22 #include <stdlib.h>
       
    23 #include <stdio.h>
       
    24 
       
    25 #include "cpu.h"
       
    26 #include "exec-all.h"
       
    27 
       
    28 #if defined(CONFIG_USER_ONLY)
       
    29 
       
    30 int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
       
    31                                 int mmu_idx, int is_softmmu)
       
    32 {
       
    33     if (rw == 2)
       
    34         env->exception_index = EXCP_ITB_MISS;
       
    35     else
       
    36         env->exception_index = EXCP_DFAULT;
       
    37     env->ipr[IPR_EXC_ADDR] = address;
       
    38 
       
    39     return 1;
       
    40 }
       
    41 
       
    42 target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
       
    43 {
       
    44     return addr;
       
    45 }
       
    46 
       
    47 void do_interrupt (CPUState *env)
       
    48 {
       
    49     env->exception_index = -1;
       
    50 }
       
    51 
       
    52 #else
       
    53 
       
    54 target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
       
    55 {
       
    56     return -1;
       
    57 }
       
    58 
       
    59 int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
       
    60                                 int mmu_idx, int is_softmmu)
       
    61 {
       
    62     uint32_t opc;
       
    63 
       
    64     if (rw == 2) {
       
    65         /* Instruction translation buffer miss */
       
    66         env->exception_index = EXCP_ITB_MISS;
       
    67     } else {
       
    68         if (env->ipr[IPR_EXC_ADDR] & 1)
       
    69             env->exception_index = EXCP_DTB_MISS_PAL;
       
    70         else
       
    71             env->exception_index = EXCP_DTB_MISS_NATIVE;
       
    72         opc = (ldl_code(env->pc) >> 21) << 4;
       
    73         if (rw) {
       
    74             opc |= 0x9;
       
    75         } else {
       
    76             opc |= 0x4;
       
    77         }
       
    78         env->ipr[IPR_MM_STAT] = opc;
       
    79     }
       
    80 
       
    81     return 1;
       
    82 }
       
    83 
       
    84 int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp)
       
    85 {
       
    86     uint64_t hwpcb;
       
    87     int ret = 0;
       
    88 
       
    89     hwpcb = env->ipr[IPR_PCBB];
       
    90     switch (iprn) {
       
    91     case IPR_ASN:
       
    92         if (env->features & FEATURE_ASN)
       
    93             *valp = env->ipr[IPR_ASN];
       
    94         else
       
    95             *valp = 0;
       
    96         break;
       
    97     case IPR_ASTEN:
       
    98         *valp = ((int64_t)(env->ipr[IPR_ASTEN] << 60)) >> 60;
       
    99         break;
       
   100     case IPR_ASTSR:
       
   101         *valp = ((int64_t)(env->ipr[IPR_ASTSR] << 60)) >> 60;
       
   102         break;
       
   103     case IPR_DATFX:
       
   104         /* Write only */
       
   105         ret = -1;
       
   106         break;
       
   107     case IPR_ESP:
       
   108         if (env->features & FEATURE_SPS)
       
   109             *valp = env->ipr[IPR_ESP];
       
   110         else
       
   111             *valp = ldq_raw(hwpcb + 8);
       
   112         break;
       
   113     case IPR_FEN:
       
   114         *valp = ((int64_t)(env->ipr[IPR_FEN] << 63)) >> 63;
       
   115         break;
       
   116     case IPR_IPIR:
       
   117         /* Write-only */
       
   118         ret = -1;
       
   119         break;
       
   120     case IPR_IPL:
       
   121         *valp = ((int64_t)(env->ipr[IPR_IPL] << 59)) >> 59;
       
   122         break;
       
   123     case IPR_KSP:
       
   124         if (!(env->ipr[IPR_EXC_ADDR] & 1)) {
       
   125             ret = -1;
       
   126         } else {
       
   127             if (env->features & FEATURE_SPS)
       
   128                 *valp = env->ipr[IPR_KSP];
       
   129             else
       
   130                 *valp = ldq_raw(hwpcb + 0);
       
   131         }
       
   132         break;
       
   133     case IPR_MCES:
       
   134         *valp = ((int64_t)(env->ipr[IPR_MCES] << 59)) >> 59;
       
   135         break;
       
   136     case IPR_PERFMON:
       
   137         /* Implementation specific */
       
   138         *valp = 0;
       
   139         break;
       
   140     case IPR_PCBB:
       
   141         *valp = ((int64_t)env->ipr[IPR_PCBB] << 16) >> 16;
       
   142         break;
       
   143     case IPR_PRBR:
       
   144         *valp = env->ipr[IPR_PRBR];
       
   145         break;
       
   146     case IPR_PTBR:
       
   147         *valp = env->ipr[IPR_PTBR];
       
   148         break;
       
   149     case IPR_SCBB:
       
   150         *valp = (int64_t)((int32_t)env->ipr[IPR_SCBB]);
       
   151         break;
       
   152     case IPR_SIRR:
       
   153         /* Write-only */
       
   154         ret = -1;
       
   155         break;
       
   156     case IPR_SISR:
       
   157         *valp = (int64_t)((int16_t)env->ipr[IPR_SISR]);
       
   158     case IPR_SSP:
       
   159         if (env->features & FEATURE_SPS)
       
   160             *valp = env->ipr[IPR_SSP];
       
   161         else
       
   162             *valp = ldq_raw(hwpcb + 16);
       
   163         break;
       
   164     case IPR_SYSPTBR:
       
   165         if (env->features & FEATURE_VIRBND)
       
   166             *valp = env->ipr[IPR_SYSPTBR];
       
   167         else
       
   168             ret = -1;
       
   169         break;
       
   170     case IPR_TBCHK:
       
   171         if ((env->features & FEATURE_TBCHK)) {
       
   172             /* XXX: TODO */
       
   173             *valp = 0;
       
   174             ret = -1;
       
   175         } else {
       
   176             ret = -1;
       
   177         }
       
   178         break;
       
   179     case IPR_TBIA:
       
   180         /* Write-only */
       
   181         ret = -1;
       
   182         break;
       
   183     case IPR_TBIAP:
       
   184         /* Write-only */
       
   185         ret = -1;
       
   186         break;
       
   187     case IPR_TBIS:
       
   188         /* Write-only */
       
   189         ret = -1;
       
   190         break;
       
   191     case IPR_TBISD:
       
   192         /* Write-only */
       
   193         ret = -1;
       
   194         break;
       
   195     case IPR_TBISI:
       
   196         /* Write-only */
       
   197         ret = -1;
       
   198         break;
       
   199     case IPR_USP:
       
   200         if (env->features & FEATURE_SPS)
       
   201             *valp = env->ipr[IPR_USP];
       
   202         else
       
   203             *valp = ldq_raw(hwpcb + 24);
       
   204         break;
       
   205     case IPR_VIRBND:
       
   206         if (env->features & FEATURE_VIRBND)
       
   207             *valp = env->ipr[IPR_VIRBND];
       
   208         else
       
   209             ret = -1;
       
   210         break;
       
   211     case IPR_VPTB:
       
   212         *valp = env->ipr[IPR_VPTB];
       
   213         break;
       
   214     case IPR_WHAMI:
       
   215         *valp = env->ipr[IPR_WHAMI];
       
   216         break;
       
   217     default:
       
   218         /* Invalid */
       
   219         ret = -1;
       
   220         break;
       
   221     }
       
   222 
       
   223     return ret;
       
   224 }
       
   225 
       
   226 int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp)
       
   227 {
       
   228     uint64_t hwpcb, tmp64;
       
   229     uint8_t tmp8;
       
   230     int ret = 0;
       
   231 
       
   232     hwpcb = env->ipr[IPR_PCBB];
       
   233     switch (iprn) {
       
   234     case IPR_ASN:
       
   235         /* Read-only */
       
   236         ret = -1;
       
   237         break;
       
   238     case IPR_ASTEN:
       
   239         tmp8 = ((int8_t)(env->ipr[IPR_ASTEN] << 4)) >> 4;
       
   240         *oldvalp = tmp8;
       
   241         tmp8 &= val & 0xF;
       
   242         tmp8 |= (val >> 4) & 0xF;
       
   243         env->ipr[IPR_ASTEN] &= ~0xF;
       
   244         env->ipr[IPR_ASTEN] |= tmp8;
       
   245         ret = 1;
       
   246         break;
       
   247     case IPR_ASTSR:
       
   248         tmp8 = ((int8_t)(env->ipr[IPR_ASTSR] << 4)) >> 4;
       
   249         *oldvalp = tmp8;
       
   250         tmp8 &= val & 0xF;
       
   251         tmp8 |= (val >> 4) & 0xF;
       
   252         env->ipr[IPR_ASTSR] &= ~0xF;
       
   253         env->ipr[IPR_ASTSR] |= tmp8;
       
   254         ret = 1;
       
   255     case IPR_DATFX:
       
   256         env->ipr[IPR_DATFX] &= ~0x1;
       
   257         env->ipr[IPR_DATFX] |= val & 1;
       
   258         tmp64 = ldq_raw(hwpcb + 56);
       
   259         tmp64 &= ~0x8000000000000000ULL;
       
   260         tmp64 |= (val & 1) << 63;
       
   261         stq_raw(hwpcb + 56, tmp64);
       
   262         break;
       
   263     case IPR_ESP:
       
   264         if (env->features & FEATURE_SPS)
       
   265             env->ipr[IPR_ESP] = val;
       
   266         else
       
   267             stq_raw(hwpcb + 8, val);
       
   268         break;
       
   269     case IPR_FEN:
       
   270         env->ipr[IPR_FEN] = val & 1;
       
   271         tmp64 = ldq_raw(hwpcb + 56);
       
   272         tmp64 &= ~1;
       
   273         tmp64 |= val & 1;
       
   274         stq_raw(hwpcb + 56, tmp64);
       
   275         break;
       
   276     case IPR_IPIR:
       
   277         /* XXX: TODO: Send IRQ to CPU #ir[16] */
       
   278         break;
       
   279     case IPR_IPL:
       
   280         *oldvalp = ((int64_t)(env->ipr[IPR_IPL] << 59)) >> 59;
       
   281         env->ipr[IPR_IPL] &= ~0x1F;
       
   282         env->ipr[IPR_IPL] |= val & 0x1F;
       
   283         /* XXX: may issue an interrupt or ASR _now_ */
       
   284         ret = 1;
       
   285         break;
       
   286     case IPR_KSP:
       
   287         if (!(env->ipr[IPR_EXC_ADDR] & 1)) {
       
   288             ret = -1;
       
   289         } else {
       
   290             if (env->features & FEATURE_SPS)
       
   291                 env->ipr[IPR_KSP] = val;
       
   292             else
       
   293                 stq_raw(hwpcb + 0, val);
       
   294         }
       
   295         break;
       
   296     case IPR_MCES:
       
   297         env->ipr[IPR_MCES] &= ~((val & 0x7) | 0x18);
       
   298         env->ipr[IPR_MCES] |= val & 0x18;
       
   299         break;
       
   300     case IPR_PERFMON:
       
   301         /* Implementation specific */
       
   302         *oldvalp = 0;
       
   303         ret = 1;
       
   304         break;
       
   305     case IPR_PCBB:
       
   306         /* Read-only */
       
   307         ret = -1;
       
   308         break;
       
   309     case IPR_PRBR:
       
   310         env->ipr[IPR_PRBR] = val;
       
   311         break;
       
   312     case IPR_PTBR:
       
   313         /* Read-only */
       
   314         ret = -1;
       
   315         break;
       
   316     case IPR_SCBB:
       
   317         env->ipr[IPR_SCBB] = (uint32_t)val;
       
   318         break;
       
   319     case IPR_SIRR:
       
   320         if (val & 0xF) {
       
   321             env->ipr[IPR_SISR] |= 1 << (val & 0xF);
       
   322             /* XXX: request a software interrupt _now_ */
       
   323         }
       
   324         break;
       
   325     case IPR_SISR:
       
   326         /* Read-only */
       
   327         ret = -1;
       
   328         break;
       
   329     case IPR_SSP:
       
   330         if (env->features & FEATURE_SPS)
       
   331             env->ipr[IPR_SSP] = val;
       
   332         else
       
   333             stq_raw(hwpcb + 16, val);
       
   334         break;
       
   335     case IPR_SYSPTBR:
       
   336         if (env->features & FEATURE_VIRBND)
       
   337             env->ipr[IPR_SYSPTBR] = val;
       
   338         else
       
   339             ret = -1;
       
   340     case IPR_TBCHK:
       
   341         /* Read-only */
       
   342         ret = -1;
       
   343         break;
       
   344     case IPR_TBIA:
       
   345         tlb_flush(env, 1);
       
   346         break;
       
   347     case IPR_TBIAP:
       
   348         tlb_flush(env, 1);
       
   349         break;
       
   350     case IPR_TBIS:
       
   351         tlb_flush_page(env, val);
       
   352         break;
       
   353     case IPR_TBISD:
       
   354         tlb_flush_page(env, val);
       
   355         break;
       
   356     case IPR_TBISI:
       
   357         tlb_flush_page(env, val);
       
   358         break;
       
   359     case IPR_USP:
       
   360         if (env->features & FEATURE_SPS)
       
   361             env->ipr[IPR_USP] = val;
       
   362         else
       
   363             stq_raw(hwpcb + 24, val);
       
   364         break;
       
   365     case IPR_VIRBND:
       
   366         if (env->features & FEATURE_VIRBND)
       
   367             env->ipr[IPR_VIRBND] = val;
       
   368         else
       
   369             ret = -1;
       
   370         break;
       
   371     case IPR_VPTB:
       
   372         env->ipr[IPR_VPTB] = val;
       
   373         break;
       
   374     case IPR_WHAMI:
       
   375         /* Read-only */
       
   376         ret = -1;
       
   377         break;
       
   378     default:
       
   379         /* Invalid */
       
   380         ret = -1;
       
   381         break;
       
   382     }
       
   383 
       
   384     return ret;
       
   385 }
       
   386 
       
   387 void do_interrupt (CPUState *env)
       
   388 {
       
   389     int excp;
       
   390 
       
   391     env->ipr[IPR_EXC_ADDR] = env->pc | 1;
       
   392     excp = env->exception_index;
       
   393     env->exception_index = 0;
       
   394     env->error_code = 0;
       
   395     /* XXX: disable interrupts and memory mapping */
       
   396     if (env->ipr[IPR_PAL_BASE] != -1ULL) {
       
   397         /* We use native PALcode */
       
   398         env->pc = env->ipr[IPR_PAL_BASE] + excp;
       
   399     } else {
       
   400         /* We use emulated PALcode */
       
   401         call_pal(env);
       
   402         /* Emulate REI */
       
   403         env->pc = env->ipr[IPR_EXC_ADDR] & ~7;
       
   404         env->ipr[IPR_EXC_ADDR] = env->ipr[IPR_EXC_ADDR] & 1;
       
   405         /* XXX: re-enable interrupts and memory mapping */
       
   406     }
       
   407 }
       
   408 #endif
       
   409 
       
   410 void cpu_dump_state (CPUState *env, FILE *f,
       
   411                      int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
       
   412                      int flags)
       
   413 {
       
   414     static const char *linux_reg_names[] = {
       
   415         "v0 ", "t0 ", "t1 ", "t2 ", "t3 ", "t4 ", "t5 ", "t6 ",
       
   416         "t7 ", "s0 ", "s1 ", "s2 ", "s3 ", "s4 ", "s5 ", "fp ",
       
   417         "a0 ", "a1 ", "a2 ", "a3 ", "a4 ", "a5 ", "t8 ", "t9 ",
       
   418         "t10", "t11", "ra ", "t12", "at ", "gp ", "sp ", "zero",
       
   419     };
       
   420     int i;
       
   421 
       
   422     cpu_fprintf(f, "     PC  " TARGET_FMT_lx "      PS  " TARGET_FMT_lx "\n",
       
   423                 env->pc, env->ps);
       
   424     for (i = 0; i < 31; i++) {
       
   425         cpu_fprintf(f, "IR%02d %s " TARGET_FMT_lx " ", i,
       
   426                     linux_reg_names[i], env->ir[i]);
       
   427         if ((i % 3) == 2)
       
   428             cpu_fprintf(f, "\n");
       
   429     }
       
   430     cpu_fprintf(f, "\n");
       
   431     for (i = 0; i < 31; i++) {
       
   432         cpu_fprintf(f, "FIR%02d    " TARGET_FMT_lx " ", i,
       
   433                     *((uint64_t *)(&env->fir[i])));
       
   434         if ((i % 3) == 2)
       
   435             cpu_fprintf(f, "\n");
       
   436     }
       
   437     cpu_fprintf(f, "\nlock     " TARGET_FMT_lx "\n", env->lock);
       
   438 }