(linenum→info "unix/slp.c:2238")

qemu/0.9.1/hw/alpha_palcode.c

    1: /*
    2:  *  Alpha emulation - PALcode emulation 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 "qemu.h"
   26: #include "cpu.h"
   27: #include "exec-all.h"
   28: 
   29: #if !defined (CONFIG_USER_ONLY)
   30: /* Shared handlers */
   31: static void pal_reset (CPUState *env);
   32: /* Console handlers */
   33: static void pal_console_call (CPUState *env, uint32_t palcode);
   34: /* OpenVMS handlers */
   35: static void pal_openvms_call (CPUState *env, uint32_t palcode);
   36: /* UNIX / Linux handlers */
   37: static void pal_unix_call (CPUState *env, uint32_t palcode);
   38: 
   39: pal_handler_t pal_handlers[] = {
   40:     /* Console handler */
   41:     {
   42:         .reset = &pal_reset,
   43:         .call_pal = &pal_console_call,
   44:     },
   45:     /* OpenVMS handler */
   46:     {
   47:         .reset = &pal_reset,
   48:         .call_pal = &pal_openvms_call,
   49:     },
   50:     /* UNIX / Linux handler */
   51:     {
   52:         .reset = &pal_reset,
   53:         .call_pal = &pal_unix_call,
   54:     },
   55: };
   56: 
   57: #if 0
   58: /* One must explicitely check that the TB is valid and the FOE bit is reset */
   59: static void update_itb ()
   60: {
   61:     /* This writes into a temp register, not the actual one */
   62:     mtpr(TB_TAG);
   63:     mtpr(TB_CTL);
   64:     /* This commits the TB update */
   65:     mtpr(ITB_PTE);
   66: }
   67: 
   68: static void update_dtb ();
   69: {
   70:     mtpr(TB_CTL);
   71:     /* This write into a temp register, not the actual one */
   72:     mtpr(TB_TAG);
   73:     /* This commits the TB update */
   74:     mtpr(DTB_PTE);
   75: }
   76: #endif
   77: 
   78: static void pal_reset (CPUState *env)
   79: {
   80: }
   81: 
   82: static void do_swappal (CPUState *env, uint64_t palid)
   83: {
   84:     pal_handler_t *pal_handler;
   85:     int status;
   86: 
   87:     status = 0;
   88:     switch (palid) {
   89:     case 0 ... 2:
   90:         pal_handler = &pal_handlers[palid];
   91:         env->pal_handler = pal_handler;
   92:         env->ipr[IPR_PAL_BASE] = -1ULL;
   93:         (*pal_handler->reset)(env);
   94:         break;
   95:     case 3 ... 255:
   96:         /* Unknown identifier */
   97:         env->ir[0] = 1;
   98:         return;
   99:     default:
  100:         /* We were given the entry point address */
  101:         env->pal_handler = NULL;
  102:         env->ipr[IPR_PAL_BASE] = palid;
  103:         env->pc = env->ipr[IPR_PAL_BASE];
  104:         cpu_loop_exit();
  105:     }
  106: }
  107: 
  108: static void pal_console_call (CPUState *env, uint32_t palcode)
  109: {
  110:     uint64_t palid;
  111: 
  112:     if (palcode < 0x00000080) {
  113:         /* Privileged palcodes */
  114:         if (!(env->ps >> 3)) {
  115:             /* TODO: generate privilege exception */
  116:         }
  117:     }
  118:     switch (palcode) {
  119:     case 0x00000000:
  120:         /* HALT */
  121:         /* REQUIRED */
  122:         break;
  123:     case 0x00000001:
  124:         /* CFLUSH */
  125:         break;
  126:     case 0x00000002:
  127:         /* DRAINA */
  128:         /* REQUIRED */
  129:         /* Implemented as no-op */
  130:         break;
  131:     case 0x00000009:
  132:         /* CSERVE */
  133:         /* REQUIRED */
  134:         break;
  135:     case 0x0000000A:
  136:         /* SWPPAL */
  137:         /* REQUIRED */
  138:         palid = env->ir[16];
  139:         do_swappal(env, palid);
  140:         break;
  141:     case 0x00000080:
  142:         /* BPT */
  143:         /* REQUIRED */
  144:         break;
  145:     case 0x00000081:
  146:         /* BUGCHK */
  147:         /* REQUIRED */
  148:         break;
  149:     case 0x00000086:
  150:         /* IMB */
  151:         /* REQUIRED */
  152:         /* Implemented as no-op */
  153:         break;
  154:     case 0x0000009E:
  155:         /* RDUNIQUE */
  156:         /* REQUIRED */
  157:         break;
  158:     case 0x0000009F:
  159:         /* WRUNIQUE */
  160:         /* REQUIRED */
  161:         break;
  162:     case 0x000000AA:
  163:         /* GENTRAP */
  164:         /* REQUIRED */
  165:         break;
  166:     default:
  167:         break;
  168:     }
  169: }
  170: 
  171: static void pal_openvms_call (CPUState *env, uint32_t palcode)
  172: {
  173:     uint64_t palid, val, oldval;
  174: 
  175:     if (palcode < 0x00000080) {
  176:         /* Privileged palcodes */
  177:         if (!(env->ps >> 3)) {
  178:             /* TODO: generate privilege exception */
  179:         }
  180:     }
  181:     switch (palcode) {
  182:     case 0x00000000:
  183:         /* HALT */
  184:         /* REQUIRED */
  185:         break;
  186:     case 0x00000001:
  187:         /* CFLUSH */
  188:         break;
  189:     case 0x00000002:
  190:         /* DRAINA */
  191:         /* REQUIRED */
  192:         /* Implemented as no-op */
  193:         break;
  194:     case 0x00000003:
  195:         /* LDQP */
  196:         break;
  197:     case 0x00000004:
  198:         /* STQP */
  199:         break;
  200:     case 0x00000005:
  201:         /* SWPCTX */
  202:         break;
  203:     case 0x00000006:
  204:         /* MFPR_ASN */
  205:         if (cpu_alpha_mfpr(env, IPR_ASN, &val) == 0)
  206:             env->ir[0] = val;
  207:         break;
  208:     case 0x00000007:
  209:         /* MTPR_ASTEN */
  210:         val = env->ir[16];
  211:         if (cpu_alpha_mtpr(env, IPR_ASTEN, val, &oldval) == 1)
  212:             env->ir[0] = val;
  213:         break;
  214:     case 0x00000008:
  215:         /* MTPR_ASTSR */
  216:         val = env->ir[16];
  217:         if (cpu_alpha_mtpr(env, IPR_ASTSR, val, &oldval) == 1)
  218:             env->ir[0] = val;
  219:         break;
  220:     case 0x00000009:
  221:         /* CSERVE */
  222:         /* REQUIRED */
  223:         break;
  224:     case 0x0000000A:
  225:         /* SWPPAL */
  226:         /* REQUIRED */
  227:         palid = env->ir[16];
  228:         do_swappal(env, palid);
  229:         break;
  230:     case 0x0000000B:
  231:         /* MFPR_FEN */
  232:         if (cpu_alpha_mfpr(env, IPR_FEN, &val) == 0)
  233:             env->ir[0] = val;
  234:         break;
  235:     case 0x0000000C:
  236:         /* MTPR_FEN */
  237:         val = env->ir[16];
  238:         if (cpu_alpha_mtpr(env, IPR_FEN, val, &oldval) == 1)
  239:             env->ir[0] = val;
  240:         break;
  241:     case 0x0000000D:
  242:         /* MTPR_IPIR */
  243:         val = env->ir[16];
  244:         if (cpu_alpha_mtpr(env, IPR_IPIR, val, &oldval) == 1)
  245:             env->ir[0] = val;
  246:         break;
  247:     case 0x0000000E:
  248:         /* MFPR_IPL */
  249:         if (cpu_alpha_mfpr(env, IPR_IPL, &val) == 0)
  250:             env->ir[0] = val;
  251:         break;
  252:     case 0x0000000F:
  253:         /* MTPR_IPL */
  254:         val = env->ir[16];
  255:         if (cpu_alpha_mtpr(env, IPR_IPL, val, &oldval) == 1)
  256:             env->ir[0] = val;
  257:         break;
  258:     case 0x00000010:
  259:         /* MFPR_MCES */
  260:         if (cpu_alpha_mfpr(env, IPR_MCES, &val) == 0)
  261:             env->ir[0] = val;
  262:         break;
  263:     case 0x00000011:
  264:         /* MTPR_MCES */
  265:         val = env->ir[16];
  266:         if (cpu_alpha_mtpr(env, IPR_MCES, val, &oldval) == 1)
  267:             env->ir[0] = val;
  268:         break;
  269:     case 0x00000012:
  270:         /* MFPR_PCBB */
  271:         if (cpu_alpha_mfpr(env, IPR_PCBB, &val) == 0)
  272:             env->ir[0] = val;
  273:         break;
  274:     case 0x00000013:
  275:         /* MFPR_PRBR */
  276:         if (cpu_alpha_mfpr(env, IPR_PRBR, &val) == 0)
  277:             env->ir[0] = val;
  278:         break;
  279:     case 0x00000014:
  280:         /* MTPR_PRBR */
  281:         val = env->ir[16];
  282:         if (cpu_alpha_mtpr(env, IPR_PRBR, val, &oldval) == 1)
  283:             env->ir[0] = val;
  284:         break;
  285:     case 0x00000015:
  286:         /* MFPR_PTBR */
  287:         if (cpu_alpha_mfpr(env, IPR_PTBR, &val) == 0)
  288:             env->ir[0] = val;
  289:         break;
  290:     case 0x00000016:
  291:         /* MFPR_SCBB */
  292:         if (cpu_alpha_mfpr(env, IPR_SCBB, &val) == 0)
  293:             env->ir[0] = val;
  294:         break;
  295:     case 0x00000017:
  296:         /* MTPR_SCBB */
  297:         val = env->ir[16];
  298:         if (cpu_alpha_mtpr(env, IPR_SCBB, val, &oldval) == 1)
  299:             env->ir[0] = val;
  300:         break;
  301:     case 0x00000018:
  302:         /* MTPR_SIRR */
  303:         val = env->ir[16];
  304:         if (cpu_alpha_mtpr(env, IPR_SIRR, val, &oldval) == 1)
  305:             env->ir[0] = val;
  306:         break;
  307:     case 0x00000019:
  308:         /* MFPR_SISR */
  309:         if (cpu_alpha_mfpr(env, IPR_SISR, &val) == 0)
  310:             env->ir[0] = val;
  311:         break;
  312:     case 0x0000001A:
  313:         /* MFPR_TBCHK */
  314:         if (cpu_alpha_mfpr(env, IPR_TBCHK, &val) == 0)
  315:             env->ir[0] = val;
  316:         break;
  317:     case 0x0000001B:
  318:         /* MTPR_TBIA */
  319:         val = env->ir[16];
  320:         if (cpu_alpha_mtpr(env, IPR_TBIA, val, &oldval) == 1)
  321:             env->ir[0] = val;
  322:         break;
  323:     case 0x0000001C:
  324:         /* MTPR_TBIAP */
  325:         val = env->ir[16];
  326:         if (cpu_alpha_mtpr(env, IPR_TBIAP, val, &oldval) == 1)
  327:             env->ir[0] = val;
  328:         break;
  329:     case 0x0000001D:
  330:         /* MTPR_TBIS */
  331:         val = env->ir[16];
  332:         if (cpu_alpha_mtpr(env, IPR_TBIS, val, &oldval) == 1)
  333:             env->ir[0] = val;
  334:         break;
  335:     case 0x0000001E:
  336:         /* MFPR_ESP */
  337:         if (cpu_alpha_mfpr(env, IPR_ESP, &val) == 0)
  338:             env->ir[0] = val;
  339:         break;
  340:     case 0x0000001F:
  341:         /* MTPR_ESP */
  342:         val = env->ir[16];
  343:         if (cpu_alpha_mtpr(env, IPR_ESP, val, &oldval) == 1)
  344:             env->ir[0] = val;
  345:         break;
  346:     case 0x00000020:
  347:         /* MFPR_SSP */
  348:         if (cpu_alpha_mfpr(env, IPR_SSP, &val) == 0)
  349:             env->ir[0] = val;
  350:         break;
  351:     case 0x00000021:
  352:         /* MTPR_SSP */
  353:         val = env->ir[16];
  354:         if (cpu_alpha_mtpr(env, IPR_SSP, val, &oldval) == 1)
  355:             env->ir[0] = val;
  356:         break;
  357:     case 0x00000022:
  358:         /* MFPR_USP */
  359:         if (cpu_alpha_mfpr(env, IPR_USP, &val) == 0)
  360:             env->ir[0] = val;
  361:         break;
  362:     case 0x00000023:
  363:         /* MTPR_USP */
  364:         val = env->ir[16];
  365:         if (cpu_alpha_mtpr(env, IPR_USP, val, &oldval) == 1)
  366:             env->ir[0] = val;
  367:         break;
  368:     case 0x00000024:
  369:         /* MTPR_TBISD */
  370:         val = env->ir[16];
  371:         if (cpu_alpha_mtpr(env, IPR_TBISD, val, &oldval) == 1)
  372:             env->ir[0] = val;
  373:         break;
  374:     case 0x00000025:
  375:         /* MTPR_TBISI */
  376:         val = env->ir[16];
  377:         if (cpu_alpha_mtpr(env, IPR_TBISI, val, &oldval) == 1)
  378:             env->ir[0] = val;
  379:         break;
  380:     case 0x00000026:
  381:         /* MFPR_ASTEN */
  382:         if (cpu_alpha_mfpr(env, IPR_ASTEN, &val) == 0)
  383:             env->ir[0] = val;
  384:         break;
  385:     case 0x00000027:
  386:         /* MFPR_ASTSR */
  387:         if (cpu_alpha_mfpr(env, IPR_ASTSR, &val) == 0)
  388:             env->ir[0] = val;
  389:         break;
  390:     case 0x00000029:
  391:         /* MFPR_VPTB */
  392:         if (cpu_alpha_mfpr(env, IPR_VPTB, &val) == 0)
  393:             env->ir[0] = val;
  394:         break;
  395:     case 0x0000002A:
  396:         /* MTPR_VPTB */
  397:         val = env->ir[16];
  398:         if (cpu_alpha_mtpr(env, IPR_VPTB, val, &oldval) == 1)
  399:             env->ir[0] = val;
  400:         break;
  401:     case 0x0000002B:
  402:         /* MTPR_PERFMON */
  403:         val = env->ir[16];
  404:         if (cpu_alpha_mtpr(env, IPR_PERFMON, val, &oldval) == 1)
  405:             env->ir[0] = val;
  406:         break;
  407:     case 0x0000002E:
  408:         /* MTPR_DATFX */
  409:         val = env->ir[16];
  410:         if (cpu_alpha_mtpr(env, IPR_DATFX, val, &oldval) == 1)
  411:             env->ir[0] = val;
  412:         break;
  413:     case 0x0000003E:
  414:         /* WTINT */
  415:         break;
  416:     case 0x0000003F:
  417:         /* MFPR_WHAMI */
  418:         if (cpu_alpha_mfpr(env, IPR_WHAMI, &val) == 0)
  419:             env->ir[0] = val;
  420:         break;
  421:     case 0x00000080:
  422:         /* BPT */
  423:         /* REQUIRED */
  424:         break;
  425:     case 0x00000081:
  426:         /* BUGCHK */
  427:         /* REQUIRED */
  428:         break;
  429:     case 0x00000082:
  430:         /* CHME */
  431:         break;
  432:     case 0x00000083:
  433:         /* CHMK */
  434:         break;
  435:     case 0x00000084:
  436:         /* CHMS */
  437:         break;
  438:     case 0x00000085:
  439:         /* CHMU */
  440:         break;
  441:     case 0x00000086:
  442:         /* IMB */
  443:         /* REQUIRED */
  444:         /* Implemented as no-op */
  445:         break;
  446:     case 0x00000087:
  447:         /* INSQHIL */
  448:         break;
  449:     case 0x00000088:
  450:         /* INSQTIL */
  451:         break;
  452:     case 0x00000089:
  453:         /* INSQHIQ */
  454:         break;
  455:     case 0x0000008A:
  456:         /* INSQTIQ */
  457:         break;
  458:     case 0x0000008B:
  459:         /* INSQUEL */
  460:         break;
  461:     case 0x0000008C:
  462:         /* INSQUEQ */
  463:         break;
  464:     case 0x0000008D:
  465:         /* INSQUEL/D */
  466:         break;
  467:     case 0x0000008E:
  468:         /* INSQUEQ/D */
  469:         break;
  470:     case 0x0000008F:
  471:         /* PROBER */
  472:         break;
  473:     case 0x00000090:
  474:         /* PROBEW */
  475:         break;
  476:     case 0x00000091:
  477:         /* RD_PS */
  478:         break;
  479:     case 0x00000092:
  480:         /* REI */
  481:         break;
  482:     case 0x00000093:
  483:         /* REMQHIL */
  484:         break;
  485:     case 0x00000094:
  486:         /* REMQTIL */
  487:         break;
  488:     case 0x00000095:
  489:         /* REMQHIQ */
  490:         break;
  491:     case 0x00000096:
  492:         /* REMQTIQ */
  493:         break;
  494:     case 0x00000097:
  495:         /* REMQUEL */
  496:         break;
  497:     case 0x00000098:
  498:         /* REMQUEQ */
  499:         break;
  500:     case 0x00000099:
  501:         /* REMQUEL/D */
  502:         break;
  503:     case 0x0000009A:
  504:         /* REMQUEQ/D */
  505:         break;
  506:     case 0x0000009B:
  507:         /* SWASTEN */
  508:         break;
  509:     case 0x0000009C:
  510:         /* WR_PS_SW */
  511:         break;
  512:     case 0x0000009D:
  513:         /* RSCC */
  514:         break;
  515:     case 0x0000009E:
  516:         /* READ_UNQ */
  517:         /* REQUIRED */
  518:         break;
  519:     case 0x0000009F:
  520:         /* WRITE_UNQ */
  521:         /* REQUIRED */
  522:         break;
  523:     case 0x000000A0:
  524:         /* AMOVRR */
  525:         break;
  526:     case 0x000000A1:
  527:         /* AMOVRM */
  528:         break;
  529:     case 0x000000A2:
  530:         /* INSQHILR */
  531:         break;
  532:     case 0x000000A3:
  533:         /* INSQTILR */
  534:         break;
  535:     case 0x000000A4:
  536:         /* INSQHIQR */
  537:         break;
  538:     case 0x000000A5:
  539:         /* INSQTIQR */
  540:         break;
  541:     case 0x000000A6:
  542:         /* REMQHILR */
  543:         break;
  544:     case 0x000000A7:
  545:         /* REMQTILR */
  546:         break;
  547:     case 0x000000A8:
  548:         /* REMQHIQR */
  549:         break;
  550:     case 0x000000A9:
  551:         /* REMQTIQR */
  552:         break;
  553:     case 0x000000AA:
  554:         /* GENTRAP */
  555:         /* REQUIRED */
  556:         break;
  557:     case 0x000000AE:
  558:         /* CLRFEN */
  559:         break;
  560:     default:
  561:         break;
  562:     }
  563: }
  564: 
  565: static void pal_unix_call (CPUState *env, uint32_t palcode)
  566: {
  567:     uint64_t palid, val, oldval;
  568: 
  569:     if (palcode < 0x00000080) {
  570:         /* Privileged palcodes */
  571:         if (!(env->ps >> 3)) {
  572:             /* TODO: generate privilege exception */
  573:         }
  574:     }
  575:     switch (palcode) {
  576:     case 0x00000000:
  577:         /* HALT */
  578:         /* REQUIRED */
  579:         break;
  580:     case 0x00000001:
  581:         /* CFLUSH */
  582:         break;
  583:     case 0x00000002:
  584:         /* DRAINA */
  585:         /* REQUIRED */
  586:         /* Implemented as no-op */
  587:         break;
  588:     case 0x00000009:
  589:         /* CSERVE */
  590:         /* REQUIRED */
  591:         break;
  592:     case 0x0000000A:
  593:         /* SWPPAL */
  594:         /* REQUIRED */
  595:         palid = env->ir[16];
  596:         do_swappal(env, palid);
  597:         break;
  598:     case 0x0000000D:
  599: