Annotation of qemu/target-i386/helper.c, revision 1.1.1.8

1.1       root        1: /*
1.1.1.7   root        2:  *  i386 helpers (without register variable usage)
1.1.1.6   root        3:  *
1.1       root        4:  *  Copyright (c) 2003 Fabrice Bellard
                      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
1.1.1.7   root       18:  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
1.1       root       19:  */
1.1.1.7   root       20: #include <stdarg.h>
                     21: #include <stdlib.h>
                     22: #include <stdio.h>
                     23: #include <string.h>
                     24: #include <inttypes.h>
                     25: #include <signal.h>
                     26: #include <assert.h>
                     27: 
                     28: #include "cpu.h"
                     29: #include "exec-all.h"
                     30: #include "qemu-common.h"
                     31: #include "kvm.h"
                     32: 
                     33: //#define DEBUG_MMU
                     34: 
                     35: static void add_flagname_to_bitmaps(char *flagname, uint32_t *features, 
                     36:                                     uint32_t *ext_features, 
                     37:                                     uint32_t *ext2_features, 
                     38:                                     uint32_t *ext3_features)
1.1       root       39: {
1.1.1.7   root       40:     int i;
                     41:     /* feature flags taken from "Intel Processor Identification and the CPUID
                     42:      * Instruction" and AMD's "CPUID Specification". In cases of disagreement 
                     43:      * about feature names, the Linux name is used. */
                     44:     static const char *feature_name[] = {
                     45:         "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
                     46:         "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
                     47:         "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */, NULL, "ds" /* Intel dts */, "acpi", "mmx",
                     48:         "fxsr", "sse", "sse2", "ss", "ht" /* Intel htt */, "tm", "ia64", "pbe",
                     49:     };
                     50:     static const char *ext_feature_name[] = {
                     51:        "pni" /* Intel,AMD sse3 */, NULL, NULL, "monitor", "ds_cpl", "vmx", NULL /* Linux smx */, "est",
                     52:        "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL,
                     53:        NULL, NULL, "dca", NULL, NULL, NULL, NULL, "popcnt",
                     54:        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                     55:     };
                     56:     static const char *ext2_feature_name[] = {
                     57:        "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
                     58:        "cx8" /* AMD CMPXCHG8B */, "apic", NULL, "syscall", "mtrr", "pge", "mca", "cmov",
                     59:        "pat", "pse36", NULL, NULL /* Linux mp */, "nx" /* Intel xd */, NULL, "mmxext", "mmx",
                     60:        "fxsr", "fxsr_opt" /* AMD ffxsr */, "pdpe1gb" /* AMD Page1GB */, "rdtscp", NULL, "lm" /* Intel 64 */, "3dnowext", "3dnow",
                     61:     };
                     62:     static const char *ext3_feature_name[] = {
                     63:        "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */, "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
                     64:        "3dnowprefetch", "osvw", NULL /* Linux ibs */, NULL, "skinit", "wdt", NULL, NULL,
                     65:        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                     66:        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                     67:     };
                     68: 
                     69:     for ( i = 0 ; i < 32 ; i++ ) 
                     70:         if (feature_name[i] && !strcmp (flagname, feature_name[i])) {
                     71:             *features |= 1 << i;
1.1       root       72:             return;
                     73:         }
1.1.1.7   root       74:     for ( i = 0 ; i < 32 ; i++ ) 
                     75:         if (ext_feature_name[i] && !strcmp (flagname, ext_feature_name[i])) {
                     76:             *ext_features |= 1 << i;
1.1       root       77:             return;
                     78:         }
1.1.1.7   root       79:     for ( i = 0 ; i < 32 ; i++ ) 
                     80:         if (ext2_feature_name[i] && !strcmp (flagname, ext2_feature_name[i])) {
                     81:             *ext2_features |= 1 << i;
1.1       root       82:             return;
                     83:         }
1.1.1.7   root       84:     for ( i = 0 ; i < 32 ; i++ ) 
                     85:         if (ext3_feature_name[i] && !strcmp (flagname, ext3_feature_name[i])) {
                     86:             *ext3_features |= 1 << i;
1.1       root       87:             return;
                     88:         }
1.1.1.7   root       89:     fprintf(stderr, "CPU feature %s not found\n", flagname);
1.1       root       90: }
                     91: 
1.1.1.7   root       92: typedef struct x86_def_t {
                     93:     const char *name;
                     94:     uint32_t level;
                     95:     uint32_t vendor1, vendor2, vendor3;
                     96:     int family;
                     97:     int model;
                     98:     int stepping;
                     99:     uint32_t features, ext_features, ext2_features, ext3_features;
                    100:     uint32_t xlevel;
                    101:     char model_id[48];
                    102: } x86_def_t;
                    103: 
                    104: #define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
                    105: #define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
                    106:           CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX)
                    107: #define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
                    108:           CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
                    109:           CPUID_PSE36 | CPUID_FXSR)
                    110: #define PENTIUM3_FEATURES (PENTIUM2_FEATURES | CPUID_SSE)
                    111: #define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
                    112:           CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
                    113:           CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
                    114:           CPUID_PAE | CPUID_SEP | CPUID_APIC)
                    115: static x86_def_t x86_defs[] = {
                    116: #ifdef TARGET_X86_64
                    117:     {
                    118:         .name = "qemu64",
                    119:         .level = 2,
                    120:         .vendor1 = CPUID_VENDOR_AMD_1,
                    121:         .vendor2 = CPUID_VENDOR_AMD_2,
                    122:         .vendor3 = CPUID_VENDOR_AMD_3,
                    123:         .family = 6,
                    124:         .model = 2,
                    125:         .stepping = 3,
                    126:         .features = PPRO_FEATURES | 
                    127:         /* these features are needed for Win64 and aren't fully implemented */
                    128:             CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
                    129:         /* this feature is needed for Solaris and isn't fully implemented */
                    130:             CPUID_PSE36,
                    131:         .ext_features = CPUID_EXT_SSE3,
                    132:         .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | 
                    133:             CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
                    134:             CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
                    135:         .ext3_features = CPUID_EXT3_SVM,
                    136:         .xlevel = 0x8000000A,
                    137:         .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
                    138:     },
                    139:     {
                    140:         .name = "phenom",
                    141:         .level = 5,
                    142:         .vendor1 = CPUID_VENDOR_AMD_1,
                    143:         .vendor2 = CPUID_VENDOR_AMD_2,
                    144:         .vendor3 = CPUID_VENDOR_AMD_3,
                    145:         .family = 16,
                    146:         .model = 2,
                    147:         .stepping = 3,
                    148:         /* Missing: CPUID_VME, CPUID_HT */
                    149:         .features = PPRO_FEATURES | 
                    150:             CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
                    151:             CPUID_PSE36,
                    152:         /* Missing: CPUID_EXT_CX16, CPUID_EXT_POPCNT */
                    153:         .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR,
                    154:         /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
                    155:         .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | 
                    156:             CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
                    157:             CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
                    158:             CPUID_EXT2_FFXSR,
                    159:         /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
                    160:                     CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
                    161:                     CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
                    162:                     CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
                    163:         .ext3_features = CPUID_EXT3_SVM,
                    164:         .xlevel = 0x8000001A,
                    165:         .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
                    166:     },
                    167:     {
                    168:         .name = "core2duo",
                    169:         .level = 10,
                    170:         .family = 6,
                    171:         .model = 15,
                    172:         .stepping = 11,
                    173:        /* The original CPU also implements these features:
                    174:                CPUID_VME, CPUID_DTS, CPUID_ACPI, CPUID_SS, CPUID_HT,
                    175:                CPUID_TM, CPUID_PBE */
                    176:         .features = PPRO_FEATURES |
                    177:             CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
                    178:             CPUID_PSE36,
                    179:        /* The original CPU also implements these ext features:
                    180:                CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_EST,
                    181:                CPUID_EXT_TM2, CPUID_EXT_CX16, CPUID_EXT_XTPR, CPUID_EXT_PDCM */
                    182:         .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3,
                    183:         .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
                    184:         /* Missing: .ext3_features = CPUID_EXT3_LAHF_LM */
                    185:         .xlevel = 0x80000008,
                    186:         .model_id = "Intel(R) Core(TM)2 Duo CPU     T7700  @ 2.40GHz",
                    187:     },
1.1       root      188: #endif
1.1.1.7   root      189:     {
                    190:         .name = "qemu32",
                    191:         .level = 2,
                    192:         .family = 6,
                    193:         .model = 3,
                    194:         .stepping = 3,
                    195:         .features = PPRO_FEATURES,
                    196:         .ext_features = CPUID_EXT_SSE3,
                    197:         .xlevel = 0,
                    198:         .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
                    199:     },
                    200:     {
                    201:         .name = "coreduo",
                    202:         .level = 10,
                    203:         .family = 6,
                    204:         .model = 14,
                    205:         .stepping = 8,
                    206:         /* The original CPU also implements these features:
                    207:                CPUID_DTS, CPUID_ACPI, CPUID_SS, CPUID_HT,
                    208:                CPUID_TM, CPUID_PBE */
                    209:         .features = PPRO_FEATURES | CPUID_VME |
                    210:             CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA,
                    211:         /* The original CPU also implements these ext features:
                    212:                CPUID_EXT_VMX, CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_XTPR,
                    213:                CPUID_EXT_PDCM */
                    214:         .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR,
                    215:         .ext2_features = CPUID_EXT2_NX,
                    216:         .xlevel = 0x80000008,
                    217:         .model_id = "Genuine Intel(R) CPU           T2600  @ 2.16GHz",
                    218:     },
                    219:     {
                    220:         .name = "486",
                    221:         .level = 0,
                    222:         .family = 4,
                    223:         .model = 0,
                    224:         .stepping = 0,
                    225:         .features = I486_FEATURES,
                    226:         .xlevel = 0,
                    227:     },
                    228:     {
                    229:         .name = "pentium",
                    230:         .level = 1,
                    231:         .family = 5,
                    232:         .model = 4,
                    233:         .stepping = 3,
                    234:         .features = PENTIUM_FEATURES,
                    235:         .xlevel = 0,
                    236:     },
                    237:     {
                    238:         .name = "pentium2",
                    239:         .level = 2,
                    240:         .family = 6,
                    241:         .model = 5,
                    242:         .stepping = 2,
                    243:         .features = PENTIUM2_FEATURES,
                    244:         .xlevel = 0,
                    245:     },
                    246:     {
                    247:         .name = "pentium3",
                    248:         .level = 2,
                    249:         .family = 6,
                    250:         .model = 7,
                    251:         .stepping = 3,
                    252:         .features = PENTIUM3_FEATURES,
                    253:         .xlevel = 0,
                    254:     },
                    255:     {
                    256:         .name = "athlon",
                    257:         .level = 2,
                    258:         .vendor1 = 0x68747541, /* "Auth" */
                    259:         .vendor2 = 0x69746e65, /* "enti" */
                    260:         .vendor3 = 0x444d4163, /* "cAMD" */
                    261:         .family = 6,
                    262:         .model = 2,
                    263:         .stepping = 3,
                    264:         .features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR | CPUID_MCA,
                    265:         .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
                    266:         .xlevel = 0x80000008,
                    267:         /* XXX: put another string ? */
                    268:         .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
                    269:     },
                    270:     {
                    271:         .name = "n270",
                    272:         /* original is on level 10 */
                    273:         .level = 5,
                    274:         .family = 6,
                    275:         .model = 28,
                    276:         .stepping = 2,
                    277:         .features = PPRO_FEATURES |
                    278:             CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME,
                    279:             /* Missing: CPUID_DTS | CPUID_ACPI | CPUID_SS |
                    280:              * CPUID_HT | CPUID_TM | CPUID_PBE */
                    281:             /* Some CPUs got no CPUID_SEP */
                    282:         .ext_features = CPUID_EXT_MONITOR |
                    283:             CPUID_EXT_SSE3 /* PNI */ | CPUID_EXT_SSSE3,
                    284:             /* Missing: CPUID_EXT_DSCPL | CPUID_EXT_EST |
                    285:              * CPUID_EXT_TM2 | CPUID_EXT_XTPR */
                    286:         .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_NX,
                    287:         /* Missing: .ext3_features = CPUID_EXT3_LAHF_LM */
                    288:         .xlevel = 0x8000000A,
                    289:         .model_id = "Intel(R) Atom(TM) CPU N270   @ 1.60GHz",
                    290:     },
                    291: };
