Annotation of qemu/target-alpha/helper.c, revision 1.1.1.1

1.1       root        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 unsigned 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, "FT " TARGET_FMT_lx " " TARGET_FMT_lx " " TARGET_FMT_lx,
                    438:                 *((uint64_t *)(&env->ft0)), *((uint64_t *)(&env->ft1)),
                    439:                 *((uint64_t *)(&env->ft2)));
                    440:     cpu_fprintf(f, "\nMEM " TARGET_FMT_lx " %d %d\n",
                    441:                 ldq_raw(0x000000004007df60ULL),
                    442:                 (uint8_t *)(&env->ft0), (uint8_t *)(&env->fir[0]));
                    443: }
                    444: 
                    445: void cpu_dump_EA (target_ulong EA)
                    446: {
                    447:     FILE *f;
                    448: 
                    449:     if (logfile)
                    450:         f = logfile;
                    451:     else
                    452:         f = stdout;
                    453:     fprintf(f, "Memory access at address " TARGET_FMT_lx "\n", EA);
                    454: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.