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