1.1       root      292: 
1.1.1.7   root      293: static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
1.1       root      294: {
1.1.1.7   root      295:     unsigned int i;
                    296:     x86_def_t *def;
1.1       root      297: 
1.1.1.7   root      298:     char *s = strdup(cpu_model);
                    299:     char *featurestr, *name = strtok(s, ",");
                    300:     uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0;
                    301:     uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0;
                    302:     int family = -1, model = -1, stepping = -1;
                    303: 
                    304:     def = NULL;
                    305:     for (i = 0; i < ARRAY_SIZE(x86_defs); i++) {
                    306:         if (strcmp(name, x86_defs[i].name) == 0) {
                    307:             def = &x86_defs[i];
1.1       root      308:             break;
1.1.1.7   root      309:         }
1.1.1.6   root      310:     }
1.1.1.7   root      311:     if (!def)
                    312:         goto error;
                    313:     memcpy(x86_cpu_def, def, sizeof(*def));
                    314: 
                    315:     featurestr = strtok(NULL, ",");
                    316: 
                    317:     while (featurestr) {
                    318:         char *val;
                    319:         if (featurestr[0] == '+') {
                    320:             add_flagname_to_bitmaps(featurestr + 1, &plus_features, &plus_ext_features, &plus_ext2_features, &plus_ext3_features);
                    321:         } else if (featurestr[0] == '-') {
                    322:             add_flagname_to_bitmaps(featurestr + 1, &minus_features, &minus_ext_features, &minus_ext2_features, &minus_ext3_features);
                    323:         } else if ((val = strchr(featurestr, '='))) {
                    324:             *val = 0; val++;
                    325:             if (!strcmp(featurestr, "family")) {
                    326:                 char *err;
                    327:                 family = strtol(val, &err, 10);
                    328:                 if (!*val || *err || family < 0) {
                    329:                     fprintf(stderr, "bad numerical value %s\n", val);
                    330:                     goto error;
                    331:                 }
                    332:                 x86_cpu_def->family = family;
                    333:             } else if (!strcmp(featurestr, "model")) {
                    334:                 char *err;
                    335:                 model = strtol(val, &err, 10);
                    336:                 if (!*val || *err || model < 0 || model > 0xff) {
                    337:                     fprintf(stderr, "bad numerical value %s\n", val);
                    338:                     goto error;
                    339:                 }
                    340:                 x86_cpu_def->model = model;
                    341:             } else if (!strcmp(featurestr, "stepping")) {
                    342:                 char *err;
                    343:                 stepping = strtol(val, &err, 10);
                    344:                 if (!*val || *err || stepping < 0 || stepping > 0xf) {
                    345:                     fprintf(stderr, "bad numerical value %s\n", val);
                    346:                     goto error;
                    347:                 }
                    348:                 x86_cpu_def->stepping = stepping;
                    349:             } else if (!strcmp(featurestr, "vendor")) {
                    350:                 if (strlen(val) != 12) {
                    351:                     fprintf(stderr, "vendor string must be 12 chars long\n");
                    352:                     goto error;
                    353:                 }
                    354:                 x86_cpu_def->vendor1 = 0;
                    355:                 x86_cpu_def->vendor2 = 0;
                    356:                 x86_cpu_def->vendor3 = 0;
                    357:                 for(i = 0; i < 4; i++) {
                    358:                     x86_cpu_def->vendor1 |= ((uint8_t)val[i    ]) << (8 * i);
                    359:                     x86_cpu_def->vendor2 |= ((uint8_t)val[i + 4]) << (8 * i);
                    360:                     x86_cpu_def->vendor3 |= ((uint8_t)val[i + 8]) << (8 * i);
                    361:                 }
                    362:             } else if (!strcmp(featurestr, "model_id")) {
                    363:                 pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id),
                    364:                         val);
                    365:             } else {
                    366:                 fprintf(stderr, "unrecognized feature %s\n", featurestr);
                    367:                 goto error;
                    368:             }
                    369:         } else {
                    370:             fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);
                    371:             goto error;
                    372:         }
                    373:         featurestr = strtok(NULL, ",");
1.1       root      374:     }
1.1.1.7   root      375:     x86_cpu_def->features |= plus_features;
                    376:     x86_cpu_def->ext_features |= plus_ext_features;
                    377:     x86_cpu_def->ext2_features |= plus_ext2_features;
                    378:     x86_cpu_def->ext3_features |= plus_ext3_features;
                    379:     x86_cpu_def->features &= ~minus_features;
                    380:     x86_cpu_def->ext_features &= ~minus_ext_features;
                    381:     x86_cpu_def->ext2_features &= ~minus_ext2_features;
                    382:     x86_cpu_def->ext3_features &= ~minus_ext3_features;
                    383:     free(s);
                    384:     return 0;
1.1       root      385: 
1.1.1.7   root      386: error:
                    387:     free(s);
                    388:     return -1;
1.1       root      389: }
                    390: 
1.1.1.7   root      391: void x86_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
1.1       root      392: {
1.1.1.7   root      393:     unsigned int i;
1.1       root      394: 
1.1.1.7   root      395:     for (i = 0; i < ARRAY_SIZE(x86_defs); i++)
                    396:         (*cpu_fprintf)(f, "x86 %16s\n", x86_defs[i].name);
1.1       root      397: }
                    398: 
1.1.1.7   root      399: static int cpu_x86_register (CPUX86State *env, const char *cpu_model)
1.1       root      400: {
1.1.1.7   root      401:     x86_def_t def1, *def = &def1;
1.1       root      402: 
1.1.1.7   root      403:     if (cpu_x86_find_by_name(def, cpu_model) < 0)
                    404:         return -1;
                    405:     if (def->vendor1) {
                    406:         env->cpuid_vendor1 = def->vendor1;
                    407:         env->cpuid_vendor2 = def->vendor2;
                    408:         env->cpuid_vendor3 = def->vendor3;
                    409:     } else {
                    410:         env->cpuid_vendor1 = CPUID_VENDOR_INTEL_1;
                    411:         env->cpuid_vendor2 = CPUID_VENDOR_INTEL_2;
                    412:         env->cpuid_vendor3 = CPUID_VENDOR_INTEL_3;
                    413:     }
                    414:     env->cpuid_level = def->level;
                    415:     if (def->family > 0x0f)
                    416:         env->cpuid_version = 0xf00 | ((def->family - 0x0f) << 20);
                    417:     else
                    418:         env->cpuid_version = def->family << 8;
                    419:     env->cpuid_version |= ((def->model & 0xf) << 4) | ((def->model >> 4) << 16);
                    420:     env->cpuid_version |= def->stepping;
                    421:     env->cpuid_features = def->features;
                    422:     env->pat = 0x0007040600070406ULL;
                    423:     env->cpuid_ext_features = def->ext_features;
                    424:     env->cpuid_ext2_features = def->ext2_features;
                    425:     env->cpuid_xlevel = def->xlevel;
                    426:     env->cpuid_ext3_features = def->ext3_features;
                    427:     {
                    428:         const char *model_id = def->model_id;
                    429:         int c, len, i;
                    430:         if (!model_id)
                    431:             model_id = "";
                    432:         len = strlen(model_id);
                    433:         for(i = 0; i < 48; i++) {
                    434:             if (i >= len)
                    435:                 c = '\0';
                    436:             else
                    437:                 c = (uint8_t)model_id[i];
                    438:             env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
                    439:         }
1.1       root      440:     }
1.1.1.7   root      441:     return 0;
1.1       root      442: }
                    443: 
1.1.1.7   root      444: /* NOTE: must be called outside the CPU execute loop */
                    445: void cpu_reset(CPUX86State *env)
1.1       root      446: {
1.1.1.7   root      447:     int i;
1.1       root      448: 
1.1.1.7   root      449:     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
                    450:         qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
                    451:         log_cpu_state(env, X86_DUMP_FPU | X86_DUMP_CCOP);
1.1       root      452:     }
                    453: 
1.1.1.7   root      454:     memset(env, 0, offsetof(CPUX86State, breakpoints));
1.1       root      455: 
1.1.1.7   root      456:     tlb_flush(env, 1);
1.1       root      457: 
1.1.1.7   root      458:     env->old_exception = -1;
1.1       root      459: 
1.1.1.7   root      460:     /* init to reset state */
1.1       root      461: 
1.1.1.7   root      462: #ifdef CONFIG_SOFTMMU
                    463:     env->hflags |= HF_SOFTMMU_MASK;
1.1       root      464: #endif
1.1.1.7   root      465:     env->hflags2 |= HF2_GIF_MASK;
1.1       root      466: 
1.1.1.7   root      467:     cpu_x86_update_cr0(env, 0x60000010);
                    468:     env->a20_mask = ~0x0;
                    469:     env->smbase = 0x30000;
                    470: 
                    471:     env->idt.limit = 0xffff;
                    472:     env->gdt.limit = 0xffff;
                    473:     env->ldt.limit = 0xffff;
                    474:     env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
                    475:     env->tr.limit = 0xffff;
                    476:     env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
                    477: 
                    478:     cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
                    479:                            DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK | DESC_R_MASK);
                    480:     cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
                    481:                            DESC_P_MASK | DESC_S_MASK | DESC_W_MASK);
                    482:     cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
                    483:                            DESC_P_MASK | DESC_S_MASK | DESC_W_MASK);
                    484:     cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
                    485:                            DESC_P_MASK | DESC_S_MASK | DESC_W_MASK);
                    486:     cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
                    487:                            DESC_P_MASK | DESC_S_MASK | DESC_W_MASK);
                    488:     cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
                    489:                            DESC_P_MASK | DESC_S_MASK | DESC_W_MASK);
                    490: 
                    491:     env->eip = 0xfff0;
                    492:     env->regs[R_EDX] = env->cpuid_version;
                    493: 
                    494:     env->eflags = 0x2;
                    495: 
                    496:     /* FPU init */
                    497:     for(i = 0;i < 8; i++)
                    498:         env->fptags[i] = 1;
1.1       root      499:     env->fpuc = 0x37f;
                    500: 
1.1.1.7   root      501:     env->mxcsr = 0x1f80;
1.1       root      502: 
1.1.1.7   root      503:     memset(env->dr, 0, sizeof(env->dr));
                    504:     env->dr[6] = DR6_FIXED_1;
                    505:     env->dr[7] = DR7_FIXED_1;
                    506:     cpu_breakpoint_remove_all(env, BP_CPU);
                    507:     cpu_watchpoint_remove_all(env, BP_CPU);
                    508: }
                    509: 
                    510: void cpu_x86_close(CPUX86State *env)
                    511: {
                    512:     qemu_free(env);
                    513: }
                    514: 
                    515: /***********************************************************/
                    516: /* x86 debug */
                    517: 
                    518: static const char *cc_op_str[] = {
                    519:     "DYNAMIC",
                    520:     "EFLAGS",
                    521: 
                    522:     "MULB",
                    523:     "MULW",
                    524:     "MULL",
                    525:     "MULQ",
                    526: 
                    527:     "ADDB",
                    528:     "ADDW",
                    529:     "ADDL",
                    530:     "ADDQ",
                    531: 
                    532:     "ADCB",
                    533:     "ADCW",
                    534:     "ADCL",
                    535:     "ADCQ",
                    536: 
                    537:     "SUBB",
                    538:     "SUBW",
                    539:     "SUBL",
                    540:     "SUBQ",
                    541: 
                    542:     "SBBB",
                    543:     "SBBW",
                    544:     "SBBL",
                    545:     "SBBQ",
                    546: 
                    547:     "LOGICB",
                    548:     "LOGICW",
                    549:     "LOGICL",
                    550:     "LOGICQ",
                    551: 
                    552:     "INCB",
                    553:     "INCW",
                    554:     "INCL",
                    555:     "INCQ",
                    556: 
                    557:     "DECB",
                    558:     "DECW",
                    559:     "DECL",
                    560:     "DECQ",
                    561: 
                    562:     "SHLB",
                    563:     "SHLW",
                    564:     "SHLL",
                    565:     "SHLQ",
                    566: 
                    567:     "SARB",
                    568:     "SARW",
                    569:     "SARL",
                    570:     "SARQ",
                    571: };
1.1       root      572: 
1.1.1.7   root      573: void cpu_dump_state(CPUState *env, FILE *f,
                    574:                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
                    575:                     int flags)
                    576: {
                    577:     int eflags, i, nb;
                    578:     char cc_op_name[32];
                    579:     static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
                    580: 
                    581:     if (kvm_enabled())
                    582:         kvm_arch_get_registers(env);
                    583: 
                    584:     eflags = env->eflags;
                    585: #ifdef TARGET_X86_64
                    586:     if (env->hflags & HF_CS64_MASK) {
                    587:         cpu_fprintf(f,
                    588:                     "RAX=%016" PRIx64 " RBX=%016" PRIx64 " RCX=%016" PRIx64 " RDX=%016" PRIx64 "\n"
                    589:                     "RSI=%016" PRIx64 " RDI=%016" PRIx64 " RBP=%016" PRIx64 " RSP=%016" PRIx64 "\n"
                    590:                     "R8 =%016" PRIx64 " R9 =%016" PRIx64 " R10=%016" PRIx64 " R11=%016" PRIx64 "\n"
                    591:                     "R12=%016" PRIx64 " R13=%016" PRIx64 " R14=%016" PRIx64 " R15=%016" PRIx64 "\n"
                    592:                     "RIP=%016" PRIx64 " RFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
                    593:                     env->regs[R_EAX],
                    594:                     env->regs[R_EBX],
                    595:                     env->regs[R_ECX],
                    596:                     env->regs[R_EDX],
                    597:                     env->regs[R_ESI],
                    598:                     env->regs[R_EDI],
                    599:                     env->regs[R_EBP],
                    600:                     env->regs[R_ESP],
                    601:                     env->regs[8],
                    602:                     env->regs[9],
                    603:                     env->regs[10],
                    604:                     env->regs[11],
                    605:                     env->regs[12],
                    606:                     env->regs[13],
                    607:                     env->regs[14],
                    608:                     env->regs[15],
                    609:                     env->eip, eflags,
                    610:                     eflags & DF_MASK ? 'D' : '-',
                    611:                     eflags & CC_O ? 'O' : '-',
                    612:                     eflags & CC_S ? 'S' : '-',
                    613:                     eflags & CC_Z ? 'Z' : '-',
                    614:                     eflags & CC_A ? 'A' : '-',
                    615:                     eflags & CC_P ? 'P' : '-',
                    616:                     eflags & CC_C ? 'C' : '-',
                    617:                     env->hflags & HF_CPL_MASK,
                    618:                     (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
                    619:                     (int)(env->a20_mask >> 20) & 1,
                    620:                     (env->hflags >> HF_SMM_SHIFT) & 1,
                    621:                     env->halted);
                    622:     } else
                    623: #endif
                    624:     {
                    625:         cpu_fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
                    626:                     "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
                    627:                     "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
                    628:                     (uint32_t)env->regs[R_EAX],
                    629:                     (uint32_t)env->regs[R_EBX],
                    630:                     (uint32_t)env->regs[R_ECX],
                    631:                     (uint32_t)env->regs[R_EDX],
                    632:                     (uint32_t)env->regs[R_ESI],
                    633:                     (uint32_t)env->regs[R_EDI],
                    634:                     (uint32_t)env->regs[R_EBP],
                    635:                     (uint32_t)env->regs[R_ESP],
                    636:                     (uint32_t)env->eip, eflags,
                    637:                     eflags & DF_MASK ? 'D' : '-',
                    638:                     eflags & CC_O ? 'O' : '-',
                    639:                     eflags & CC_S ? 'S' : '-',
                    640:                     eflags & CC_Z ? 'Z' : '-',
                    641:                     eflags & CC_A ? 'A' : '-',
                    642:                     eflags & CC_P ? 'P' : '-',
                    643:                     eflags & CC_C ? 'C' : '-',
                    644:                     env->hflags & HF_CPL_MASK,
                    645:                     (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
                    646:                     (int)(env->a20_mask >> 20) & 1,
                    647:                     (env->hflags >> HF_SMM_SHIFT) & 1,
                    648:                     env->halted);
1.1       root      649:     }
                    650: 
1.1.1.7   root      651: #ifdef TARGET_X86_64
                    652:     if (env->hflags & HF_LMA_MASK) {
                    653:         for(i = 0; i < 6; i++) {
                    654:             SegmentCache *sc = &env->segs[i];
                    655:             cpu_fprintf(f, "%s =%04x %016" PRIx64 " %08x %08x\n",
                    656:                         seg_name[i],
                    657:                         sc->selector,
                    658:                         sc->base,
                    659:                         sc->limit,
                    660:                         sc->flags);
                    661:         }
                    662:         cpu_fprintf(f, "LDT=%04x %016" PRIx64 " %08x %08x\n",
                    663:                     env->ldt.selector,
                    664:                     env->ldt.base,
                    665:                     env->ldt.limit,
                    666:                     env->ldt.flags);
                    667:         cpu_fprintf(f, "TR =%04x %016" PRIx64 " %08x %08x\n",
                    668:                     env->tr.selector,
                    669:                     env->tr.base,
                    670:                     env->tr.limit,
                    671:                     env->tr.flags);
                    672:         cpu_fprintf(f, "GDT=     %016" PRIx64 " %08x\n",
                    673:                     env->gdt.base, env->gdt.limit);
                    674:         cpu_fprintf(f, "IDT=     %016" PRIx64 " %08x\n",
                    675:                     env->idt.base, env->idt.limit);
                    676:         cpu_fprintf(f, "CR0=%08x CR2=%016" PRIx64 " CR3=%016" PRIx64 " CR4=%08x\n",
                    677:                     (uint32_t)env->cr[0],
                    678:                     env->cr[2],
                    679:                     env->cr[3],
                    680:                     (uint32_t)env->cr[4]);
                    681:         for(i = 0; i < 4; i++)
                    682:             cpu_fprintf(f, "DR%d=%016" PRIx64 " ", i, env->dr[i]);
                    683:         cpu_fprintf(f, "\nDR6=%016" PRIx64 " DR7=%016" PRIx64 "\n",
                    684:                     env->dr[6], env->dr[7]);
                    685:     } else
                    686: #endif
                    687:     {
                    688:         for(i = 0; i < 6; i++) {
                    689:             SegmentCache *sc = &env->segs[i];
                    690:             cpu_fprintf(f, "%s =%04x %08x %08x %08x\n",
                    691:                         seg_name[i],
                    692:                         sc->selector,
                    693:                         (uint32_t)sc->base,
                    694:                         sc->limit,
                    695:                         sc->flags);
                    696:         }
                    697:         cpu_fprintf(f, "LDT=%04x %08x %08x %08x\n",
                    698:                     env->ldt.selector,
                    699:                     (uint32_t)env->ldt.base,
                    700:                     env->ldt.limit,
                    701:                     env->ldt.flags);
                    702:         cpu_fprintf(f, "TR =%04x %08x %08x %08x\n",
                    703:                     env->tr.selector,
                    704:                     (uint32_t)env->tr.base,
                    705:                     env->tr.limit,
                    706:                     env->tr.flags);
                    707:         cpu_fprintf(f, "GDT=     %08x %08x\n",
                    708:                     (uint32_t)env->gdt.base, env->gdt.limit);
                    709:         cpu_fprintf(f, "IDT=     %08x %08x\n",
                    710:                     (uint32_t)env->idt.base, env->idt.limit);
                    711:         cpu_fprintf(f, "CR0=%08x CR2=%08x CR3=%08x CR4=%08x\n",
                    712:                     (uint32_t)env->cr[0],
                    713:                     (uint32_t)env->cr[2],
                    714:                     (uint32_t)env->cr[3],
                    715:                     (uint32_t)env->cr[4]);
                    716:         for(i = 0; i < 4; i++)
                    717:             cpu_fprintf(f, "DR%d=%08x ", i, env->dr[i]);
                    718:         cpu_fprintf(f, "\nDR6=%08x DR7=%08x\n", env->dr[6], env->dr[7]);
1.1       root      719:     }
1.1.1.7   root      720:     if (flags & X86_DUMP_CCOP) {
                    721:         if ((unsigned)env->cc_op < CC_OP_NB)
                    722:             snprintf(cc_op_name, sizeof(cc_op_name), "%s", cc_op_str[env->cc_op]);
                    723:         else
                    724:             snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);
                    725: #ifdef TARGET_X86_64
                    726:         if (env->hflags & HF_CS64_MASK) {
                    727:             cpu_fprintf(f, "CCS=%016" PRIx64 " CCD=%016" PRIx64 " CCO=%-8s\n",
                    728:                         env->cc_src, env->cc_dst,
                    729:                         cc_op_name);
                    730:         } else
1.1       root      731: #endif
1.1.1.7   root      732:         {
                    733:             cpu_fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n",
                    734:                         (uint32_t)env->cc_src, (uint32_t)env->cc_dst,
                    735:                         cc_op_name);
                    736:         }
                    737:     }
                    738:     if (flags & X86_DUMP_FPU) {
                    739:         int fptag;
                    740:         fptag = 0;
                    741:         for(i = 0; i < 8; i++) {
                    742:             fptag |= ((!env->fptags[i]) << i);
                    743:         }
                    744:         cpu_fprintf(f, "FCW=%04x FSW=%04x [ST=%d] FTW=%02x MXCSR=%08x\n",
                    745:                     env->fpuc,
                    746:                     (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11,
                    747:                     env->fpstt,
                    748:                     fptag,
                    749:                     env->mxcsr);
                    750:         for(i=0;i<8;i++) {
                    751: #if defined(USE_X86LDOUBLE)
                    752:             union {
                    753:                 long double d;
                    754:                 struct {
                    755:                     uint64_t lower;
                    756:                     uint16_t upper;
                    757:                 } l;
                    758:             } tmp;
                    759:             tmp.d = env->fpregs[i].d;
                    760:             cpu_fprintf(f, "FPR%d=%016" PRIx64 " %04x",
                    761:                         i, tmp.l.lower, tmp.l.upper);
1.1       root      762: #else
1.1.1.7   root      763:             cpu_fprintf(f, "FPR%d=%016" PRIx64,
                    764:                         i, env->fpregs[i].mmx.q);
1.1       root      765: #endif
1.1.1.7   root      766:             if ((i & 1) == 1)
                    767:                 cpu_fprintf(f, "\n");
                    768:             else
                    769:                 cpu_fprintf(f, " ");
                    770:         }
                    771:         if (env->hflags & HF_CS64_MASK)
                    772:             nb = 16;
                    773:         else
                    774:             nb = 8;
                    775:         for(i=0;i<nb;i++) {
                    776:             cpu_fprintf(f, "XMM%02d=%08x%08x%08x%08x",
                    777:                         i,
                    778:                         env->xmm_regs[i].XMM_L(3),
                    779:                         env->xmm_regs[i].XMM_L(2),
                    780:                         env->xmm_regs[i].XMM_L(1),
                    781:                         env->xmm_regs[i].XMM_L(0));
                    782:             if ((i & 1) == 1)
                    783:                 cpu_fprintf(f, "\n");
                    784:             else
                    785:                 cpu_fprintf(f, " ");
1.1       root      786:         }
                    787:     }
                    788: }
                    789: 
1.1.1.7   root      790: /***********************************************************/
                    791: /* x86 mmu */
                    792: /* XXX: add PGE support */
1.1       root      793: 
1.1.1.7   root      794: void cpu_x86_set_a20(CPUX86State *env, int a20_state)
1.1       root      795: {
1.1.1.7   root      796:     a20_state = (a20_state != 0);
                    797:     if (a20_state != ((env->a20_mask >> 20) & 1)) {
                    798: #if defined(DEBUG_MMU)
                    799:         printf("A20 update: a20=%d\n", a20_state);
                    800: #endif
                    801:         /* if the cpu is currently executing code, we must unlink it and
                    802:            all the potentially executing TB */
                    803:         cpu_interrupt(env, CPU_INTERRUPT_EXITTB);
1.1       root      804: 
1.1.1.7   root      805:         /* when a20 is changed, all the MMU mappings are invalid, so
                    806:            we must flush everything */
                    807:         tlb_flush(env, 1);
                    808:         env->a20_mask = (~0x100000) | (a20_state << 20);
                    809:     }
1.1       root      810: }
                    811: 
1.1.1.7   root      812: void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
1.1       root      813: {
1.1.1.7   root      814:     int pe_state;
1.1       root      815: 
1.1.1.7   root      816: #if defined(DEBUG_MMU)
                    817:     printf("CR0 update: CR0=0x%08x\n", new_cr0);
                    818: #endif
                    819:     if ((new_cr0 & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK)) !=
                    820:         (env->cr[0] & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK))) {
                    821:         tlb_flush(env, 1);
1.1       root      822:     }
                    823: 
1.1.1.7   root      824: #ifdef TARGET_X86_64
                    825:     if (!(env->cr[0] & CR0_PG_MASK) && (new_cr0 & CR0_PG_MASK) &&
                    826:         (env->efer & MSR_EFER_LME)) {
                    827:         /* enter in long mode */
                    828:         /* XXX: generate an exception */
                    829:         if (!(env->cr[4] & CR4_PAE_MASK))
                    830:             return;
                    831:         env->efer |= MSR_EFER_LMA;
                    832:         env->hflags |= HF_LMA_MASK;
                    833:     } else if ((env->cr[0] & CR0_PG_MASK) && !(new_cr0 & CR0_PG_MASK) &&
                    834:                (env->efer & MSR_EFER_LMA)) {
                    835:         /* exit long mode */
                    836:         env->efer &= ~MSR_EFER_LMA;
                    837:         env->hflags &= ~(HF_LMA_MASK | HF_CS64_MASK);
                    838:         env->eip &= 0xffffffff;
1.1       root      839:     }
                    840: #endif
1.1.1.7   root      841:     env->cr[0] = new_cr0 | CR0_ET_MASK;
1.1       root      842: 
1.1.1.7   root      843:     /* update PE flag in hidden flags */
                    844:     pe_state = (env->cr[0] & CR0_PE_MASK);
                    845:     env->hflags = (env->hflags & ~HF_PE_MASK) | (pe_state << HF_PE_SHIFT);
                    846:     /* ensure that ADDSEG is always set in real mode */
                    847:     env->hflags |= ((pe_state ^ 1) << HF_ADDSEG_SHIFT);
                    848:     /* update FPU flags */
                    849:     env->hflags = (env->hflags & ~(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)) |
                    850:         ((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK));
1.1.1.4   root      851: }
                    852: 
1.1.1.7   root      853: /* XXX: in legacy PAE mode, generate a GPF if reserved bits are set in
                    854:    the PDPT */
                    855: void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3)
1.1.1.4   root      856: {
1.1.1.7   root      857:     env->cr[3] = new_cr3;
                    858:     if (env->cr[0] & CR0_PG_MASK) {
                    859: #if defined(DEBUG_MMU)
                    860:         printf("CR3 update: CR3=" TARGET_FMT_lx "\n", new_cr3);
                    861: #endif
                    862:         tlb_flush(env, 0);
                    863:     }
1.1.1.4   root      864: }
                    865: 
1.1.1.7   root      866: void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
1.1.1.4   root      867: {
1.1.1.7   root      868: #if defined(DEBUG_MMU)
                    869:     printf("CR4 update: CR4=%08x\n", (uint32_t)env->cr[4]);
                    870: #endif
                    871:     if ((new_cr4 & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK)) !=
                    872:         (env->cr[4] & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK))) {
                    873:         tlb_flush(env, 1);
1.1.1.4   root      874:     }
1.1.1.7   root      875:     /* SSE handling */
                    876:     if (!(env->cpuid_features & CPUID_SSE))
                    877:         new_cr4 &= ~CR4_OSFXSR_MASK;
                    878:     if (new_cr4 & CR4_OSFXSR_MASK)
                    879:         env->hflags |= HF_OSFXSR_MASK;
                    880:     else
                    881:         env->hflags &= ~HF_OSFXSR_MASK;
1.1.1.4   root      882: 
1.1.1.7   root      883:     env->cr[4] = new_cr4;
1.1       root      884: }
                    885: 
1.1.1.7   root      886: #if defined(CONFIG_USER_ONLY)
                    887: 
                    888: int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
                    889:                              int is_write, int mmu_idx, int is_softmmu)
1.1       root      890: {
1.1.1.7   root      891:     /* user mode only emulation */
                    892:     is_write &= 1;
                    893:     env->cr[2] = addr;
                    894:     env->error_code = (is_write << PG_ERROR_W_BIT);
                    895:     env->error_code |= PG_ERROR_U_MASK;
                    896:     env->exception_index = EXCP0E_PAGE;
                    897:     return 1;
1.1       root      898: }
                    899: 
1.1.1.7   root      900: target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
1.1       root      901: {
1.1.1.7   root      902:     return addr;
1.1       root      903: }
                    904: 
1.1.1.6   root      905: #else
1.1       root      906: 
1.1.1.7   root      907: /* XXX: This value should match the one returned by CPUID
                    908:  * and in exec.c */
                    909: #if defined(USE_KQEMU)
                    910: #define PHYS_ADDR_MASK 0xfffff000LL
                    911: #else
                    912: # if defined(TARGET_X86_64)
                    913: # define PHYS_ADDR_MASK 0xfffffff000LL
                    914: # else
                    915: # define PHYS_ADDR_MASK 0xffffff000LL
                    916: # endif
                    917: #endif
                    918: 
                    919: /* return value:
                    920:    -1 = cannot handle fault
                    921:    0  = nothing more to do
                    922:    1  = generate PF fault
                    923:    2  = soft MMU activation required for this block
                    924: */
                    925: int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
                    926:                              int is_write1, int mmu_idx, int is_softmmu)
                    927: {
                    928:     uint64_t ptep, pte;
                    929:     target_ulong pde_addr, pte_addr;
                    930:     int error_code, is_dirty, prot, page_size, ret, is_write, is_user;
                    931:     target_phys_addr_t paddr;
                    932:     uint32_t page_offset;
                    933:     target_ulong vaddr, virt_addr;
                    934: 
                    935:     is_user = mmu_idx == MMU_USER_IDX;
                    936: #if defined(DEBUG_MMU)
                    937:     printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
                    938:            addr, is_write1, is_user, env->eip);
                    939: #endif
                    940:     is_write = is_write1 & 1;
                    941: 
                    942:     if (!(env->cr[0] & CR0_PG_MASK)) {
                    943:         pte = addr;
                    944:         virt_addr = addr & TARGET_PAGE_MASK;
                    945:         prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
                    946:         page_size = 4096;
                    947:         goto do_mapping;
                    948:     }
                    949: 
                    950:     if (env->cr[4] & CR4_PAE_MASK) {
                    951:         uint64_t pde, pdpe;
                    952:         target_ulong pdpe_addr;
1.1       root      953: 
1.1.1.7   root      954: #ifdef TARGET_X86_64
                    955:         if (env->hflags & HF_LMA_MASK) {
                    956:             uint64_t pml4e_addr, pml4e;
                    957:             int32_t sext;
1.1       root      958: 
1.1.1.7   root      959:             /* test virtual address sign extension */
                    960:             sext = (int64_t)addr >> 47;
                    961:             if (sext != 0 && sext != -1) {
                    962:                 env->error_code = 0;
                    963:                 env->exception_index = EXCP0D_GPF;
                    964:                 return 1;
                    965:             }
1.1       root      966: 
1.1.1.7   root      967:             pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
                    968:                 env->a20_mask;
                    969:             pml4e = ldq_phys(pml4e_addr);
                    970:             if (!(pml4e & PG_PRESENT_MASK)) {
                    971:                 error_code = 0;
                    972:                 goto do_fault;
                    973:             }
                    974:             if (!(env->efer & MSR_EFER_NXE) && (pml4e & PG_NX_MASK)) {
                    975:                 error_code = PG_ERROR_RSVD_MASK;
                    976:                 goto do_fault;
                    977:             }
                    978:             if (!(pml4e & PG_ACCESSED_MASK)) {
                    979:                 pml4e |= PG_ACCESSED_MASK;
                    980:                 stl_phys_notdirty(pml4e_addr, pml4e);
                    981:             }
                    982:             ptep = pml4e ^ PG_NX_MASK;
                    983:             pdpe_addr = ((pml4e & PHYS_ADDR_MASK) + (((addr >> 30) & 0x1ff) << 3)) &
                    984:                 env->a20_mask;
                    985:             pdpe = ldq_phys(pdpe_addr);
                    986:             if (!(pdpe & PG_PRESENT_MASK)) {
                    987:                 error_code = 0;
                    988:                 goto do_fault;
                    989:             }
                    990:             if (!(env->efer & MSR_EFER_NXE) && (pdpe & PG_NX_MASK)) {
                    991:                 error_code = PG_ERROR_RSVD_MASK;
                    992:                 goto do_fault;
                    993:             }
                    994:             ptep &= pdpe ^ PG_NX_MASK;
                    995:             if (!(pdpe & PG_ACCESSED_MASK)) {
                    996:                 pdpe |= PG_ACCESSED_MASK;
                    997:                 stl_phys_notdirty(pdpe_addr, pdpe);
                    998:             }
                    999:         } else
1.1       root     1000: #endif
1.1.1.7   root     1001:         {
                   1002:             /* XXX: load them when cr3 is loaded ? */
                   1003:             pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
                   1004:                 env->a20_mask;
                   1005:             pdpe = ldq_phys(pdpe_addr);
                   1006:             if (!(pdpe & PG_PRESENT_MASK)) {
                   1007:                 error_code = 0;
                   1008:                 goto do_fault;
1.1       root     1009:             }
1.1.1.7   root     1010:             ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;
1.1       root     1011:         }
1.1.1.6   root     1012: 
1.1.1.7   root     1013:         pde_addr = ((pdpe & PHYS_ADDR_MASK) + (((addr >> 21) & 0x1ff) << 3)) &
                   1014:             env->a20_mask;
                   1015:         pde = ldq_phys(pde_addr);
                   1016:         if (!(pde & PG_PRESENT_MASK)) {
                   1017:             error_code = 0;
                   1018:             goto do_fault;
                   1019:         }
                   1020:         if (!(env->efer & MSR_EFER_NXE) && (pde & PG_NX_MASK)) {
                   1021:             error_code = PG_ERROR_RSVD_MASK;
                   1022:             goto do_fault;
                   1023:         }
                   1024:         ptep &= pde ^ PG_NX_MASK;
                   1025:         if (pde & PG_PSE_MASK) {
                   1026:             /* 2 MB page */
                   1027:             page_size = 2048 * 1024;
                   1028:             ptep ^= PG_NX_MASK;
                   1029:             if ((ptep & PG_NX_MASK) && is_write1 == 2)
                   1030:                 goto do_fault_protect;
                   1031:             if (is_user) {
                   1032:                 if (!(ptep & PG_USER_MASK))
                   1033:                     goto do_fault_protect;
                   1034:                 if (is_write && !(ptep & PG_RW_MASK))
                   1035:                     goto do_fault_protect;
                   1036:             } else {
                   1037:                 if ((env->cr[0] & CR0_WP_MASK) &&
                   1038:                     is_write && !(ptep & PG_RW_MASK))
                   1039:                     goto do_fault_protect;
                   1040:             }
                   1041:             is_dirty = is_write && !(pde & PG_DIRTY_MASK);
                   1042:             if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
                   1043:                 pde |= PG_ACCESSED_MASK;
                   1044:                 if (is_dirty)
                   1045:                     pde |= PG_DIRTY_MASK;
                   1046:                 stl_phys_notdirty(pde_addr, pde);
                   1047:             }
                   1048:             /* align to page_size */
                   1049:             pte = pde & ((PHYS_ADDR_MASK & ~(page_size - 1)) | 0xfff);
                   1050:             virt_addr = addr & ~(page_size - 1);
                   1051:         } else {
                   1052:             /* 4 KB page */
                   1053:             if (!(pde & PG_ACCESSED_MASK)) {
                   1054:                 pde |= PG_ACCESSED_MASK;
                   1055:                 stl_phys_notdirty(pde_addr, pde);
                   1056:             }
                   1057:             pte_addr = ((pde & PHYS_ADDR_MASK) + (((addr >> 12) & 0x1ff) << 3)) &
                   1058:                 env->a20_mask;
                   1059:             pte = ldq_phys(pte_addr);
                   1060:             if (!(pte & PG_PRESENT_MASK)) {
                   1061:                 error_code = 0;
                   1062:                 goto do_fault;
                   1063:             }
                   1064:             if (!(env->efer & MSR_EFER_NXE) && (pte & PG_NX_MASK)) {
                   1065:                 error_code = PG_ERROR_RSVD_MASK;
                   1066:                 goto do_fault;
                   1067:             }
                   1068:             /* combine pde and pte nx, user and rw protections */
                   1069:             ptep &= pte ^ PG_NX_MASK;
                   1070:             ptep ^= PG_NX_MASK;
                   1071:             if ((ptep & PG_NX_MASK) && is_write1 == 2)
                   1072:                 goto do_fault_protect;
                   1073:             if (is_user) {
                   1074:                 if (!(ptep & PG_USER_MASK))
                   1075:                     goto do_fault_protect;
                   1076:                 if (is_write && !(ptep & PG_RW_MASK))
                   1077:                     goto do_fault_protect;
                   1078:             } else {
                   1079:                 if ((env->cr[0] & CR0_WP_MASK) &&
                   1080:                     is_write && !(ptep & PG_RW_MASK))
                   1081:                     goto do_fault_protect;
                   1082:             }
                   1083:             is_dirty = is_write && !(pte & PG_DIRTY_MASK);
                   1084:             if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
                   1085:                 pte |= PG_ACCESSED_MASK;
                   1086:                 if (is_dirty)
                   1087:                     pte |= PG_DIRTY_MASK;
                   1088:                 stl_phys_notdirty(pte_addr, pte);
                   1089:             }
                   1090:             page_size = 4096;
                   1091:             virt_addr = addr & ~0xfff;
                   1092:             pte = pte & (PHYS_ADDR_MASK | 0xfff);
                   1093:         }
                   1094:     } else {
                   1095:         uint32_t pde;
                   1096: 
                   1097:         /* page directory entry */
                   1098:         pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) &
                   1099:             env->a20_mask;
                   1100:         pde = ldl_phys(pde_addr);
                   1101:         if (!(pde & PG_PRESENT_MASK)) {
                   1102:             error_code = 0;
                   1103:             goto do_fault;
                   1104:         }
                   1105:         /* if PSE bit is set, then we use a 4MB page */
                   1106:         if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
                   1107:             page_size = 4096 * 1024;
                   1108:             if (is_user) {
                   1109:                 if (!(pde & PG_USER_MASK))
                   1110:                     goto do_fault_protect;
                   1111:                 if (is_write && !(pde & PG_RW_MASK))
                   1112:                     goto do_fault_protect;
                   1113:             } else {
                   1114:                 if ((env->cr[0] & CR0_WP_MASK) &&
                   1115:                     is_write && !(pde & PG_RW_MASK))
                   1116:                     goto do_fault_protect;
                   1117:             }
                   1118:             is_dirty = is_write && !(pde & PG_DIRTY_MASK);
                   1119:             if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
                   1120:                 pde |= PG_ACCESSED_MASK;
                   1121:                 if (is_dirty)
                   1122:                     pde |= PG_DIRTY_MASK;
                   1123:                 stl_phys_notdirty(pde_addr, pde);
                   1124:             }
1.1.1.6   root     1125: 
1.1.1.7   root     1126:             pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
                   1127:             ptep = pte;
                   1128:             virt_addr = addr & ~(page_size - 1);
                   1129:         } else {
                   1130:             if (!(pde & PG_ACCESSED_MASK)) {
                   1131:                 pde |= PG_ACCESSED_MASK;
                   1132:                 stl_phys_notdirty(pde_addr, pde);
                   1133:             }
1.1.1.6   root     1134: 
1.1.1.7   root     1135:             /* page directory entry */
                   1136:             pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) &
                   1137:                 env->a20_mask;
                   1138:             pte = ldl_phys(pte_addr);
                   1139:             if (!(pte & PG_PRESENT_MASK)) {
                   1140:                 error_code = 0;
                   1141:                 goto do_fault;
                   1142:             }
                   1143:             /* combine pde and pte user and rw protections */
                   1144:             ptep = pte & pde;
                   1145:             if (is_user) {
                   1146:                 if (!(ptep & PG_USER_MASK))
                   1147:                     goto do_fault_protect;
                   1148:                 if (is_write && !(ptep & PG_RW_MASK))
                   1149:                     goto do_fault_protect;
                   1150:             } else {
                   1151:                 if ((env->cr[0] & CR0_WP_MASK) &&
                   1152:                     is_write && !(ptep & PG_RW_MASK))
                   1153:                     goto do_fault_protect;
                   1154:             }
                   1155:             is_dirty = is_write && !(pte & PG_DIRTY_MASK);
                   1156:             if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
                   1157:                 pte |= PG_ACCESSED_MASK;
                   1158:                 if (is_dirty)
                   1159:                     pte |= PG_DIRTY_MASK;
                   1160:                 stl_phys_notdirty(pte_addr, pte);
                   1161:             }
                   1162:             page_size = 4096;
                   1163:             virt_addr = addr & ~0xfff;
                   1164:         }
                   1165:     }
                   1166:     /* the page can be put in the TLB */
                   1167:     prot = PAGE_READ;
                   1168:     if (!(ptep & PG_NX_MASK))
                   1169:         prot |= PAGE_EXEC;
                   1170:     if (pte & PG_DIRTY_MASK) {
                   1171:         /* only set write access if already dirty... otherwise wait
                   1172:            for dirty access */
                   1173:         if (is_user) {
                   1174:             if (ptep & PG_RW_MASK)
                   1175:                 prot |= PAGE_WRITE;
                   1176:         } else {
                   1177:             if (!(env->cr[0] & CR0_WP_MASK) ||
                   1178:                 (ptep & PG_RW_MASK))
                   1179:                 prot |= PAGE_WRITE;
                   1180:         }
                   1181:     }
                   1182:  do_mapping:
                   1183:     pte = pte & env->a20_mask;
                   1184: 
                   1185:     /* Even if 4MB pages, we map only one 4KB page in the cache to
                   1186:        avoid filling it too fast */
                   1187:     page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
                   1188:     paddr = (pte & TARGET_PAGE_MASK) + page_offset;
                   1189:     vaddr = virt_addr + page_offset;
                   1190: 
                   1191:     ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
                   1192:     return ret;
                   1193:  do_fault_protect:
                   1194:     error_code = PG_ERROR_P_MASK;
                   1195:  do_fault:
                   1196:     error_code |= (is_write << PG_ERROR_W_BIT);
                   1197:     if (is_user)
                   1198:         error_code |= PG_ERROR_U_MASK;
                   1199:     if (is_write1 == 2 &&
                   1200:         (env->efer & MSR_EFER_NXE) &&
                   1201:         (env->cr[4] & CR4_PAE_MASK))
                   1202:         error_code |= PG_ERROR_I_D_MASK;
                   1203:     if (env->intercept_exceptions & (1 << EXCP0E_PAGE)) {
                   1204:         /* cr2 is not modified in case of exceptions */
                   1205:         stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2), 
                   1206:                  addr);
                   1207:     } else {
                   1208:         env->cr[2] = addr;
                   1209:     }
                   1210:     env->error_code = error_code;
                   1211:     env->exception_index = EXCP0E_PAGE;
                   1212:     return 1;
1.1.1.6   root     1213: }
                   1214: 
