From patchwork Thu Feb 28 02:12:32 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H. Peter Anvin" X-Patchwork-Id: 223767 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 5EB392C008C for ; Thu, 28 Feb 2013 14:17:22 +1100 (EST) Received: from localhost ([::1]:52312 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UAtzk-0007jY-HR for incoming@patchwork.ozlabs.org; Wed, 27 Feb 2013 22:17:20 -0500 Received: from eggs.gnu.org ([208.118.235.92]:42960) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UAtye-0006GX-Gy for qemu-devel@nongnu.org; Wed, 27 Feb 2013 22:16:16 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UAtyb-0000eg-Fj for qemu-devel@nongnu.org; Wed, 27 Feb 2013 22:16:12 -0500 Received: from terminus.zytor.com ([2001:1868:205::10]:34671 helo=mail.zytor.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UAtyb-0000OI-3E for qemu-devel@nongnu.org; Wed, 27 Feb 2013 22:16:09 -0500 Received: from tazenda.hos.anvin.org ([IPv6:2601:9:3340:26:e269:95ff:fe35:9f3c]) (authenticated bits=0) by mail.zytor.com (8.14.5/8.14.5) with ESMTP id r1S2Cg6t032387 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 27 Feb 2013 18:12:43 -0800 Received: from tazenda.hos.anvin.org (localhost [127.0.0.1]) by tazenda.hos.anvin.org (8.14.5/8.14.5) with ESMTP id r1S2CbgZ001300; Wed, 27 Feb 2013 18:12:37 -0800 Received: (from hpa@localhost) by tazenda.hos.anvin.org (8.14.5/8.14.5/Submit) id r1S2CasQ001299; Wed, 27 Feb 2013 18:12:36 -0800 From: "H. Peter Anvin" To: qemu-devel@nongnu.org Date: Wed, 27 Feb 2013 18:12:32 -0800 Message-Id: <1362017554-1260-1-git-send-email-hpa@zytor.com> X-Mailer: git-send-email 1.7.11.7 X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2001:1868:205::10 Cc: "H. Peter Anvin" Subject: [Qemu-devel] [RFC PATCH 1/3] target-i386: Add 486sx, old486, and old486sx CPU models X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: "H. Peter Anvin" Add models for 486SX, and pre-CPUID versions of the 486 (DX & SX). Change the model number for the standard 486DX to a model which actually had CPUID. Note: these models are fairly vestigial, for example most of the FPU operations still work; only F*ST[CS]W have been modified to appear as through there is no FPU. This also changes the classic 486 model number to 8 (DX4) which matches the feature set presented. Signed-off-by: H. Peter Anvin --- target-i386/cpu.c | 39 ++++++++++++++++++++++++++--- target-i386/fpu_helper.c | 12 +++++++-- target-i386/misc_helper.c | 15 ++++++++---- target-i386/translate.c | 62 +++++++++++++++-------------------------------- 4 files changed, 75 insertions(+), 53 deletions(-) diff --git a/target-i386/cpu.c b/target-i386/cpu.c index aab35c7..a5aad19 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -365,8 +365,11 @@ typedef struct x86_def_t { uint32_t cpuid_7_0_ebx_features; } x86_def_t; -#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE) -#define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \ +#define OLD_I486SX_FEATURES 0 +#define OLD_I486_FEATURES CPUID_FP87 +#define I486SX_FEATURES CPUID_VME /* SX2+ */ +#define I486_FEATURES (CPUID_FP87 | CPUID_VME) /* DX4 and some DX2 */ +#define PENTIUM_FEATURES (I486_FEATURES | CPUID_PSE | CPUID_DE | CPUID_TSC | \ CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX | CPUID_APIC) #define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \ CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \ @@ -535,16 +538,46 @@ static x86_def_t builtin_x86_defs[] = { .model_id = "Genuine Intel(R) CPU T2600 @ 2.16GHz", }, { + .name = "old486", + .level = 0, + .vendor = CPUID_VENDOR_INTEL, + .family = 4, + .model = 1, + .stepping = 0, + .features = OLD_I486_FEATURES, + .xlevel = 0, + }, + { + .name = "old486sx", + .level = 0, + .vendor = CPUID_VENDOR_INTEL, + .family = 4, + .model = 2, + .stepping = 0, + .features = OLD_I486SX_FEATURES, + .xlevel = 0, + }, + { .name = "486", .level = 1, .vendor = CPUID_VENDOR_INTEL, .family = 4, - .model = 0, + .model = 8, .stepping = 0, .features = I486_FEATURES, .xlevel = 0, }, { + .name = "486sx", + .level = 1, + .vendor = CPUID_VENDOR_INTEL, + .family = 4, + .model = 5, + .stepping = 0, + .features = I486SX_FEATURES, + .xlevel = 0, + }, + { .name = "pentium", .level = 1, .vendor = CPUID_VENDOR_INTEL, diff --git a/target-i386/fpu_helper.c b/target-i386/fpu_helper.c index 44f3d27..c4c2724 100644 --- a/target-i386/fpu_helper.c +++ b/target-i386/fpu_helper.c @@ -530,12 +530,20 @@ void helper_fldz_FT0(CPUX86State *env) uint32_t helper_fnstsw(CPUX86State *env) { - return (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11; + if (!(env->cpuid_features & CPUID_FP87)) { + return 0xffff; + } else { + return (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11; + } } uint32_t helper_fnstcw(CPUX86State *env) { - return env->fpuc; + if (!(env->cpuid_features & CPUID_FP87)) { + return 0xffff; + } else { + return env->fpuc; + } } static void update_fp_status(CPUX86State *env) diff --git a/target-i386/misc_helper.c b/target-i386/misc_helper.c index b6d5740..1ff25d1 100644 --- a/target-i386/misc_helper.c +++ b/target-i386/misc_helper.c @@ -122,11 +122,16 @@ void helper_cpuid(CPUX86State *env) cpu_svm_check_intercept_param(env, SVM_EXIT_CPUID, 0); - cpu_x86_cpuid(env, (uint32_t)EAX, (uint32_t)ECX, &eax, &ebx, &ecx, &edx); - EAX = eax; - EBX = ebx; - ECX = ecx; - EDX = edx; + if (!env->cpuid_level) { + raise_exception_err(env, EXCP06_ILLOP, 0); + } else { + cpu_x86_cpuid(env, (uint32_t)EAX, (uint32_t)ECX, + &eax, &ebx, &ecx, &edx); + EAX = eax; + EBX = ebx; + ECX = ecx; + EDX = edx; + } } #if defined(CONFIG_USER_ONLY) diff --git a/target-i386/translate.c b/target-i386/translate.c index 112c310..6d8abff 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -103,6 +103,8 @@ typedef struct DisasContext { struct TranslationBlock *tb; int popl_esp_hack; /* for correct popl with esp base handling */ int rip_offset; /* only used in x86_64, but left for simplicity */ + int cpuid_family; + int cpuid_level; int cpuid_features; int cpuid_ext_features; int cpuid_ext2_features; @@ -6513,52 +6515,24 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, if (s->vm86 && s->iopl != 3) { gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); } else { + uint32_t mask; gen_pop_T0(s); + mask = TF_MASK | NT_MASK | IF_MASK; + if (s->cpuid_family >= 4) { + mask |= AC_MASK; + } + if (s->cpuid_level) { + mask |= ID_MASK; + } if (s->cpl == 0) { - if (s->dflag) { - gen_helper_write_eflags(cpu_env, cpu_T[0], - tcg_const_i32((TF_MASK | AC_MASK | - ID_MASK | NT_MASK | - IF_MASK | - IOPL_MASK))); - } else { - gen_helper_write_eflags(cpu_env, cpu_T[0], - tcg_const_i32((TF_MASK | AC_MASK | - ID_MASK | NT_MASK | - IF_MASK | IOPL_MASK) - & 0xffff)); - } - } else { - if (s->cpl <= s->iopl) { - if (s->dflag) { - gen_helper_write_eflags(cpu_env, cpu_T[0], - tcg_const_i32((TF_MASK | - AC_MASK | - ID_MASK | - NT_MASK | - IF_MASK))); - } else { - gen_helper_write_eflags(cpu_env, cpu_T[0], - tcg_const_i32((TF_MASK | - AC_MASK | - ID_MASK | - NT_MASK | - IF_MASK) - & 0xffff)); - } - } else { - if (s->dflag) { - gen_helper_write_eflags(cpu_env, cpu_T[0], - tcg_const_i32((TF_MASK | AC_MASK | - ID_MASK | NT_MASK))); - } else { - gen_helper_write_eflags(cpu_env, cpu_T[0], - tcg_const_i32((TF_MASK | AC_MASK | - ID_MASK | NT_MASK) - & 0xffff)); - } - } + mask |= IF_MASK | IOPL_MASK; + } else if (s->cpl <= s->iopl) { + mask |= IF_MASK; + } + if (!s->dflag) { + mask &= 0xffff; } + gen_helper_write_eflags(cpu_env, cpu_T[0], tcg_const_i32(mask)); gen_pop_update(s); s->cc_op = CC_OP_EFLAGS; /* abort translation because TF/AC flag may change */ @@ -7926,6 +7900,8 @@ static inline void gen_intermediate_code_internal(CPUX86State *env, if (flags & HF_SOFTMMU_MASK) { dc->mem_index = (cpu_mmu_index(env) + 1) << 2; } + dc->cpuid_family = (env->cpuid_version >> 8) & 0x0f; + dc->cpuid_level = env->cpuid_level; dc->cpuid_features = env->cpuid_features; dc->cpuid_ext_features = env->cpuid_ext_features; dc->cpuid_ext2_features = env->cpuid_ext2_features;