186797937017f52bff088d02edf64fb931177a7eaJun Nakajima/*
286797937017f52bff088d02edf64fb931177a7eaJun Nakajima *  i386 helpers (without register variable usage)
386797937017f52bff088d02edf64fb931177a7eaJun Nakajima *
486797937017f52bff088d02edf64fb931177a7eaJun Nakajima *  Copyright (c) 2003 Fabrice Bellard
586797937017f52bff088d02edf64fb931177a7eaJun Nakajima *
686797937017f52bff088d02edf64fb931177a7eaJun Nakajima * This library is free software; you can redistribute it and/or
786797937017f52bff088d02edf64fb931177a7eaJun Nakajima * modify it under the terms of the GNU Lesser General Public
886797937017f52bff088d02edf64fb931177a7eaJun Nakajima * License as published by the Free Software Foundation; either
986797937017f52bff088d02edf64fb931177a7eaJun Nakajima * version 2 of the License, or (at your option) any later version.
1086797937017f52bff088d02edf64fb931177a7eaJun Nakajima *
1186797937017f52bff088d02edf64fb931177a7eaJun Nakajima * This library is distributed in the hope that it will be useful,
1286797937017f52bff088d02edf64fb931177a7eaJun Nakajima * but WITHOUT ANY WARRANTY; without even the implied warranty of
1386797937017f52bff088d02edf64fb931177a7eaJun Nakajima * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1486797937017f52bff088d02edf64fb931177a7eaJun Nakajima * Lesser General Public License for more details.
1586797937017f52bff088d02edf64fb931177a7eaJun Nakajima *
1686797937017f52bff088d02edf64fb931177a7eaJun Nakajima * You should have received a copy of the GNU Lesser General Public
1786797937017f52bff088d02edf64fb931177a7eaJun Nakajima * License along with this library; if not, write to the Free Software
1886797937017f52bff088d02edf64fb931177a7eaJun Nakajima * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
1986797937017f52bff088d02edf64fb931177a7eaJun Nakajima */
2086797937017f52bff088d02edf64fb931177a7eaJun Nakajima#include <stdarg.h>
2186797937017f52bff088d02edf64fb931177a7eaJun Nakajima#include <stdlib.h>
2286797937017f52bff088d02edf64fb931177a7eaJun Nakajima#include <stdio.h>
2386797937017f52bff088d02edf64fb931177a7eaJun Nakajima#include <string.h>
2486797937017f52bff088d02edf64fb931177a7eaJun Nakajima#include <inttypes.h>
2586797937017f52bff088d02edf64fb931177a7eaJun Nakajima#include <signal.h>
2686797937017f52bff088d02edf64fb931177a7eaJun Nakajima
2786797937017f52bff088d02edf64fb931177a7eaJun Nakajima#include "cpu.h"
2886797937017f52bff088d02edf64fb931177a7eaJun Nakajima#include "exec-all.h"
2986797937017f52bff088d02edf64fb931177a7eaJun Nakajima#include "qemu-common.h"
3086797937017f52bff088d02edf64fb931177a7eaJun Nakajima#include "kvm.h"
31a381ef07088ce479610129e37bfef42538f397daJun Nakajima#include "hax.h"
3286797937017f52bff088d02edf64fb931177a7eaJun Nakajima
3386797937017f52bff088d02edf64fb931177a7eaJun Nakajima//#define DEBUG_MMU
3486797937017f52bff088d02edf64fb931177a7eaJun Nakajima
3586797937017f52bff088d02edf64fb931177a7eaJun Nakajima/* feature flags taken from "Intel Processor Identification and the CPUID
3686797937017f52bff088d02edf64fb931177a7eaJun Nakajima * Instruction" and AMD's "CPUID Specification". In cases of disagreement
3786797937017f52bff088d02edf64fb931177a7eaJun Nakajima * about feature names, the Linux name is used. */
3886797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic const char *feature_name[] = {
3986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
4086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
4186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */, NULL, "ds" /* Intel dts */, "acpi", "mmx",
4286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "fxsr", "sse", "sse2", "ss", "ht" /* Intel htt */, "tm", "ia64", "pbe",
4386797937017f52bff088d02edf64fb931177a7eaJun Nakajima};
4486797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic const char *ext_feature_name[] = {
4586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "pni" /* Intel,AMD sse3 */, NULL, NULL, "monitor", "ds_cpl", "vmx", NULL /* Linux smx */, "est",
4686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL,
4786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    NULL, NULL, "dca", NULL, NULL, NULL, NULL, "popcnt",
4886797937017f52bff088d02edf64fb931177a7eaJun Nakajima       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
4986797937017f52bff088d02edf64fb931177a7eaJun Nakajima};
5086797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic const char *ext2_feature_name[] = {
5186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
5286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "cx8" /* AMD CMPXCHG8B */, "apic", NULL, "syscall", "mtrr", "pge", "mca", "cmov",
5386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "pat", "pse36", NULL, NULL /* Linux mp */, "nx" /* Intel xd */, NULL, "mmxext", "mmx",
5486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "fxsr", "fxsr_opt" /* AMD ffxsr */, "pdpe1gb" /* AMD Page1GB */, "rdtscp", NULL, "lm" /* Intel 64 */, "3dnowext", "3dnow",
5586797937017f52bff088d02edf64fb931177a7eaJun Nakajima};
5686797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic const char *ext3_feature_name[] = {
5786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */, "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
5886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "3dnowprefetch", "osvw", NULL /* Linux ibs */, NULL, "skinit", "wdt", NULL, NULL,
5986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
6086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
6186797937017f52bff088d02edf64fb931177a7eaJun Nakajima};
6286797937017f52bff088d02edf64fb931177a7eaJun Nakajima
6386797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic void add_flagname_to_bitmaps(char *flagname, uint32_t *features,
6486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                                    uint32_t *ext_features,
6586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                                    uint32_t *ext2_features,
6686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                                    uint32_t *ext3_features)
6786797937017f52bff088d02edf64fb931177a7eaJun Nakajima{
6886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    int i;
6986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    int found = 0;
7086797937017f52bff088d02edf64fb931177a7eaJun Nakajima
7186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    for ( i = 0 ; i < 32 ; i++ )
7286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if (feature_name[i] && !strcmp (flagname, feature_name[i])) {
7386797937017f52bff088d02edf64fb931177a7eaJun Nakajima            *features |= 1 << i;
7486797937017f52bff088d02edf64fb931177a7eaJun Nakajima            found = 1;
7586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        }
7686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    for ( i = 0 ; i < 32 ; i++ )
7786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if (ext_feature_name[i] && !strcmp (flagname, ext_feature_name[i])) {
7886797937017f52bff088d02edf64fb931177a7eaJun Nakajima            *ext_features |= 1 << i;
7986797937017f52bff088d02edf64fb931177a7eaJun Nakajima            found = 1;
8086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        }
8186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    for ( i = 0 ; i < 32 ; i++ )
8286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if (ext2_feature_name[i] && !strcmp (flagname, ext2_feature_name[i])) {
8386797937017f52bff088d02edf64fb931177a7eaJun Nakajima            *ext2_features |= 1 << i;
8486797937017f52bff088d02edf64fb931177a7eaJun Nakajima            found = 1;
8586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        }
8686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    for ( i = 0 ; i < 32 ; i++ )
8786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if (ext3_feature_name[i] && !strcmp (flagname, ext3_feature_name[i])) {
8886797937017f52bff088d02edf64fb931177a7eaJun Nakajima            *ext3_features |= 1 << i;
8986797937017f52bff088d02edf64fb931177a7eaJun Nakajima            found = 1;
9086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        }
9186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (!found) {
9286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        fprintf(stderr, "CPU feature %s not found\n", flagname);
9386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
9486797937017f52bff088d02edf64fb931177a7eaJun Nakajima}
9586797937017f52bff088d02edf64fb931177a7eaJun Nakajima
9686797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic void kvm_trim_features(uint32_t *features, uint32_t supported,
9786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                              const char *names[])
9886797937017f52bff088d02edf64fb931177a7eaJun Nakajima{
9986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    int i;
10086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    uint32_t mask;
10186797937017f52bff088d02edf64fb931177a7eaJun Nakajima
10286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    for (i = 0; i < 32; ++i) {
10386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        mask = 1U << i;
10486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if ((*features & mask) && !(supported & mask)) {
10586797937017f52bff088d02edf64fb931177a7eaJun Nakajima            *features &= ~mask;
10686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        }
10786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
10886797937017f52bff088d02edf64fb931177a7eaJun Nakajima}
10986797937017f52bff088d02edf64fb931177a7eaJun Nakajima
11086797937017f52bff088d02edf64fb931177a7eaJun Nakajimatypedef struct x86_def_t {
11186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    const char *name;
11286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    uint32_t level;
11386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    uint32_t vendor1, vendor2, vendor3;
11486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    int family;
11586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    int model;
11686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    int stepping;
11786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    uint32_t features, ext_features, ext2_features, ext3_features;
11886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    uint32_t xlevel;
11986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    char model_id[48];
12086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    int vendor_override;
12186797937017f52bff088d02edf64fb931177a7eaJun Nakajima} x86_def_t;
12286797937017f52bff088d02edf64fb931177a7eaJun Nakajima
12386797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
12486797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
12586797937017f52bff088d02edf64fb931177a7eaJun Nakajima          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX)
12686797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
12786797937017f52bff088d02edf64fb931177a7eaJun Nakajima          CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
12886797937017f52bff088d02edf64fb931177a7eaJun Nakajima          CPUID_PSE36 | CPUID_FXSR)
12986797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define PENTIUM3_FEATURES (PENTIUM2_FEATURES | CPUID_SSE)
13086797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
13186797937017f52bff088d02edf64fb931177a7eaJun Nakajima          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
13286797937017f52bff088d02edf64fb931177a7eaJun Nakajima          CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
13386797937017f52bff088d02edf64fb931177a7eaJun Nakajima          CPUID_PAE | CPUID_SEP | CPUID_APIC)
13486797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic x86_def_t x86_defs[] = {
13586797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef TARGET_X86_64
13686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    {
13786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .name = "qemu64",
13886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .level = 2,
13986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .vendor1 = CPUID_VENDOR_AMD_1,
14086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .vendor2 = CPUID_VENDOR_AMD_2,
14186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .vendor3 = CPUID_VENDOR_AMD_3,
14286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .family = 6,
14386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .model = 2,
14486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .stepping = 3,
14586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .features = PPRO_FEATURES |
14686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* these features are needed for Win64 and aren't fully implemented */
14786797937017f52bff088d02edf64fb931177a7eaJun Nakajima            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
14886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* this feature is needed for Solaris and isn't fully implemented */
14986797937017f52bff088d02edf64fb931177a7eaJun Nakajima            CPUID_PSE36,
15086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .ext_features = CPUID_EXT_SSE3,
15186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) |
15286797937017f52bff088d02edf64fb931177a7eaJun Nakajima            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
15386797937017f52bff088d02edf64fb931177a7eaJun Nakajima            CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
15486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .ext3_features = CPUID_EXT3_SVM,
15586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .xlevel = 0x8000000A,
15686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
15786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    },
15886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    {
15986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .name = "phenom",
16086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .level = 5,
16186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .vendor1 = CPUID_VENDOR_AMD_1,
16286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .vendor2 = CPUID_VENDOR_AMD_2,
16386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .vendor3 = CPUID_VENDOR_AMD_3,
16486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .family = 16,
16586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .model = 2,
16686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .stepping = 3,
16786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* Missing: CPUID_VME, CPUID_HT */
16886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .features = PPRO_FEATURES |
16986797937017f52bff088d02edf64fb931177a7eaJun Nakajima            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
17086797937017f52bff088d02edf64fb931177a7eaJun Nakajima            CPUID_PSE36,
17186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* Missing: CPUID_EXT_CX16, CPUID_EXT_POPCNT */
17286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR,
17386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
17486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) |
17586797937017f52bff088d02edf64fb931177a7eaJun Nakajima            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
17686797937017f52bff088d02edf64fb931177a7eaJun Nakajima            CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
17786797937017f52bff088d02edf64fb931177a7eaJun Nakajima            CPUID_EXT2_FFXSR,
17886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
17986797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
18086797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
18186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
18286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .ext3_features = CPUID_EXT3_SVM,
18386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .xlevel = 0x8000001A,
18486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
18586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    },
18686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    {
18786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .name = "core2duo",
18886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .level = 10,
18986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .family = 6,
19086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .model = 15,
19186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .stepping = 11,
19286797937017f52bff088d02edf64fb931177a7eaJun Nakajima	/* The original CPU also implements these features:
19386797937017f52bff088d02edf64fb931177a7eaJun Nakajima               CPUID_VME, CPUID_DTS, CPUID_ACPI, CPUID_SS, CPUID_HT,
19486797937017f52bff088d02edf64fb931177a7eaJun Nakajima               CPUID_TM, CPUID_PBE */
19586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .features = PPRO_FEATURES |
19686797937017f52bff088d02edf64fb931177a7eaJun Nakajima            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
19786797937017f52bff088d02edf64fb931177a7eaJun Nakajima            CPUID_PSE36,
19886797937017f52bff088d02edf64fb931177a7eaJun Nakajima	/* The original CPU also implements these ext features:
19986797937017f52bff088d02edf64fb931177a7eaJun Nakajima               CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_EST,
20086797937017f52bff088d02edf64fb931177a7eaJun Nakajima               CPUID_EXT_TM2, CPUID_EXT_CX16, CPUID_EXT_XTPR, CPUID_EXT_PDCM */
20186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3,
20286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
20386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* Missing: .ext3_features = CPUID_EXT3_LAHF_LM */
20486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .xlevel = 0x80000008,
20586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .model_id = "Intel(R) Core(TM)2 Duo CPU     T7700  @ 2.40GHz",
20686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    },
20786797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif
20886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    {
20986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .name = "qemu32",
21086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .level = 2,
21186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .family = 6,
21286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .model = 3,
21386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .stepping = 3,
21486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .features = PPRO_FEATURES,
215599662dc9671378c1471ce812a415bc4274736f2Jun Nakajima        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_SSSE3,
21686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .xlevel = 0,
21786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
21886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    },
21986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    {
22086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .name = "coreduo",
22186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .level = 10,
22286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .family = 6,
22386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .model = 14,
22486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .stepping = 8,
22586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* The original CPU also implements these features:
22686797937017f52bff088d02edf64fb931177a7eaJun Nakajima               CPUID_DTS, CPUID_ACPI, CPUID_SS, CPUID_HT,
22786797937017f52bff088d02edf64fb931177a7eaJun Nakajima               CPUID_TM, CPUID_PBE */
22886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .features = PPRO_FEATURES | CPUID_VME |
22986797937017f52bff088d02edf64fb931177a7eaJun Nakajima            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA,
23086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* The original CPU also implements these ext features:
23186797937017f52bff088d02edf64fb931177a7eaJun Nakajima               CPUID_EXT_VMX, CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_XTPR,
23286797937017f52bff088d02edf64fb931177a7eaJun Nakajima               CPUID_EXT_PDCM */
23386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR,
23486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .ext2_features = CPUID_EXT2_NX,
23586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .xlevel = 0x80000008,
23686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .model_id = "Genuine Intel(R) CPU           T2600  @ 2.16GHz",
23786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    },
23886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    {
23986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .name = "486",
24086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .level = 0,
24186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .family = 4,
24286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .model = 0,
24386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .stepping = 0,
24486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .features = I486_FEATURES,
24586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .xlevel = 0,
24686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    },
24786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    {
24886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .name = "pentium",
24986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .level = 1,
25086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .family = 5,
25186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .model = 4,
25286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .stepping = 3,
25386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .features = PENTIUM_FEATURES,
25486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .xlevel = 0,
25586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    },
25686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    {
25786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .name = "pentium2",
25886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .level = 2,
25986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .family = 6,
26086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .model = 5,
26186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .stepping = 2,
26286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .features = PENTIUM2_FEATURES,
26386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .xlevel = 0,
26486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    },
26586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    {
26686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .name = "pentium3",
26786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .level = 2,
26886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .family = 6,
26986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .model = 7,
27086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .stepping = 3,
27186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .features = PENTIUM3_FEATURES,
27286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .xlevel = 0,
27386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    },
27486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    {
27586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .name = "athlon",
27686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .level = 2,
27786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .vendor1 = 0x68747541, /* "Auth" */
27886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .vendor2 = 0x69746e65, /* "enti" */
27986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .vendor3 = 0x444d4163, /* "cAMD" */
28086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .family = 6,
28186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .model = 2,
28286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .stepping = 3,
28386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR | CPUID_MCA,
28486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
28586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .xlevel = 0x80000008,
28686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* XXX: put another string ? */
28786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
28886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    },
28986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    {
29086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .name = "n270",
29186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* original is on level 10 */
29286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .level = 5,
29386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .family = 6,
29486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .model = 28,
29586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .stepping = 2,
29686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .features = PPRO_FEATURES |
29786797937017f52bff088d02edf64fb931177a7eaJun Nakajima            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME,
29886797937017f52bff088d02edf64fb931177a7eaJun Nakajima            /* Missing: CPUID_DTS | CPUID_ACPI | CPUID_SS |
29986797937017f52bff088d02edf64fb931177a7eaJun Nakajima             * CPUID_HT | CPUID_TM | CPUID_PBE */
30086797937017f52bff088d02edf64fb931177a7eaJun Nakajima            /* Some CPUs got no CPUID_SEP */
30186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .ext_features = CPUID_EXT_MONITOR |
30286797937017f52bff088d02edf64fb931177a7eaJun Nakajima            CPUID_EXT_SSE3 /* PNI */ | CPUID_EXT_SSSE3,
30386797937017f52bff088d02edf64fb931177a7eaJun Nakajima            /* Missing: CPUID_EXT_DSCPL | CPUID_EXT_EST |
30486797937017f52bff088d02edf64fb931177a7eaJun Nakajima             * CPUID_EXT_TM2 | CPUID_EXT_XTPR */
30586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_NX,
30686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* Missing: .ext3_features = CPUID_EXT3_LAHF_LM */
30786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .xlevel = 0x8000000A,
30886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        .model_id = "Intel(R) Atom(TM) CPU N270   @ 1.60GHz",
30986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    },
31086797937017f52bff088d02edf64fb931177a7eaJun Nakajima};
31186797937017f52bff088d02edf64fb931177a7eaJun Nakajima
31286797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
31386797937017f52bff088d02edf64fb931177a7eaJun Nakajima{
31486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    unsigned int i;
31586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    x86_def_t *def;
31686797937017f52bff088d02edf64fb931177a7eaJun Nakajima
31786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    char *s = strdup(cpu_model);
31886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    char *featurestr, *name = strtok(s, ",");
31986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0;
32086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0;
32186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    int family = -1, model = -1, stepping = -1;
32286797937017f52bff088d02edf64fb931177a7eaJun Nakajima
32386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    def = NULL;
32486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    for (i = 0; i < ARRAY_SIZE(x86_defs); i++) {
32586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if (strcmp(name, x86_defs[i].name) == 0) {
32686797937017f52bff088d02edf64fb931177a7eaJun Nakajima            def = &x86_defs[i];
32786797937017f52bff088d02edf64fb931177a7eaJun Nakajima            break;
32886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        }
32986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
33086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (!def)
33186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        goto error;
33286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    memcpy(x86_cpu_def, def, sizeof(*def));
33386797937017f52bff088d02edf64fb931177a7eaJun Nakajima
33486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    featurestr = strtok(NULL, ",");
33586797937017f52bff088d02edf64fb931177a7eaJun Nakajima
33686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    while (featurestr) {
33786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        char *val;
33886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if (featurestr[0] == '+') {
33986797937017f52bff088d02edf64fb931177a7eaJun Nakajima            add_flagname_to_bitmaps(featurestr + 1, &plus_features, &plus_ext_features, &plus_ext2_features, &plus_ext3_features);
34086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        } else if (featurestr[0] == '-') {
34186797937017f52bff088d02edf64fb931177a7eaJun Nakajima            add_flagname_to_bitmaps(featurestr + 1, &minus_features, &minus_ext_features, &minus_ext2_features, &minus_ext3_features);
34286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        } else if ((val = strchr(featurestr, '='))) {
34386797937017f52bff088d02edf64fb931177a7eaJun Nakajima            *val = 0; val++;
34486797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (!strcmp(featurestr, "family")) {
34586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                char *err;
34686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                family = strtol(val, &err, 10);
34786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                if (!*val || *err || family < 0) {
34886797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    fprintf(stderr, "bad numerical value %s\n", val);
34986797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    goto error;
35086797937017f52bff088d02edf64fb931177a7eaJun Nakajima                }
35186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                x86_cpu_def->family = family;
35286797937017f52bff088d02edf64fb931177a7eaJun Nakajima            } else if (!strcmp(featurestr, "model")) {
35386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                char *err;
35486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                model = strtol(val, &err, 10);
35586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                if (!*val || *err || model < 0 || model > 0xff) {
35686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    fprintf(stderr, "bad numerical value %s\n", val);
35786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    goto error;
35886797937017f52bff088d02edf64fb931177a7eaJun Nakajima                }
35986797937017f52bff088d02edf64fb931177a7eaJun Nakajima                x86_cpu_def->model = model;
36086797937017f52bff088d02edf64fb931177a7eaJun Nakajima            } else if (!strcmp(featurestr, "stepping")) {
36186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                char *err;
36286797937017f52bff088d02edf64fb931177a7eaJun Nakajima                stepping = strtol(val, &err, 10);
36386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                if (!*val || *err || stepping < 0 || stepping > 0xf) {
36486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    fprintf(stderr, "bad numerical value %s\n", val);
36586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    goto error;
36686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                }
36786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                x86_cpu_def->stepping = stepping;
36886797937017f52bff088d02edf64fb931177a7eaJun Nakajima            } else if (!strcmp(featurestr, "vendor")) {
36986797937017f52bff088d02edf64fb931177a7eaJun Nakajima                if (strlen(val) != 12) {
37086797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    fprintf(stderr, "vendor string must be 12 chars long\n");
37186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    goto error;
37286797937017f52bff088d02edf64fb931177a7eaJun Nakajima                }
37386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                x86_cpu_def->vendor1 = 0;
37486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                x86_cpu_def->vendor2 = 0;
37586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                x86_cpu_def->vendor3 = 0;
37686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                for(i = 0; i < 4; i++) {
37786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    x86_cpu_def->vendor1 |= ((uint8_t)val[i    ]) << (8 * i);
37886797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    x86_cpu_def->vendor2 |= ((uint8_t)val[i + 4]) << (8 * i);
37986797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    x86_cpu_def->vendor3 |= ((uint8_t)val[i + 8]) << (8 * i);
38086797937017f52bff088d02edf64fb931177a7eaJun Nakajima                }
38186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                x86_cpu_def->vendor_override = 1;
38286797937017f52bff088d02edf64fb931177a7eaJun Nakajima            } else if (!strcmp(featurestr, "model_id")) {
38386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id),
38486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                        val);
38586797937017f52bff088d02edf64fb931177a7eaJun Nakajima            } else {
38686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                fprintf(stderr, "unrecognized feature %s\n", featurestr);
38786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                goto error;
38886797937017f52bff088d02edf64fb931177a7eaJun Nakajima            }
38986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        } else {
39086797937017f52bff088d02edf64fb931177a7eaJun Nakajima            fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);
39186797937017f52bff088d02edf64fb931177a7eaJun Nakajima            goto error;
39286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        }
39386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        featurestr = strtok(NULL, ",");
39486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
39586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    x86_cpu_def->features |= plus_features;
39686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    x86_cpu_def->ext_features |= plus_ext_features;
39786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    x86_cpu_def->ext2_features |= plus_ext2_features;
39886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    x86_cpu_def->ext3_features |= plus_ext3_features;
39986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    x86_cpu_def->features &= ~minus_features;
40086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    x86_cpu_def->ext_features &= ~minus_ext_features;
40186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    x86_cpu_def->ext2_features &= ~minus_ext2_features;
40286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    x86_cpu_def->ext3_features &= ~minus_ext3_features;
40386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    free(s);
40486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    return 0;
40586797937017f52bff088d02edf64fb931177a7eaJun Nakajima
40686797937017f52bff088d02edf64fb931177a7eaJun Nakajimaerror:
40786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    free(s);
40886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    return -1;
40986797937017f52bff088d02edf64fb931177a7eaJun Nakajima}
41086797937017f52bff088d02edf64fb931177a7eaJun Nakajima
41186797937017f52bff088d02edf64fb931177a7eaJun Nakajimavoid x86_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
41286797937017f52bff088d02edf64fb931177a7eaJun Nakajima{
41386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    unsigned int i;
41486797937017f52bff088d02edf64fb931177a7eaJun Nakajima
41586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    for (i = 0; i < ARRAY_SIZE(x86_defs); i++)
41686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        (*cpu_fprintf)(f, "x86 %16s\n", x86_defs[i].name);
41786797937017f52bff088d02edf64fb931177a7eaJun Nakajima}
41886797937017f52bff088d02edf64fb931177a7eaJun Nakajima
41986797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic int cpu_x86_register (CPUX86State *env, const char *cpu_model)
42086797937017f52bff088d02edf64fb931177a7eaJun Nakajima{
42186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    x86_def_t def1, *def = &def1;
42286797937017f52bff088d02edf64fb931177a7eaJun Nakajima
42386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (cpu_x86_find_by_name(def, cpu_model) < 0)
42486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        return -1;
42586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (def->vendor1) {
42686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        env->cpuid_vendor1 = def->vendor1;
42786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        env->cpuid_vendor2 = def->vendor2;
42886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        env->cpuid_vendor3 = def->vendor3;
42986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    } else {
43086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        env->cpuid_vendor1 = CPUID_VENDOR_INTEL_1;
43186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        env->cpuid_vendor2 = CPUID_VENDOR_INTEL_2;
43286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        env->cpuid_vendor3 = CPUID_VENDOR_INTEL_3;
43386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
43486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->cpuid_vendor_override = def->vendor_override;
43586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->cpuid_level = def->level;
43686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (def->family > 0x0f)
43786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        env->cpuid_version = 0xf00 | ((def->family - 0x0f) << 20);
43886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    else
43986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        env->cpuid_version = def->family << 8;
44086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->cpuid_version |= ((def->model & 0xf) << 4) | ((def->model >> 4) << 16);
44186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->cpuid_version |= def->stepping;
44286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->cpuid_features = def->features;
44386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->pat = 0x0007040600070406ULL;
44486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->cpuid_ext_features = def->ext_features;
44586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->cpuid_ext2_features = def->ext2_features;
44686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->cpuid_xlevel = def->xlevel;
44786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->cpuid_ext3_features = def->ext3_features;
44886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    {
44986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        const char *model_id = def->model_id;
45086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        int c, len, i;
45186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if (!model_id)
45286797937017f52bff088d02edf64fb931177a7eaJun Nakajima            model_id = "";
45386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        len = strlen(model_id);
45486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        for(i = 0; i < 48; i++) {
45586797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (i >= len)
45686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                c = '\0';
45786797937017f52bff088d02edf64fb931177a7eaJun Nakajima            else
45886797937017f52bff088d02edf64fb931177a7eaJun Nakajima                c = (uint8_t)model_id[i];
45986797937017f52bff088d02edf64fb931177a7eaJun Nakajima            env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
46086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        }
46186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
46286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    return 0;
46386797937017f52bff088d02edf64fb931177a7eaJun Nakajima}
46486797937017f52bff088d02edf64fb931177a7eaJun Nakajima
46586797937017f52bff088d02edf64fb931177a7eaJun Nakajima/* NOTE: must be called outside the CPU execute loop */
46686797937017f52bff088d02edf64fb931177a7eaJun Nakajimavoid cpu_reset(CPUX86State *env)
46786797937017f52bff088d02edf64fb931177a7eaJun Nakajima{
46886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    int i;
46986797937017f52bff088d02edf64fb931177a7eaJun Nakajima
47086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
47186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
47286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        log_cpu_state(env, X86_DUMP_FPU | X86_DUMP_CCOP);
47386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
47486797937017f52bff088d02edf64fb931177a7eaJun Nakajima
47586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    memset(env, 0, offsetof(CPUX86State, breakpoints));
47686797937017f52bff088d02edf64fb931177a7eaJun Nakajima
47786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    tlb_flush(env, 1);
47886797937017f52bff088d02edf64fb931177a7eaJun Nakajima
47986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->old_exception = -1;
48086797937017f52bff088d02edf64fb931177a7eaJun Nakajima
48186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    /* init to reset state */
48286797937017f52bff088d02edf64fb931177a7eaJun Nakajima
48386797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef CONFIG_SOFTMMU
48486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->hflags |= HF_SOFTMMU_MASK;
48586797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif
48686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->hflags2 |= HF2_GIF_MASK;
48786797937017f52bff088d02edf64fb931177a7eaJun Nakajima
48886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    cpu_x86_update_cr0(env, 0x60000010);
48986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->a20_mask = ~0x0;
49086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->smbase = 0x30000;
49186797937017f52bff088d02edf64fb931177a7eaJun Nakajima
49286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->idt.limit = 0xffff;
49386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->gdt.limit = 0xffff;
49486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->ldt.limit = 0xffff;
49586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
49686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->tr.limit = 0xffff;
49786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
49886797937017f52bff088d02edf64fb931177a7eaJun Nakajima
49986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
50086797937017f52bff088d02edf64fb931177a7eaJun Nakajima                           DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
50186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                           DESC_R_MASK | DESC_A_MASK);
50286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
50386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
50486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                           DESC_A_MASK);
50586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
50686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
50786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                           DESC_A_MASK);
50886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
50986797937017f52bff088d02edf64fb931177a7eaJun Nakajima                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
51086797937017f52bff088d02edf64fb931177a7eaJun Nakajima                           DESC_A_MASK);
51186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
51286797937017f52bff088d02edf64fb931177a7eaJun Nakajima                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
51386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                           DESC_A_MASK);
51486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
51586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
51686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                           DESC_A_MASK);
51786797937017f52bff088d02edf64fb931177a7eaJun Nakajima
51886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->eip = 0xfff0;
51986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->regs[R_EDX] = env->cpuid_version;
52086797937017f52bff088d02edf64fb931177a7eaJun Nakajima
52186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->eflags = 0x2;
52286797937017f52bff088d02edf64fb931177a7eaJun Nakajima
52386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    /* FPU init */
52486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    for(i = 0;i < 8; i++)
52586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        env->fptags[i] = 1;
52686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->fpuc = 0x37f;
52786797937017f52bff088d02edf64fb931177a7eaJun Nakajima
52886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->mxcsr = 0x1f80;
52986797937017f52bff088d02edf64fb931177a7eaJun Nakajima
53086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    memset(env->dr, 0, sizeof(env->dr));
53186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->dr[6] = DR6_FIXED_1;
53286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->dr[7] = DR7_FIXED_1;
53386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    cpu_breakpoint_remove_all(env, BP_CPU);
53486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    cpu_watchpoint_remove_all(env, BP_CPU);
53586797937017f52bff088d02edf64fb931177a7eaJun Nakajima}
53686797937017f52bff088d02edf64fb931177a7eaJun Nakajima
53786797937017f52bff088d02edf64fb931177a7eaJun Nakajimavoid cpu_x86_close(CPUX86State *env)
53886797937017f52bff088d02edf64fb931177a7eaJun Nakajima{
53986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    qemu_free(env);
54086797937017f52bff088d02edf64fb931177a7eaJun Nakajima}
54186797937017f52bff088d02edf64fb931177a7eaJun Nakajima
54286797937017f52bff088d02edf64fb931177a7eaJun Nakajima/***********************************************************/
54386797937017f52bff088d02edf64fb931177a7eaJun Nakajima/* x86 debug */
54486797937017f52bff088d02edf64fb931177a7eaJun Nakajima
54586797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic const char *cc_op_str[] = {
54686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "DYNAMIC",
54786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "EFLAGS",
54886797937017f52bff088d02edf64fb931177a7eaJun Nakajima
54986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "MULB",
55086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "MULW",
55186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "MULL",
55286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "MULQ",
55386797937017f52bff088d02edf64fb931177a7eaJun Nakajima
55486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "ADDB",
55586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "ADDW",
55686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "ADDL",
55786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "ADDQ",
55886797937017f52bff088d02edf64fb931177a7eaJun Nakajima
55986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "ADCB",
56086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "ADCW",
56186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "ADCL",
56286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "ADCQ",
56386797937017f52bff088d02edf64fb931177a7eaJun Nakajima
56486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "SUBB",
56586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "SUBW",
56686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "SUBL",
56786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "SUBQ",
56886797937017f52bff088d02edf64fb931177a7eaJun Nakajima
56986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "SBBB",
57086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "SBBW",
57186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "SBBL",
57286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "SBBQ",
57386797937017f52bff088d02edf64fb931177a7eaJun Nakajima
57486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "LOGICB",
57586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "LOGICW",
57686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "LOGICL",
57786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "LOGICQ",
57886797937017f52bff088d02edf64fb931177a7eaJun Nakajima
57986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "INCB",
58086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "INCW",
58186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "INCL",
58286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "INCQ",
58386797937017f52bff088d02edf64fb931177a7eaJun Nakajima
58486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "DECB",
58586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "DECW",
58686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "DECL",
58786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "DECQ",
58886797937017f52bff088d02edf64fb931177a7eaJun Nakajima
58986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "SHLB",
59086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "SHLW",
59186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "SHLL",
59286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "SHLQ",
59386797937017f52bff088d02edf64fb931177a7eaJun Nakajima
59486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "SARB",
59586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "SARW",
59686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "SARL",
59786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    "SARQ",
59886797937017f52bff088d02edf64fb931177a7eaJun Nakajima};
59986797937017f52bff088d02edf64fb931177a7eaJun Nakajima
60086797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic void
60186797937017f52bff088d02edf64fb931177a7eaJun Nakajimacpu_x86_dump_seg_cache(CPUState *env, FILE *f,
60286797937017f52bff088d02edf64fb931177a7eaJun Nakajima                       int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
60386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                       const char *name, struct SegmentCache *sc)
60486797937017f52bff088d02edf64fb931177a7eaJun Nakajima{
60586797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef TARGET_X86_64
60686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (env->hflags & HF_CS64_MASK) {
60786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        cpu_fprintf(f, "%-3s=%04x %016" PRIx64 " %08x %08x", name,
60886797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    sc->selector, sc->base, sc->limit, sc->flags);
60986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    } else
61086797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif
61186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    {
61286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        cpu_fprintf(f, "%-3s=%04x %08x %08x %08x", name, sc->selector,
61386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    (uint32_t)sc->base, sc->limit, sc->flags);
61486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
61586797937017f52bff088d02edf64fb931177a7eaJun Nakajima
61686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (!(env->hflags & HF_PE_MASK) || !(sc->flags & DESC_P_MASK))
61786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        goto done;
61886797937017f52bff088d02edf64fb931177a7eaJun Nakajima
61986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    cpu_fprintf(f, " DPL=%d ", (sc->flags & DESC_DPL_MASK) >> DESC_DPL_SHIFT);
62086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (sc->flags & DESC_S_MASK) {
62186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if (sc->flags & DESC_CS_MASK) {
62286797937017f52bff088d02edf64fb931177a7eaJun Nakajima            cpu_fprintf(f, (sc->flags & DESC_L_MASK) ? "CS64" :
62386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                           ((sc->flags & DESC_B_MASK) ? "CS32" : "CS16"));
62486797937017f52bff088d02edf64fb931177a7eaJun Nakajima            cpu_fprintf(f, " [%c%c", (sc->flags & DESC_C_MASK) ? 'C' : '-',
62586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                        (sc->flags & DESC_R_MASK) ? 'R' : '-');
62686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        } else {
62786797937017f52bff088d02edf64fb931177a7eaJun Nakajima            cpu_fprintf(f, (sc->flags & DESC_B_MASK) ? "DS  " : "DS16");
62886797937017f52bff088d02edf64fb931177a7eaJun Nakajima            cpu_fprintf(f, " [%c%c", (sc->flags & DESC_E_MASK) ? 'E' : '-',
62986797937017f52bff088d02edf64fb931177a7eaJun Nakajima                        (sc->flags & DESC_W_MASK) ? 'W' : '-');
63086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        }
63186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        cpu_fprintf(f, "%c]", (sc->flags & DESC_A_MASK) ? 'A' : '-');
63286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    } else {
63386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        static const char *sys_type_name[2][16] = {
63486797937017f52bff088d02edf64fb931177a7eaJun Nakajima            { /* 32 bit mode */
63586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                "Reserved", "TSS16-avl", "LDT", "TSS16-busy",
63686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                "CallGate16", "TaskGate", "IntGate16", "TrapGate16",
63786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                "Reserved", "TSS32-avl", "Reserved", "TSS32-busy",
63886797937017f52bff088d02edf64fb931177a7eaJun Nakajima                "CallGate32", "Reserved", "IntGate32", "TrapGate32"
63986797937017f52bff088d02edf64fb931177a7eaJun Nakajima            },
64086797937017f52bff088d02edf64fb931177a7eaJun Nakajima            { /* 64 bit mode */
64186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                "<hiword>", "Reserved", "LDT", "Reserved", "Reserved",
64286797937017f52bff088d02edf64fb931177a7eaJun Nakajima                "Reserved", "Reserved", "Reserved", "Reserved",
64386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                "TSS64-avl", "Reserved", "TSS64-busy", "CallGate64",
64486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                "Reserved", "IntGate64", "TrapGate64"
64586797937017f52bff088d02edf64fb931177a7eaJun Nakajima            }
64686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        };
64786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        cpu_fprintf(f, sys_type_name[(env->hflags & HF_LMA_MASK) ? 1 : 0]
64886797937017f52bff088d02edf64fb931177a7eaJun Nakajima                                    [(sc->flags & DESC_TYPE_MASK)
64986797937017f52bff088d02edf64fb931177a7eaJun Nakajima                                     >> DESC_TYPE_SHIFT]);
65086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
65186797937017f52bff088d02edf64fb931177a7eaJun Nakajimadone:
65286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    cpu_fprintf(f, "\n");
65386797937017f52bff088d02edf64fb931177a7eaJun Nakajima}
65486797937017f52bff088d02edf64fb931177a7eaJun Nakajima
65586797937017f52bff088d02edf64fb931177a7eaJun Nakajimavoid cpu_dump_state(CPUState *env, FILE *f,
65686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
65786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    int flags)
65886797937017f52bff088d02edf64fb931177a7eaJun Nakajima{
65986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    int eflags, i, nb;
66086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    char cc_op_name[32];
66186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
66286797937017f52bff088d02edf64fb931177a7eaJun Nakajima
66386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (kvm_enabled())
66486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        kvm_arch_get_registers(env);
66586797937017f52bff088d02edf64fb931177a7eaJun Nakajima
666a381ef07088ce479610129e37bfef42538f397daJun Nakajima#ifdef CONFIG_HAX
667a381ef07088ce479610129e37bfef42538f397daJun Nakajima    if (hax_enabled())
668a381ef07088ce479610129e37bfef42538f397daJun Nakajima        hax_arch_get_registers(env);
669a381ef07088ce479610129e37bfef42538f397daJun Nakajima#endif
670a381ef07088ce479610129e37bfef42538f397daJun Nakajima
67186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    eflags = env->eflags;
67286797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef TARGET_X86_64
67386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (env->hflags & HF_CS64_MASK) {
67486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        cpu_fprintf(f,
67586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    "RAX=%016" PRIx64 " RBX=%016" PRIx64 " RCX=%016" PRIx64 " RDX=%016" PRIx64 "\n"
67686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    "RSI=%016" PRIx64 " RDI=%016" PRIx64 " RBP=%016" PRIx64 " RSP=%016" PRIx64 "\n"
67786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    "R8 =%016" PRIx64 " R9 =%016" PRIx64 " R10=%016" PRIx64 " R11=%016" PRIx64 "\n"
67886797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    "R12=%016" PRIx64 " R13=%016" PRIx64 " R14=%016" PRIx64 " R15=%016" PRIx64 "\n"
67986797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    "RIP=%016" PRIx64 " RFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
68086797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    env->regs[R_EAX],
68186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    env->regs[R_EBX],
68286797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    env->regs[R_ECX],
68386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    env->regs[R_EDX],
68486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    env->regs[R_ESI],
68586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    env->regs[R_EDI],
68686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    env->regs[R_EBP],
68786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    env->regs[R_ESP],
68886797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    env->regs[8],
68986797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    env->regs[9],
69086797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    env->regs[10],
69186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    env->regs[11],
69286797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    env->regs[12],
69386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    env->regs[13],
69486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    env->regs[14],
69586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    env->regs[15],
69686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    env->eip, eflags,
69786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    eflags & DF_MASK ? 'D' : '-',
69886797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    eflags & CC_O ? 'O' : '-',
69986797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    eflags & CC_S ? 'S' : '-',
70086797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    eflags & CC_Z ? 'Z' : '-',
70186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    eflags & CC_A ? 'A' : '-',
70286797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    eflags & CC_P ? 'P' : '-',
70386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    eflags & CC_C ? 'C' : '-',
70486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    env->hflags & HF_CPL_MASK,
70586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
70686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    (int)(env->a20_mask >> 20) & 1,
70786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    (env->hflags >> HF_SMM_SHIFT) & 1,
70886797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    env->halted);
70986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    } else
71086797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif
71186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    {
71286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        cpu_fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
71386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
71486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
71586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    (uint32_t)env->regs[R_EAX],
71686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    (uint32_t)env->regs[R_EBX],
71786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    (uint32_t)env->regs[R_ECX],
71886797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    (uint32_t)env->regs[R_EDX],
71986797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    (uint32_t)env->regs[R_ESI],
72086797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    (uint32_t)env->regs[R_EDI],
72186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    (uint32_t)env->regs[R_EBP],
72286797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    (uint32_t)env->regs[R_ESP],
72386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    (uint32_t)env->eip, eflags,
72486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    eflags & DF_MASK ? 'D' : '-',
72586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    eflags & CC_O ? 'O' : '-',
72686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    eflags & CC_S ? 'S' : '-',
72786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    eflags & CC_Z ? 'Z' : '-',
72886797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    eflags & CC_A ? 'A' : '-',
72986797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    eflags & CC_P ? 'P' : '-',
73086797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    eflags & CC_C ? 'C' : '-',
73186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    env->hflags & HF_CPL_MASK,
73286797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
73386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    (int)(env->a20_mask >> 20) & 1,
73486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    (env->hflags >> HF_SMM_SHIFT) & 1,
73586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    env->halted);
73686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
73786797937017f52bff088d02edf64fb931177a7eaJun Nakajima
73886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    for(i = 0; i < 6; i++) {
73986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        cpu_x86_dump_seg_cache(env, f, cpu_fprintf, seg_name[i],
74086797937017f52bff088d02edf64fb931177a7eaJun Nakajima                               &env->segs[i]);
74186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
74286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "LDT", &env->ldt);
74386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "TR", &env->tr);
74486797937017f52bff088d02edf64fb931177a7eaJun Nakajima
74586797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef TARGET_X86_64
74686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (env->hflags & HF_LMA_MASK) {
74786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        cpu_fprintf(f, "GDT=     %016" PRIx64 " %08x\n",
74886797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    env->gdt.base, env->gdt.limit);
74986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        cpu_fprintf(f, "IDT=     %016" PRIx64 " %08x\n",
75086797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    env->idt.base, env->idt.limit);
75186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        cpu_fprintf(f, "CR0=%08x CR2=%016" PRIx64 " CR3=%016" PRIx64 " CR4=%08x\n",
75286797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    (uint32_t)env->cr[0],
75386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    env->cr[2],
75486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    env->cr[3],
75586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    (uint32_t)env->cr[4]);
75686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        for(i = 0; i < 4; i++)
75786797937017f52bff088d02edf64fb931177a7eaJun Nakajima            cpu_fprintf(f, "DR%d=%016" PRIx64 " ", i, env->dr[i]);
75886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        cpu_fprintf(f, "\nDR6=%016" PRIx64 " DR7=%016" PRIx64 "\n",
75986797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    env->dr[6], env->dr[7]);
76086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    } else
76186797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif
76286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    {
76386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        cpu_fprintf(f, "GDT=     %08x %08x\n",
76486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    (uint32_t)env->gdt.base, env->gdt.limit);
76586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        cpu_fprintf(f, "IDT=     %08x %08x\n",
76686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    (uint32_t)env->idt.base, env->idt.limit);
76786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        cpu_fprintf(f, "CR0=%08x CR2=%08x CR3=%08x CR4=%08x\n",
76886797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    (uint32_t)env->cr[0],
76986797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    (uint32_t)env->cr[2],
77086797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    (uint32_t)env->cr[3],
77186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    (uint32_t)env->cr[4]);
77286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        for(i = 0; i < 4; i++)
77386797937017f52bff088d02edf64fb931177a7eaJun Nakajima            cpu_fprintf(f, "DR%d=%08x ", i, env->dr[i]);
77486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        cpu_fprintf(f, "\nDR6=%08x DR7=%08x\n", env->dr[6], env->dr[7]);
77586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
77686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (flags & X86_DUMP_CCOP) {
77786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if ((unsigned)env->cc_op < CC_OP_NB)
77886797937017f52bff088d02edf64fb931177a7eaJun Nakajima            snprintf(cc_op_name, sizeof(cc_op_name), "%s", cc_op_str[env->cc_op]);
77986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        else
78086797937017f52bff088d02edf64fb931177a7eaJun Nakajima            snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);
78186797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef TARGET_X86_64
78286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if (env->hflags & HF_CS64_MASK) {
78386797937017f52bff088d02edf64fb931177a7eaJun Nakajima            cpu_fprintf(f, "CCS=%016" PRIx64 " CCD=%016" PRIx64 " CCO=%-8s\n",
78486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                        env->cc_src, env->cc_dst,
78586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                        cc_op_name);
78686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        } else
78786797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif
78886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        {
78986797937017f52bff088d02edf64fb931177a7eaJun Nakajima            cpu_fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n",
79086797937017f52bff088d02edf64fb931177a7eaJun Nakajima                        (uint32_t)env->cc_src, (uint32_t)env->cc_dst,
79186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                        cc_op_name);
79286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        }
79386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
79486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (flags & X86_DUMP_FPU) {
79586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        int fptag;
79686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        fptag = 0;
79786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        for(i = 0; i < 8; i++) {
79886797937017f52bff088d02edf64fb931177a7eaJun Nakajima            fptag |= ((!env->fptags[i]) << i);
79986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        }
80086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        cpu_fprintf(f, "FCW=%04x FSW=%04x [ST=%d] FTW=%02x MXCSR=%08x\n",
80186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    env->fpuc,
80286797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11,
80386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    env->fpstt,
80486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    fptag,
80586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    env->mxcsr);
80686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        for(i=0;i<8;i++) {
80786797937017f52bff088d02edf64fb931177a7eaJun Nakajima#if defined(USE_X86LDOUBLE)
80886797937017f52bff088d02edf64fb931177a7eaJun Nakajima            union {
80986797937017f52bff088d02edf64fb931177a7eaJun Nakajima                long double d;
81086797937017f52bff088d02edf64fb931177a7eaJun Nakajima                struct {
81186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    uint64_t lower;
81286797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    uint16_t upper;
81386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                } l;
81486797937017f52bff088d02edf64fb931177a7eaJun Nakajima            } tmp;
81586797937017f52bff088d02edf64fb931177a7eaJun Nakajima            tmp.d = env->fpregs[i].d;
81686797937017f52bff088d02edf64fb931177a7eaJun Nakajima            cpu_fprintf(f, "FPR%d=%016" PRIx64 " %04x",
81786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                        i, tmp.l.lower, tmp.l.upper);
81886797937017f52bff088d02edf64fb931177a7eaJun Nakajima#else
81986797937017f52bff088d02edf64fb931177a7eaJun Nakajima            cpu_fprintf(f, "FPR%d=%016" PRIx64,
82086797937017f52bff088d02edf64fb931177a7eaJun Nakajima                        i, env->fpregs[i].mmx.q);
82186797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif
82286797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if ((i & 1) == 1)
82386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                cpu_fprintf(f, "\n");
82486797937017f52bff088d02edf64fb931177a7eaJun Nakajima            else
82586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                cpu_fprintf(f, " ");
82686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        }
82786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if (env->hflags & HF_CS64_MASK)
82886797937017f52bff088d02edf64fb931177a7eaJun Nakajima            nb = 16;
82986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        else
83086797937017f52bff088d02edf64fb931177a7eaJun Nakajima            nb = 8;
83186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        for(i=0;i<nb;i++) {
83286797937017f52bff088d02edf64fb931177a7eaJun Nakajima            cpu_fprintf(f, "XMM%02d=%08x%08x%08x%08x",
83386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                        i,
83486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                        env->xmm_regs[i].XMM_L(3),
83586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                        env->xmm_regs[i].XMM_L(2),
83686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                        env->xmm_regs[i].XMM_L(1),
83786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                        env->xmm_regs[i].XMM_L(0));
83886797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if ((i & 1) == 1)
83986797937017f52bff088d02edf64fb931177a7eaJun Nakajima                cpu_fprintf(f, "\n");
84086797937017f52bff088d02edf64fb931177a7eaJun Nakajima            else
84186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                cpu_fprintf(f, " ");
84286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        }
84386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
84486797937017f52bff088d02edf64fb931177a7eaJun Nakajima}
84586797937017f52bff088d02edf64fb931177a7eaJun Nakajima
84686797937017f52bff088d02edf64fb931177a7eaJun Nakajima/***********************************************************/
84786797937017f52bff088d02edf64fb931177a7eaJun Nakajima/* x86 mmu */
84886797937017f52bff088d02edf64fb931177a7eaJun Nakajima/* XXX: add PGE support */
84986797937017f52bff088d02edf64fb931177a7eaJun Nakajima
85086797937017f52bff088d02edf64fb931177a7eaJun Nakajimavoid cpu_x86_set_a20(CPUX86State *env, int a20_state)
85186797937017f52bff088d02edf64fb931177a7eaJun Nakajima{
85286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    a20_state = (a20_state != 0);
85386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (a20_state != ((env->a20_mask >> 20) & 1)) {
85486797937017f52bff088d02edf64fb931177a7eaJun Nakajima#if defined(DEBUG_MMU)
85586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        printf("A20 update: a20=%d\n", a20_state);
85686797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif
85786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* if the cpu is currently executing code, we must unlink it and
85886797937017f52bff088d02edf64fb931177a7eaJun Nakajima           all the potentially executing TB */
85986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        cpu_interrupt(env, CPU_INTERRUPT_EXITTB);
86086797937017f52bff088d02edf64fb931177a7eaJun Nakajima
86186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* when a20 is changed, all the MMU mappings are invalid, so
86286797937017f52bff088d02edf64fb931177a7eaJun Nakajima           we must flush everything */
86386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        tlb_flush(env, 1);
86486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        env->a20_mask = (~0x100000) | (a20_state << 20);
86586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
86686797937017f52bff088d02edf64fb931177a7eaJun Nakajima}
86786797937017f52bff088d02edf64fb931177a7eaJun Nakajima
86886797937017f52bff088d02edf64fb931177a7eaJun Nakajimavoid cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
86986797937017f52bff088d02edf64fb931177a7eaJun Nakajima{
87086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    int pe_state;
87186797937017f52bff088d02edf64fb931177a7eaJun Nakajima
87286797937017f52bff088d02edf64fb931177a7eaJun Nakajima#if defined(DEBUG_MMU)
87386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    printf("CR0 update: CR0=0x%08x\n", new_cr0);
87486797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif
87586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if ((new_cr0 & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK)) !=
87686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        (env->cr[0] & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK))) {
87786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        tlb_flush(env, 1);
87886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
87986797937017f52bff088d02edf64fb931177a7eaJun Nakajima
88086797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef TARGET_X86_64
88186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (!(env->cr[0] & CR0_PG_MASK) && (new_cr0 & CR0_PG_MASK) &&
88286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        (env->efer & MSR_EFER_LME)) {
88386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* enter in long mode */
88486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* XXX: generate an exception */
88586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if (!(env->cr[4] & CR4_PAE_MASK))
88686797937017f52bff088d02edf64fb931177a7eaJun Nakajima            return;
88786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        env->efer |= MSR_EFER_LMA;
88886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        env->hflags |= HF_LMA_MASK;
88986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    } else if ((env->cr[0] & CR0_PG_MASK) && !(new_cr0 & CR0_PG_MASK) &&
89086797937017f52bff088d02edf64fb931177a7eaJun Nakajima               (env->efer & MSR_EFER_LMA)) {
89186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* exit long mode */
89286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        env->efer &= ~MSR_EFER_LMA;
89386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        env->hflags &= ~(HF_LMA_MASK | HF_CS64_MASK);
89486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        env->eip &= 0xffffffff;
89586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
89686797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif
89786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->cr[0] = new_cr0 | CR0_ET_MASK;
89886797937017f52bff088d02edf64fb931177a7eaJun Nakajima
89986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    /* update PE flag in hidden flags */
90086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    pe_state = (env->cr[0] & CR0_PE_MASK);
90186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->hflags = (env->hflags & ~HF_PE_MASK) | (pe_state << HF_PE_SHIFT);
90286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    /* ensure that ADDSEG is always set in real mode */
90386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->hflags |= ((pe_state ^ 1) << HF_ADDSEG_SHIFT);
90486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    /* update FPU flags */
90586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->hflags = (env->hflags & ~(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)) |
90686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        ((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK));
90786797937017f52bff088d02edf64fb931177a7eaJun Nakajima}
90886797937017f52bff088d02edf64fb931177a7eaJun Nakajima
90986797937017f52bff088d02edf64fb931177a7eaJun Nakajima/* XXX: in legacy PAE mode, generate a GPF if reserved bits are set in
91086797937017f52bff088d02edf64fb931177a7eaJun Nakajima   the PDPT */
91186797937017f52bff088d02edf64fb931177a7eaJun Nakajimavoid cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3)
91286797937017f52bff088d02edf64fb931177a7eaJun Nakajima{
91386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->cr[3] = new_cr3;
91486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (env->cr[0] & CR0_PG_MASK) {
91586797937017f52bff088d02edf64fb931177a7eaJun Nakajima#if defined(DEBUG_MMU)
91686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        printf("CR3 update: CR3=" TARGET_FMT_lx "\n", new_cr3);
91786797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif
91886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        tlb_flush(env, 0);
91986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
92086797937017f52bff088d02edf64fb931177a7eaJun Nakajima}
92186797937017f52bff088d02edf64fb931177a7eaJun Nakajima
92286797937017f52bff088d02edf64fb931177a7eaJun Nakajimavoid cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
92386797937017f52bff088d02edf64fb931177a7eaJun Nakajima{
92486797937017f52bff088d02edf64fb931177a7eaJun Nakajima#if defined(DEBUG_MMU)
92586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    printf("CR4 update: CR4=%08x\n", (uint32_t)env->cr[4]);
92686797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif
92786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if ((new_cr4 & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK)) !=
92886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        (env->cr[4] & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK))) {
92986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        tlb_flush(env, 1);
93086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
93186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    /* SSE handling */
93286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (!(env->cpuid_features & CPUID_SSE))
93386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        new_cr4 &= ~CR4_OSFXSR_MASK;
93486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (new_cr4 & CR4_OSFXSR_MASK)
93586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        env->hflags |= HF_OSFXSR_MASK;
93686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    else
93786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        env->hflags &= ~HF_OSFXSR_MASK;
93886797937017f52bff088d02edf64fb931177a7eaJun Nakajima
93986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->cr[4] = new_cr4;
94086797937017f52bff088d02edf64fb931177a7eaJun Nakajima}
94186797937017f52bff088d02edf64fb931177a7eaJun Nakajima
94286797937017f52bff088d02edf64fb931177a7eaJun Nakajima#if defined(CONFIG_USER_ONLY)
94386797937017f52bff088d02edf64fb931177a7eaJun Nakajima
94486797937017f52bff088d02edf64fb931177a7eaJun Nakajimaint cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
94586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                             int is_write, int mmu_idx, int is_softmmu)
94686797937017f52bff088d02edf64fb931177a7eaJun Nakajima{
94786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    /* user mode only emulation */
94886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    is_write &= 1;
94986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->cr[2] = addr;
95086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->error_code = (is_write << PG_ERROR_W_BIT);
95186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->error_code |= PG_ERROR_U_MASK;
95286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->exception_index = EXCP0E_PAGE;
95386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    return 1;
95486797937017f52bff088d02edf64fb931177a7eaJun Nakajima}
95586797937017f52bff088d02edf64fb931177a7eaJun Nakajima
95686797937017f52bff088d02edf64fb931177a7eaJun Nakajimatarget_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
95786797937017f52bff088d02edf64fb931177a7eaJun Nakajima{
95886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    return addr;
95986797937017f52bff088d02edf64fb931177a7eaJun Nakajima}
96086797937017f52bff088d02edf64fb931177a7eaJun Nakajima
96186797937017f52bff088d02edf64fb931177a7eaJun Nakajima#else
96286797937017f52bff088d02edf64fb931177a7eaJun Nakajima
96386797937017f52bff088d02edf64fb931177a7eaJun Nakajima/* XXX: This value should match the one returned by CPUID
96486797937017f52bff088d02edf64fb931177a7eaJun Nakajima * and in exec.c */
96586797937017f52bff088d02edf64fb931177a7eaJun Nakajima#if defined(CONFIG_KQEMU)
96686797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define PHYS_ADDR_MASK 0xfffff000LL
96786797937017f52bff088d02edf64fb931177a7eaJun Nakajima#else
96886797937017f52bff088d02edf64fb931177a7eaJun Nakajima# if defined(TARGET_X86_64)
96986797937017f52bff088d02edf64fb931177a7eaJun Nakajima# define PHYS_ADDR_MASK 0xfffffff000LL
97086797937017f52bff088d02edf64fb931177a7eaJun Nakajima# else
97186797937017f52bff088d02edf64fb931177a7eaJun Nakajima# define PHYS_ADDR_MASK 0xffffff000LL
97286797937017f52bff088d02edf64fb931177a7eaJun Nakajima# endif
97386797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif
97486797937017f52bff088d02edf64fb931177a7eaJun Nakajima
97586797937017f52bff088d02edf64fb931177a7eaJun Nakajima/* return value:
97686797937017f52bff088d02edf64fb931177a7eaJun Nakajima   -1 = cannot handle fault
97786797937017f52bff088d02edf64fb931177a7eaJun Nakajima   0  = nothing more to do
97886797937017f52bff088d02edf64fb931177a7eaJun Nakajima   1  = generate PF fault
97986797937017f52bff088d02edf64fb931177a7eaJun Nakajima   2  = soft MMU activation required for this block
98086797937017f52bff088d02edf64fb931177a7eaJun Nakajima*/
98186797937017f52bff088d02edf64fb931177a7eaJun Nakajimaint cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
98286797937017f52bff088d02edf64fb931177a7eaJun Nakajima                             int is_write1, int mmu_idx, int is_softmmu)
98386797937017f52bff088d02edf64fb931177a7eaJun Nakajima{
98486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    uint64_t ptep, pte;
98586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    target_ulong pde_addr, pte_addr;
98686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    int error_code, is_dirty, prot, page_size, ret, is_write, is_user;
98786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    target_phys_addr_t paddr;
98886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    uint32_t page_offset;
98986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    target_ulong vaddr, virt_addr;
99086797937017f52bff088d02edf64fb931177a7eaJun Nakajima
99186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    is_user = mmu_idx == MMU_USER_IDX;
99286797937017f52bff088d02edf64fb931177a7eaJun Nakajima#if defined(DEBUG_MMU)
99386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
99486797937017f52bff088d02edf64fb931177a7eaJun Nakajima           addr, is_write1, is_user, env->eip);
99586797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif
99686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    is_write = is_write1 & 1;
99786797937017f52bff088d02edf64fb931177a7eaJun Nakajima
99886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (!(env->cr[0] & CR0_PG_MASK)) {
99986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        pte = addr;
100086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        virt_addr = addr & TARGET_PAGE_MASK;
100186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
100286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        page_size = 4096;
100386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        goto do_mapping;
100486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
100586797937017f52bff088d02edf64fb931177a7eaJun Nakajima
100686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (env->cr[4] & CR4_PAE_MASK) {
100786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        uint64_t pde, pdpe;
100886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        target_ulong pdpe_addr;
100986797937017f52bff088d02edf64fb931177a7eaJun Nakajima
101086797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef TARGET_X86_64
101186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if (env->hflags & HF_LMA_MASK) {
101286797937017f52bff088d02edf64fb931177a7eaJun Nakajima            uint64_t pml4e_addr, pml4e;
101386797937017f52bff088d02edf64fb931177a7eaJun Nakajima            int32_t sext;
101486797937017f52bff088d02edf64fb931177a7eaJun Nakajima
101586797937017f52bff088d02edf64fb931177a7eaJun Nakajima            /* test virtual address sign extension */
101686797937017f52bff088d02edf64fb931177a7eaJun Nakajima            sext = (int64_t)addr >> 47;
101786797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (sext != 0 && sext != -1) {
101886797937017f52bff088d02edf64fb931177a7eaJun Nakajima                env->error_code = 0;
101986797937017f52bff088d02edf64fb931177a7eaJun Nakajima                env->exception_index = EXCP0D_GPF;
102086797937017f52bff088d02edf64fb931177a7eaJun Nakajima                return 1;
102186797937017f52bff088d02edf64fb931177a7eaJun Nakajima            }
102286797937017f52bff088d02edf64fb931177a7eaJun Nakajima
102386797937017f52bff088d02edf64fb931177a7eaJun Nakajima            pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
102486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                env->a20_mask;
102586797937017f52bff088d02edf64fb931177a7eaJun Nakajima            pml4e = ldq_phys(pml4e_addr);
102686797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (!(pml4e & PG_PRESENT_MASK)) {
102786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                error_code = 0;
102886797937017f52bff088d02edf64fb931177a7eaJun Nakajima                goto do_fault;
102986797937017f52bff088d02edf64fb931177a7eaJun Nakajima            }
103086797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (!(env->efer & MSR_EFER_NXE) && (pml4e & PG_NX_MASK)) {
103186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                error_code = PG_ERROR_RSVD_MASK;
103286797937017f52bff088d02edf64fb931177a7eaJun Nakajima                goto do_fault;
103386797937017f52bff088d02edf64fb931177a7eaJun Nakajima            }
103486797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (!(pml4e & PG_ACCESSED_MASK)) {
103586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                pml4e |= PG_ACCESSED_MASK;
103686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                stl_phys_notdirty(pml4e_addr, pml4e);
103786797937017f52bff088d02edf64fb931177a7eaJun Nakajima            }
103886797937017f52bff088d02edf64fb931177a7eaJun Nakajima            ptep = pml4e ^ PG_NX_MASK;
103986797937017f52bff088d02edf64fb931177a7eaJun Nakajima            pdpe_addr = ((pml4e & PHYS_ADDR_MASK) + (((addr >> 30) & 0x1ff) << 3)) &
104086797937017f52bff088d02edf64fb931177a7eaJun Nakajima                env->a20_mask;
104186797937017f52bff088d02edf64fb931177a7eaJun Nakajima            pdpe = ldq_phys(pdpe_addr);
104286797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (!(pdpe & PG_PRESENT_MASK)) {
104386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                error_code = 0;
104486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                goto do_fault;
104586797937017f52bff088d02edf64fb931177a7eaJun Nakajima            }
104686797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (!(env->efer & MSR_EFER_NXE) && (pdpe & PG_NX_MASK)) {
104786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                error_code = PG_ERROR_RSVD_MASK;
104886797937017f52bff088d02edf64fb931177a7eaJun Nakajima                goto do_fault;
104986797937017f52bff088d02edf64fb931177a7eaJun Nakajima            }
105086797937017f52bff088d02edf64fb931177a7eaJun Nakajima            ptep &= pdpe ^ PG_NX_MASK;
105186797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (!(pdpe & PG_ACCESSED_MASK)) {
105286797937017f52bff088d02edf64fb931177a7eaJun Nakajima                pdpe |= PG_ACCESSED_MASK;
105386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                stl_phys_notdirty(pdpe_addr, pdpe);
105486797937017f52bff088d02edf64fb931177a7eaJun Nakajima            }
105586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        } else
105686797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif
105786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        {
105886797937017f52bff088d02edf64fb931177a7eaJun Nakajima            /* XXX: load them when cr3 is loaded ? */
105986797937017f52bff088d02edf64fb931177a7eaJun Nakajima            pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
106086797937017f52bff088d02edf64fb931177a7eaJun Nakajima                env->a20_mask;
106186797937017f52bff088d02edf64fb931177a7eaJun Nakajima            pdpe = ldq_phys(pdpe_addr);
106286797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (!(pdpe & PG_PRESENT_MASK)) {
106386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                error_code = 0;
106486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                goto do_fault;
106586797937017f52bff088d02edf64fb931177a7eaJun Nakajima            }
106686797937017f52bff088d02edf64fb931177a7eaJun Nakajima            ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;
106786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        }
106886797937017f52bff088d02edf64fb931177a7eaJun Nakajima
106986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        pde_addr = ((pdpe & PHYS_ADDR_MASK) + (((addr >> 21) & 0x1ff) << 3)) &
107086797937017f52bff088d02edf64fb931177a7eaJun Nakajima            env->a20_mask;
107186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        pde = ldq_phys(pde_addr);
107286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if (!(pde & PG_PRESENT_MASK)) {
107386797937017f52bff088d02edf64fb931177a7eaJun Nakajima            error_code = 0;
107486797937017f52bff088d02edf64fb931177a7eaJun Nakajima            goto do_fault;
107586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        }
107686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if (!(env->efer & MSR_EFER_NXE) && (pde & PG_NX_MASK)) {
107786797937017f52bff088d02edf64fb931177a7eaJun Nakajima            error_code = PG_ERROR_RSVD_MASK;
107886797937017f52bff088d02edf64fb931177a7eaJun Nakajima            goto do_fault;
107986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        }
108086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        ptep &= pde ^ PG_NX_MASK;
108186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if (pde & PG_PSE_MASK) {
108286797937017f52bff088d02edf64fb931177a7eaJun Nakajima            /* 2 MB page */
108386797937017f52bff088d02edf64fb931177a7eaJun Nakajima            page_size = 2048 * 1024;
108486797937017f52bff088d02edf64fb931177a7eaJun Nakajima            ptep ^= PG_NX_MASK;
108586797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if ((ptep & PG_NX_MASK) && is_write1 == 2)
108686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                goto do_fault_protect;
108786797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (is_user) {
108886797937017f52bff088d02edf64fb931177a7eaJun Nakajima                if (!(ptep & PG_USER_MASK))
108986797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    goto do_fault_protect;
109086797937017f52bff088d02edf64fb931177a7eaJun Nakajima                if (is_write && !(ptep & PG_RW_MASK))
109186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    goto do_fault_protect;
109286797937017f52bff088d02edf64fb931177a7eaJun Nakajima            } else {
109386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                if ((env->cr[0] & CR0_WP_MASK) &&
109486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    is_write && !(ptep & PG_RW_MASK))
109586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    goto do_fault_protect;
109686797937017f52bff088d02edf64fb931177a7eaJun Nakajima            }
109786797937017f52bff088d02edf64fb931177a7eaJun Nakajima            is_dirty = is_write && !(pde & PG_DIRTY_MASK);
109886797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
109986797937017f52bff088d02edf64fb931177a7eaJun Nakajima                pde |= PG_ACCESSED_MASK;
110086797937017f52bff088d02edf64fb931177a7eaJun Nakajima                if (is_dirty)
110186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    pde |= PG_DIRTY_MASK;
110286797937017f52bff088d02edf64fb931177a7eaJun Nakajima                stl_phys_notdirty(pde_addr, pde);
110386797937017f52bff088d02edf64fb931177a7eaJun Nakajima            }
110486797937017f52bff088d02edf64fb931177a7eaJun Nakajima            /* align to page_size */
110586797937017f52bff088d02edf64fb931177a7eaJun Nakajima            pte = pde & ((PHYS_ADDR_MASK & ~(page_size - 1)) | 0xfff);
110686797937017f52bff088d02edf64fb931177a7eaJun Nakajima            virt_addr = addr & ~(page_size - 1);
110786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        } else {
110886797937017f52bff088d02edf64fb931177a7eaJun Nakajima            /* 4 KB page */
110986797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (!(pde & PG_ACCESSED_MASK)) {
111086797937017f52bff088d02edf64fb931177a7eaJun Nakajima                pde |= PG_ACCESSED_MASK;
111186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                stl_phys_notdirty(pde_addr, pde);
111286797937017f52bff088d02edf64fb931177a7eaJun Nakajima            }
111386797937017f52bff088d02edf64fb931177a7eaJun Nakajima            pte_addr = ((pde & PHYS_ADDR_MASK) + (((addr >> 12) & 0x1ff) << 3)) &
111486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                env->a20_mask;
111586797937017f52bff088d02edf64fb931177a7eaJun Nakajima            pte = ldq_phys(pte_addr);
111686797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (!(pte & PG_PRESENT_MASK)) {
111786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                error_code = 0;
111886797937017f52bff088d02edf64fb931177a7eaJun Nakajima                goto do_fault;
111986797937017f52bff088d02edf64fb931177a7eaJun Nakajima            }
112086797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (!(env->efer & MSR_EFER_NXE) && (pte & PG_NX_MASK)) {
112186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                error_code = PG_ERROR_RSVD_MASK;
112286797937017f52bff088d02edf64fb931177a7eaJun Nakajima                goto do_fault;
112386797937017f52bff088d02edf64fb931177a7eaJun Nakajima            }
112486797937017f52bff088d02edf64fb931177a7eaJun Nakajima            /* combine pde and pte nx, user and rw protections */
112586797937017f52bff088d02edf64fb931177a7eaJun Nakajima            ptep &= pte ^ PG_NX_MASK;
112686797937017f52bff088d02edf64fb931177a7eaJun Nakajima            ptep ^= PG_NX_MASK;
112786797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if ((ptep & PG_NX_MASK) && is_write1 == 2)
112886797937017f52bff088d02edf64fb931177a7eaJun Nakajima                goto do_fault_protect;
112986797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (is_user) {
113086797937017f52bff088d02edf64fb931177a7eaJun Nakajima                if (!(ptep & PG_USER_MASK))
113186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    goto do_fault_protect;
113286797937017f52bff088d02edf64fb931177a7eaJun Nakajima                if (is_write && !(ptep & PG_RW_MASK))
113386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    goto do_fault_protect;
113486797937017f52bff088d02edf64fb931177a7eaJun Nakajima            } else {
113586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                if ((env->cr[0] & CR0_WP_MASK) &&
113686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    is_write && !(ptep & PG_RW_MASK))
113786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    goto do_fault_protect;
113886797937017f52bff088d02edf64fb931177a7eaJun Nakajima            }
113986797937017f52bff088d02edf64fb931177a7eaJun Nakajima            is_dirty = is_write && !(pte & PG_DIRTY_MASK);
114086797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
114186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                pte |= PG_ACCESSED_MASK;
114286797937017f52bff088d02edf64fb931177a7eaJun Nakajima                if (is_dirty)
114386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    pte |= PG_DIRTY_MASK;
114486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                stl_phys_notdirty(pte_addr, pte);
114586797937017f52bff088d02edf64fb931177a7eaJun Nakajima            }
114686797937017f52bff088d02edf64fb931177a7eaJun Nakajima            page_size = 4096;
114786797937017f52bff088d02edf64fb931177a7eaJun Nakajima            virt_addr = addr & ~0xfff;
114886797937017f52bff088d02edf64fb931177a7eaJun Nakajima            pte = pte & (PHYS_ADDR_MASK | 0xfff);
114986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        }
115086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    } else {
115186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        uint32_t pde;
115286797937017f52bff088d02edf64fb931177a7eaJun Nakajima
115386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* page directory entry */
115486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) &
115586797937017f52bff088d02edf64fb931177a7eaJun Nakajima            env->a20_mask;
115686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        pde = ldl_phys(pde_addr);
115786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if (!(pde & PG_PRESENT_MASK)) {
115886797937017f52bff088d02edf64fb931177a7eaJun Nakajima            error_code = 0;
115986797937017f52bff088d02edf64fb931177a7eaJun Nakajima            goto do_fault;
116086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        }
116186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* if PSE bit is set, then we use a 4MB page */
116286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
116386797937017f52bff088d02edf64fb931177a7eaJun Nakajima            page_size = 4096 * 1024;
116486797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (is_user) {
116586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                if (!(pde & PG_USER_MASK))
116686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    goto do_fault_protect;
116786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                if (is_write && !(pde & PG_RW_MASK))
116886797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    goto do_fault_protect;
116986797937017f52bff088d02edf64fb931177a7eaJun Nakajima            } else {
117086797937017f52bff088d02edf64fb931177a7eaJun Nakajima                if ((env->cr[0] & CR0_WP_MASK) &&
117186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    is_write && !(pde & PG_RW_MASK))
117286797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    goto do_fault_protect;
117386797937017f52bff088d02edf64fb931177a7eaJun Nakajima            }
117486797937017f52bff088d02edf64fb931177a7eaJun Nakajima            is_dirty = is_write && !(pde & PG_DIRTY_MASK);
117586797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
117686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                pde |= PG_ACCESSED_MASK;
117786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                if (is_dirty)
117886797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    pde |= PG_DIRTY_MASK;
117986797937017f52bff088d02edf64fb931177a7eaJun Nakajima                stl_phys_notdirty(pde_addr, pde);
118086797937017f52bff088d02edf64fb931177a7eaJun Nakajima            }
118186797937017f52bff088d02edf64fb931177a7eaJun Nakajima
118286797937017f52bff088d02edf64fb931177a7eaJun Nakajima            pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
118386797937017f52bff088d02edf64fb931177a7eaJun Nakajima            ptep = pte;
118486797937017f52bff088d02edf64fb931177a7eaJun Nakajima            virt_addr = addr & ~(page_size - 1);
118586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        } else {
118686797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (!(pde & PG_ACCESSED_MASK)) {
118786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                pde |= PG_ACCESSED_MASK;
118886797937017f52bff088d02edf64fb931177a7eaJun Nakajima                stl_phys_notdirty(pde_addr, pde);
118986797937017f52bff088d02edf64fb931177a7eaJun Nakajima            }
119086797937017f52bff088d02edf64fb931177a7eaJun Nakajima
119186797937017f52bff088d02edf64fb931177a7eaJun Nakajima            /* page directory entry */
119286797937017f52bff088d02edf64fb931177a7eaJun Nakajima            pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) &
119386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                env->a20_mask;
119486797937017f52bff088d02edf64fb931177a7eaJun Nakajima            pte = ldl_phys(pte_addr);
119586797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (!(pte & PG_PRESENT_MASK)) {
119686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                error_code = 0;
119786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                goto do_fault;
119886797937017f52bff088d02edf64fb931177a7eaJun Nakajima            }
119986797937017f52bff088d02edf64fb931177a7eaJun Nakajima            /* combine pde and pte user and rw protections */
120086797937017f52bff088d02edf64fb931177a7eaJun Nakajima            ptep = pte & pde;
120186797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (is_user) {
120286797937017f52bff088d02edf64fb931177a7eaJun Nakajima                if (!(ptep & PG_USER_MASK))
120386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    goto do_fault_protect;
120486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                if (is_write && !(ptep & PG_RW_MASK))
120586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    goto do_fault_protect;
120686797937017f52bff088d02edf64fb931177a7eaJun Nakajima            } else {
120786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                if ((env->cr[0] & CR0_WP_MASK) &&
120886797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    is_write && !(ptep & PG_RW_MASK))
120986797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    goto do_fault_protect;
121086797937017f52bff088d02edf64fb931177a7eaJun Nakajima            }
121186797937017f52bff088d02edf64fb931177a7eaJun Nakajima            is_dirty = is_write && !(pte & PG_DIRTY_MASK);
121286797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
121386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                pte |= PG_ACCESSED_MASK;
121486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                if (is_dirty)
121586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    pte |= PG_DIRTY_MASK;
121686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                stl_phys_notdirty(pte_addr, pte);
121786797937017f52bff088d02edf64fb931177a7eaJun Nakajima            }
121886797937017f52bff088d02edf64fb931177a7eaJun Nakajima            page_size = 4096;
121986797937017f52bff088d02edf64fb931177a7eaJun Nakajima            virt_addr = addr & ~0xfff;
122086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        }
122186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
122286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    /* the page can be put in the TLB */
122386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    prot = PAGE_READ;
122486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (!(ptep & PG_NX_MASK))
122586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        prot |= PAGE_EXEC;
122686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (pte & PG_DIRTY_MASK) {
122786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* only set write access if already dirty... otherwise wait
122886797937017f52bff088d02edf64fb931177a7eaJun Nakajima           for dirty access */
122986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if (is_user) {
123086797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (ptep & PG_RW_MASK)
123186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                prot |= PAGE_WRITE;
123286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        } else {
123386797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (!(env->cr[0] & CR0_WP_MASK) ||
123486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                (ptep & PG_RW_MASK))
123586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                prot |= PAGE_WRITE;
123686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        }
123786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
123886797937017f52bff088d02edf64fb931177a7eaJun Nakajima do_mapping:
123986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    pte = pte & env->a20_mask;
124086797937017f52bff088d02edf64fb931177a7eaJun Nakajima
124186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    /* Even if 4MB pages, we map only one 4KB page in the cache to
124286797937017f52bff088d02edf64fb931177a7eaJun Nakajima       avoid filling it too fast */
124386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
124486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    paddr = (pte & TARGET_PAGE_MASK) + page_offset;
124586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    vaddr = virt_addr + page_offset;
124686797937017f52bff088d02edf64fb931177a7eaJun Nakajima
124786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
124886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    return ret;
124986797937017f52bff088d02edf64fb931177a7eaJun Nakajima do_fault_protect:
125086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    error_code = PG_ERROR_P_MASK;
125186797937017f52bff088d02edf64fb931177a7eaJun Nakajima do_fault:
125286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    error_code |= (is_write << PG_ERROR_W_BIT);
125386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (is_user)
125486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        error_code |= PG_ERROR_U_MASK;
125586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (is_write1 == 2 &&
125686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        (env->efer & MSR_EFER_NXE) &&
125786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        (env->cr[4] & CR4_PAE_MASK))
125886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        error_code |= PG_ERROR_I_D_MASK;
125986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (env->intercept_exceptions & (1 << EXCP0E_PAGE)) {
126086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* cr2 is not modified in case of exceptions */
126186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2),
126286797937017f52bff088d02edf64fb931177a7eaJun Nakajima                 addr);
126386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    } else {
126486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        env->cr[2] = addr;
126586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
126686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->error_code = error_code;
126786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->exception_index = EXCP0E_PAGE;
126886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    return 1;
126986797937017f52bff088d02edf64fb931177a7eaJun Nakajima}
127086797937017f52bff088d02edf64fb931177a7eaJun Nakajima
127186797937017f52bff088d02edf64fb931177a7eaJun Nakajimatarget_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
127286797937017f52bff088d02edf64fb931177a7eaJun Nakajima{
127386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    target_ulong pde_addr, pte_addr;
127486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    uint64_t pte;
127586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    target_phys_addr_t paddr;
127686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    uint32_t page_offset;
127786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    int page_size;
127886797937017f52bff088d02edf64fb931177a7eaJun Nakajima
127986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (env->cr[4] & CR4_PAE_MASK) {
128086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        target_ulong pdpe_addr;
128186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        uint64_t pde, pdpe;
128286797937017f52bff088d02edf64fb931177a7eaJun Nakajima
128386797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef TARGET_X86_64
128486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if (env->hflags & HF_LMA_MASK) {
128586797937017f52bff088d02edf64fb931177a7eaJun Nakajima            uint64_t pml4e_addr, pml4e;
128686797937017f52bff088d02edf64fb931177a7eaJun Nakajima            int32_t sext;
128786797937017f52bff088d02edf64fb931177a7eaJun Nakajima
128886797937017f52bff088d02edf64fb931177a7eaJun Nakajima            /* test virtual address sign extension */
128986797937017f52bff088d02edf64fb931177a7eaJun Nakajima            sext = (int64_t)addr >> 47;
129086797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (sext != 0 && sext != -1)
129186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                return -1;
129286797937017f52bff088d02edf64fb931177a7eaJun Nakajima
129386797937017f52bff088d02edf64fb931177a7eaJun Nakajima            pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
129486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                env->a20_mask;
129586797937017f52bff088d02edf64fb931177a7eaJun Nakajima            pml4e = ldq_phys(pml4e_addr);
129686797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (!(pml4e & PG_PRESENT_MASK))
129786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                return -1;
129886797937017f52bff088d02edf64fb931177a7eaJun Nakajima
129986797937017f52bff088d02edf64fb931177a7eaJun Nakajima            pdpe_addr = ((pml4e & ~0xfff) + (((addr >> 30) & 0x1ff) << 3)) &
130086797937017f52bff088d02edf64fb931177a7eaJun Nakajima                env->a20_mask;
130186797937017f52bff088d02edf64fb931177a7eaJun Nakajima            pdpe = ldq_phys(pdpe_addr);
130286797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (!(pdpe & PG_PRESENT_MASK))
130386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                return -1;
130486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        } else
130586797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif
130686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        {
130786797937017f52bff088d02edf64fb931177a7eaJun Nakajima            pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
130886797937017f52bff088d02edf64fb931177a7eaJun Nakajima                env->a20_mask;
130986797937017f52bff088d02edf64fb931177a7eaJun Nakajima            pdpe = ldq_phys(pdpe_addr);
131086797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (!(pdpe & PG_PRESENT_MASK))
131186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                return -1;
131286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        }
131386797937017f52bff088d02edf64fb931177a7eaJun Nakajima
131486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        pde_addr = ((pdpe & ~0xfff) + (((addr >> 21) & 0x1ff) << 3)) &
131586797937017f52bff088d02edf64fb931177a7eaJun Nakajima            env->a20_mask;
131686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        pde = ldq_phys(pde_addr);
131786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if (!(pde & PG_PRESENT_MASK)) {
131886797937017f52bff088d02edf64fb931177a7eaJun Nakajima            return -1;
131986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        }
132086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if (pde & PG_PSE_MASK) {
132186797937017f52bff088d02edf64fb931177a7eaJun Nakajima            /* 2 MB page */
132286797937017f52bff088d02edf64fb931177a7eaJun Nakajima            page_size = 2048 * 1024;
132386797937017f52bff088d02edf64fb931177a7eaJun Nakajima            pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
132486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        } else {
132586797937017f52bff088d02edf64fb931177a7eaJun Nakajima            /* 4 KB page */
132686797937017f52bff088d02edf64fb931177a7eaJun Nakajima            pte_addr = ((pde & ~0xfff) + (((addr >> 12) & 0x1ff) << 3)) &
132786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                env->a20_mask;
132886797937017f52bff088d02edf64fb931177a7eaJun Nakajima            page_size = 4096;
132986797937017f52bff088d02edf64fb931177a7eaJun Nakajima            pte = ldq_phys(pte_addr);
133086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        }
133186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if (!(pte & PG_PRESENT_MASK))
133286797937017f52bff088d02edf64fb931177a7eaJun Nakajima            return -1;
133386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    } else {
133486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        uint32_t pde;
133586797937017f52bff088d02edf64fb931177a7eaJun Nakajima
133686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if (!(env->cr[0] & CR0_PG_MASK)) {
133786797937017f52bff088d02edf64fb931177a7eaJun Nakajima            pte = addr;
133886797937017f52bff088d02edf64fb931177a7eaJun Nakajima            page_size = 4096;
133986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        } else {
134086797937017f52bff088d02edf64fb931177a7eaJun Nakajima            /* page directory entry */
134186797937017f52bff088d02edf64fb931177a7eaJun Nakajima            pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & env->a20_mask;
134286797937017f52bff088d02edf64fb931177a7eaJun Nakajima            pde = ldl_phys(pde_addr);
134386797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (!(pde & PG_PRESENT_MASK))
134486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                return -1;
134586797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
134686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                pte = pde & ~0x003ff000; /* align to 4MB */
134786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                page_size = 4096 * 1024;
134886797937017f52bff088d02edf64fb931177a7eaJun Nakajima            } else {
134986797937017f52bff088d02edf64fb931177a7eaJun Nakajima                /* page directory entry */
135086797937017f52bff088d02edf64fb931177a7eaJun Nakajima                pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask;
135186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                pte = ldl_phys(pte_addr);
135286797937017f52bff088d02edf64fb931177a7eaJun Nakajima                if (!(pte & PG_PRESENT_MASK))
135386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    return -1;
135486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                page_size = 4096;
135586797937017f52bff088d02edf64fb931177a7eaJun Nakajima            }
135686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        }
135786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        pte = pte & env->a20_mask;
135886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
135986797937017f52bff088d02edf64fb931177a7eaJun Nakajima
136086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
136186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    paddr = (pte & TARGET_PAGE_MASK) + page_offset;
136286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    return paddr;
136386797937017f52bff088d02edf64fb931177a7eaJun Nakajima}
136486797937017f52bff088d02edf64fb931177a7eaJun Nakajima
136586797937017f52bff088d02edf64fb931177a7eaJun Nakajimavoid hw_breakpoint_insert(CPUState *env, int index)
136686797937017f52bff088d02edf64fb931177a7eaJun Nakajima{
136786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    int type, err = 0;
136886797937017f52bff088d02edf64fb931177a7eaJun Nakajima
136986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    switch (hw_breakpoint_type(env->dr[7], index)) {
137086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    case 0:
137186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if (hw_breakpoint_enabled(env->dr[7], index))
137286797937017f52bff088d02edf64fb931177a7eaJun Nakajima            err = cpu_breakpoint_insert(env, env->dr[index], BP_CPU,
137386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                                        &env->cpu_breakpoint[index]);
137486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        break;
137586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    case 1:
137686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        type = BP_CPU | BP_MEM_WRITE;
137786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        goto insert_wp;
137886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    case 2:
137986797937017f52bff088d02edf64fb931177a7eaJun Nakajima         /* No support for I/O watchpoints yet */
138086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        break;
138186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    case 3:
138286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        type = BP_CPU | BP_MEM_ACCESS;
138386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    insert_wp:
138486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        err = cpu_watchpoint_insert(env, env->dr[index],
138586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                                    hw_breakpoint_len(env->dr[7], index),
138686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                                    type, &env->cpu_watchpoint[index]);
138786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        break;
138886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
138986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (err)
139086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        env->cpu_breakpoint[index] = NULL;
139186797937017f52bff088d02edf64fb931177a7eaJun Nakajima}
139286797937017f52bff088d02edf64fb931177a7eaJun Nakajima
139386797937017f52bff088d02edf64fb931177a7eaJun Nakajimavoid hw_breakpoint_remove(CPUState *env, int index)
139486797937017f52bff088d02edf64fb931177a7eaJun Nakajima{
139586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (!env->cpu_breakpoint[index])
139686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        return;
139786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    switch (hw_breakpoint_type(env->dr[7], index)) {
139886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    case 0:
139986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if (hw_breakpoint_enabled(env->dr[7], index))
140086797937017f52bff088d02edf64fb931177a7eaJun Nakajima            cpu_breakpoint_remove_by_ref(env, env->cpu_breakpoint[index]);
140186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        break;
140286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    case 1:
140386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    case 3:
140486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        cpu_watchpoint_remove_by_ref(env, env->cpu_watchpoint[index]);
140586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        break;
140686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    case 2:
140786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* No support for I/O watchpoints yet */
140886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        break;
140986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
141086797937017f52bff088d02edf64fb931177a7eaJun Nakajima}
141186797937017f52bff088d02edf64fb931177a7eaJun Nakajima
141286797937017f52bff088d02edf64fb931177a7eaJun Nakajimaint check_hw_breakpoints(CPUState *env, int force_dr6_update)
141386797937017f52bff088d02edf64fb931177a7eaJun Nakajima{
141486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    target_ulong dr6;
141586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    int reg, type;
141686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    int hit_enabled = 0;
141786797937017f52bff088d02edf64fb931177a7eaJun Nakajima
141886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    dr6 = env->dr[6] & ~0xf;
141986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    for (reg = 0; reg < 4; reg++) {
142086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        type = hw_breakpoint_type(env->dr[7], reg);
142186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if ((type == 0 && env->dr[reg] == env->eip) ||
142286797937017f52bff088d02edf64fb931177a7eaJun Nakajima            ((type & 1) && env->cpu_watchpoint[reg] &&
142386797937017f52bff088d02edf64fb931177a7eaJun Nakajima             (env->cpu_watchpoint[reg]->flags & BP_WATCHPOINT_HIT))) {
142486797937017f52bff088d02edf64fb931177a7eaJun Nakajima            dr6 |= 1 << reg;
142586797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (hw_breakpoint_enabled(env->dr[7], reg))
142686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                hit_enabled = 1;
142786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        }
142886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
142986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (hit_enabled || force_dr6_update)
143086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        env->dr[6] = dr6;
143186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    return hit_enabled;
143286797937017f52bff088d02edf64fb931177a7eaJun Nakajima}
143386797937017f52bff088d02edf64fb931177a7eaJun Nakajima
143486797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic CPUDebugExcpHandler *prev_debug_excp_handler;
143586797937017f52bff088d02edf64fb931177a7eaJun Nakajima
143686797937017f52bff088d02edf64fb931177a7eaJun Nakajimavoid raise_exception(int exception_index);
143786797937017f52bff088d02edf64fb931177a7eaJun Nakajima
143886797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic void breakpoint_handler(CPUState *env)
143986797937017f52bff088d02edf64fb931177a7eaJun Nakajima{
144086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    CPUBreakpoint *bp;
144186797937017f52bff088d02edf64fb931177a7eaJun Nakajima
144286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (env->watchpoint_hit) {
144386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if (env->watchpoint_hit->flags & BP_CPU) {
144486797937017f52bff088d02edf64fb931177a7eaJun Nakajima            env->watchpoint_hit = NULL;
144586797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (check_hw_breakpoints(env, 0))
144686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                raise_exception(EXCP01_DB);
144786797937017f52bff088d02edf64fb931177a7eaJun Nakajima            else
144886797937017f52bff088d02edf64fb931177a7eaJun Nakajima                cpu_resume_from_signal(env, NULL);
144986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        }
145086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    } else {
145186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        QTAILQ_FOREACH(bp, &env->breakpoints, entry)
145286797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (bp->pc == env->eip) {
145386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                if (bp->flags & BP_CPU) {
145486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    check_hw_breakpoints(env, 1);
145586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    raise_exception(EXCP01_DB);
145686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                }
145786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                break;
145886797937017f52bff088d02edf64fb931177a7eaJun Nakajima            }
145986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
146086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (prev_debug_excp_handler)
146186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        prev_debug_excp_handler(env);
146286797937017f52bff088d02edf64fb931177a7eaJun Nakajima}
146386797937017f52bff088d02edf64fb931177a7eaJun Nakajima
146486797937017f52bff088d02edf64fb931177a7eaJun Nakajima
146586797937017f52bff088d02edf64fb931177a7eaJun Nakajima/* This should come from sysemu.h - if we could include it here... */
146686797937017f52bff088d02edf64fb931177a7eaJun Nakajimavoid qemu_system_reset_request(void);
146786797937017f52bff088d02edf64fb931177a7eaJun Nakajima
146886797937017f52bff088d02edf64fb931177a7eaJun Nakajimavoid cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
146986797937017f52bff088d02edf64fb931177a7eaJun Nakajima                        uint64_t mcg_status, uint64_t addr, uint64_t misc)
147086797937017f52bff088d02edf64fb931177a7eaJun Nakajima{
147186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    uint64_t mcg_cap = cenv->mcg_cap;
147286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    unsigned bank_num = mcg_cap & 0xff;
147386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    uint64_t *banks = cenv->mce_banks;
147486797937017f52bff088d02edf64fb931177a7eaJun Nakajima
147586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (bank >= bank_num || !(status & MCI_STATUS_VAL))
147686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        return;
147786797937017f52bff088d02edf64fb931177a7eaJun Nakajima
147886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    /*
147986797937017f52bff088d02edf64fb931177a7eaJun Nakajima     * if MSR_MCG_CTL is not all 1s, the uncorrected error
148086797937017f52bff088d02edf64fb931177a7eaJun Nakajima     * reporting is disabled
148186797937017f52bff088d02edf64fb931177a7eaJun Nakajima     */
148286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if ((status & MCI_STATUS_UC) && (mcg_cap & MCG_CTL_P) &&
148386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        cenv->mcg_ctl != ~(uint64_t)0)
148486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        return;
148586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    banks += 4 * bank;
148686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    /*
148786797937017f52bff088d02edf64fb931177a7eaJun Nakajima     * if MSR_MCi_CTL is not all 1s, the uncorrected error
148886797937017f52bff088d02edf64fb931177a7eaJun Nakajima     * reporting is disabled for the bank
148986797937017f52bff088d02edf64fb931177a7eaJun Nakajima     */
149086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if ((status & MCI_STATUS_UC) && banks[0] != ~(uint64_t)0)
149186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        return;
149286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (status & MCI_STATUS_UC) {
149386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if ((cenv->mcg_status & MCG_STATUS_MCIP) ||
149486797937017f52bff088d02edf64fb931177a7eaJun Nakajima            !(cenv->cr[4] & CR4_MCE_MASK)) {
149586797937017f52bff088d02edf64fb931177a7eaJun Nakajima            fprintf(stderr, "injects mce exception while previous "
149686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                    "one is in progress!\n");
149786797937017f52bff088d02edf64fb931177a7eaJun Nakajima            qemu_log_mask(CPU_LOG_RESET, "Triple fault\n");
149886797937017f52bff088d02edf64fb931177a7eaJun Nakajima            qemu_system_reset_request();
149986797937017f52bff088d02edf64fb931177a7eaJun Nakajima            return;
150086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        }
150186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if (banks[1] & MCI_STATUS_VAL)
150286797937017f52bff088d02edf64fb931177a7eaJun Nakajima            status |= MCI_STATUS_OVER;
150386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        banks[2] = addr;
150486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        banks[3] = misc;
150586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        cenv->mcg_status = mcg_status;
150686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        banks[1] = status;
150786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        cpu_interrupt(cenv, CPU_INTERRUPT_MCE);
150886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    } else if (!(banks[1] & MCI_STATUS_VAL)
150986797937017f52bff088d02edf64fb931177a7eaJun Nakajima               || !(banks[1] & MCI_STATUS_UC)) {
151086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if (banks[1] & MCI_STATUS_VAL)
151186797937017f52bff088d02edf64fb931177a7eaJun Nakajima            status |= MCI_STATUS_OVER;
151286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        banks[2] = addr;
151386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        banks[3] = misc;
151486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        banks[1] = status;
151586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    } else
151686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        banks[1] |= MCI_STATUS_OVER;
151786797937017f52bff088d02edf64fb931177a7eaJun Nakajima}
151886797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif /* !CONFIG_USER_ONLY */
151986797937017f52bff088d02edf64fb931177a7eaJun Nakajima
152086797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic void mce_init(CPUX86State *cenv)
152186797937017f52bff088d02edf64fb931177a7eaJun Nakajima{
152286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    unsigned int bank, bank_num;
152386797937017f52bff088d02edf64fb931177a7eaJun Nakajima
152486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (((cenv->cpuid_version >> 8)&0xf) >= 6
152586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        && (cenv->cpuid_features&(CPUID_MCE|CPUID_MCA)) == (CPUID_MCE|CPUID_MCA)) {
152686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
152786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        cenv->mcg_ctl = ~(uint64_t)0;
152886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        bank_num = cenv->mcg_cap & 0xff;
152986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        cenv->mce_banks = qemu_mallocz(bank_num * sizeof(uint64_t) * 4);
153086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        for (bank = 0; bank < bank_num; bank++)
153186797937017f52bff088d02edf64fb931177a7eaJun Nakajima            cenv->mce_banks[bank*4] = ~(uint64_t)0;
153286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
153386797937017f52bff088d02edf64fb931177a7eaJun Nakajima}
153486797937017f52bff088d02edf64fb931177a7eaJun Nakajima
153586797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic void host_cpuid(uint32_t function, uint32_t count,
153686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                       uint32_t *eax, uint32_t *ebx,
153786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                       uint32_t *ecx, uint32_t *edx)
153886797937017f52bff088d02edf64fb931177a7eaJun Nakajima{
153986797937017f52bff088d02edf64fb931177a7eaJun Nakajima#if defined(CONFIG_KVM)
154086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    uint32_t vec[4];
154186797937017f52bff088d02edf64fb931177a7eaJun Nakajima
154286797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef __x86_64__
154386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    asm volatile("cpuid"
154486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                 : "=a"(vec[0]), "=b"(vec[1]),
154586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                   "=c"(vec[2]), "=d"(vec[3])
154686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                 : "0"(function), "c"(count) : "cc");
154786797937017f52bff088d02edf64fb931177a7eaJun Nakajima#else
154886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    asm volatile("pusha \n\t"
154986797937017f52bff088d02edf64fb931177a7eaJun Nakajima                 "cpuid \n\t"
155086797937017f52bff088d02edf64fb931177a7eaJun Nakajima                 "mov %%eax, 0(%2) \n\t"
155186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                 "mov %%ebx, 4(%2) \n\t"
155286797937017f52bff088d02edf64fb931177a7eaJun Nakajima                 "mov %%ecx, 8(%2) \n\t"
155386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                 "mov %%edx, 12(%2) \n\t"
155486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                 "popa"
155586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                 : : "a"(function), "c"(count), "S"(vec)
155686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                 : "memory", "cc");
155786797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif
155886797937017f52bff088d02edf64fb931177a7eaJun Nakajima
155986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (eax)
156086797937017f52bff088d02edf64fb931177a7eaJun Nakajima	*eax = vec[0];
156186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (ebx)
156286797937017f52bff088d02edf64fb931177a7eaJun Nakajima	*ebx = vec[1];
156386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (ecx)
156486797937017f52bff088d02edf64fb931177a7eaJun Nakajima	*ecx = vec[2];
156586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (edx)
156686797937017f52bff088d02edf64fb931177a7eaJun Nakajima	*edx = vec[3];
156786797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif
156886797937017f52bff088d02edf64fb931177a7eaJun Nakajima}
156986797937017f52bff088d02edf64fb931177a7eaJun Nakajima
157086797937017f52bff088d02edf64fb931177a7eaJun Nakajimavoid cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
157186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                   uint32_t *eax, uint32_t *ebx,
157286797937017f52bff088d02edf64fb931177a7eaJun Nakajima                   uint32_t *ecx, uint32_t *edx)
157386797937017f52bff088d02edf64fb931177a7eaJun Nakajima{
157486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    /* test if maximum index reached */
157586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (index & 0x80000000) {
157686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if (index > env->cpuid_xlevel)
157786797937017f52bff088d02edf64fb931177a7eaJun Nakajima            index = env->cpuid_level;
157886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    } else {
157986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if (index > env->cpuid_level)
158086797937017f52bff088d02edf64fb931177a7eaJun Nakajima            index = env->cpuid_level;
158186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
158286797937017f52bff088d02edf64fb931177a7eaJun Nakajima
158386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    switch(index) {
158486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    case 0:
158586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *eax = env->cpuid_level;
158686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *ebx = env->cpuid_vendor1;
158786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *edx = env->cpuid_vendor2;
158886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *ecx = env->cpuid_vendor3;
158986797937017f52bff088d02edf64fb931177a7eaJun Nakajima
159086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* sysenter isn't supported on compatibility mode on AMD.  and syscall
159186797937017f52bff088d02edf64fb931177a7eaJun Nakajima         * isn't supported in compatibility mode on Intel.  so advertise the
159286797937017f52bff088d02edf64fb931177a7eaJun Nakajima         * actuall cpu, and say goodbye to migration between different vendors
159386797937017f52bff088d02edf64fb931177a7eaJun Nakajima         * is you use compatibility mode. */
159486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if (kvm_enabled() && !env->cpuid_vendor_override)
159586797937017f52bff088d02edf64fb931177a7eaJun Nakajima            host_cpuid(0, 0, NULL, ebx, ecx, edx);
159686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        break;
159786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    case 1:
159886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *eax = env->cpuid_version;
1599aab4f055c481d3b0c4ee06154eeb5d9d25e71977Maciek Molerus        if (kvm_enabled() && !env->cpuid_vendor_override) {
1600aab4f055c481d3b0c4ee06154eeb5d9d25e71977Maciek Molerus            /* take only subset of ext features which processor can handle */
1601aab4f055c481d3b0c4ee06154eeb5d9d25e71977Maciek Molerus            uint32_t unused;
1602aab4f055c481d3b0c4ee06154eeb5d9d25e71977Maciek Molerus            host_cpuid(1, 0, NULL, &unused, ecx, &unused);
1603aab4f055c481d3b0c4ee06154eeb5d9d25e71977Maciek Molerus        } else {
1604aab4f055c481d3b0c4ee06154eeb5d9d25e71977Maciek Molerus            *ecx = UINT32_MAX;
1605aab4f055c481d3b0c4ee06154eeb5d9d25e71977Maciek Molerus        }
160686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
1607aab4f055c481d3b0c4ee06154eeb5d9d25e71977Maciek Molerus        *ecx &= env->cpuid_ext_features;
160886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *edx = env->cpuid_features;
160986797937017f52bff088d02edf64fb931177a7eaJun Nakajima
161086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* "Hypervisor present" bit required for Microsoft SVVP */
161186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if (kvm_enabled())
161286797937017f52bff088d02edf64fb931177a7eaJun Nakajima            *ecx |= (1 << 31);
161386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        break;
161486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    case 2:
161586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* cache info: needed for Pentium Pro compatibility */
161686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *eax = 1;
161786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *ebx = 0;
161886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *ecx = 0;
161986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *edx = 0x2c307d;
162086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        break;
162186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    case 4:
162286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* cache info: needed for Core compatibility */
162386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        switch (count) {
162486797937017f52bff088d02edf64fb931177a7eaJun Nakajima            case 0: /* L1 dcache info */
162586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                *eax = 0x0000121;
162686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                *ebx = 0x1c0003f;
162786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                *ecx = 0x000003f;
162886797937017f52bff088d02edf64fb931177a7eaJun Nakajima                *edx = 0x0000001;
162986797937017f52bff088d02edf64fb931177a7eaJun Nakajima                break;
163086797937017f52bff088d02edf64fb931177a7eaJun Nakajima            case 1: /* L1 icache info */
163186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                *eax = 0x0000122;
163286797937017f52bff088d02edf64fb931177a7eaJun Nakajima                *ebx = 0x1c0003f;
163386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                *ecx = 0x000003f;
163486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                *edx = 0x0000001;
163586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                break;
163686797937017f52bff088d02edf64fb931177a7eaJun Nakajima            case 2: /* L2 cache info */
163786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                *eax = 0x0000143;
163886797937017f52bff088d02edf64fb931177a7eaJun Nakajima                *ebx = 0x3c0003f;
163986797937017f52bff088d02edf64fb931177a7eaJun Nakajima                *ecx = 0x0000fff;
164086797937017f52bff088d02edf64fb931177a7eaJun Nakajima                *edx = 0x0000001;
164186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                break;
164286797937017f52bff088d02edf64fb931177a7eaJun Nakajima            default: /* end of info */
164386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                *eax = 0;
164486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                *ebx = 0;
164586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                *ecx = 0;
164686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                *edx = 0;
164786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                break;
164886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        }
164986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        break;
165086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    case 5:
165186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* mwait info: needed for Core compatibility */
165286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *eax = 0; /* Smallest monitor-line size in bytes */
165386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *ebx = 0; /* Largest monitor-line size in bytes */
165486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
165586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *edx = 0;
165686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        break;
165786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    case 6:
165886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* Thermal and Power Leaf */
165986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *eax = 0;
166086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *ebx = 0;
166186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *ecx = 0;
166286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *edx = 0;
166386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        break;
166486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    case 9:
166586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* Direct Cache Access Information Leaf */
166686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
166786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *ebx = 0;
166886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *ecx = 0;
166986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *edx = 0;
167086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        break;
167186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    case 0xA:
167286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* Architectural Performance Monitoring Leaf */
167386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *eax = 0;
167486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *ebx = 0;
167586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *ecx = 0;
167686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *edx = 0;
167786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        break;
167886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    case 0x80000000:
167986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *eax = env->cpuid_xlevel;
168086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *ebx = env->cpuid_vendor1;
168186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *edx = env->cpuid_vendor2;
168286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *ecx = env->cpuid_vendor3;
168386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        break;
168486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    case 0x80000001:
168586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *eax = env->cpuid_features;
168686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *ebx = 0;
168786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *ecx = env->cpuid_ext3_features;
168886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *edx = env->cpuid_ext2_features;
168986797937017f52bff088d02edf64fb931177a7eaJun Nakajima
169086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if (kvm_enabled()) {
169186797937017f52bff088d02edf64fb931177a7eaJun Nakajima            uint32_t h_eax, h_edx;
169286797937017f52bff088d02edf64fb931177a7eaJun Nakajima
169386797937017f52bff088d02edf64fb931177a7eaJun Nakajima            host_cpuid(index, 0, &h_eax, NULL, NULL, &h_edx);
169486797937017f52bff088d02edf64fb931177a7eaJun Nakajima
169586797937017f52bff088d02edf64fb931177a7eaJun Nakajima            /* disable CPU features that the host does not support */
169686797937017f52bff088d02edf64fb931177a7eaJun Nakajima
169786797937017f52bff088d02edf64fb931177a7eaJun Nakajima            /* long mode */
169886797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if ((h_edx & 0x20000000) == 0 /* || !lm_capable_kernel */)
169986797937017f52bff088d02edf64fb931177a7eaJun Nakajima                *edx &= ~0x20000000;
170086797937017f52bff088d02edf64fb931177a7eaJun Nakajima            /* syscall */
170186797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if ((h_edx & 0x00000800) == 0)
170286797937017f52bff088d02edf64fb931177a7eaJun Nakajima                *edx &= ~0x00000800;
170386797937017f52bff088d02edf64fb931177a7eaJun Nakajima            /* nx */
170486797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if ((h_edx & 0x00100000) == 0)
170586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                *edx &= ~0x00100000;
170686797937017f52bff088d02edf64fb931177a7eaJun Nakajima
170786797937017f52bff088d02edf64fb931177a7eaJun Nakajima            /* disable CPU features that KVM cannot support */
170886797937017f52bff088d02edf64fb931177a7eaJun Nakajima
170986797937017f52bff088d02edf64fb931177a7eaJun Nakajima            /* svm */
171086797937017f52bff088d02edf64fb931177a7eaJun Nakajima            *ecx &= ~4UL;
171186797937017f52bff088d02edf64fb931177a7eaJun Nakajima            /* 3dnow */
171286797937017f52bff088d02edf64fb931177a7eaJun Nakajima            *edx &= ~0xc0000000;
171386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        }
171486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        break;
171586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    case 0x80000002:
171686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    case 0x80000003:
171786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    case 0x80000004:
171886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
171986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
172086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
172186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
172286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        break;
172386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    case 0x80000005:
172486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* cache info (L1 cache) */
172586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *eax = 0x01ff01ff;
172686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *ebx = 0x01ff01ff;
172786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *ecx = 0x40020140;
172886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *edx = 0x40020140;
172986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        break;
173086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    case 0x80000006:
173186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* cache info (L2 cache) */
173286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *eax = 0;
173386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *ebx = 0x42004200;
173486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *ecx = 0x02008140;
173586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *edx = 0;
173686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        break;
173786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    case 0x80000008:
173886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* virtual & phys address size in low 2 bytes. */
173986797937017f52bff088d02edf64fb931177a7eaJun Nakajima/* XXX: This value must match the one used in the MMU code. */
174086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        if (env->cpuid_ext2_features & CPUID_EXT2_LM) {
174186797937017f52bff088d02edf64fb931177a7eaJun Nakajima            /* 64 bit processor */
174286797937017f52bff088d02edf64fb931177a7eaJun Nakajima#if defined(CONFIG_KQEMU)
174386797937017f52bff088d02edf64fb931177a7eaJun Nakajima            *eax = 0x00003020;	/* 48 bits virtual, 32 bits physical */
174486797937017f52bff088d02edf64fb931177a7eaJun Nakajima#else
174586797937017f52bff088d02edf64fb931177a7eaJun Nakajima/* XXX: The physical address space is limited to 42 bits in exec.c. */
174686797937017f52bff088d02edf64fb931177a7eaJun Nakajima            *eax = 0x00003028;	/* 48 bits virtual, 40 bits physical */
174786797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif
174886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        } else {
174986797937017f52bff088d02edf64fb931177a7eaJun Nakajima#if defined(CONFIG_KQEMU)
175086797937017f52bff088d02edf64fb931177a7eaJun Nakajima            *eax = 0x00000020;	/* 32 bits physical */
175186797937017f52bff088d02edf64fb931177a7eaJun Nakajima#else
175286797937017f52bff088d02edf64fb931177a7eaJun Nakajima            if (env->cpuid_features & CPUID_PSE36)
175386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                *eax = 0x00000024; /* 36 bits physical */
175486797937017f52bff088d02edf64fb931177a7eaJun Nakajima            else
175586797937017f52bff088d02edf64fb931177a7eaJun Nakajima                *eax = 0x00000020; /* 32 bits physical */
175686797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif
175786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        }
175886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *ebx = 0;
175986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *ecx = 0;
176086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *edx = 0;
176186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        break;
176286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    case 0x8000000A:
176386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *eax = 0x00000001; /* SVM Revision */
176486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *ebx = 0x00000010; /* nr of ASIDs */
176586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *ecx = 0;
176686797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *edx = 0; /* optional features */
176786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        break;
176886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    default:
176986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        /* reserved values: zero */
177086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *eax = 0;
177186797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *ebx = 0;
177286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *ecx = 0;
177386797937017f52bff088d02edf64fb931177a7eaJun Nakajima        *edx = 0;
177486797937017f52bff088d02edf64fb931177a7eaJun Nakajima        break;
177586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
177686797937017f52bff088d02edf64fb931177a7eaJun Nakajima}
177786797937017f52bff088d02edf64fb931177a7eaJun Nakajima
177886797937017f52bff088d02edf64fb931177a7eaJun NakajimaCPUX86State *cpu_x86_init(const char *cpu_model)
177986797937017f52bff088d02edf64fb931177a7eaJun Nakajima{
178086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    CPUX86State *env;
178186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    static int inited;
178286797937017f52bff088d02edf64fb931177a7eaJun Nakajima
178386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env = qemu_mallocz(sizeof(CPUX86State));
178486797937017f52bff088d02edf64fb931177a7eaJun Nakajima    cpu_exec_init(env);
178586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->cpu_model_str = cpu_model;
178686797937017f52bff088d02edf64fb931177a7eaJun Nakajima
178786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    /* init various static tables */
178886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (!inited) {
178986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        inited = 1;
179086797937017f52bff088d02edf64fb931177a7eaJun Nakajima        optimize_flags_init();
179186797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifndef CONFIG_USER_ONLY
179286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        prev_debug_excp_handler =
179386797937017f52bff088d02edf64fb931177a7eaJun Nakajima            cpu_set_debug_excp_handler(breakpoint_handler);
179486797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif
179586797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
179686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (cpu_x86_register(env, cpu_model) < 0) {
179786797937017f52bff088d02edf64fb931177a7eaJun Nakajima        cpu_x86_close(env);
179886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        return NULL;
179986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
180086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    mce_init(env);
180186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    cpu_reset(env);
180286797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef CONFIG_KQEMU
180386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    kqemu_init(env);
180486797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif
180586797937017f52bff088d02edf64fb931177a7eaJun Nakajima
180686797937017f52bff088d02edf64fb931177a7eaJun Nakajima    qemu_init_vcpu(env);
180786797937017f52bff088d02edf64fb931177a7eaJun Nakajima
180886797937017f52bff088d02edf64fb931177a7eaJun Nakajima    if (kvm_enabled()) {
180986797937017f52bff088d02edf64fb931177a7eaJun Nakajima        kvm_trim_features(&env->cpuid_features,
181086797937017f52bff088d02edf64fb931177a7eaJun Nakajima                          kvm_arch_get_supported_cpuid(env, 1, R_EDX),
181186797937017f52bff088d02edf64fb931177a7eaJun Nakajima                          feature_name);
181286797937017f52bff088d02edf64fb931177a7eaJun Nakajima        kvm_trim_features(&env->cpuid_ext_features,
181386797937017f52bff088d02edf64fb931177a7eaJun Nakajima                          kvm_arch_get_supported_cpuid(env, 1, R_ECX),
181486797937017f52bff088d02edf64fb931177a7eaJun Nakajima                          ext_feature_name);
181586797937017f52bff088d02edf64fb931177a7eaJun Nakajima        kvm_trim_features(&env->cpuid_ext2_features,
181686797937017f52bff088d02edf64fb931177a7eaJun Nakajima                          kvm_arch_get_supported_cpuid(env, 0x80000001, R_EDX),
181786797937017f52bff088d02edf64fb931177a7eaJun Nakajima                          ext2_feature_name);
181886797937017f52bff088d02edf64fb931177a7eaJun Nakajima        kvm_trim_features(&env->cpuid_ext3_features,
181986797937017f52bff088d02edf64fb931177a7eaJun Nakajima                          kvm_arch_get_supported_cpuid(env, 0x80000001, R_ECX),
182086797937017f52bff088d02edf64fb931177a7eaJun Nakajima                          ext3_feature_name);
182186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    }
182286797937017f52bff088d02edf64fb931177a7eaJun Nakajima
182386797937017f52bff088d02edf64fb931177a7eaJun Nakajima    return env;
182486797937017f52bff088d02edf64fb931177a7eaJun Nakajima}
182586797937017f52bff088d02edf64fb931177a7eaJun Nakajima
182686797937017f52bff088d02edf64fb931177a7eaJun Nakajima#if !defined(CONFIG_USER_ONLY)
182786797937017f52bff088d02edf64fb931177a7eaJun Nakajimavoid do_cpu_init(CPUState *env)
182886797937017f52bff088d02edf64fb931177a7eaJun Nakajima{
182986797937017f52bff088d02edf64fb931177a7eaJun Nakajima    int sipi = env->interrupt_request & CPU_INTERRUPT_SIPI;
183086797937017f52bff088d02edf64fb931177a7eaJun Nakajima    cpu_reset(env);
183186797937017f52bff088d02edf64fb931177a7eaJun Nakajima    env->interrupt_request = sipi;
183286797937017f52bff088d02edf64fb931177a7eaJun Nakajima    apic_init_reset(env);
183386797937017f52bff088d02edf64fb931177a7eaJun Nakajima}
183486797937017f52bff088d02edf64fb931177a7eaJun Nakajima
183586797937017f52bff088d02edf64fb931177a7eaJun Nakajimavoid do_cpu_sipi(CPUState *env)
183686797937017f52bff088d02edf64fb931177a7eaJun Nakajima{
183786797937017f52bff088d02edf64fb931177a7eaJun Nakajima    apic_sipi(env);
183886797937017f52bff088d02edf64fb931177a7eaJun Nakajima}
183986797937017f52bff088d02edf64fb931177a7eaJun Nakajima#else
184086797937017f52bff088d02edf64fb931177a7eaJun Nakajimavoid do_cpu_init(CPUState *env)
184186797937017f52bff088d02edf64fb931177a7eaJun Nakajima{
184286797937017f52bff088d02edf64fb931177a7eaJun Nakajima}
184386797937017f52bff088d02edf64fb931177a7eaJun Nakajimavoid do_cpu_sipi(CPUState *env)
184486797937017f52bff088d02edf64fb931177a7eaJun Nakajima{
184586797937017f52bff088d02edf64fb931177a7eaJun Nakajima}
184686797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif
1847