1.1.1.7   root     1215: target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
1.1.1.6   root     1216: {
1.1.1.7   root     1217:     target_ulong pde_addr, pte_addr;
                   1218:     uint64_t pte;
                   1219:     target_phys_addr_t paddr;
                   1220:     uint32_t page_offset;
                   1221:     int page_size;
1.1.1.6   root     1222: 
1.1.1.7   root     1223:     if (env->cr[4] & CR4_PAE_MASK) {
                   1224:         target_ulong pdpe_addr;
                   1225:         uint64_t pde, pdpe;
1.1.1.6   root     1226: 
1.1.1.7   root     1227: #ifdef TARGET_X86_64
                   1228:         if (env->hflags & HF_LMA_MASK) {
                   1229:             uint64_t pml4e_addr, pml4e;
                   1230:             int32_t sext;
1.1.1.6   root     1231: 
1.1.1.7   root     1232:             /* test virtual address sign extension */
                   1233:             sext = (int64_t)addr >> 47;
                   1234:             if (sext != 0 && sext != -1)
                   1235:                 return -1;
                   1236: 
                   1237:             pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
                   1238:                 env->a20_mask;
                   1239:             pml4e = ldq_phys(pml4e_addr);
                   1240:             if (!(pml4e & PG_PRESENT_MASK))
                   1241:                 return -1;
                   1242: 
                   1243:             pdpe_addr = ((pml4e & ~0xfff) + (((addr >> 30) & 0x1ff) << 3)) &
                   1244:                 env->a20_mask;
                   1245:             pdpe = ldq_phys(pdpe_addr);
                   1246:             if (!(pdpe & PG_PRESENT_MASK))
                   1247:                 return -1;
                   1248:         } else
                   1249: #endif
                   1250:         {
                   1251:             pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
                   1252:                 env->a20_mask;
                   1253:             pdpe = ldq_phys(pdpe_addr);
                   1254:             if (!(pdpe & PG_PRESENT_MASK))
                   1255:                 return -1;
                   1256:         }
                   1257: 
                   1258:         pde_addr = ((pdpe & ~0xfff) + (((addr >> 21) & 0x1ff) << 3)) &
                   1259:             env->a20_mask;
                   1260:         pde = ldq_phys(pde_addr);
                   1261:         if (!(pde & PG_PRESENT_MASK)) {
                   1262:             return -1;
                   1263:         }
                   1264:         if (pde & PG_PSE_MASK) {
                   1265:             /* 2 MB page */
                   1266:             page_size = 2048 * 1024;
                   1267:             pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
                   1268:         } else {
                   1269:             /* 4 KB page */
                   1270:             pte_addr = ((pde & ~0xfff) + (((addr >> 12) & 0x1ff) << 3)) &
                   1271:                 env->a20_mask;
                   1272:             page_size = 4096;
                   1273:             pte = ldq_phys(pte_addr);
                   1274:         }
                   1275:         if (!(pte & PG_PRESENT_MASK))
                   1276:             return -1;
                   1277:     } else {
                   1278:         uint32_t pde;
                   1279: 
                   1280:         if (!(env->cr[0] & CR0_PG_MASK)) {
                   1281:             pte = addr;
                   1282:             page_size = 4096;
                   1283:         } else {
                   1284:             /* page directory entry */
                   1285:             pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & env->a20_mask;
                   1286:             pde = ldl_phys(pde_addr);
                   1287:             if (!(pde & PG_PRESENT_MASK))
                   1288:                 return -1;
                   1289:             if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
                   1290:                 pte = pde & ~0x003ff000; /* align to 4MB */
                   1291:                 page_size = 4096 * 1024;
                   1292:             } else {
                   1293:                 /* page directory entry */
                   1294:                 pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask;
                   1295:                 pte = ldl_phys(pte_addr);
                   1296:                 if (!(pte & PG_PRESENT_MASK))
                   1297:                     return -1;
                   1298:                 page_size = 4096;
                   1299:             }
                   1300:         }
                   1301:         pte = pte & env->a20_mask;
                   1302:     }
1.1.1.6   root     1303: 
1.1.1.7   root     1304:     page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
                   1305:     paddr = (pte & TARGET_PAGE_MASK) + page_offset;
                   1306:     return paddr;
1.1.1.6   root     1307: }
                   1308: 
1.1.1.7   root     1309: void hw_breakpoint_insert(CPUState *env, int index)
1.1.1.6   root     1310: {
1.1.1.7   root     1311:     int type, err = 0;
1.1.1.6   root     1312: 
1.1.1.7   root     1313:     switch (hw_breakpoint_type(env->dr[7], index)) {
                   1314:     case 0:
                   1315:         if (hw_breakpoint_enabled(env->dr[7], index))
                   1316:             err = cpu_breakpoint_insert(env, env->dr[index], BP_CPU,
                   1317:                                         &env->cpu_breakpoint[index]);
                   1318:         break;
                   1319:     case 1:
                   1320:         type = BP_CPU | BP_MEM_WRITE;
                   1321:         goto insert_wp;
                   1322:     case 2:
                   1323:          /* No support for I/O watchpoints yet */
                   1324:         break;
                   1325:     case 3:
                   1326:         type = BP_CPU | BP_MEM_ACCESS;
                   1327:     insert_wp:
                   1328:         err = cpu_watchpoint_insert(env, env->dr[index],
                   1329:                                     hw_breakpoint_len(env->dr[7], index),
                   1330:                                     type, &env->cpu_watchpoint[index]);
                   1331:         break;
1.1.1.6   root     1332:     }
1.1.1.7   root     1333:     if (err)
                   1334:         env->cpu_breakpoint[index] = NULL;
                   1335: }
1.1.1.6   root     1336: 
1.1.1.7   root     1337: void hw_breakpoint_remove(CPUState *env, int index)
                   1338: {
                   1339:     if (!env->cpu_breakpoint[index])
                   1340:         return;
                   1341:     switch (hw_breakpoint_type(env->dr[7], index)) {
                   1342:     case 0:
                   1343:         if (hw_breakpoint_enabled(env->dr[7], index))
                   1344:             cpu_breakpoint_remove_by_ref(env, env->cpu_breakpoint[index]);
                   1345:         break;
                   1346:     case 1:
                   1347:     case 3:
                   1348:         cpu_watchpoint_remove_by_ref(env, env->cpu_watchpoint[index]);
                   1349:         break;
                   1350:     case 2:
                   1351:         /* No support for I/O watchpoints yet */
1.1.1.6   root     1352:         break;
                   1353:     }
1.1.1.7   root     1354: }
1.1.1.6   root     1355: 
1.1.1.7   root     1356: int check_hw_breakpoints(CPUState *env, int force_dr6_update)
                   1357: {
                   1358:     target_ulong dr6;
                   1359:     int reg, type;
                   1360:     int hit_enabled = 0;
1.1.1.6   root     1361: 
1.1.1.7   root     1362:     dr6 = env->dr[6] & ~0xf;
                   1363:     for (reg = 0; reg < 4; reg++) {
                   1364:         type = hw_breakpoint_type(env->dr[7], reg);
                   1365:         if ((type == 0 && env->dr[reg] == env->eip) ||
                   1366:             ((type & 1) && env->cpu_watchpoint[reg] &&
                   1367:              (env->cpu_watchpoint[reg]->flags & BP_WATCHPOINT_HIT))) {
                   1368:             dr6 |= 1 << reg;
                   1369:             if (hw_breakpoint_enabled(env->dr[7], reg))
                   1370:                 hit_enabled = 1;
1.1.1.6   root     1371:         }
                   1372:     }
1.1.1.7   root     1373:     if (hit_enabled || force_dr6_update)
                   1374:         env->dr[6] = dr6;
                   1375:     return hit_enabled;
1.1.1.6   root     1376: }
                   1377: 
1.1.1.7   root     1378: static CPUDebugExcpHandler *prev_debug_excp_handler;
1.1.1.6   root     1379: 
1.1.1.7   root     1380: void raise_exception(int exception_index);
1.1.1.6   root     1381: 
1.1.1.7   root     1382: static void breakpoint_handler(CPUState *env)
1.1.1.6   root     1383: {
1.1.1.7   root     1384:     CPUBreakpoint *bp;
1.1.1.6   root     1385: 
1.1.1.7   root     1386:     if (env->watchpoint_hit) {
                   1387:         if (env->watchpoint_hit->flags & BP_CPU) {
                   1388:             env->watchpoint_hit = NULL;
                   1389:             if (check_hw_breakpoints(env, 0))
                   1390:                 raise_exception(EXCP01_DB);
                   1391:             else
                   1392:                 cpu_resume_from_signal(env, NULL);
                   1393:         }
                   1394:     } else {
                   1395:         TAILQ_FOREACH(bp, &env->breakpoints, entry)
                   1396:             if (bp->pc == env->eip) {
                   1397:                 if (bp->flags & BP_CPU) {
                   1398:                     check_hw_breakpoints(env, 1);
                   1399:                     raise_exception(EXCP01_DB);
                   1400:                 }
                   1401:                 break;
                   1402:             }
                   1403:     }
                   1404:     if (prev_debug_excp_handler)
                   1405:         prev_debug_excp_handler(env);
1.1.1.6   root     1406: }
1.1.1.7   root     1407: #endif /* !CONFIG_USER_ONLY */
1.1.1.6   root     1408: 
1.1.1.7   root     1409: static void host_cpuid(uint32_t function, uint32_t count,
                   1410:                        uint32_t *eax, uint32_t *ebx,
                   1411:                        uint32_t *ecx, uint32_t *edx)
                   1412: {
                   1413: #if defined(CONFIG_KVM)
                   1414:     uint32_t vec[4];
                   1415: 
                   1416: #ifdef __x86_64__
                   1417:     asm volatile("cpuid"
                   1418:                  : "=a"(vec[0]), "=b"(vec[1]),
                   1419:                    "=c"(vec[2]), "=d"(vec[3])
                   1420:                  : "0"(function), "c"(count) : "cc");
                   1421: #else
                   1422:     asm volatile("pusha \n\t"
                   1423:                  "cpuid \n\t"
1.1.1.8 ! root     1424:                  "mov %%eax, 0(%2) \n\t"
        !          1425:                  "mov %%ebx, 4(%2) \n\t"
        !          1426:                  "mov %%ecx, 8(%2) \n\t"
        !          1427:                  "mov %%edx, 12(%2) \n\t"
1.1.1.7   root     1428:                  "popa"
                   1429:                  : : "a"(function), "c"(count), "S"(vec)
                   1430:                  : "memory", "cc");
                   1431: #endif
                   1432: 
                   1433:     if (eax)
                   1434:        *eax = vec[0];
                   1435:     if (ebx)
                   1436:        *ebx = vec[1];
                   1437:     if (ecx)
                   1438:        *ecx = vec[2];
                   1439:     if (edx)
                   1440:        *edx = vec[3];
                   1441: #endif
1.1.1.6   root     1442: }
                   1443: 
1.1.1.7   root     1444: void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
                   1445:                    uint32_t *eax, uint32_t *ebx,
                   1446:                    uint32_t *ecx, uint32_t *edx)
1.1.1.6   root     1447: {
1.1.1.7   root     1448:     /* test if maximum index reached */
                   1449:     if (index & 0x80000000) {
                   1450:         if (index > env->cpuid_xlevel)
                   1451:             index = env->cpuid_level;
                   1452:     } else {
                   1453:         if (index > env->cpuid_level)
                   1454:             index = env->cpuid_level;
                   1455:     }
1.1.1.6   root     1456: 
1.1.1.7   root     1457:     switch(index) {
                   1458:     case 0:
                   1459:         *eax = env->cpuid_level;
                   1460:         *ebx = env->cpuid_vendor1;
                   1461:         *edx = env->cpuid_vendor2;
                   1462:         *ecx = env->cpuid_vendor3;
                   1463: 
                   1464:         /* sysenter isn't supported on compatibility mode on AMD.  and syscall
                   1465:          * isn't supported in compatibility mode on Intel.  so advertise the
                   1466:          * actuall cpu, and say goodbye to migration between different vendors
                   1467:          * is you use compatibility mode. */
                   1468:         if (kvm_enabled())
                   1469:             host_cpuid(0, 0, NULL, ebx, ecx, edx);
1.1.1.6   root     1470:         break;
1.1.1.7   root     1471:     case 1:
                   1472:         *eax = env->cpuid_version;
                   1473:         *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
                   1474:         *ecx = env->cpuid_ext_features;
                   1475:         *edx = env->cpuid_features;
                   1476: 
                   1477:         /* "Hypervisor present" bit required for Microsoft SVVP */
                   1478:         if (kvm_enabled())
                   1479:             *ecx |= (1 << 31);
1.1.1.6   root     1480:         break;
1.1.1.7   root     1481:     case 2:
                   1482:         /* cache info: needed for Pentium Pro compatibility */
                   1483:         *eax = 1;
                   1484:         *ebx = 0;
                   1485:         *ecx = 0;
                   1486:         *edx = 0x2c307d;
1.1.1.6   root     1487:         break;
1.1.1.7   root     1488:     case 4:
                   1489:         /* cache info: needed for Core compatibility */
                   1490:         switch (count) {
                   1491:             case 0: /* L1 dcache info */
                   1492:                 *eax = 0x0000121;
                   1493:                 *ebx = 0x1c0003f;
                   1494:                 *ecx = 0x000003f;
                   1495:                 *edx = 0x0000001;
                   1496:                 break;
                   1497:             case 1: /* L1 icache info */
                   1498:                 *eax = 0x0000122;
                   1499:                 *ebx = 0x1c0003f;
                   1500:                 *ecx = 0x000003f;
                   1501:                 *edx = 0x0000001;
                   1502:                 break;
                   1503:             case 2: /* L2 cache info */
                   1504:                 *eax = 0x0000143;
                   1505:                 *ebx = 0x3c0003f;
                   1506:                 *ecx = 0x0000fff;
                   1507:                 *edx = 0x0000001;
                   1508:                 break;
                   1509:             default: /* end of info */
                   1510:                 *eax = 0;
                   1511:                 *ebx = 0;
                   1512:                 *ecx = 0;
                   1513:                 *edx = 0;
                   1514:                 break;
1.1.1.6   root     1515:         }
                   1516:         break;
1.1.1.7   root     1517:     case 5:
                   1518:         /* mwait info: needed for Core compatibility */
                   1519:         *eax = 0; /* Smallest monitor-line size in bytes */
                   1520:         *ebx = 0; /* Largest monitor-line size in bytes */
                   1521:         *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
                   1522:         *edx = 0;
                   1523:         break;
                   1524:     case 6:
                   1525:         /* Thermal and Power Leaf */
                   1526:         *eax = 0;
                   1527:         *ebx = 0;
                   1528:         *ecx = 0;
                   1529:         *edx = 0;
                   1530:         break;
                   1531:     case 9:
                   1532:         /* Direct Cache Access Information Leaf */
                   1533:         *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
                   1534:         *ebx = 0;
                   1535:         *ecx = 0;
                   1536:         *edx = 0;
                   1537:         break;
                   1538:     case 0xA:
                   1539:         /* Architectural Performance Monitoring Leaf */
                   1540:         *eax = 0;
                   1541:         *ebx = 0;
                   1542:         *ecx = 0;
                   1543:         *edx = 0;
                   1544:         break;
                   1545:     case 0x80000000:
                   1546:         *eax = env->cpuid_xlevel;
                   1547:         *ebx = env->cpuid_vendor1;
                   1548:         *edx = env->cpuid_vendor2;
                   1549:         *ecx = env->cpuid_vendor3;
1.1.1.6   root     1550:         break;
1.1.1.7   root     1551:     case 0x80000001:
                   1552:         *eax = env->cpuid_features;
                   1553:         *ebx = 0;
                   1554:         *ecx = env->cpuid_ext3_features;
                   1555:         *edx = env->cpuid_ext2_features;
                   1556: 
                   1557:         if (kvm_enabled()) {
                   1558:             uint32_t h_eax, h_edx;
                   1559: 
                   1560:             host_cpuid(index, 0, &h_eax, NULL, NULL, &h_edx);
                   1561: 
                   1562:             /* disable CPU features that the host does not support */
                   1563: 
                   1564:             /* long mode */
                   1565:             if ((h_edx & 0x20000000) == 0 /* || !lm_capable_kernel */)
                   1566:                 *edx &= ~0x20000000;
                   1567:             /* syscall */
                   1568:             if ((h_edx & 0x00000800) == 0)
                   1569:                 *edx &= ~0x00000800;
                   1570:             /* nx */
                   1571:             if ((h_edx & 0x00100000) == 0)
                   1572:                 *edx &= ~0x00100000;
                   1573: 
                   1574:             /* disable CPU features that KVM cannot support */
                   1575: 
                   1576:             /* svm */
                   1577:             *ecx &= ~4UL;
                   1578:             /* 3dnow */
                   1579:             *edx &= ~0xc0000000;
1.1.1.6   root     1580:         }
                   1581:         break;
1.1.1.7   root     1582:     case 0x80000002:
                   1583:     case 0x80000003:
                   1584:     case 0x80000004:
                   1585:         *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
                   1586:         *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
                   1587:         *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
                   1588:         *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
                   1589:         break;
                   1590:     case 0x80000005:
                   1591:         /* cache info (L1 cache) */
                   1592:         *eax = 0x01ff01ff;
                   1593:         *ebx = 0x01ff01ff;
                   1594:         *ecx = 0x40020140;
                   1595:         *edx = 0x40020140;
                   1596:         break;
                   1597:     case 0x80000006:
                   1598:         /* cache info (L2 cache) */
                   1599:         *eax = 0;
                   1600:         *ebx = 0x42004200;
                   1601:         *ecx = 0x02008140;
                   1602:         *edx = 0;
                   1603:         break;
                   1604:     case 0x80000008:
                   1605:         /* virtual & phys address size in low 2 bytes. */
                   1606: /* XXX: This value must match the one used in the MMU code. */ 
                   1607:         if (env->cpuid_ext2_features & CPUID_EXT2_LM) {
                   1608:             /* 64 bit processor */
                   1609: #if defined(USE_KQEMU)
                   1610:             *eax = 0x00003020; /* 48 bits virtual, 32 bits physical */
                   1611: #else
                   1612: /* XXX: The physical address space is limited to 42 bits in exec.c. */
                   1613:             *eax = 0x00003028; /* 48 bits virtual, 40 bits physical */
                   1614: #endif
                   1615:         } else {
                   1616: #if defined(USE_KQEMU)
                   1617:             *eax = 0x00000020; /* 32 bits physical */
                   1618: #else
                   1619:             if (env->cpuid_features & CPUID_PSE36)
                   1620:                 *eax = 0x00000024; /* 36 bits physical */
                   1621:             else
                   1622:                 *eax = 0x00000020; /* 32 bits physical */
                   1623: #endif
1.1.1.6   root     1624:         }
1.1.1.7   root     1625:         *ebx = 0;
                   1626:         *ecx = 0;
                   1627:         *edx = 0;
                   1628:         break;
                   1629:     case 0x8000000A:
                   1630:         *eax = 0x00000001; /* SVM Revision */
                   1631:         *ebx = 0x00000010; /* nr of ASIDs */
                   1632:         *ecx = 0;
                   1633:         *edx = 0; /* optional features */
1.1.1.6   root     1634:         break;
                   1635:     default:
1.1.1.7   root     1636:         /* reserved values: zero */
                   1637:         *eax = 0;
                   1638:         *ebx = 0;
                   1639:         *ecx = 0;
                   1640:         *edx = 0;
1.1.1.6   root     1641:         break;
                   1642:     }
                   1643: }
                   1644: 
1.1.1.7   root     1645: CPUX86State *cpu_x86_init(const char *cpu_model)
1.1.1.6   root     1646: {
1.1.1.7   root     1647:     CPUX86State *env;
                   1648:     static int inited;
1.1.1.6   root     1649: 
1.1.1.7   root     1650:     env = qemu_mallocz(sizeof(CPUX86State));
                   1651:     cpu_exec_init(env);
                   1652:     env->cpu_model_str = cpu_model;
1.1.1.6   root     1653: 
1.1.1.7   root     1654:     /* init various static tables */
                   1655:     if (!inited) {
                   1656:         inited = 1;
                   1657:         optimize_flags_init();
                   1658: #ifndef CONFIG_USER_ONLY
                   1659:         prev_debug_excp_handler =
                   1660:             cpu_set_debug_excp_handler(breakpoint_handler);
                   1661: #endif
1.1.1.6   root     1662:     }
1.1.1.7   root     1663:     if (cpu_x86_register(env, cpu_model) < 0) {
                   1664:         cpu_x86_close(env);
                   1665:         return NULL;
                   1666:     }
                   1667:     cpu_reset(env);
                   1668: #ifdef USE_KQEMU
                   1669:     kqemu_init(env);
1.1.1.6   root     1670: #endif
1.1.1.7   root     1671:     if (kvm_enabled())
                   1672:         kvm_init_vcpu(env);
                   1673:     return env;
1.1.1.6   root     1674: }

unix.superglobalmegacorp.com

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