?? alpha_palcode.c
字號:
/* * Alpha emulation - PALcode emulation for qemu. * * Copyright (c) 2007 Jocelyn Mayer * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <stdint.h>#include <stdlib.h>#include <stdio.h>#include "qemu.h"#include "cpu.h"#include "exec-all.h"#if !defined (CONFIG_USER_ONLY)/* Shared handlers */static void pal_reset (CPUState *env);/* Console handlers */static void pal_console_call (CPUState *env, uint32_t palcode);/* OpenVMS handlers */static void pal_openvms_call (CPUState *env, uint32_t palcode);/* UNIX / Linux handlers */static void pal_unix_call (CPUState *env, uint32_t palcode);pal_handler_t pal_handlers[] = { /* Console handler */ { .reset = &pal_reset, .call_pal = &pal_console_call, }, /* OpenVMS handler */ { .reset = &pal_reset, .call_pal = &pal_openvms_call, }, /* UNIX / Linux handler */ { .reset = &pal_reset, .call_pal = &pal_unix_call, },};#if 0/* One must explicitely check that the TB is valid and the FOE bit is reset */static void update_itb (){ /* This writes into a temp register, not the actual one */ mtpr(TB_TAG); mtpr(TB_CTL); /* This commits the TB update */ mtpr(ITB_PTE);}static void update_dtb ();{ mtpr(TB_CTL); /* This write into a temp register, not the actual one */ mtpr(TB_TAG); /* This commits the TB update */ mtpr(DTB_PTE);}#endifstatic void pal_reset (CPUState *env){}static void do_swappal (CPUState *env, uint64_t palid){ pal_handler_t *pal_handler; int status; status = 0; switch (palid) { case 0 ... 2: pal_handler = &pal_handlers[palid]; env->pal_handler = pal_handler; env->ipr[IPR_PAL_BASE] = -1ULL; (*pal_handler->reset)(env); break; case 3 ... 255: /* Unknown identifier */ env->ir[0] = 1; return; default: /* We were given the entry point address */ env->pal_handler = NULL; env->ipr[IPR_PAL_BASE] = palid; env->pc = env->ipr[IPR_PAL_BASE]; cpu_loop_exit(); }}static void pal_console_call (CPUState *env, uint32_t palcode){ uint64_t palid; if (palcode < 0x00000080) { /* Privileged palcodes */ if (!(env->ps >> 3)) { /* TODO: generate privilege exception */ } } switch (palcode) { case 0x00000000: /* HALT */ /* REQUIRED */ break; case 0x00000001: /* CFLUSH */ break; case 0x00000002: /* DRAINA */ /* REQUIRED */ /* Implemented as no-op */ break; case 0x00000009: /* CSERVE */ /* REQUIRED */ break; case 0x0000000A: /* SWPPAL */ /* REQUIRED */ palid = env->ir[16]; do_swappal(env, palid); break; case 0x00000080: /* BPT */ /* REQUIRED */ break; case 0x00000081: /* BUGCHK */ /* REQUIRED */ break; case 0x00000086: /* IMB */ /* REQUIRED */ /* Implemented as no-op */ break; case 0x0000009E: /* RDUNIQUE */ /* REQUIRED */ break; case 0x0000009F: /* WRUNIQUE */ /* REQUIRED */ break; case 0x000000AA: /* GENTRAP */ /* REQUIRED */ break; default: break; }}static void pal_openvms_call (CPUState *env, uint32_t palcode){ uint64_t palid, val, oldval; if (palcode < 0x00000080) { /* Privileged palcodes */ if (!(env->ps >> 3)) { /* TODO: generate privilege exception */ } } switch (palcode) { case 0x00000000: /* HALT */ /* REQUIRED */ break; case 0x00000001: /* CFLUSH */ break; case 0x00000002: /* DRAINA */ /* REQUIRED */ /* Implemented as no-op */ break; case 0x00000003: /* LDQP */ break; case 0x00000004: /* STQP */ break; case 0x00000005: /* SWPCTX */ break; case 0x00000006: /* MFPR_ASN */ if (cpu_alpha_mfpr(env, IPR_ASN, &val) == 0) env->ir[0] = val; break; case 0x00000007: /* MTPR_ASTEN */ val = env->ir[16]; if (cpu_alpha_mtpr(env, IPR_ASTEN, val, &oldval) == 1) env->ir[0] = val; break; case 0x00000008: /* MTPR_ASTSR */ val = env->ir[16]; if (cpu_alpha_mtpr(env, IPR_ASTSR, val, &oldval) == 1) env->ir[0] = val; break; case 0x00000009: /* CSERVE */ /* REQUIRED */ break; case 0x0000000A: /* SWPPAL */ /* REQUIRED */ palid = env->ir[16]; do_swappal(env, palid); break; case 0x0000000B: /* MFPR_FEN */ if (cpu_alpha_mfpr(env, IPR_FEN, &val) == 0) env->ir[0] = val; break; case 0x0000000C: /* MTPR_FEN */ val = env->ir[16]; if (cpu_alpha_mtpr(env, IPR_FEN, val, &oldval) == 1) env->ir[0] = val; break; case 0x0000000D: /* MTPR_IPIR */ val = env->ir[16]; if (cpu_alpha_mtpr(env, IPR_IPIR, val, &oldval) == 1) env->ir[0] = val; break; case 0x0000000E: /* MFPR_IPL */ if (cpu_alpha_mfpr(env, IPR_IPL, &val) == 0) env->ir[0] = val; break; case 0x0000000F: /* MTPR_IPL */ val = env->ir[16]; if (cpu_alpha_mtpr(env, IPR_IPL, val, &oldval) == 1) env->ir[0] = val; break; case 0x00000010: /* MFPR_MCES */ if (cpu_alpha_mfpr(env, IPR_MCES, &val) == 0) env->ir[0] = val; break; case 0x00000011: /* MTPR_MCES */ val = env->ir[16]; if (cpu_alpha_mtpr(env, IPR_MCES, val, &oldval) == 1) env->ir[0] = val; break; case 0x00000012: /* MFPR_PCBB */ if (cpu_alpha_mfpr(env, IPR_PCBB, &val) == 0) env->ir[0] = val; break; case 0x00000013: /* MFPR_PRBR */ if (cpu_alpha_mfpr(env, IPR_PRBR, &val) == 0) env->ir[0] = val; break; case 0x00000014: /* MTPR_PRBR */ val = env->ir[16]; if (cpu_alpha_mtpr(env, IPR_PRBR, val, &oldval) == 1) env->ir[0] = val; break; case 0x00000015: /* MFPR_PTBR */ if (cpu_alpha_mfpr(env, IPR_PTBR, &val) == 0) env->ir[0] = val; break; case 0x00000016: /* MFPR_SCBB */ if (cpu_alpha_mfpr(env, IPR_SCBB, &val) == 0) env->ir[0] = val; break; case 0x00000017: /* MTPR_SCBB */ val = env->ir[16]; if (cpu_alpha_mtpr(env, IPR_SCBB, val, &oldval) == 1) env->ir[0] = val; break; case 0x00000018: /* MTPR_SIRR */ val = env->ir[16]; if (cpu_alpha_mtpr(env, IPR_SIRR, val, &oldval) == 1) env->ir[0] = val; break; case 0x00000019: /* MFPR_SISR */ if (cpu_alpha_mfpr(env, IPR_SISR, &val) == 0) env->ir[0] = val; break; case 0x0000001A: /* MFPR_TBCHK */ if (cpu_alpha_mfpr(env, IPR_TBCHK, &val) == 0) env->ir[0] = val; break; case 0x0000001B: /* MTPR_TBIA */ val = env->ir[16]; if (cpu_alpha_mtpr(env, IPR_TBIA, val, &oldval) == 1) env->ir[0] = val; break; case 0x0000001C: /* MTPR_TBIAP */ val = env->ir[16]; if (cpu_alpha_mtpr(env, IPR_TBIAP, val, &oldval) == 1) env->ir[0] = val; break; case 0x0000001D: /* MTPR_TBIS */ val = env->ir[16]; if (cpu_alpha_mtpr(env, IPR_TBIS, val, &oldval) == 1) env->ir[0] = val; break; case 0x0000001E: /* MFPR_ESP */ if (cpu_alpha_mfpr(env, IPR_ESP, &val) == 0) env->ir[0] = val; break; case 0x0000001F: /* MTPR_ESP */ val = env->ir[16]; if (cpu_alpha_mtpr(env, IPR_ESP, val, &oldval) == 1) env->ir[0] = val; break; case 0x00000020: /* MFPR_SSP */ if (cpu_alpha_mfpr(env, IPR_SSP, &val) == 0) env->ir[0] = val; break; case 0x00000021: /* MTPR_SSP */ val = env->ir[16]; if (cpu_alpha_mtpr(env, IPR_SSP, val, &oldval) == 1) env->ir[0] = val; break; case 0x00000022: /* MFPR_USP */ if (cpu_alpha_mfpr(env, IPR_USP, &val) == 0) env->ir[0] = val; break; case 0x00000023: /* MTPR_USP */ val = env->ir[16]; if (cpu_alpha_mtpr(env, IPR_USP, val, &oldval) == 1) env->ir[0] = val; break; case 0x00000024: /* MTPR_TBISD */ val = env->ir[16]; if (cpu_alpha_mtpr(env, IPR_TBISD, val, &oldval) == 1) env->ir[0] = val; break; case 0x00000025: /* MTPR_TBISI */ val = env->ir[16]; if (cpu_alpha_mtpr(env, IPR_TBISI, val, &oldval) == 1) env->ir[0] = val; break; case 0x00000026: /* MFPR_ASTEN */ if (cpu_alpha_mfpr(env, IPR_ASTEN, &val) == 0) env->ir[0] = val; break; case 0x00000027: /* MFPR_ASTSR */ if (cpu_alpha_mfpr(env, IPR_ASTSR, &val) == 0) env->ir[0] = val; break; case 0x00000029: /* MFPR_VPTB */ if (cpu_alpha_mfpr(env, IPR_VPTB, &val) == 0) env->ir[0] = val; break; case 0x0000002A: /* MTPR_VPTB */ val = env->ir[16]; if (cpu_alpha_mtpr(env, IPR_VPTB, val, &oldval) == 1) env->ir[0] = val; break; case 0x0000002B: /* MTPR_PERFMON */ val = env->ir[16]; if (cpu_alpha_mtpr(env, IPR_PERFMON, val, &oldval) == 1) env->ir[0] = val; break; case 0x0000002E: /* MTPR_DATFX */ val = env->ir[16]; if (cpu_alpha_mtpr(env, IPR_DATFX, val, &oldval) == 1) env->ir[0] = val; break; case 0x0000003E: /* WTINT */ break; case 0x0000003F: /* MFPR_WHAMI */ if (cpu_alpha_mfpr(env, IPR_WHAMI, &val) == 0) env->ir[0] = val; break; case 0x00000080: /* BPT */ /* REQUIRED */ break; case 0x00000081: /* BUGCHK */ /* REQUIRED */ break; case 0x00000082: /* CHME */ break; case 0x00000083: /* CHMK */ break; case 0x00000084: /* CHMS */ break; case 0x00000085: /* CHMU */ break; case 0x00000086: /* IMB */ /* REQUIRED */ /* Implemented as no-op */ break; case 0x00000087: /* INSQHIL */ break; case 0x00000088: /* INSQTIL */ break; case 0x00000089: /* INSQHIQ */ break; case 0x0000008A: /* INSQTIQ */ break; case 0x0000008B: /* INSQUEL */ break; case 0x0000008C: /* INSQUEQ */ break; case 0x0000008D: /* INSQUEL/D */ break; case 0x0000008E: /* INSQUEQ/D */ break; case 0x0000008F: /* PROBER */ break; case 0x00000090: /* PROBEW */ break; case 0x00000091: /* RD_PS */ break; case 0x00000092: /* REI */ break; case 0x00000093: /* REMQHIL */ break; case 0x00000094: /* REMQTIL */ break; case 0x00000095: /* REMQHIQ */ break; case 0x00000096: /* REMQTIQ */ break; case 0x00000097: /* REMQUEL */ break; case 0x00000098: /* REMQUEQ */ break; case 0x00000099: /* REMQUEL/D */ break; case 0x0000009A: /* REMQUEQ/D */ break; case 0x0000009B: /* SWASTEN */ break; case 0x0000009C: /* WR_PS_SW */ break; case 0x0000009D: /* RSCC */ break; case 0x0000009E: /* READ_UNQ */ /* REQUIRED */ break; case 0x0000009F: /* WRITE_UNQ */ /* REQUIRED */ break; case 0x000000A0: /* AMOVRR */ break; case 0x000000A1: /* AMOVRM */ break; case 0x000000A2: /* INSQHILR */ break; case 0x000000A3: /* INSQTILR */ break; case 0x000000A4: /* INSQHIQR */ break; case 0x000000A5: /* INSQTIQR */ break; case 0x000000A6: /* REMQHILR */ break; case 0x000000A7: /* REMQTILR */ break; case 0x000000A8: /* REMQHIQR */ break; case 0x000000A9: /* REMQTIQR */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -