Bochs/bochs/cpu/cpudb/turion64_tyler.cc
Stanislav Shwartsman 9f57e70d5f Rewritten handling of supported CPUID features to be able to handle large amount of CPU extensions
Now enable support for up to 128 CPU extensions and could easily extend it more
Also reduce memory footprint for bx_ia_opcodes.h arrays
2014-08-31 18:39:18 +00:00

501 lines
15 KiB
C++

/////////////////////////////////////////////////////////////////////////
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2011-2014 Stanislav Shwartsman
// Written by Stanislav Shwartsman [sshwarts at sourceforge net]
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA B 02110-1301 USA
//
/////////////////////////////////////////////////////////////////////////
#include "bochs.h"
#include "cpu.h"
#include "turion64_tyler.h"
#define LOG_THIS cpu->
#if BX_SUPPORT_X86_64
turion64_tyler_t::turion64_tyler_t(BX_CPU_C *cpu): bx_cpuid_t(cpu)
{
if (! BX_SUPPORT_X86_64)
BX_PANIC(("You must enable x86-64 for Turion64 configuration"));
BX_INFO(("WARNING: 3DNow! is not implemented yet !"));
if (! BX_SUPPORT_SVM)
BX_INFO(("WARNING: SVM Support is not compiled in !"));
static Bit8u supported_extensions[] = {
BX_ISA_X87,
BX_ISA_486,
BX_ISA_PENTIUM,
BX_ISA_MMX,
BX_ISA_3DNOW,
BX_ISA_SYSCALL_SYSRET_LEGACY,
BX_ISA_SYSENTER_SYSEXIT,
BX_ISA_P6,
BX_ISA_SSE,
BX_ISA_SSE2,
BX_ISA_SSE3,
BX_ISA_CLFLUSH,
BX_ISA_DEBUG_EXTENSIONS,
BX_ISA_VME,
BX_ISA_PSE,
BX_ISA_PAE,
BX_ISA_PGE,
#if BX_PHY_ADDRESS_LONG
BX_ISA_PSE36,
#endif
BX_ISA_MTRR,
BX_ISA_PAT,
BX_ISA_XAPIC,
BX_ISA_LONG_MODE,
BX_ISA_LM_LAHF_SAHF,
BX_ISA_NX,
BX_ISA_FFXSR,
BX_ISA_CMPXCHG16B,
BX_ISA_RDTSCP,
#if BX_SUPPORT_SVM
BX_ISA_SVM,
#endif
BX_ISA_ALT_MOV_CR8,
BX_ISA_XAPIC_EXT,
BX_ISA_EXTENSION_LAST
};
register_cpu_extensions(supported_extensions);
}
void turion64_tyler_t::get_cpuid_leaf(Bit32u function, Bit32u subfunction, cpuid_function_t *leaf) const
{
static const char* brand_string = "AMD Turion(tm) 64 X2 Mobile Technology TL-60";
switch(function) {
case 0x80000000:
get_ext_cpuid_leaf_0(leaf);
return;
case 0x80000001:
get_ext_cpuid_leaf_1(leaf);
return;
case 0x80000002:
case 0x80000003:
case 0x80000004:
get_ext_cpuid_brand_string_leaf(brand_string, function, leaf);
return;
case 0x80000005:
get_ext_cpuid_leaf_5(leaf);
return;
case 0x80000006:
get_ext_cpuid_leaf_6(leaf);
return;
case 0x80000007:
get_ext_cpuid_leaf_7(leaf);
return;
case 0x80000008:
get_ext_cpuid_leaf_8(leaf);
return;
#if BX_SUPPORT_SVM
case 0x8000000A:
get_ext_cpuid_leaf_A(leaf);
return;
#endif
case 0x00000000:
get_std_cpuid_leaf_0(leaf);
return;
case 0x00000001:
get_std_cpuid_leaf_1(leaf);
return;
default:
get_reserved_leaf(leaf);
return;
}
}
// leaf 0x00000000 //
void turion64_tyler_t::get_std_cpuid_leaf_0(cpuid_function_t *leaf) const
{
static const char* vendor_string = "AuthenticAMD";
// EAX: highest std function understood by CPUID
// EBX: vendor ID string
// EDX: vendor ID string
// ECX: vendor ID string
leaf->eax = 0x1;
// CPUID vendor string (e.g. GenuineIntel, AuthenticAMD, CentaurHauls, ...)
memcpy(&(leaf->ebx), vendor_string, 4);
memcpy(&(leaf->edx), vendor_string + 4, 4);
memcpy(&(leaf->ecx), vendor_string + 8, 4);
#ifdef BX_BIG_ENDIAN
leaf->ebx = bx_bswap32(leaf->ebx);
leaf->ecx = bx_bswap32(leaf->ecx);
leaf->edx = bx_bswap32(leaf->edx);
#endif
}
// leaf 0x00000001 //
void turion64_tyler_t::get_std_cpuid_leaf_1(cpuid_function_t *leaf) const
{
// EAX: CPU Version Information
// [3:0] Stepping ID
// [7:4] Model: starts at 1
// [11:8] Family: 4=486, 5=Pentium, 6=PPro, ...
// [13:12] Type: 0=OEM, 1=overdrive, 2=dual cpu, 3=reserved
// [19:16] Extended Model
// [27:20] Extended Family
leaf->eax = 0x00060F82;
// EBX:
// [7:0] Brand ID
// [15:8] CLFLUSH cache line size (value*8 = cache line size in bytes)
// [23:16] Number of logical processors in one physical processor
// [31:24] Local Apic ID
unsigned n_logical_processors = ncores*nthreads;
leaf->ebx = ((CACHE_LINE_SIZE / 8) << 8) |
(n_logical_processors << 16);
#if BX_SUPPORT_APIC
leaf->ebx |= ((cpu->get_apic_id() & 0xff) << 24);
#endif
// ECX: Extended Feature Flags
// * [0:0] SSE3: SSE3 Instructions
// [1:1] PCLMULQDQ Instruction support
// [2:2] DTES64: 64-bit DS area
// [3:3] MONITOR/MWAIT support
// [4:4] DS-CPL: CPL qualified debug store
// [5:5] VMX: Virtual Machine Technology
// [6:6] SMX: Secure Virtual Machine Technology
// [7:7] EST: Enhanced Intel SpeedStep Technology
// [8:8] TM2: Thermal Monitor 2
// [9:9] SSSE3: SSSE3 Instructions
// [10:10] CNXT-ID: L1 context ID
// [11:11] reserved
// [12:12] FMA Instructions support
// * [13:13] CMPXCHG16B: CMPXCHG16B instruction support
// [14:14] xTPR update control
// [15:15] PDCM - Perfon and Debug Capability MSR
// [16:16] reserved
// [17:17] PCID: Process Context Identifiers
// [18:18] DCA - Direct Cache Access
// [19:19] SSE4.1 Instructions
// [20:20] SSE4.2 Instructions
// [21:21] X2APIC
// [22:22] MOVBE instruction
// [23:23] POPCNT instruction
// [24:24] TSC Deadline
// [25:25] AES Instructions
// [26:26] XSAVE extensions support
// [27:27] OSXSAVE support
// [28:28] AVX extensions support
// [29:29] AVX F16C - Float16 conversion support
// [30:30] RDRAND instruction
// [31:31] reserved
leaf->ecx = BX_CPUID_EXT_SSE3 | BX_CPUID_EXT_CMPXCHG16B;
// EDX: Standard Feature Flags
// * [0:0] FPU on chip
// * [1:1] VME: Virtual-8086 Mode enhancements
// * [2:2] DE: Debug Extensions (I/O breakpoints)
// * [3:3] PSE: Page Size Extensions
// * [4:4] TSC: Time Stamp Counter
// * [5:5] MSR: RDMSR and WRMSR support
// * [6:6] PAE: Physical Address Extensions
// * [7:7] MCE: Machine Check Exception
// * [8:8] CXS: CMPXCHG8B instruction
// * [9:9] APIC: APIC on Chip
// [10:10] Reserved
// * [11:11] SYSENTER/SYSEXIT support
// * [12:12] MTRR: Memory Type Range Reg
// * [13:13] PGE/PTE Global Bit
// * [14:14] MCA: Machine Check Architecture
// * [15:15] CMOV: Cond Mov/Cmp Instructions
// * [16:16] PAT: Page Attribute Table
// * [17:17] PSE-36: Physical Address Extensions
// [18:18] PSN: Processor Serial Number
// * [19:19] CLFLUSH: CLFLUSH Instruction support
// [20:20] Reserved
// [21:21] DS: Debug Store
// [22:22] ACPI: Thermal Monitor and Software Controlled Clock Facilities
// * [23:23] MMX Technology
// * [24:24] FXSR: FXSAVE/FXRSTOR (also indicates CR4.OSFXSR is available)
// * [25:25] SSE: SSE Extensions
// * [26:26] SSE2: SSE2 Extensions
// [27:27] Self Snoop
// * [28:28] Hyper Threading Technology
// [29:29] TM: Thermal Monitor
// [30:30] Reserved
// [31:31] PBE: Pending Break Enable
leaf->edx = BX_CPUID_STD_X87 |
BX_CPUID_STD_VME |
BX_CPUID_STD_DEBUG_EXTENSIONS |
BX_CPUID_STD_PSE |
BX_CPUID_STD_TSC |
BX_CPUID_STD_MSR |
BX_CPUID_STD_PAE |
BX_CPUID_STD_MCE |
BX_CPUID_STD_CMPXCHG8B |
BX_CPUID_STD_SYSENTER_SYSEXIT |
BX_CPUID_STD_MTRR |
BX_CPUID_STD_GLOBAL_PAGES |
BX_CPUID_STD_MCA |
BX_CPUID_STD_CMOV |
BX_CPUID_STD_PAT |
BX_CPUID_STD_PSE36 |
BX_CPUID_STD_CLFLUSH |
BX_CPUID_STD_MMX |
BX_CPUID_STD_FXSAVE_FXRSTOR |
BX_CPUID_STD_SSE |
BX_CPUID_STD_SSE2 |
BX_CPUID_STD_HT;
#if BX_SUPPORT_APIC
// if MSR_APICBASE APIC Global Enable bit has been cleared,
// the CPUID feature flag for the APIC is set to 0.
if (cpu->msr.apicbase & 0x800)
leaf->edx |= BX_CPUID_STD_APIC; // APIC on chip
#endif
}
// leaf 0x80000000 //
void turion64_tyler_t::get_ext_cpuid_leaf_0(cpuid_function_t *leaf) const
{
static const char* vendor_string = "AuthenticAMD";
// EAX: highest extended function understood by CPUID
// EBX: reserved
// EDX: reserved
// ECX: reserved
leaf->eax = 0x80000018;
memcpy(&(leaf->ebx), vendor_string, 4);
memcpy(&(leaf->edx), vendor_string + 4, 4);
memcpy(&(leaf->ecx), vendor_string + 8, 4);
#ifdef BX_BIG_ENDIAN
leaf->ebx = bx_bswap32(leaf->ebx);
leaf->ecx = bx_bswap32(leaf->ecx);
leaf->edx = bx_bswap32(leaf->edx);
#endif
}
// leaf 0x80000001 //
void turion64_tyler_t::get_ext_cpuid_leaf_1(cpuid_function_t *leaf) const
{
// EAX: CPU Version Information (same as 0x00000001.EAX)
leaf->eax = 0x00060F82;
// EBX: Brand ID
leaf->ebx = 0x0000059F;
// ECX:
// * [0:0] LAHF/SAHF instructions support in 64-bit mode
// * [1:1] CMP_Legacy: Core multi-processing legacy mode (AMD)
// * [2:2] SVM: Secure Virtual Machine (AMD)
// * [3:3] Extended APIC Space
// * [4:4] AltMovCR8: LOCK MOV CR0 means MOV CR8
// [5:5] LZCNT: LZCNT instruction support
// [6:6] SSE4A: SSE4A Instructions support
// [7:7] Misaligned SSE support
// * [8:8] PREFETCHW: PREFETCHW instruction support
// [9:9] OSVW: OS visible workarounds (AMD)
// [10:10] IBS: Instruction based sampling
// [11:11] XOP: Extended Operations Support and XOP Prefix
// [12:12] SKINIT support
// [13:13] WDT: Watchdog timer support
// [14:14] Reserved
// [15:15] LWP: Light weight profiling
// [16:16] FMA4: Four-operand FMA instructions support
// [17:17] Reserved
// [18:18] Reserved
// [19:19] Reserved
// [20:20] NodeId: Indicates support for NodeId MSR (0xc001100c)
// [21:21] Reserved
// [22:22] TBM: trailing bit manipulation instructions support
// [23:23] Topology extensions support
// [31:24] Reserved
leaf->ecx = BX_CPUID_EXT2_LAHF_SAHF |
BX_CPUID_EXT2_CMP_LEGACY |
#if BX_SUPPORT_SVM
BX_CPUID_EXT2_SVM |
#endif
BX_CPUID_EXT2_EXT_APIC_SPACE |
BX_CPUID_EXT2_ALT_MOV_CR8 |
BX_CPUID_EXT2_PREFETCHW;
// EDX:
// Many of the bits in EDX are the same as FN 0x00000001 for AMD
// * [0:0] FPU on chip
// * [1:1] VME: Virtual-8086 Mode enhancements
// * [2:2] DE: Debug Extensions (I/O breakpoints)
// * [3:3] PSE: Page Size Extensions
// * [4:4] TSC: Time Stamp Counter
// * [5:5] MSR: RDMSR and WRMSR support
// * [6:6] PAE: Physical Address Extensions
// * [7:7] MCE: Machine Check Exception
// * [8:8] CXS: CMPXCHG8B instruction
// * [9:9] APIC: APIC on Chip
// [10:10] Reserved
// * [11:11] SYSCALL/SYSRET support
// * [12:12] MTRR: Memory Type Range Reg
// * [13:13] PGE/PTE Global Bit
// * [14:14] MCA: Machine Check Architecture
// * [15:15] CMOV: Cond Mov/Cmp Instructions
// * [16:16] PAT: Page Attribute Table
// * [17:17] PSE-36: Physical Address Extensions
// [18:18] Reserved
// [19:19] Reserved
// * [20:20] No-Execute page protection
// [21:21] Reserved
// * [22:22] AMD MMX Extensions
// * [23:23] MMX Technology
// * [24:24] FXSR: FXSAVE/FXRSTOR (also indicates CR4.OSFXSR is available)
// * [25:25] Fast FXSAVE/FXRSTOR mode support
// [26:26] 1G paging support
// * [27:27] Support RDTSCP Instruction
// [28:28] Reserved
// * [29:29] Long Mode
// * [30:30] AMD 3DNow! Extensions
// * [31:31] AMD 3DNow! Instructions
leaf->edx = BX_CPUID_STD_X87 |
BX_CPUID_STD_VME |
BX_CPUID_STD_DEBUG_EXTENSIONS |
BX_CPUID_STD_PSE |
BX_CPUID_STD_TSC |
BX_CPUID_STD_MSR |
BX_CPUID_STD_PAE |
BX_CPUID_STD_MCE |
BX_CPUID_STD_CMPXCHG8B |
BX_CPUID_STD2_SYSCALL_SYSRET |
BX_CPUID_STD_MTRR |
BX_CPUID_STD_GLOBAL_PAGES |
BX_CPUID_STD_MCA |
BX_CPUID_STD_CMOV |
BX_CPUID_STD_PAT |
BX_CPUID_STD_PSE36 |
BX_CPUID_STD2_NX |
BX_CPUID_STD2_AMD_MMX_EXT |
BX_CPUID_STD_MMX |
BX_CPUID_STD_FXSAVE_FXRSTOR |
BX_CPUID_STD2_FFXSR |
BX_CPUID_STD2_RDTSCP |
BX_CPUID_STD2_LONG_MODE |
BX_CPUID_STD2_3DNOW_EXT |
BX_CPUID_STD2_3DNOW;
#if BX_SUPPORT_APIC
// if MSR_APICBASE APIC Global Enable bit has been cleared,
// the CPUID feature flag for the APIC is set to 0.
if (cpu->msr.apicbase & 0x800)
leaf->edx |= BX_CPUID_STD_APIC; // APIC on chip
#endif
}
// leaf 0x80000002 //
// leaf 0x80000003 //
// leaf 0x80000004 //
// leaf 0x80000005 //
void turion64_tyler_t::get_ext_cpuid_leaf_5(cpuid_function_t *leaf) const
{
// CPUID function 0x800000005 - L1 Cache and TLB Identifiers
leaf->eax = 0xFF08FF08;
leaf->ebx = 0xFF20FF20;
leaf->ecx = 0x40020140;
leaf->edx = 0x40020140;
}
// leaf 0x80000006 //
void turion64_tyler_t::get_ext_cpuid_leaf_6(cpuid_function_t *leaf) const
{
// CPUID function 0x800000006 - L2 Cache and TLB Identifiers
leaf->eax = 0x00000000;
leaf->ebx = 0x42004200;
leaf->ecx = 0x02008140;
leaf->edx = 0x00000000;
}
// leaf 0x80000007 //
void turion64_tyler_t::get_ext_cpuid_leaf_7(cpuid_function_t *leaf) const
{
// CPUID function 0x800000007 - Advanced Power Management
leaf->eax = 0;
leaf->ebx = 0;
leaf->ecx = 0;
leaf->edx = 0x0000007F;
}
// leaf 0x80000008 //
void turion64_tyler_t::get_ext_cpuid_leaf_8(cpuid_function_t *leaf) const
{
// virtual & phys address size in low 2 bytes.
leaf->eax = BX_PHY_ADDRESS_WIDTH | (BX_LIN_ADDRESS_WIDTH << 8);
leaf->ebx = 0;
leaf->ecx = ncores - 1;
leaf->edx = 0;
}
// leaf 0x80000009 : Reserved //
#if BX_SUPPORT_SVM
// leaf 0x8000000A : SVM //
void turion64_tyler_t::get_ext_cpuid_leaf_A(cpuid_function_t *leaf) const
{
leaf->eax = 0x01; /* SVM revision ID */
leaf->ebx = 0x40; /* number of ASIDs */
leaf->ecx = 0;
// [0:0] NP - Nested paging support
// * [1:1] LBR virtualization
// [2:2] SVM Lock
// [3:3] NRIPS - Next RIP save on VMEXIT
// [4:4] TscRate - MSR based TSC ratio control
// [5:5] VMCB Clean bits support
// [6:6] Flush by ASID support
// [7:7] Decode assists support
// [9:8] Reserved
// [10:10] Pause filter support
// [11:11] Reserved
// [12:12] Pause filter threshold support
// [31:13] Reserved
leaf->edx = BX_CPUID_SVM_LBR_VIRTUALIZATION;
}
#endif
// leaf 0x8000000B - 0x80000018: Reserved //
void turion64_tyler_t::dump_cpuid(void) const
{
struct cpuid_function_t leaf;
unsigned n;
for (n=0; n<=1; n++) {
get_cpuid_leaf(n, 0x00000000, &leaf);
BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx));
}
for (n=0x80000000; n<=0x80000018; n++) {
get_cpuid_leaf(n, 0x00000000, &leaf);
BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx));
}
}
bx_cpuid_t *create_turion64_tyler_cpuid(BX_CPU_C *cpu) { return new turion64_tyler_t(cpu); }
#endif