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

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

unix.superglobalmegacorp.com

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