VirtualBox

Ignore:
Timestamp:
Jun 29, 2011 4:01:23 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
72549
Message:

recompiler: Merged in changes from 0.13.0.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/recompiler/target-i386/helper.c

    r37675 r37689  
    4343//#define DEBUG_MMU
    4444
    45 #ifndef VBOX
    46 /* feature flags taken from "Intel Processor Identification and the CPUID
    47  * Instruction" and AMD's "CPUID Specification". In cases of disagreement
    48  * about feature names, the Linux name is used. */
    49 static const char *feature_name[] = {
    50     "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
    51     "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
    52     "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */, NULL, "ds" /* Intel dts */, "acpi", "mmx",
    53     "fxsr", "sse", "sse2", "ss", "ht" /* Intel htt */, "tm", "ia64", "pbe",
    54 };
    55 static const char *ext_feature_name[] = {
    56     "pni" /* Intel,AMD sse3 */, NULL, NULL, "monitor", "ds_cpl", "vmx", NULL /* Linux smx */, "est",
    57     "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL,
    58     NULL, NULL, "dca", NULL, NULL, NULL, NULL, "popcnt",
    59     NULL, NULL, NULL, NULL, NULL, NULL, NULL, "hypervisor",
    60 };
    61 static const char *ext2_feature_name[] = {
    62     "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
    63     "cx8" /* AMD CMPXCHG8B */, "apic", NULL, "syscall", "mtrr", "pge", "mca", "cmov",
    64     "pat", "pse36", NULL, NULL /* Linux mp */, "nx" /* Intel xd */, NULL, "mmxext", "mmx",
    65     "fxsr", "fxsr_opt" /* AMD ffxsr */, "pdpe1gb" /* AMD Page1GB */, "rdtscp", NULL, "lm" /* Intel 64 */, "3dnowext", "3dnow",
    66 };
    67 static const char *ext3_feature_name[] = {
    68     "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */, "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
    69     "3dnowprefetch", "osvw", NULL /* Linux ibs */, NULL, "skinit", "wdt", NULL, NULL,
    70     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
    71     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
    72 };
    73 
    74 static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
    75                                     uint32_t *ext_features,
    76                                     uint32_t *ext2_features,
    77                                     uint32_t *ext3_features)
    78 {
    79     int i;
    80     int found = 0;
    81 
    82     for ( i = 0 ; i < 32 ; i++ )
    83         if (feature_name[i] && !strcmp (flagname, feature_name[i])) {
    84             *features |= 1 << i;
    85             found = 1;
    86         }
    87     for ( i = 0 ; i < 32 ; i++ )
    88         if (ext_feature_name[i] && !strcmp (flagname, ext_feature_name[i])) {
    89             *ext_features |= 1 << i;
    90             found = 1;
    91         }
    92     for ( i = 0 ; i < 32 ; i++ )
    93         if (ext2_feature_name[i] && !strcmp (flagname, ext2_feature_name[i])) {
    94             *ext2_features |= 1 << i;
    95             found = 1;
    96         }
    97     for ( i = 0 ; i < 32 ; i++ )
    98         if (ext3_feature_name[i] && !strcmp (flagname, ext3_feature_name[i])) {
    99             *ext3_features |= 1 << i;
    100             found = 1;
    101         }
    102     if (!found) {
    103         fprintf(stderr, "CPU feature %s not found\n", flagname);
    104     }
    105 }
    106 #endif /* !VBOX */
    107 
    108 typedef struct x86_def_t {
    109     const char *name;
    110     uint32_t level;
    111     uint32_t vendor1, vendor2, vendor3;
    112     int family;
    113     int model;
    114     int stepping;
    115     uint32_t features, ext_features, ext2_features, ext3_features;
    116     uint32_t xlevel;
    117     char model_id[48];
    118     int vendor_override;
    119 } x86_def_t;
    120 
    121 #ifndef VBOX
    122 #define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
    123 #define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
    124           CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX)
    125 #define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
    126           CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
    127           CPUID_PSE36 | CPUID_FXSR)
    128 #define PENTIUM3_FEATURES (PENTIUM2_FEATURES | CPUID_SSE)
    129 #define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
    130           CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
    131           CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
    132           CPUID_PAE | CPUID_SEP | CPUID_APIC)
    133 static x86_def_t x86_defs[] = {
    134 #ifdef TARGET_X86_64
    135     {
    136         .name = "qemu64",
    137         .level = 4,
    138         .vendor1 = CPUID_VENDOR_AMD_1,
    139         .vendor2 = CPUID_VENDOR_AMD_2,
    140         .vendor3 = CPUID_VENDOR_AMD_3,
    141         .family = 6,
    142         .model = 2,
    143         .stepping = 3,
    144         .features = PPRO_FEATURES |
    145         /* these features are needed for Win64 and aren't fully implemented */
    146             CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
    147         /* this feature is needed for Solaris and isn't fully implemented */
    148             CPUID_PSE36,
    149         .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT,
    150         .ext2_features = (PPRO_FEATURES & 0x0183F3FF) |
    151             CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
    152         .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
    153             CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
    154         .xlevel = 0x8000000A,
    155         .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
    156     },
    157     {
    158         .name = "phenom",
    159         .level = 5,
    160         .vendor1 = CPUID_VENDOR_AMD_1,
    161         .vendor2 = CPUID_VENDOR_AMD_2,
    162         .vendor3 = CPUID_VENDOR_AMD_3,
    163         .family = 16,
    164         .model = 2,
    165         .stepping = 3,
    166         /* Missing: CPUID_VME, CPUID_HT */
    167         .features = PPRO_FEATURES |
    168             CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
    169             CPUID_PSE36,
    170         .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 |
    171             CPUID_EXT_POPCNT,
    172         /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
    173         .ext2_features = (PPRO_FEATURES & 0x0183F3FF) |
    174             CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
    175             CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
    176             CPUID_EXT2_FFXSR,
    177         /* Missing: CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
    178                     CPUID_EXT3_CR8LEG,
    179                     CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
    180                     CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
    181         .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
    182             CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
    183         .xlevel = 0x8000001A,
    184         .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
    185     },
    186     {
    187         .name = "core2duo",
    188         .level = 10,
    189         .family = 6,
    190         .model = 15,
    191         .stepping = 11,
    192         /* The original CPU also implements these features:
    193                CPUID_VME, CPUID_DTS, CPUID_ACPI, CPUID_SS, CPUID_HT,
    194                CPUID_TM, CPUID_PBE */
    195         .features = PPRO_FEATURES |
    196             CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
    197             CPUID_PSE36,
    198         /* The original CPU also implements these ext features:
    199                CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_EST,
    200                CPUID_EXT_TM2, CPUID_EXT_CX16, CPUID_EXT_XTPR, CPUID_EXT_PDCM */
    201         .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3,
    202         .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
    203         .ext3_features = CPUID_EXT3_LAHF_LM,
    204         .xlevel = 0x80000008,
    205         .model_id = "Intel(R) Core(TM)2 Duo CPU     T7700  @ 2.40GHz",
    206     },
    207     {
    208         .name = "kvm64",
    209         .level = 5,
    210         .vendor1 = CPUID_VENDOR_INTEL_1,
    211         .vendor2 = CPUID_VENDOR_INTEL_2,
    212         .vendor3 = CPUID_VENDOR_INTEL_3,
    213         .family = 15,
    214         .model = 6,
    215         .stepping = 1,
    216         /* Missing: CPUID_VME, CPUID_HT */
    217         .features = PPRO_FEATURES |
    218             CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
    219             CPUID_PSE36,
    220         /* Missing: CPUID_EXT_POPCNT, CPUID_EXT_MONITOR */
    221         .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16,
    222         /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
    223         .ext2_features = (PPRO_FEATURES & 0x0183F3FF) |
    224             CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
    225         /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
    226                     CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
    227                     CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
    228                     CPUID_EXT3_OSVW, CPUID_EXT3_IBS, CPUID_EXT3_SVM */
    229         .ext3_features = 0,
    230         .xlevel = 0x80000008,
    231         .model_id = "Common KVM processor"
    232     },
    233 #endif
    234     {
    235         .name = "qemu32",
    236         .level = 4,
    237         .family = 6,
    238         .model = 3,
    239         .stepping = 3,
    240         .features = PPRO_FEATURES,
    241         .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_POPCNT,
    242         .xlevel = 0,
    243         .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
    244     },
    245     {
    246         .name = "coreduo",
    247         .level = 10,
    248         .family = 6,
    249         .model = 14,
    250         .stepping = 8,
    251         /* The original CPU also implements these features:
    252                CPUID_DTS, CPUID_ACPI, CPUID_SS, CPUID_HT,
    253                CPUID_TM, CPUID_PBE */
    254         .features = PPRO_FEATURES | CPUID_VME |
    255             CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA,
    256         /* The original CPU also implements these ext features:
    257                CPUID_EXT_VMX, CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_XTPR,
    258                CPUID_EXT_PDCM */
    259         .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR,
    260         .ext2_features = CPUID_EXT2_NX,
    261         .xlevel = 0x80000008,
    262         .model_id = "Genuine Intel(R) CPU           T2600  @ 2.16GHz",
    263     },
    264     {
    265         .name = "486",
    266         .level = 0,
    267         .family = 4,
    268         .model = 0,
    269         .stepping = 0,
    270         .features = I486_FEATURES,
    271         .xlevel = 0,
    272     },
    273     {
    274         .name = "pentium",
    275         .level = 1,
    276         .family = 5,
    277         .model = 4,
    278         .stepping = 3,
    279         .features = PENTIUM_FEATURES,
    280         .xlevel = 0,
    281     },
    282     {
    283         .name = "pentium2",
    284         .level = 2,
    285         .family = 6,
    286         .model = 5,
    287         .stepping = 2,
    288         .features = PENTIUM2_FEATURES,
    289         .xlevel = 0,
    290     },
    291     {
    292         .name = "pentium3",
    293         .level = 2,
    294         .family = 6,
    295         .model = 7,
    296         .stepping = 3,
    297         .features = PENTIUM3_FEATURES,
    298         .xlevel = 0,
    299     },
    300     {
    301         .name = "athlon",
    302         .level = 2,
    303         .vendor1 = CPUID_VENDOR_AMD_1,
    304         .vendor2 = CPUID_VENDOR_AMD_2,
    305         .vendor3 = CPUID_VENDOR_AMD_3,
    306         .family = 6,
    307         .model = 2,
    308         .stepping = 3,
    309         .features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR | CPUID_MCA,
    310         .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
    311         .xlevel = 0x80000008,
    312         /* XXX: put another string ? */
    313         .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
    314     },
    315     {
    316         .name = "n270",
    317         /* original is on level 10 */
    318         .level = 5,
    319         .family = 6,
    320         .model = 28,
    321         .stepping = 2,
    322         .features = PPRO_FEATURES |
    323             CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME,
    324             /* Missing: CPUID_DTS | CPUID_ACPI | CPUID_SS |
    325              * CPUID_HT | CPUID_TM | CPUID_PBE */
    326             /* Some CPUs got no CPUID_SEP */
    327         .ext_features = CPUID_EXT_MONITOR |
    328             CPUID_EXT_SSE3 /* PNI */ | CPUID_EXT_SSSE3,
    329             /* Missing: CPUID_EXT_DSCPL | CPUID_EXT_EST |
    330              * CPUID_EXT_TM2 | CPUID_EXT_XTPR */
    331         .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_NX,
    332         /* Missing: .ext3_features = CPUID_EXT3_LAHF_LM */
    333         .xlevel = 0x8000000A,
    334         .model_id = "Intel(R) Atom(TM) CPU N270   @ 1.60GHz",
    335     },
    336 };
    337 
    338 static void host_cpuid(uint32_t function, uint32_t count, uint32_t *eax,
    339                                uint32_t *ebx, uint32_t *ecx, uint32_t *edx);
    340 
    341 static int cpu_x86_fill_model_id(char *str)
    342 {
    343     uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
    344     int i;
    345 
    346     for (i = 0; i < 3; i++) {
    347         host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);
    348         memcpy(str + i * 16 +  0, &eax, 4);
    349         memcpy(str + i * 16 +  4, &ebx, 4);
    350         memcpy(str + i * 16 +  8, &ecx, 4);
    351         memcpy(str + i * 16 + 12, &edx, 4);
    352     }
    353     return 0;
    354 }
    355 
    356 static int cpu_x86_fill_host(x86_def_t *x86_cpu_def)
    357 {
    358     uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
    359 
    360     x86_cpu_def->name = "host";
    361     host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
    362     x86_cpu_def->level = eax;
    363     x86_cpu_def->vendor1 = ebx;
    364     x86_cpu_def->vendor2 = edx;
    365     x86_cpu_def->vendor3 = ecx;
    366 
    367     host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
    368     x86_cpu_def->family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
    369     x86_cpu_def->model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
    370     x86_cpu_def->stepping = eax & 0x0F;
    371     x86_cpu_def->ext_features = ecx;
    372     x86_cpu_def->features = edx;
    373 
    374     host_cpuid(0x80000000, 0, &eax, &ebx, &ecx, &edx);
    375     x86_cpu_def->xlevel = eax;
    376 
    377     host_cpuid(0x80000001, 0, &eax, &ebx, &ecx, &edx);
    378     x86_cpu_def->ext2_features = edx;
    379     x86_cpu_def->ext3_features = ecx;
    380     cpu_x86_fill_model_id(x86_cpu_def->model_id);
    381     x86_cpu_def->vendor_override = 0;
    382 
    383     return 0;
    384 }
    385 
    386 static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
    387 {
    388     unsigned int i;
    389     x86_def_t *def;
    390 
    391     char *s = strdup(cpu_model);
    392     char *featurestr, *name = strtok(s, ",");
    393     uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0;
    394     uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0;
    395     uint32_t numvalue;
    396 
    397     def = NULL;
    398     for (i = 0; i < ARRAY_SIZE(x86_defs); i++) {
    399         if (strcmp(name, x86_defs[i].name) == 0) {
    400             def = &x86_defs[i];
    401             break;
    402         }
    403     }
    404     if (kvm_enabled() && strcmp(name, "host") == 0) {
    405         cpu_x86_fill_host(x86_cpu_def);
    406     } else if (!def) {
    407         goto error;
    408     } else {
    409         memcpy(x86_cpu_def, def, sizeof(*def));
    410     }
    411 
    412     add_flagname_to_bitmaps("hypervisor", &plus_features,
    413         &plus_ext_features, &plus_ext2_features, &plus_ext3_features);
    414 
    415     featurestr = strtok(NULL, ",");
    416 
    417     while (featurestr) {
    418         char *val;
    419         if (featurestr[0] == '+') {
    420             add_flagname_to_bitmaps(featurestr + 1, &plus_features, &plus_ext_features, &plus_ext2_features, &plus_ext3_features);
    421         } else if (featurestr[0] == '-') {
    422             add_flagname_to_bitmaps(featurestr + 1, &minus_features, &minus_ext_features, &minus_ext2_features, &minus_ext3_features);
    423         } else if ((val = strchr(featurestr, '='))) {
    424             *val = 0; val++;
    425             if (!strcmp(featurestr, "family")) {
    426                 char *err;
    427                 numvalue = strtoul(val, &err, 0);
    428                 if (!*val || *err) {
    429                     fprintf(stderr, "bad numerical value %s\n", val);
    430                     goto error;
    431                 }
    432                 x86_cpu_def->family = numvalue;
    433             } else if (!strcmp(featurestr, "model")) {
    434                 char *err;
    435                 numvalue = strtoul(val, &err, 0);
    436                 if (!*val || *err || numvalue > 0xff) {
    437                     fprintf(stderr, "bad numerical value %s\n", val);
    438                     goto error;
    439                 }
    440                 x86_cpu_def->model = numvalue;
    441             } else if (!strcmp(featurestr, "stepping")) {
    442                 char *err;
    443                 numvalue = strtoul(val, &err, 0);
    444                 if (!*val || *err || numvalue > 0xf) {
    445                     fprintf(stderr, "bad numerical value %s\n", val);
    446                     goto error;
    447                 }
    448                 x86_cpu_def->stepping = numvalue ;
    449             } else if (!strcmp(featurestr, "level")) {
    450                 char *err;
    451                 numvalue = strtoul(val, &err, 0);
    452                 if (!*val || *err) {
    453                     fprintf(stderr, "bad numerical value %s\n", val);
    454                     goto error;
    455                 }
    456                 x86_cpu_def->level = numvalue;
    457             } else if (!strcmp(featurestr, "xlevel")) {
    458                 char *err;
    459                 numvalue = strtoul(val, &err, 0);
    460                 if (!*val || *err) {
    461                     fprintf(stderr, "bad numerical value %s\n", val);
    462                     goto error;
    463                 }
    464                 if (numvalue < 0x80000000) {
    465                         numvalue += 0x80000000;
    466                 }
    467                 x86_cpu_def->xlevel = numvalue;
    468             } else if (!strcmp(featurestr, "vendor")) {
    469                 if (strlen(val) != 12) {
    470                     fprintf(stderr, "vendor string must be 12 chars long\n");
    471                     goto error;
    472                 }
    473                 x86_cpu_def->vendor1 = 0;
    474                 x86_cpu_def->vendor2 = 0;
    475                 x86_cpu_def->vendor3 = 0;
    476                 for(i = 0; i < 4; i++) {
    477                     x86_cpu_def->vendor1 |= ((uint8_t)val[i    ]) << (8 * i);
    478                     x86_cpu_def->vendor2 |= ((uint8_t)val[i + 4]) << (8 * i);
    479                     x86_cpu_def->vendor3 |= ((uint8_t)val[i + 8]) << (8 * i);
    480                 }
    481                 x86_cpu_def->vendor_override = 1;
    482             } else if (!strcmp(featurestr, "model_id")) {
    483                 pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id),
    484                         val);
    485             } else {
    486                 fprintf(stderr, "unrecognized feature %s\n", featurestr);
    487                 goto error;
    488             }
    489         } else {
    490             fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);
    491             goto error;
    492         }
    493         featurestr = strtok(NULL, ",");
    494     }
    495     x86_cpu_def->features |= plus_features;
    496     x86_cpu_def->ext_features |= plus_ext_features;
    497     x86_cpu_def->ext2_features |= plus_ext2_features;
    498     x86_cpu_def->ext3_features |= plus_ext3_features;
    499     x86_cpu_def->features &= ~minus_features;
    500     x86_cpu_def->ext_features &= ~minus_ext_features;
    501     x86_cpu_def->ext2_features &= ~minus_ext2_features;
    502     x86_cpu_def->ext3_features &= ~minus_ext3_features;
    503     free(s);
    504     return 0;
    505 
    506 error:
    507     free(s);
    508     return -1;
    509 }
    510 
    511 void x86_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
    512 {
    513     unsigned int i;
    514 
    515     for (i = 0; i < ARRAY_SIZE(x86_defs); i++)
    516         (*cpu_fprintf)(f, "x86 %16s\n", x86_defs[i].name);
    517 }
    518 #endif /* !VBOX */
    519 
    520 static int cpu_x86_register (CPUX86State *env, const char *cpu_model)
    521 {
    522 #ifndef VBOX
    523     x86_def_t def1, *def = &def1;
    524 
    525     if (cpu_x86_find_by_name(def, cpu_model) < 0)
    526         return -1;
    527     if (def->vendor1) {
    528         env->cpuid_vendor1 = def->vendor1;
    529         env->cpuid_vendor2 = def->vendor2;
    530         env->cpuid_vendor3 = def->vendor3;
    531     } else {
    532         env->cpuid_vendor1 = CPUID_VENDOR_INTEL_1;
    533         env->cpuid_vendor2 = CPUID_VENDOR_INTEL_2;
    534         env->cpuid_vendor3 = CPUID_VENDOR_INTEL_3;
    535     }
    536     env->cpuid_vendor_override = def->vendor_override;
    537     env->cpuid_level = def->level;
    538     if (def->family > 0x0f)
    539         env->cpuid_version = 0xf00 | ((def->family - 0x0f) << 20);
    540     else
    541         env->cpuid_version = def->family << 8;
    542     env->cpuid_version |= ((def->model & 0xf) << 4) | ((def->model >> 4) << 16);
    543     env->cpuid_version |= def->stepping;
    544     env->cpuid_features = def->features;
    545     env->pat = 0x0007040600070406ULL;
    546     env->cpuid_ext_features = def->ext_features;
    547     env->cpuid_ext2_features = def->ext2_features;
    548     env->cpuid_xlevel = def->xlevel;
    549     env->cpuid_ext3_features = def->ext3_features;
    550     {
    551         const char *model_id = def->model_id;
    552         int c, len, i;
    553         if (!model_id)
    554             model_id = "";
    555         len = strlen(model_id);
    556         for(i = 0; i < 48; i++) {
    557             if (i >= len)
    558                 c = '\0';
    559             else
    560                 c = (uint8_t)model_id[i];
    561             env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
    562         }
    563     }
    564 #endif /* !VBOX */
    565     return 0;
    566 }
    567 
    56845/* NOTE: must be called outside the CPU execute loop */
    56946void cpu_reset(CPUX86State *env)
     
    62097
    62198    env->eip = 0xfff0;
    622 #ifndef VBOX
     99#ifndef VBOX /* We'll get the right value from CPUM. */
    623100    env->regs[R_EDX] = env->cpuid_version;
    624 #else
    625     /** @todo: is it right? */
    626     env->regs[R_EDX] = 0x600; /* indicate P6 processor */
    627101#endif
    628102
     
    762236            }
    763237        };
    764         cpu_fprintf(f, sys_type_name[(env->hflags & HF_LMA_MASK) ? 1 : 0]
    765                                     [(sc->flags & DESC_TYPE_MASK)
    766                                      >> DESC_TYPE_SHIFT]);
     238        cpu_fprintf(f, "%s",
     239                    sys_type_name[(env->hflags & HF_LMA_MASK) ? 1 : 0]
     240                                 [(sc->flags & DESC_TYPE_MASK)
     241                                  >> DESC_TYPE_SHIFT]);
    767242    }
    768243done:
     
    909384        }
    910385    }
     386    cpu_fprintf(f, "EFER=%016" PRIx64 "\n", env->efer);
    911387    if (flags & X86_DUMP_FPU) {
    912388        int fptag;
     
    1026502        ((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK));
    1027503#ifdef VBOX
    1028 
    1029504    remR3ChangeCpuMode(env);
    1030505#endif
     
    1081556}
    1082557
    1083 target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
    1084 {
    1085     return addr;
    1086 }
    1087 
    1088558#else
    1089559
     
    1100570   0  = nothing more to do
    1101571   1  = generate PF fault
    1102    2  = soft MMU activation required for this block
    1103572*/
    1104573int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
     
    1107576    uint64_t ptep, pte;
    1108577    target_ulong pde_addr, pte_addr;
    1109     int error_code, is_dirty, prot, page_size, ret, is_write, is_user;
     578    int error_code, is_dirty, prot, page_size, is_write, is_user;
    1110579    target_phys_addr_t paddr;
    1111580    uint32_t page_offset;
     
    1368837    vaddr = virt_addr + page_offset;
    1369838
    1370     ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
    1371     return ret;
     839    tlb_set_page(env, vaddr, paddr, prot, mmu_idx, page_size);
     840    return 0;
    1372841 do_fault_protect:
    1373842    error_code = PG_ERROR_P_MASK;
     
    15571026static CPUDebugExcpHandler *prev_debug_excp_handler;
    15581027
    1559 void raise_exception(int exception_index);
     1028void raise_exception_env(int exception_index, CPUState *env);
    15601029
    15611030static void breakpoint_handler(CPUState *env)
     
    15671036            env->watchpoint_hit = NULL;
    15681037            if (check_hw_breakpoints(env, 0))
    1569                 raise_exception(EXCP01_DB);
     1038                raise_exception_env(EXCP01_DB, env);
    15701039            else
    15711040                cpu_resume_from_signal(env, NULL);
     
    15761045                if (bp->flags & BP_CPU) {
    15771046                    check_hw_breakpoints(env, 1);
    1578                     raise_exception(EXCP01_DB);
     1047                    raise_exception_env(EXCP01_DB, env);
    15791048                }
    15801049                break;
     
    15841053        prev_debug_excp_handler(env);
    15851054}
    1586 
    15871055
    15881056#ifndef VBOX
     
    16591127}
    16601128
    1661 static void host_cpuid(uint32_t function, uint32_t count,
    1662                        uint32_t *eax, uint32_t *ebx,
    1663                        uint32_t *ecx, uint32_t *edx)
    1664 {
    1665 #if defined(CONFIG_KVM)
    1666     uint32_t vec[4];
    1667 
    1668 #ifdef __x86_64__
    1669     asm volatile("cpuid"
    1670                  : "=a"(vec[0]), "=b"(vec[1]),
    1671                    "=c"(vec[2]), "=d"(vec[3])
    1672                  : "0"(function), "c"(count) : "cc");
    1673 #else
    1674     asm volatile("pusha \n\t"
    1675                  "cpuid \n\t"
    1676                  "mov %%eax, 0(%2) \n\t"
    1677                  "mov %%ebx, 4(%2) \n\t"
    1678                  "mov %%ecx, 8(%2) \n\t"
    1679                  "mov %%edx, 12(%2) \n\t"
    1680                  "popa"
    1681                  : : "a"(function), "c"(count), "S"(vec)
    1682                  : "memory", "cc");
    1683 #endif
    1684 
    1685     if (eax)
    1686         *eax = vec[0];
    1687     if (ebx)
    1688         *ebx = vec[1];
    1689     if (ecx)
    1690         *ecx = vec[2];
    1691     if (edx)
    1692         *edx = vec[3];
    1693 #endif
    1694 }
    1695 
    1696 static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
    1697                              uint32_t *ecx, uint32_t *edx)
    1698 {
    1699     *ebx = env->cpuid_vendor1;
    1700     *edx = env->cpuid_vendor2;
    1701     *ecx = env->cpuid_vendor3;
    1702 
    1703     /* sysenter isn't supported on compatibility mode on AMD, syscall
    1704      * isn't supported in compatibility mode on Intel.
    1705      * Normally we advertise the actual cpu vendor, but you can override
    1706      * this if you want to use KVM's sysenter/syscall emulation
    1707      * in compatibility mode and when doing cross vendor migration
    1708      */
    1709     if (kvm_enabled() && env->cpuid_vendor_override) {
    1710         host_cpuid(0, 0, NULL, ebx, ecx, edx);
    1711     }
    1712 }
    1713 
    1714 void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
    1715                    uint32_t *eax, uint32_t *ebx,
    1716                    uint32_t *ecx, uint32_t *edx)
    1717 {
    1718     /* test if maximum index reached */
    1719     if (index & 0x80000000) {
    1720         if (index > env->cpuid_xlevel)
    1721             index = env->cpuid_level;
    1722     } else {
    1723         if (index > env->cpuid_level)
    1724             index = env->cpuid_level;
    1725     }
    1726 
    1727     switch(index) {
    1728     case 0:
    1729         *eax = env->cpuid_level;
    1730         get_cpuid_vendor(env, ebx, ecx, edx);
    1731         break;
    1732     case 1:
    1733         *eax = env->cpuid_version;
    1734         *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
    1735         *ecx = env->cpuid_ext_features;
    1736         *edx = env->cpuid_features;
    1737         if (env->nr_cores * env->nr_threads > 1) {
    1738             *ebx |= (env->nr_cores * env->nr_threads) << 16;
    1739             *edx |= 1 << 28;    /* HTT bit */
    1740         }
    1741         break;
    1742     case 2:
    1743         /* cache info: needed for Pentium Pro compatibility */
    1744         *eax = 1;
    1745         *ebx = 0;
    1746         *ecx = 0;
    1747         *edx = 0x2c307d;
    1748         break;
    1749     case 4:
    1750         /* cache info: needed for Core compatibility */
    1751         if (env->nr_cores > 1) {
    1752                 *eax = (env->nr_cores - 1) << 26;
    1753         } else {
    1754                 *eax = 0;
    1755         }
    1756         switch (count) {
    1757             case 0: /* L1 dcache info */
    1758                 *eax |= 0x0000121;
    1759                 *ebx = 0x1c0003f;
    1760                 *ecx = 0x000003f;
    1761                 *edx = 0x0000001;
    1762                 break;
    1763             case 1: /* L1 icache info */
    1764                 *eax |= 0x0000122;
    1765                 *ebx = 0x1c0003f;
    1766                 *ecx = 0x000003f;
    1767                 *edx = 0x0000001;
    1768                 break;
    1769             case 2: /* L2 cache info */
    1770                 *eax |= 0x0000143;
    1771                 if (env->nr_threads > 1) {
    1772                     *eax |= (env->nr_threads - 1) << 14;
    1773                 }
    1774                 *ebx = 0x3c0003f;
    1775                 *ecx = 0x0000fff;
    1776                 *edx = 0x0000001;
    1777                 break;
    1778             default: /* end of info */
    1779                 *eax = 0;
    1780                 *ebx = 0;
    1781                 *ecx = 0;
    1782                 *edx = 0;
    1783                 break;
    1784         }
    1785         break;
    1786     case 5:
    1787         /* mwait info: needed for Core compatibility */
    1788         *eax = 0; /* Smallest monitor-line size in bytes */
    1789         *ebx = 0; /* Largest monitor-line size in bytes */
    1790         *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
    1791         *edx = 0;
    1792         break;
    1793     case 6:
    1794         /* Thermal and Power Leaf */
    1795         *eax = 0;
    1796         *ebx = 0;
    1797         *ecx = 0;
    1798         *edx = 0;
    1799         break;
    1800     case 9:
    1801         /* Direct Cache Access Information Leaf */
    1802         *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
    1803         *ebx = 0;
    1804         *ecx = 0;
    1805         *edx = 0;
    1806         break;
    1807     case 0xA:
    1808         /* Architectural Performance Monitoring Leaf */
    1809         *eax = 0;
    1810         *ebx = 0;
    1811         *ecx = 0;
    1812         *edx = 0;
    1813         break;
    1814     case 0x80000000:
    1815         *eax = env->cpuid_xlevel;
    1816         *ebx = env->cpuid_vendor1;
    1817         *edx = env->cpuid_vendor2;
    1818         *ecx = env->cpuid_vendor3;
    1819         break;
    1820     case 0x80000001:
    1821         *eax = env->cpuid_version;
    1822         *ebx = 0;
    1823         *ecx = env->cpuid_ext3_features;
    1824         *edx = env->cpuid_ext2_features;
    1825 
    1826         /* The Linux kernel checks for the CMPLegacy bit and
    1827          * discards multiple thread information if it is set.
    1828          * So dont set it here for Intel to make Linux guests happy.
    1829          */
    1830         if (env->nr_cores * env->nr_threads > 1) {
    1831             uint32_t tebx, tecx, tedx;
    1832             get_cpuid_vendor(env, &tebx, &tecx, &tedx);
    1833             if (tebx != CPUID_VENDOR_INTEL_1 ||
    1834                 tedx != CPUID_VENDOR_INTEL_2 ||
    1835                 tecx != CPUID_VENDOR_INTEL_3) {
    1836                 *ecx |= 1 << 1;    /* CmpLegacy bit */
    1837             }
    1838         }
    1839 
    1840         if (kvm_enabled()) {
    1841             /* Nested SVM not yet supported in upstream QEMU */
    1842             *ecx &= ~CPUID_EXT3_SVM;
    1843         }
    1844         break;
    1845     case 0x80000002:
    1846     case 0x80000003:
    1847     case 0x80000004:
    1848         *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
    1849         *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
    1850         *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
    1851         *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
    1852         break;
    1853     case 0x80000005:
    1854         /* cache info (L1 cache) */
    1855         *eax = 0x01ff01ff;
    1856         *ebx = 0x01ff01ff;
    1857         *ecx = 0x40020140;
    1858         *edx = 0x40020140;
    1859         break;
    1860     case 0x80000006:
    1861         /* cache info (L2 cache) */
    1862         *eax = 0;
    1863         *ebx = 0x42004200;
    1864         *ecx = 0x02008140;
    1865         *edx = 0;
    1866         break;
    1867     case 0x80000008:
    1868         /* virtual & phys address size in low 2 bytes. */
    1869 /* XXX: This value must match the one used in the MMU code. */
    1870         if (env->cpuid_ext2_features & CPUID_EXT2_LM) {
    1871             /* 64 bit processor */
    1872 /* XXX: The physical address space is limited to 42 bits in exec.c. */
    1873             *eax = 0x00003028;  /* 48 bits virtual, 40 bits physical */
    1874         } else {
    1875             if (env->cpuid_features & CPUID_PSE36)
    1876                 *eax = 0x00000024; /* 36 bits physical */
    1877             else
    1878                 *eax = 0x00000020; /* 32 bits physical */
    1879         }
    1880         *ebx = 0;
    1881         *ecx = 0;
    1882         *edx = 0;
    1883         if (env->nr_cores * env->nr_threads > 1) {
    1884             *ecx |= (env->nr_cores * env->nr_threads) - 1;
    1885         }
    1886         break;
    1887     case 0x8000000A:
    1888         *eax = 0x00000001; /* SVM Revision */
    1889         *ebx = 0x00000010; /* nr of ASIDs */
    1890         *ecx = 0;
    1891         *edx = 0; /* optional features */
    1892         break;
    1893     default:
    1894         /* reserved values: zero */
    1895         *eax = 0;
    1896         *ebx = 0;
    1897         *ecx = 0;
    1898         *edx = 0;
    1899         break;
    1900     }
    1901 }
    1902 
    1903 
    19041129int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
    19051130                            target_ulong *base, unsigned int *limit,
     
    19591184#endif
    19601185    }
     1186#ifndef VBOX
    19611187    if (cpu_x86_register(env, cpu_model) < 0) {
    19621188        cpu_x86_close(env);
    19631189        return NULL;
    19641190    }
    1965 #ifndef VBOX
    19661191    mce_init(env);
    19671192#endif
     
    19791204    cpu_reset(env);
    19801205    env->interrupt_request = sipi;
    1981     apic_init_reset(env);
     1206    apic_init_reset(env->apic_state);
     1207    env->halted = !cpu_is_bsp(env);
    19821208}
    19831209
    19841210void do_cpu_sipi(CPUState *env)
    19851211{
    1986     apic_sipi(env);
     1212    apic_sipi(env->apic_state);
    19871213}
    19881214#else
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette