Annotation of qemu/target-alpha/helper.c, revision 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.