cpu_pal.h

Go to the documentation of this file.
00001 /* ES40 emulator.
00002  * Copyright (C) 2007-2008 by the ES40 Emulator Project
00003  *
00004  * WWW    : http://sourceforge.net/projects/es40
00005  * E-mail : camiel@camicom.com
00006  * 
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  * 
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  * 
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00020  * 
00021  * Although this is not required, the author would appreciate being notified of, 
00022  * and receiving any modifications you may make to the source code that might serve
00023  * the general public.
00024  */
00025 
00087 #define DO_HW_MFPR  if((function & 0xc0) == 0x40)                                                              \
00088   { /* PCTX */                                                                                                 \
00089     state.r[REG_1] = ((u64) state.asn << 39) | ((u64) state.astrr << 9) |                                      \
00090       ((u64) state.aster << 5) | (state.fpen ? U64(0x1) << 2 : 0) |                                            \
00091         (state.ppcen ? U64(0x1) << 1 : 0);                                                                     \
00092   }                                                                                                            \
00093   else                                                                                                         \
00094   {                                                                                                            \
00095     switch(function)                                                                                           \
00096     {                                                                                                          \
00097     case 0x05:  /* PMPC     */                                                                                 \
00098       state.r[REG_1] = state.pmpc;                                                                             \
00099       break;                                                                                                   \
00100                                                                                                           \
00101     case 0x06:  /* EXC_ADDR */                                                                                 \
00102       state.r[REG_1] = state.exc_addr;                                                                         \
00103       break;                                                                                                   \
00104                                                                                                           \
00105     case 0x07:  /* IVA_FORM */                                                                                 \
00106       state.r[REG_1] = va_form(state.exc_addr, true);                                                          \
00107       break;                                                                                                   \
00108                                                                                                           \
00109     case 0x08:  /* IER_CM   */                                                                                 \
00110     case 0x09:  /* CM       */                                                                                 \
00111     case 0x0a:  /* IER      */                                                                                 \
00112     case 0x0b:  /* IER_CM   */                                                                                 \
00113       state.r[REG_1] = (((u64) state.eien) << 33) | (((u64) state.slen) << 32) |                               \
00114         (((u64) state.cren) << 31) | (((u64) state.pcen) << 29) |                                              \
00115           (((u64) state.sien) << 13) | (((u64) state.asten) << 13) |                                           \
00116             (((u64) state.cm) << 3);                                                                           \
00117       break;                                                                                                   \
00118                                                                                                           \
00119     case 0x0c:  /* SIRR */                                                                                     \
00120       state.r[REG_1] = ((u64) state.sir) << 13;                                                                \
00121       break;                                                                                                   \
00122                                                                                                           \
00123     case 0x0d:  /* ISUM */                                                                                     \
00124       state.r[REG_1] = (((u64) (state.eir & state.eien)) << 33) |                                              \
00125         (((u64) (state.slr & state.slen)) << 32) |                                                             \
00126           (((u64) (state.crr & state.cren)) << 31) |                                                           \
00127             (((u64) (state.pcr & state.pcen)) << 29) |                                                         \
00128               (((u64) (state.sir & state.sien)) << 13) |                                                       \
00129                 (                                                                                              \
00130                   (                                                                                            \
00131                     (u64)                                                                                      \
00132                       (((U64(0x1) << (state.cm + 1)) - 1) & state.aster & state.astrr & (state.asten * 0x3))   \
00133                   ) << 3                                                                                       \
00134                 ) |                                                                                            \
00135                   (                                                                                            \
00136                     (                                                                                          \
00137                       (u64)                                                                                    \
00138                         (((U64(0x1) << (state.cm + 1)) - 1) & state.aster & state.astrr & (state.asten * 0xc)) \
00139                     ) << 7                                                                                     \
00140                   );                                                                                           \
00141       break;                                                                                                   \
00142                                                                                                           \
00143     case 0x0f:  /* EXC_SUM */                                                                                  \
00144       state.r[REG_1] = state.exc_sum;                                                                          \
00145       break;                                                                                                   \
00146                                                                                                           \
00147     case 0x10:  /* PAL_BASE */                                                                                 \
00148       state.r[REG_1] = state.pal_base;                                                                         \
00149       break;                                                                                                   \
00150                                                                                                           \
00151     case 0x11:  /* i_ctl */                                                                                    \
00152       state.r[REG_1] = state.i_ctl_other |                                                                     \
00153         (((u64) CPU_CHIP_ID) << 24) |                                                                          \
00154         (u64) state.i_ctl_vptb |                                                                               \
00155         (((u64) state.i_ctl_va_mode) << 15) |                                                                  \
00156         (state.hwe ? U64(0x1) << 12 : 0) |                                                                     \
00157         (state.sde ? U64(0x1) << 7 : 0) |                                                                      \
00158         (((u64) state.i_ctl_spe) << 3);                                                                        \
00159       break;                                                                                                   \
00160                                                                                                           \
00161     case 0x14:  /* PCTR_CTL */                                                                                 \
00162       state.r[REG_1] = state.pctr_ctl;                                                                         \
00163       break;                                                                                                   \
00164                                                                                                           \
00165     case 0x16:  /* I_STAT */                                                                                   \
00166       state.r[REG_1] = state.i_stat;                                                                           \
00167       break;                                                                                                   \
00168                                                                                                           \
00169     case 0x27:  /* MM_STAT */                                                                                  \
00170       state.r[REG_1] = state.mm_stat;                                                                          \
00171       break;                                                                                                   \
00172                                                                                                           \
00173     case 0x2a:  /* DC_STAT */                                                                                  \
00174       state.r[REG_1] = state.dc_stat;                                                                          \
00175       break;                                                                                                   \
00176                                                                                                           \
00177     case 0x2b:  /* C_DATA */                                                                                   \
00178       state.r[REG_1] = 0;                                                                                      \
00179       break;                                                                                                   \
00180                                                                                                           \
00181     case 0xc0:  /* CC */                                                                                       \
00182       state.r[REG_1] = (((u64) state.cc_offset) << 32) | (state.cc & U64(0xffffffff));                         \
00183       break;                                                                                                   \
00184                                                                                                           \
00185     case 0xc2:  /* VA */                                                                                       \
00186       state.r[REG_1] = state.fault_va;                                                                         \
00187       break;                                                                                                   \
00188                                                                                                           \
00189     case 0xc3:  /* VA_FORM */                                                                                  \
00190       state.r[REG_1] = va_form(state.fault_va, false);                                                         \
00191       break;                                                                                                   \
00192                                                                                                           \
00193     default:                                                                                                   \
00194       UNKNOWN2;                                                                                                \
00195     }                                                                                                          \
00196   }
00197 
00198 #define DO_HW_MTPR  if((function & 0xc0) == 0x40)                                \
00199   {                                                                              \
00200     if(function & 1)                                                             \
00201       state.asn = (int) (state.r[REG_2] >> 39) & 0xff;                           \
00202     if(function & 2)                                                             \
00203     {                                                                            \
00204       state.aster = (int) (state.r[REG_2] >> 5) & 0xf;                           \
00205       state.check_int = true;                                                    \
00206     }                                                                            \
00207     if(function & 4)                                                             \
00208     {                                                                            \
00209       state.astrr = (int) (state.r[REG_2] >> 9) & 0xf;                           \
00210       state.check_int = true;                                                    \
00211     }                                                                            \
00212     if(function & 8)                                                             \
00213       state.ppcen = (int) (state.r[REG_2] >> 1) & 1;                             \
00214     if(function & 16)                                                            \
00215       state.fpen = (int) (state.r[REG_2] >> 2) & 1;                              \
00216   }                                                                              \
00217   else                                                                           \
00218   {                                                                              \
00219     switch(function)                                                             \
00220     {                                                                            \
00221     case 0x00:  /* ITB_TAG */                                                    \
00222       state.last_tb_virt = state.r[REG_2];                                       \
00223       break;                                                                     \
00224                                                                             \
00225     case 0x01:  /* ITB_PTE */                                                    \
00226       add_tb_i(state.last_tb_virt, state.r[REG_2]);                              \
00227       break;                                                                     \
00228                                                                             \
00229     case 0x02:  /* ITB_IAP */                                                    \
00230       tbiap(ACCESS_EXEC);                                                        \
00231       break;                                                                     \
00232                                                                             \
00233     case 0x03:  /* ITB_IA */                                                     \
00234       tbia(ACCESS_EXEC);                                                         \
00235       break;                                                                     \
00236                                                                             \
00237     case 0x04:  /* ITB_IS */                                                     \
00238       tbis(state.r[REG_2], ACCESS_EXEC);                                         \
00239       break;                                                                     \
00240                                                                             \
00241     case 0x09:  /* CM */                                                         \
00242       state.cm = (int) (state.r[REG_2] >> 3) & 3;                                \
00243       state.check_int = true;                                                    \
00244       break;                                                                     \
00245                                                                             \
00246     case 0x0b:  /* IER_CM */                                                     \
00247       state.cm = (int) (state.r[REG_2] >> 3) & 3;                                \
00248       state.check_int = true;                                                    \
00249                                                                             \
00250     case 0x0a:  /* IER */                                                        \
00251       state.asten = (int) (state.r[REG_2] >> 13) & 1;                            \
00252       state.sien = (int) (state.r[REG_2] >> 13) & 0xfffe;                        \
00253       state.pcen = (int) (state.r[REG_2] >> 29) & 3;                             \
00254       state.cren = (int) (state.r[REG_2] >> 31) & 1;                             \
00255       state.slen = (int) (state.r[REG_2] >> 32) & 1;                             \
00256       state.eien = (int) (state.r[REG_2] >> 33) & 0x3f;                          \
00257       state.check_int = true;                                                    \
00258       break;                                                                     \
00259                                                                             \
00260     case 0x0c:  /* SIRR */                                                       \
00261       state.sir = (int) (state.r[REG_2] >> 13) & 0xfffe;                         \
00262       state.check_int = true;                                                    \
00263       break;                                                                     \
00264                                                                             \
00265     case 0x0e:  /* HW_INT_CLR */                                                 \
00266       state.pcr &= ~((state.r[REG_2] >> 29) & U64(0x3));                         \
00267       state.crr &= ~((state.r[REG_2] >> 31) & U64(0x1));                         \
00268       state.slr &= ~((state.r[REG_2] >> 32) & U64(0x1));                         \
00269       break;                                                                     \
00270                                                                             \
00271     case 0x10:  /* PAL_BASE */                                                   \
00272       set_PAL_BASE(state.r[REG_2] & U64(0x00000fffffff8000));                    \
00273       break;                                                                     \
00274                                                                             \
00275     case 0x11:  /* i_ctl */                                                      \
00276       state.i_ctl_other = state.r[REG_2] & U64(0x00000000007e2f67);              \
00277       state.i_ctl_vptb = sext_u64_48(state.r[REG_2] & U64(0x0000ffffc0000000));  \
00278       state.i_ctl_spe = (int) (state.r[REG_2] >> 3) & 3;                         \
00279       state.sde = (state.r[REG_2] >> 7) & 1;                                     \
00280       state.hwe = (state.r[REG_2] >> 12) & 1;                                    \
00281       state.i_ctl_va_mode = (int) (state.r[REG_2] >> 15) & 3;                    \
00282       break;                                                                     \
00283                                                                             \
00284     case 0x12:  /* ic_flush_asm */                                               \
00285       flush_icache_asm();                                                        \
00286       break;                                                                     \
00287                                                                             \
00288     case 0x13:  /* IC_FLUSH */                                                   \
00289       flush_icache();                                                            \
00290       break;                                                                     \
00291                                                                             \
00292     case 0x14:  /* PCTR_CTL */                                                   \
00293       state.pctr_ctl = state.r[REG_2] & U64(0xffffffffffffffdf);                 \
00294       break;                                                                     \
00295                                                                             \
00296     case 0x15:  /* CLR_MAP */                                                    \
00297     case 0x17:  /* SLEEP   */                                                    \
00298     case 0x27:  /* MM_STAT */                                                    \
00299     case 0x2b:  /* C_DATA  */                                                    \
00300     case 0x2c:  /* C_SHIFT */                                                    \
00301     case 0x2d:  /* M_FIX */                                                      \
00302       break;                                                                     \
00303                                                                             \
00304     case 0x16:  /* I_STAT */                                                     \
00305       state.i_stat &= ~state.r[REG_2];  /* W1C */                                \
00306       break;                                                                     \
00307                                                                             \
00308     case 0x20:  /* DTB_TAG0 */                                                   \
00309       state.last_tb_virt = state.r[REG_2];                                       \
00310       break;                                                                     \
00311                                                                             \
00312     case 0x21:  /* DTB_PTE0 */                                                   \
00313       add_tb_d(state.last_tb_virt, state.r[REG_2]);                              \
00314       break;                                                                     \
00315                                                                             \
00316     case 0x24:  /* DTB_IS0 */                                                    \
00317       tbis(state.r[REG_2], ACCESS_READ);                                         \
00318       break;                                                                     \
00319                                                                             \
00320     case 0x25:  /* DTB_ASN0 */                                                   \
00321       state.asn0 = (int) (state.r[REG_2] >> 56);                                 \
00322       break;                                                                     \
00323                                                                             \
00324     case 0x26:  /* DTB_ALTMODE */                                                \
00325       state.alt_cm = (int) (state.r[REG_2] & 3);                                 \
00326       break;                                                                     \
00327                                                                             \
00328     case 0x28:  /* M_CTL */                                                      \
00329       state.smc = (int) (state.r[REG_2] >> 4) & 3;                               \
00330       state.m_ctl_spe = (int) (state.r[REG_2] >> 1) & 7;                         \
00331       break;                                                                     \
00332                                                                             \
00333     case 0x29:  /* DC_CTL */                                                     \
00334       state.dc_ctl = state.r[REG_2];                                             \
00335       break;                                                                     \
00336                                                                             \
00337     case 0x2a:  /* DC_STAT */                                                    \
00338       state.dc_stat &= ~state.r[REG_2];                                          \
00339       break;                                                                     \
00340                                                                             \
00341     case 0xa0:  /* DTB_TAG1 */                                                   \
00342       state.last_tb_virt = state.r[REG_2];                                       \
00343       break;                                                                     \
00344                                                                             \
00345     case 0xa1:  /* DTB_PTE1 */                                                   \
00346       add_tb_d(state.last_tb_virt, state.r[REG_2]);                              \
00347       break;                                                                     \
00348                                                                             \
00349     case 0xa2:  /* DTB_IAP */                                                    \
00350       tbiap(ACCESS_READ);                                                        \
00351       break;                                                                     \
00352                                                                             \
00353     case 0xa3:  /* DTB_IA */                                                     \
00354       tbia(ACCESS_READ);                                                         \
00355       break;                                                                     \
00356                                                                             \
00357     case 0xa4:  /* DTB_IS1 */                                                    \
00358       tbis(state.r[REG_2], ACCESS_READ);                                         \
00359       break;                                                                     \
00360                                                                             \
00361     case 0xa5:  /* DTB_ASN1 */                                                   \
00362       state.asn1 = (int) (state.r[REG_2] >> 56);                                 \
00363       break;                                                                     \
00364                                                                             \
00365     case 0xc0:  /* CC */                                                         \
00366       state.cc_offset = (u32) (state.r[REG_2] >> 32);                            \
00367       break;                                                                     \
00368                                                                             \
00369     case 0xc1:  /* CC_CTL */                                                     \
00370       state.cc_ena = (state.r[REG_2] >> 32) & 1;                                 \
00371       state.cc = (u32) (state.r[REG_2] & U64(0xfffffff0));                       \
00372       break;                                                                     \
00373                                                                             \
00374     case 0xc4:  /* VA_CTL */                                                     \
00375       state.va_ctl_vptb = sext_u64_48(state.r[REG_2] & U64(0x0000ffffc0000000)); \
00376       state.va_ctl_va_mode = (int) (state.r[REG_2] >> 1) & 3;                    \
00377       break;                                                                     \
00378                                                                             \
00379     default:                                                                     \
00380       UNKNOWN2;                                                                  \
00381     }                                                                            \
00382   }
00383 
00384 #define DO_HW_RET   set_pc(state.r[REG_2])
00385 #define DO_HW_LDL   switch(function)                                          \
00386   {                                                                           \
00387   case 0:       /* longword physical */                                       \
00388     phys_address = state.r[REG_2] + DISP_12;                                  \
00389     state.r[REG_1] = READ_PHYS_NT(32);                                        \
00390     break;                                                                    \
00391                                                                            \
00392   case 2:       /* longword physical locked */                                \
00393     phys_address = state.r[REG_2] + DISP_12;                                  \
00394     cSystem->cpu_lock(state.iProcNum, phys_address);                          \
00395     state.r[REG_1] = READ_PHYS_NT(32);                                        \
00396     break;                                                                    \
00397                                                                            \
00398   case 4:       /* longword virtual vpte                 chk   alt    vpte */ \
00399     DATA_PHYS_NT(state.r[REG_2] + DISP_12, ACCESS_READ | NO_CHECK | VPTE);    \
00400     state.r[REG_1] = READ_PHYS_NT(32);                                        \
00401     break;                                                                    \
00402                                                                            \
00403   case 8:       /* longword virtual */                                        \
00404     DATA_PHYS_NT(state.r[REG_2] + DISP_12, ACCESS_READ | NO_CHECK);           \
00405     state.r[REG_1] = READ_PHYS_NT(32);                                        \
00406     break;                                                                    \
00407                                                                            \
00408   case 10:      /* longword virtual check */                                  \
00409     DATA_PHYS_NT(state.r[REG_2] + DISP_12, ACCESS_READ);                      \
00410     state.r[REG_1] = READ_PHYS_NT(32);                                        \
00411     break;                                                                    \
00412                                                                            \
00413   case 12:      /* longword virtual alt */                                    \
00414     DATA_PHYS_NT(state.r[REG_2] + DISP_12, ACCESS_READ | NO_CHECK | ALT);     \
00415     state.r[REG_1] = READ_PHYS_NT(32);                                        \
00416     break;                                                                    \
00417                                                                            \
00418   case 14:      /* longword virtual alt check */                              \
00419     DATA_PHYS_NT(state.r[REG_2] + DISP_12, ACCESS_READ | ALT);                \
00420     state.r[REG_1] = READ_PHYS_NT(32);                                        \
00421     break;                                                                    \
00422                                                                            \
00423   default:                                                                    \
00424     UNKNOWN2;                                                                 \
00425   }
00426 
00427 #define DO_HW_LDQ   switch(function)                                          \
00428   {                                                                           \
00429   case 1:       /* quadword physical */                                       \
00430     phys_address = state.r[REG_2] + DISP_12;                                  \
00431     state.r[REG_1] = READ_PHYS_NT(64);                                        \
00432     break;                                                                    \
00433                                                                            \
00434   case 3:       /* quadword physical locked */                                \
00435     phys_address = state.r[REG_2] + DISP_12;                                  \
00436     cSystem->cpu_lock(state.iProcNum, phys_address);                          \
00437     state.r[REG_1] = READ_PHYS_NT(64);                                        \
00438     break;                                                                    \
00439                                                                            \
00440   case 5:       /* quadword virtual vpte                 chk   alt    vpte */ \
00441     DATA_PHYS_NT(state.r[REG_2] + DISP_12, ACCESS_READ | NO_CHECK | VPTE);    \
00442     state.r[REG_1] = READ_PHYS_NT(64);                                        \
00443     break;                                                                    \
00444                                                                            \
00445   case 9:       /* quadword virtual */                                        \
00446     DATA_PHYS_NT(state.r[REG_2] + DISP_12, ACCESS_READ | NO_CHECK);           \
00447     state.r[REG_1] = READ_PHYS_NT(64);                                        \
00448     break;                                                                    \
00449                                                                            \
00450   case 11:      /* quadword virtual check */                                  \
00451     DATA_PHYS_NT(state.r[REG_2] + DISP_12, ACCESS_READ);                      \
00452     state.r[REG_1] = READ_PHYS_NT(64);                                        \
00453     break;                                                                    \
00454                                                                            \
00455   case 13:      /* quadword virtual alt */                                    \
00456     DATA_PHYS_NT(state.r[REG_2] + DISP_12, ACCESS_READ | NO_CHECK | ALT);     \
00457     state.r[REG_1] = READ_PHYS_NT(64);                                        \
00458     break;                                                                    \
00459                                                                            \
00460   case 15:      /* quadword virtual alt check */                              \
00461     DATA_PHYS_NT(state.r[REG_2] + DISP_12, ACCESS_READ | ALT);                \
00462     state.r[REG_1] = READ_PHYS_NT(64);                                        \
00463     break;                                                                    \
00464                                                                            \
00465   default:                                                                    \
00466     UNKNOWN2;                                                                 \
00467   }
00468 
00469 #define DO_HW_STL   switch(function)                                          \
00470   {                                                                           \
00471   case 0:       /* longword physical */                                       \
00472     phys_address = state.r[REG_2] + DISP_12;                                  \
00473     WRITE_PHYS_NT(state.r[REG_1], 32);                                        \
00474     break;                                                                    \
00475                                                                            \
00476   case 2:       /* longword physical conditional */                           \
00477     if(cSystem->cpu_unlock(state.iProcNum))                                   \
00478     {                                                                         \
00479       phys_address = state.r[REG_2] + DISP_12;                                \
00480       WRITE_PHYS_NT(state.r[REG_1], 32);                                      \
00481       state.r[REG_1] = 1;                                                     \
00482     }                                                                         \
00483     else                                                                      \
00484       state.r[REG_1] = 0;                                                     \
00485     break;                                                                    \
00486                                                                            \
00487   case 4:       /* longword virtual                      chk   alt    vpte */ \
00488     DATA_PHYS_NT(state.r[REG_2] + DISP_12, ACCESS_READ | NO_CHECK);           \
00489     WRITE_PHYS_NT(state.r[REG_1], 32);                                        \
00490     break;                                                                    \
00491                                                                            \
00492   case 12:      /* longword virtual alt */                                    \
00493     DATA_PHYS_NT(state.r[REG_2] + DISP_12, ACCESS_READ | NO_CHECK | ALT);     \
00494     WRITE_PHYS_NT(state.r[REG_1], 32);                                        \
00495     break;                                                                    \
00496                                                                            \
00497   default:                                                                    \
00498     UNKNOWN2;                                                                 \
00499   }
00500 
00501 #define DO_HW_STQ   switch(function)                                           \
00502   {                                                                            \
00503   case 1:       /* quadword physical */                                        \
00504     phys_address = state.r[REG_2] + DISP_12;                                   \
00505     WRITE_PHYS_NT(state.r[REG_1], 64);                                         \
00506     break;                                                                     \
00507                                                                             \
00508   case 3:       /* quadword physical conditional */                            \
00509     if(cSystem->cpu_unlock(state.iProcNum))                                    \
00510     {                                                                          \
00511       phys_address = state.r[REG_2] + DISP_12;                                 \
00512       WRITE_PHYS_NT(state.r[REG_1], 64);                                       \
00513       state.r[REG_1] = 1;                                                      \
00514     }                                                                          \
00515     else                                                                       \
00516       state.r[REG_1] = 0;                                                      \
00517     break;                                                                     \
00518                                                                             \
00519   case 5:       /* quadword virtual                      chk    alt    vpte */ \
00520     DATA_PHYS_NT(state.r[REG_2] + DISP_12, ACCESS_READ | NO_CHECK);            \
00521     WRITE_PHYS_NT(state.r[REG_1], 64);                                         \
00522     break;                                                                     \
00523                                                                             \
00524   case 13:      /* quadword virtual alt */                                     \
00525     DATA_PHYS_NT(state.r[REG_2] + DISP_12, ACCESS_READ | NO_CHECK | ALT);      \
00526     WRITE_PHYS_NT(state.r[REG_1], 64);                                         \
00527     break;                                                                     \
00528                                                                             \
00529   default:                                                                     \
00530     UNKNOWN2;                                                                  \
00531   }

SourceForge.net Logo
Project space on SourceForge.net