Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff -Naur -x BUILD -x .DS_Store -x '*.orig' -x '*.swp' -x '*.rej' xnu-2050.7.9/iokit/Kernel/IOCatalogue.cpp xnu-2050.7.9-sinetek/iokit/Kernel/IOCatalogue.cpp
- --- xnu-2050.7.9/iokit/Kernel/IOCatalogue.cpp 2012-02-15 20:11:52.000000000 -0500
- +++ xnu-2050.7.9-sinetek/iokit/Kernel/IOCatalogue.cpp 2012-12-31 10:38:11.000000000 -0500
- @@ -38,6 +38,21 @@
- * Version 2.0.
- */
- +/* Sinetek: Array of blacklisted Kexts.
- + * Should be moved somewhere convenient?
- + */
- +const char *blak [] = {
- + "com.apple.driver.AppleIntelMeromProfile",
- + "com.apple.driver.AppleIntelNehalemProfile",
- + "com.apple.driver.AppleIntelPenrynProfile",
- + "com.apple.driver.AppleIntelYonahProfile",
- + "com.apple.driver.AppleIntelCPUPowerManagement",
- + "com.apple.iokit.CHUDKernLib",
- + "com.apple.iokit.CHUDProf",
- + "com.apple.iokit.CHUDUtils",
- + 0, // terminate!
- +};
- +
- extern "C" {
- #include <machine/machine_routines.h>
- #include <libkern/kernel_mach_header.h>
- @@ -332,6 +347,30 @@
- break;
- }
- + /* Sinetek: if the kext is in blacklist, skip it TODO make this a function */
- + boolean_t blacklistEnabled = TRUE;
- + printf("BLACKLIST %s\n", blacklistEnabled? "enabled" : "disabled");
- + if(blacklistEnabled) {
- + OSString *moduleName = OSDynamicCast(OSString, personality->getObject(gIOModuleIdentifierKey));
- + const char *cName = NULL;
- + cName = moduleName->getCStringNoCopy();
- + boolean_t blackPersonality = FALSE;
- +
- + if(cName) {
- + for(int i = 0; blak[i] != NULL; ++i) {
- + int equal;
- + equal = !strcmp(blak[i], cName);
- + if(equal) {
- + printf("Skipping personality %s", cName);
- + blackPersonality = TRUE;
- + }
- + }
- + }
- +
- + if(blackPersonality) continue;
- + }
- + /* end Sinetek */
- +
- OSKext::uniquePersonalityProperties(personality);
- // Add driver personality to catalogue.
- @@ -840,6 +879,31 @@
- (thisNewPersonality = (OSDictionary *) newPersonalities->getObject(newIdx));
- newIdx++)
- {
- + /* Sinetek: if the kext is in blacklist, skip it TODO make this a function */
- + boolean_t blacklistEnabled = TRUE;
- + printf("BLACKLIST %s\n", blacklistEnabled? "enabled" : "disabled");
- + if(blacklistEnabled) {
- + OSString *moduleName = OSDynamicCast(OSString, thisNewPersonality->getObject(gIOModuleIdentifierKey));
- + const char *cName = NULL;
- + cName = moduleName->getCStringNoCopy();
- + boolean_t blackPersonality = FALSE;
- +
- + if(cName) {
- + for(int i = 0; blak[i] != NULL; ++i) {
- + int equal;
- + equal = !strcmp(blak[i], cName);
- + if(equal) {
- + printf("Skipping personality %s", cName);
- + blackPersonality = TRUE;
- + }
- + }
- + }
- +
- + if(blackPersonality) continue;
- + }
- + /* end Sinetek */
- +
- +
- OSKext::uniquePersonalityProperties(thisNewPersonality);
- addPersonality(thisNewPersonality);
- matchSet->setObject(thisNewPersonality);
- diff -Naur -x BUILD -x .DS_Store -x '*.orig' -x '*.swp' -x '*.rej' xnu-2050.7.9/makedefs/MakeInc.def xnu-2050.7.9-sinetek/makedefs/MakeInc.def
- --- xnu-2050.7.9/makedefs/MakeInc.def 2012-07-24 11:57:49.000000000 -0400
- +++ xnu-2050.7.9-sinetek/makedefs/MakeInc.def 2012-12-31 10:38:11.000000000 -0500
- @@ -243,11 +243,11 @@
- # Compiler warning flags
- #
- -CWARNFLAGS_STD = \
- - -Wall -Werror -Wno-format-y2k -Wextra -Wstrict-prototypes \
- - -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wcast-qual \
- - -Wwrite-strings -Wswitch -Wshadow -Wcast-align -Wchar-subscripts \
- - -Winline -Wnested-externs -Wredundant-decls -Wextra-tokens
- +#CWARNFLAGS_STD = \
- +# -Wall -Werror -Wno-format-y2k -Wextra -Wstrict-prototypes \
- +# -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wcast-qual \
- +# -Wwrite-strings -Wswitch -Wshadow -Wcast-align -Wchar-subscripts \
- +# -Winline -Wnested-externs -Wredundant-decls -Wextra-tokens
- # Certain warnings are non-fatal (8474835)
- CWARNFLAGS_STD += -Wno-error=cast-align
- @@ -259,10 +259,10 @@
- $(1)_CWARNFLAGS_ADD += $2
- endef
- -CXXWARNFLAGS_STD = \
- - -Wall -Werror -Wno-format-y2k -Wextra -Wpointer-arith -Wreturn-type \
- - -Wcast-qual -Wwrite-strings -Wswitch -Wcast-align -Wchar-subscripts \
- - -Wredundant-decls -Wextra-tokens
- +#CXXWARNFLAGS_STD = \
- +# -Wall -Werror -Wno-format-y2k -Wextra -Wpointer-arith -Wreturn-type \
- +# -Wcast-qual -Wwrite-strings -Wswitch -Wcast-align -Wchar-subscripts \
- +# -Wredundant-decls -Wextra-tokens
- # Certain warnings are non-fatal (8474835, 9000888)
- CXXWARNFLAGS_STD += -Wno-error=cast-align -Wno-error=overloaded-virtual
- @@ -337,13 +337,13 @@
- endif
- -export CFLAGS_RELEASEI386 = -O2
- -export CFLAGS_DEVELOPMENTI386 = -O2
- +export CFLAGS_RELEASEI386 = -O2 -march=k8
- +export CFLAGS_DEVELOPMENTI386 = -O2 -march=k8
- export CFLAGS_DEBUGI386 = -O0
- export CFLAGS_PROFILEI386 = -O2
- -export CFLAGS_RELEASEX86_64 = -O2
- -export CFLAGS_DEVELOPMENTX86_64 = -O2
- +export CFLAGS_RELEASEX86_64 = -O3 -march=k8
- +export CFLAGS_DEVELOPMENTX86_64 = -O2 -march=k8
- # No space optimization for the DEBUG kernel for the benefit of gdb:
- export CFLAGS_DEBUGX86_64 = -O0
- export CFLAGS_PROFILEX86_64 = -O2
- diff -Naur -x BUILD -x .DS_Store -x '*.orig' -x '*.swp' -x '*.rej' xnu-2050.7.9/osfmk/conf/files xnu-2050.7.9-sinetek/osfmk/conf/files
- --- xnu-2050.7.9/osfmk/conf/files 2012-04-06 20:50:07.000000000 -0400
- +++ xnu-2050.7.9-sinetek/osfmk/conf/files 2012-12-31 10:38:11.000000000 -0500
- @@ -275,3 +275,5 @@
- osfmk/kperf/timetrigger.c optional kperf
- osfmk/console/serial_general.c standard
- +
- +osfmk/kern/opemu.c standard
- diff -Naur -x BUILD -x .DS_Store -x '*.orig' -x '*.swp' -x '*.rej' xnu-2050.7.9/osfmk/i386/commpage/commpage.c xnu-2050.7.9-sinetek/osfmk/i386/commpage/commpage.c
- --- xnu-2050.7.9/osfmk/i386/commpage/commpage.c 2012-02-25 01:42:08.000000000 -0500
- +++ xnu-2050.7.9-sinetek/osfmk/i386/commpage/commpage.c 2012-12-31 11:24:46.000000000 -0500
- @@ -226,7 +226,7 @@
- bits |= kHasSupplementalSSE3;
- /* fall thru */
- case 5:
- - bits |= kHasSSE3;
- + bits |= kHasSSE3 | kHasSupplementalSSE3 | kHasSSE4_2;
- /* fall thru */
- case 4:
- bits |= kHasSSE2;
- diff -Naur -x BUILD -x .DS_Store -x '*.orig' -x '*.swp' -x '*.rej' xnu-2050.7.9/osfmk/i386/cpuid.c xnu-2050.7.9-sinetek/osfmk/i386/cpuid.c
- --- xnu-2050.7.9/osfmk/i386/cpuid.c 2012-07-24 11:57:43.000000000 -0400
- +++ xnu-2050.7.9-sinetek/osfmk/i386/cpuid.c 2012-12-31 11:18:06.000000000 -0500
- @@ -260,6 +260,135 @@
- "Lnone", "L1I", "L1D", "L2U", "L3U"
- };
- +/* Sinetek: reimplemented, based on AnV, mercurySquad, thanks go to them.
- + * Function is AMD-specific.
- + */
- +static void
- +cpuid_set_AMDcache_info( i386_cpu_info_t * info_p )
- +{
- + uint32_t reg[4];
- + uint32_t linesizes[LCACHE_MAX];
- + cache_type_t type;
- + uint32_t j;
- + uint32_t colors;
- +
- + bzero( linesizes, sizeof(linesizes) );
- +
- + /* get number of cores in processor */
- + /* No HT on AMD so logicals = cores */
- + cpuid_fn(0x80000008, reg);
- + info_p->cpuid_cores_per_package = bitfield32(reg[ecx], 7, 0) + 1;
- + info_p->cpuid_logical_per_package = info_p->cpuid_cores_per_package;
- +
- +
- + /* L1 Data */
- + {
- + type = L1D;
- + cpuid_fn(0x80000005, reg);
- + uint32_t cpuid_c_linesize = bitfield32(reg[ecx], 7, 0);
- + uint32_t cpuid_c_partitions = bitfield32(reg[ecx], 15, 8);
- + uint32_t cpuid_c_associativity = bitfield32(reg[ecx], 23, 16);
- + uint32_t cpuid_c_size = bitfield32(reg[ecx], 31, 24);
- +
- + uint32_t cache_associativity = cpuid_c_associativity;
- +
- + // size reported in KB.
- + info_p->cache_size[type] = cpuid_c_size * 1024;
- + info_p->cache_sharing[type] = 1;
- + info_p->cache_partitions[type] = cpuid_c_partitions;
- +
- + linesizes[type] = cpuid_c_linesize;
- + uint32_t cache_sets = info_p->cache_size[type] / (cpuid_c_partitions * cpuid_c_linesize * cache_associativity);
- +
- + colors = ( cpuid_c_linesize * cache_sets ) >> 12;
- + if ( colors > vm_cache_geometry_colors )
- + vm_cache_geometry_colors = colors;
- + }
- + /* L1 Instruction */
- + {
- + type = L1I;
- + cpuid_fn(0x80000005, reg);
- + uint32_t cpuid_c_linesize = bitfield32(reg[edx], 7, 0);
- + uint32_t cpuid_c_partitions = bitfield32(reg[edx], 15, 8);
- + uint32_t cpuid_c_associativity = bitfield32(reg[edx], 23, 16);
- + uint32_t cpuid_c_size = bitfield32(reg[edx], 31, 24);
- +
- + uint32_t cache_associativity = cpuid_c_associativity;
- +
- + // size reported in KB.
- + info_p->cache_size[type] = cpuid_c_size * 1024;
- + info_p->cache_sharing[type] = 1;
- + info_p->cache_partitions[type] = cpuid_c_partitions;
- +
- + linesizes[type] = cpuid_c_linesize;
- + uint32_t cache_sets = info_p->cache_size[type] / (cpuid_c_partitions * cpuid_c_linesize * cache_associativity);
- +
- + colors = ( cpuid_c_linesize * cache_sets ) >> 12;
- + if ( colors > vm_cache_geometry_colors )
- + vm_cache_geometry_colors = colors;
- + }
- + /* L2 Unified */
- + {
- + type = L1D;
- + cpuid_fn(0x80000006, reg);
- + uint32_t cpuid_c_linesize = bitfield32(reg[ecx], 7, 0);
- + uint32_t cpuid_c_partitions = bitfield32(reg[ecx], 11, 8);
- + uint32_t cpuid_c_associativity = bitfield32(reg[ecx], 15, 12);
- + uint32_t cpuid_c_size = bitfield32(reg[ecx], 31, 16);
- +
- + // Special formula for associativity: 2^(assoc / 2)
- + uint32_t cache_associativity = 1ul << (cpuid_c_associativity / 2);
- +
- + // size reported in KB.
- + info_p->cache_size[type] = cpuid_c_size * 1024;
- + info_p->cache_sharing[type] = 1;
- + info_p->cache_partitions[type] = cpuid_c_partitions;
- +
- + linesizes[type] = cpuid_c_linesize;
- + uint32_t cache_sets = info_p->cache_size[type] / (cpuid_c_partitions * cpuid_c_linesize * cache_associativity);
- +
- + colors = ( cpuid_c_linesize * cache_sets ) >> 12;
- + if ( colors > vm_cache_geometry_colors )
- + vm_cache_geometry_colors = colors;
- +
- + // use for cache size etc.
- + info_p->cpuid_cache_L2_associativity = cache_associativity;
- + info_p->cpuid_cache_size = info_p->cache_size[type];
- + info_p->cache_linesize = cpuid_c_linesize;
- + }
- + /* L3 Unified */
- + {
- + type = L1D;
- + cpuid_fn(0x80000006, reg);
- + uint32_t cpuid_c_linesize = bitfield32(reg[edx], 7, 0);
- + uint32_t cpuid_c_partitions = bitfield32(reg[edx], 11, 8);
- + uint32_t cpuid_c_associativity = bitfield32(reg[edx], 15, 12);
- + uint32_t cpuid_c_size = bitfield32(reg[edx], 31, 18);
- +
- + // Special formula for associativity: 2^(assoc / 2)
- + uint32_t cache_associativity = 1ul << (cpuid_c_associativity / 2);
- +
- + if(cpuid_c_size == 0) {
- + // no L3
- + info_p->cache_size[type] = 0;
- + info_p->cache_sharing[type] = 0;
- + info_p->cache_partitions[type] = 0;
- + } else {
- + // size reported in 512 KB packs.
- + info_p->cache_size[type] = cpuid_c_size * 1024;
- + info_p->cache_sharing[type] = 1;
- + info_p->cache_partitions[type] = cpuid_c_partitions;
- +
- + linesizes[type] = cpuid_c_linesize;
- + uint32_t cache_sets = info_p->cache_size[type] / (cpuid_c_partitions * cpuid_c_linesize * cache_associativity);
- +
- + colors = ( cpuid_c_linesize * cache_sets ) >> 12;
- + if ( colors > vm_cache_geometry_colors )
- + vm_cache_geometry_colors = colors;
- + }
- + }
- +}
- +
- /* this function is Intel-specific */
- static void
- cpuid_set_cache_info( i386_cpu_info_t * info_p )
- @@ -572,10 +701,10 @@
- * and bracket this with the approved procedure for reading the
- * the microcode version number a.k.a. signature a.k.a. BIOS ID
- */
- - wrmsr64(MSR_IA32_BIOS_SIGN_ID, 0);
- + //wrmsr64(MSR_IA32_BIOS_SIGN_ID, 0);
- cpuid_fn(1, reg);
- - info_p->cpuid_microcode_version =
- - (uint32_t) (rdmsr64(MSR_IA32_BIOS_SIGN_ID) >> 32);
- + //info_p->cpuid_microcode_version =
- + // (uint32_t) (rdmsr64(MSR_IA32_BIOS_SIGN_ID) >> 32);
- info_p->cpuid_signature = reg[eax];
- info_p->cpuid_stepping = bitfield32(reg[eax], 3, 0);
- info_p->cpuid_model = bitfield32(reg[eax], 7, 4);
- @@ -587,7 +716,7 @@
- info_p->cpuid_features = quad(reg[ecx], reg[edx]);
- /* Get "processor flag"; necessary for microcode update matching */
- - info_p->cpuid_processor_flag = (rdmsr64(MSR_IA32_PLATFORM_ID)>> 50) & 3;
- + //info_p->cpuid_processor_flag = (rdmsr64(MSR_IA32_PLATFORM_ID)>> 50) & 3;
- /* Fold extensions into family/model */
- if (info_p->cpuid_family == 0x0f)
- @@ -604,7 +733,8 @@
- if (info_p->cpuid_max_ext >= 0x80000001) {
- cpuid_fn(0x80000001, reg);
- info_p->cpuid_extfeatures =
- - quad(reg[ecx], reg[edx]);
- + quad(reg[ecx], reg[edx]) & ~CPUID_EXTFEATURE_XD;
- + /* Sinetek: AMD doesn't like the XD bit. */
- }
- DBG(" max_basic : %d\n", info_p->cpuid_max_basic);
- @@ -801,16 +931,22 @@
- cpuid_set_generic_info(info_p);
- /* verify we are running on a supported CPU */
- - if ((strncmp(CPUID_VID_INTEL, info_p->cpuid_vendor,
- + /*if ((strncmp(CPUID_VID_INTEL, info_p->cpuid_vendor,
- min(strlen(CPUID_STRING_UNKNOWN) + 1,
- sizeof(info_p->cpuid_vendor)))) ||
- (cpuid_set_cpufamily(info_p) == CPUFAMILY_UNKNOWN))
- - panic("Unsupported CPU");
- + panic("Unsupported CPU");*/
- + cpuid_set_cpufamily(info_p);
- info_p->cpuid_cpu_type = CPU_TYPE_X86;
- info_p->cpuid_cpu_subtype = CPU_SUBTYPE_X86_ARCH1;
- /* Must be invoked after set_generic_info */
- - cpuid_set_cache_info(&cpuid_cpu_info);
- + /* check if running on AMD, call right cache info function */
- + if(!strncmp(CPUID_VID_AMD, info_p->cpuid_vendor,
- + min(strlen(CPUID_STRING_UNKNOWN) + 1,
- + sizeof(info_p->cpuid_vendor)))) {
- + cpuid_set_AMDcache_info(&cpuid_cpu_info);
- + } else cpuid_set_cache_info(&cpuid_cpu_info);
- /*
- * Find the number of enabled cores and threads
- diff -Naur -x BUILD -x .DS_Store -x '*.orig' -x '*.swp' -x '*.rej' xnu-2050.7.9/osfmk/i386/cpuid.h xnu-2050.7.9-sinetek/osfmk/i386/cpuid.h
- --- xnu-2050.7.9/osfmk/i386/cpuid.h 2012-07-24 11:57:43.000000000 -0400
- +++ xnu-2050.7.9-sinetek/osfmk/i386/cpuid.h 2012-12-31 10:46:08.000000000 -0500
- @@ -167,6 +167,14 @@
- #define CPUID_MODEL_JAKETOWN 0x2D
- #define CPUID_MODEL_IVYBRIDGE 0x3A
- +/* kaitek: the following definitions are needed by tsc.c and kern_mib.c */
- +#define CPU_FAMILY_PENTIUM_M (0x6)
- +#define CPU_FAMILY_PENTIUM_4 (0xF)
- +#define CPU_FAMILY_AMD_PHENOM (0x10)
- +#define CPU_FAMILY_AMD_SHANGHAI (0x11)
- +#define CPU_FAMILY_I5 (0x1E)
- +#define CPU_FAMILY_I9 (0x2C)
- +#define CPU_FAMILY_SANDY (0x2A)
- #define CPUID_VMM_FAMILY_UNKNOWN 0x0
- #define CPUID_VMM_FAMILY_VMWARE 0x1
- @@ -358,6 +366,8 @@
- #ifdef __cplusplus
- extern "C" {
- #endif
- +extern boolean_t IsAmdCPU(void);
- +extern boolean_t IsIntelCPU(void);
- /*
- * External declarations
- diff -Naur -x BUILD -x .DS_Store -x '*.orig' -x '*.swp' -x '*.rej' xnu-2050.7.9/osfmk/i386/lapic_native.c xnu-2050.7.9-sinetek/osfmk/i386/lapic_native.c
- --- xnu-2050.7.9/osfmk/i386/lapic_native.c 2011-09-09 15:23:12.000000000 -0400
- +++ xnu-2050.7.9-sinetek/osfmk/i386/lapic_native.c 2012-12-31 10:38:11.000000000 -0500
- @@ -218,7 +218,7 @@
- lapic_ops->init();
- - if ((LAPIC_READ(VERSION)&LAPIC_VERSION_MASK) < 0x14) {
- + if ((LAPIC_READ(VERSION)&LAPIC_VERSION_MASK) < 0x10) {
- panic("Local APIC version 0x%x, 0x14 or more expected\n",
- (LAPIC_READ(VERSION)&LAPIC_VERSION_MASK));
- }
- diff -Naur -x BUILD -x .DS_Store -x '*.orig' -x '*.swp' -x '*.rej' xnu-2050.7.9/osfmk/i386/start.s xnu-2050.7.9-sinetek/osfmk/i386/start.s
- --- xnu-2050.7.9/osfmk/i386/start.s 2011-12-01 20:25:12.000000000 -0500
- +++ xnu-2050.7.9-sinetek/osfmk/i386/start.s 2012-12-31 10:38:11.000000000 -0500
- @@ -302,10 +302,6 @@
- orl $(CR4_PAE),%eax
- movl %eax,%cr4 /* enable page size extensions */
- - movl $(MSR_IA32_EFER), %ecx /* MSR number in ecx */
- - rdmsr /* MSR value return in edx: eax */
- - orl $(MSR_IA32_EFER_NXE), %eax /* Set NXE bit in low 32-bits */
- - wrmsr /* Update Extended Feature Enable reg */
- movl %cr0, %eax
- orl $(CR0_PG|CR0_WP), %eax
- diff -Naur -x BUILD -x .DS_Store -x '*.orig' -x '*.swp' -x '*.rej' xnu-2050.7.9/osfmk/i386/trap.c xnu-2050.7.9-sinetek/osfmk/i386/trap.c
- --- xnu-2050.7.9/osfmk/i386/trap.c 2012-02-25 01:42:08.000000000 -0500
- +++ xnu-2050.7.9-sinetek/osfmk/i386/trap.c 2012-12-31 10:38:11.000000000 -0500
- @@ -1059,6 +1059,9 @@
- break;
- case T_INVALID_OPCODE:
- + /* Sinetek: we'll handle this. */
- + opemu_trap(saved_state);
- +
- exc = EXC_BAD_INSTRUCTION;
- code = EXC_I386_INVOP;
- break;
- diff -Naur -x BUILD -x .DS_Store -x '*.orig' -x '*.swp' -x '*.rej' xnu-2050.7.9/osfmk/i386/tsc.c xnu-2050.7.9-sinetek/osfmk/i386/tsc.c
- --- xnu-2050.7.9/osfmk/i386/tsc.c 2012-03-21 20:24:34.000000000 -0400
- +++ xnu-2050.7.9-sinetek/osfmk/i386/tsc.c 2012-12-31 10:48:06.000000000 -0500
- @@ -72,6 +72,7 @@
- uint64_t tscGranularity = 0;
- uint64_t bus2tsc = 0;
- uint64_t busFreq = 0;
- +uint32_t kTscPanicOn = 0;
- uint32_t flex_ratio = 0;
- uint32_t flex_ratio_min = 0;
- uint32_t flex_ratio_max = 0;
- @@ -88,9 +89,31 @@
- #define Tera (kilo * Giga)
- #define Peta (kilo * Tera)
- -#define CPU_FAMILY_PENTIUM_M (0x6)
- +/* mercurysquad: The following enum specifies one of the bus ratio calc paths to take */
- +typedef enum {
- + BUSRATIO_BOOTFLAG,
- + BUSRATIO_ATHLON,
- + BUSRATIO_EFI,
- + BUSRATIO_PHENOM_SHANGHAI,
- + BUSRATIO_INTEL_MSR,
- + BUSRATIO_AUTODETECT,
- + BUSRATIO_PENTIUM4_MSR, // P4 model 2+ have an MSR too
- + BUSRATIO_TIMER
- +} busratio_path_t;
- +
- +static const char* busRatioPathNames[] = {
- + "Boot-time argument",
- + "AMD Athlon",
- + "Pentium 4 (via EFI)",
- + "AMD Phenom",
- + "Intel / Apple",
- + "Autodetect",
- + "Pentium 4 (via MSR)",
- + "Time the TSC"
- +};
- static const char FSB_Frequency_prop[] = "FSBFrequency";
- +static const char FSB_CPUFrequency_prop[] = "CPUFrequency";
- /*
- * This routine extracts the bus frequency in Hz from the device tree.
- */
- @@ -124,6 +147,87 @@
- }
- return frequency;
- }
- +/* mercurysquad:
- + * This routine extracts the cpu frequency from the efi device tree
- + * The value should be set by a custom EFI bootloader (only needed on CPUs which
- + * don't report the bus ratio in one of the MSRs.)
- + */
- +static uint64_t
- +EFI_CPU_Frequency(void)
- +{
- + uint64_t frequency = 0;
- + DTEntry entry;
- + void *value;
- + unsigned int size;
- +
- + if (DTLookupEntry(0, "/efi/platform", &entry) != kSuccess) {
- + kprintf("EFI_CPU_Frequency: didn't find /efi/platform\n");
- + return 0;
- + }
- + if (DTGetProperty(entry,FSB_CPUFrequency_prop,&value,&size) != kSuccess) {
- + kprintf("EFI_CPU_Frequency: property %s not found\n",
- + FSB_Frequency_prop);
- + return 0;
- + }
- + if (size == sizeof(uint64_t)) {
- + frequency = *(uint64_t *) value;
- + kprintf("EFI_CPU_Frequency: read %s value: %llu\n",
- + FSB_Frequency_prop, frequency);
- + if (!(10*Mega < frequency && frequency < 50*Giga)) {
- + kprintf("EFI_Fake_MSR: value out of range\n");
- + frequency = 0;
- + }
- + } else {
- + kprintf("EFI_CPU_Frequency: unexpected size %d\n", size);
- + }
- + return frequency;
- +}
- +
- +/*
- + * Convert the cpu frequency info into a 'fake' MSR198h in Intel format
- + */
- +static uint64_t
- +getFakeMSR(uint64_t frequency, uint64_t bFreq) {
- + uint64_t fakeMSR = 0ull;
- + uint64_t multi = 0;
- +
- + if (frequency == 0 || bFreq == 0)
- + return 0;
- +
- + multi = frequency / (bFreq / 1000); // = multi*1000
- + // divide by 1000, rounding up if it was x.75 or more
- + // Example: 12900 will get rounded to 13150/1000 = 13
- + // but 12480 will be 12730/1000 = 12
- + fakeMSR = (multi + 250) / 1000;
- + fakeMSR <<= 40; // push multiplier into bits 44 to 40
- +
- + // If fractional part was within (0.25, 0.75), set N/2
- + if ((multi % 1000 > 250) && (multi % 1000 < 750))
- + fakeMSR |= (1ull << 46);
- +
- + return fakeMSR;
- +}
- +
- +int ForceAmdCpu = 0;
- +
- +/* Handy functions to check what platform we're on */
- +boolean_t IsAmdCPU(void) {
- + if (ForceAmdCpu) return TRUE;
- +
- + uint32_t ourcpuid[4];
- + do_cpuid(0, ourcpuid);
- + if (ourcpuid[ebx] == 0x68747541 &&
- + ourcpuid[ecx] == 0x444D4163 &&
- + ourcpuid[edx] == 0x69746E65)
- + return TRUE;
- + else
- + return FALSE;
- +};
- +
- +boolean_t IsIntelCPU(void) {
- + return !IsAmdCPU(); // dirty hack
- +}
- +
- /*
- * Initialize the various conversion factors needed by code referencing
- @@ -192,22 +296,197 @@
- if (busFreq == 0)
- busFreq = BASE_NHM_CLOCK_SOURCE;
- - break;
- }
- + break;
- default: {
- - uint64_t prfsts;
- + /*
- + * mercurysquad: The bus ratio is crucial to setting the proper rtc increment.
- + * There are several methods so we first check any bootlfags. If none is specified, we choose
- + * based on the CPU type.
- + */
- + uint64_t cpuFreq = 0, prfsts = 0, boot_arg = 0;
- + busratio_path_t busRatioPath = BUSRATIO_AUTODETECT;
- +
- + if (PE_parse_boot_argn("busratiopath", &boot_arg, sizeof(boot_arg)))
- + busRatioPath = (busratio_path_t) boot_arg;
- + else
- + busRatioPath = BUSRATIO_AUTODETECT;
- +
- + if (PE_parse_boot_argn("busratio", &tscGranularity, sizeof(tscGranularity)))
- + busRatioPath = BUSRATIO_BOOTFLAG;
- +
- + if (busRatioPath == BUSRATIO_AUTODETECT) {
- + /* This happens if no bootflag above was specified.
- + * We'll choose based on CPU type */
- + switch (cpuid_info()->cpuid_family) {
- + case CPU_FAMILY_PENTIUM_4:
- + /* This could be AMD Athlon or Intel P4 as both have family Fh */
- + if (IsAmdCPU())
- + busRatioPath = BUSRATIO_ATHLON;
- + else if (cpuid_info()->cpuid_model < 2 )
- + /* These models don't implement proper MSR 198h or 2Ch */
- + busRatioPath = BUSRATIO_TIMER;
- + else if (cpuid_info()->cpuid_model == 2)
- + /* This model has an MSR we can use */
- + busRatioPath = BUSRATIO_PENTIUM4_MSR;
- + else /* 3 or higher */
- + /* Other models should implement MSR 198h */
- + busRatioPath = BUSRATIO_INTEL_MSR;
- + break;
- + case CPU_FAMILY_PENTIUM_M:
- + if (cpuid_info()->cpuid_model >= 0xD)
- + /* Pentium M or Core and above can use Apple method*/
- + busRatioPath = BUSRATIO_INTEL_MSR;
- + else
- + /* Other Pentium class CPU, use safest option */
- + busRatioPath = BUSRATIO_TIMER;
- + break;
- + case CPU_FAMILY_AMD_PHENOM:
- + case CPU_FAMILY_AMD_SHANGHAI:
- + /* These have almost the same method, with a minor difference */
- + busRatioPath = BUSRATIO_PHENOM_SHANGHAI;
- + break;
- + default:
- + /* Fall back to safest method */
- + busRatioPath = BUSRATIO_TIMER;
- + };
- + }
- +
- + /*
- + * Now that we have elected a bus ratio path, we can proceed to calculate it.
- + */
- + printf("rtclock_init: Taking bus ratio path %d (%s)\n",
- + busRatioPath, busRatioPathNames[busRatioPath]);
- + switch (busRatioPath) {
- + case BUSRATIO_BOOTFLAG:
- + /* tscGranularity was already set. However, check for N/2. N/2 is specified by
- + * giving a busratio of 10 times what it is (so last digit is 5). We set a cutoff
- + * of 30 before deciding it's n/2. TODO: find a better way */
- + if (tscGranularity == 0) tscGranularity = 1; // avoid div by zero
- + N_by_2_bus_ratio = (tscGranularity > 30) && ((tscGranularity % 10) != 0);
- + if (N_by_2_bus_ratio) tscGranularity /= 10; /* Scale it back to normal */
- + break;
- +#ifndef __i386__ //AnV: in case of x86_64 boot default for busratio timer to EFI value
- + case BUSRATIO_TIMER:
- +#endif
- + case BUSRATIO_EFI:
- + /* This uses the CPU frequency exported into EFI by the bootloader */
- + cpuFreq = EFI_CPU_Frequency();
- + prfsts = getFakeMSR(cpuFreq, busFreq);
- + tscGranularity = (uint32_t)bitfield(prfsts, 44, 40);
- + N_by_2_bus_ratio = prfsts & bit(46);
- + break;
- + case BUSRATIO_INTEL_MSR:
- + /* This will read the performance status MSR on intel systems (Apple method) */
- + prfsts = rdmsr64(IA32_PERF_STS);
- + tscGranularity = (uint32_t)bitfield(prfsts, 44, 40);
- + N_by_2_bus_ratio= prfsts & bit(46);
- + break;
- + case BUSRATIO_ATHLON:
- + /* Athlons specify the bus ratio directly in an MSR using a simple formula */
- + prfsts = rdmsr64(AMD_PERF_STS);
- + tscGranularity = 4 + bitfield(prfsts, 5, 1);
- + N_by_2_bus_ratio= prfsts & bit(0); /* FIXME: This is experimental! */
- + break;
- + case BUSRATIO_PENTIUM4_MSR:
- + prfsts = rdmsr64(0x2C); // TODO: Add to header
- + tscGranularity = bitfield(prfsts, 31, 24);
- + break;
- + case BUSRATIO_PHENOM_SHANGHAI:
- + /* Phenoms and Shanghai processors have a different MSR to read the frequency
- + * multiplier and divisor, from which the cpu frequency can be calculated.
- + * This can then be used to construct the fake MSR. */
- + prfsts = rdmsr64(AMD_COFVID_STS);
- + printf("rtclock_init: Phenom MSR 0x%x returned: 0x%llx\n", AMD_COFVID_STS, prfsts);
- + uint64_t cpuFid = bitfield(prfsts, 5, 0);
- + uint64_t cpuDid = bitfield(prfsts, 8, 6);
- + /* The base for Fid could be either 8 or 16 depending on the cpu family */
- + if (cpuid_info()->cpuid_family == CPU_FAMILY_AMD_PHENOM)
- + cpuFreq = (100 * Mega * (cpuFid + 0x10)) >> cpuDid;
- + else /* shanghai */
- + cpuFreq = (100 * Mega * (cpuFid + 0x08)) >> cpuDid;
- + prfsts = getFakeMSR(cpuFreq, busFreq);
- + tscGranularity = (uint32_t)bitfield(prfsts, 44, 40);
- + N_by_2_bus_ratio = prfsts & bit(46);
- + break;
- +#ifdef __i386__ //qoopz: no get_PIT2 for x86_64
- + case BUSRATIO_TIMER:
- + /* Fun fun fun. :-| */
- + cpuFreq = timeRDTSC() * 20;
- + prfsts = getFakeMSR(cpuFreq, busFreq);
- + tscGranularity = (uint32_t)bitfield(prfsts, 44, 40);
- + N_by_2_bus_ratio = prfsts & bit(46);
- + break;
- +#endif
- + case BUSRATIO_AUTODETECT:
- + default:
- + kTscPanicOn = 1; /* see sanity check below */
- + };
- +
- +#ifdef __i386__
- + /* Verify */
- + if (!PE_parse_boot_argn("-notscverify", &boot_arg, sizeof(boot_arg))) {
- + uint64_t realCpuFreq = timeRDTSC() * 20;
- + cpuFreq = tscGranularity * busFreq;
- + if (N_by_2_bus_ratio) cpuFreq += (busFreq / 2);
- + uint64_t difference = 0;
- + if (realCpuFreq > cpuFreq)
- + difference = realCpuFreq - cpuFreq;
- + else
- + difference = cpuFreq - realCpuFreq;
- +
- + if (difference >= 4*Mega) {
- + // Shouldn't have more than 4MHz difference. This is about 2-3% of most FSBs.
- + // Fall back to using measured speed and correct the busFreq
- + // Note that the tscGran was read from CPU so should be correct.
- + // Only on Phenom the tscGran is calculated by dividing by busFreq.
- + printf("TSC: Reported FSB: %4d.%04dMHz, ", (uint32_t)(busFreq / Mega), (uint32_t)(busFreq % Mega));
- + if (N_by_2_bus_ratio)
- + busFreq = (realCpuFreq * 2) / (1 + 2*tscGranularity);
- + else
- + busFreq = realCpuFreq / tscGranularity;
- + printf("corrected FSB: %4d.%04dMHz\n", (uint32_t)(busFreq / Mega), (uint32_t)(busFreq % Mega));
- + // Reset the busCvt factors
- + busFCvtt2n = ((1 * Giga) << 32) / busFreq;
- + busFCvtn2t = 0xFFFFFFFFFFFFFFFFULL / busFCvtt2n;
- + busFCvtInt = tmrCvt(1 * Peta, 0xFFFFFFFFFFFFFFFFULL / busFreq);
- + printf("TSC: Verification of clock speed failed. "
- + "Fallback correction was performed. Please upgrade bootloader.\n");
- + } else {
- + printf("TSC: Verification of clock speed PASSED.\n");
- + }
- + }
- +#else
- + printf("TSC: Verification of clock speed not available in x86_64.\n");
- +#endif
- +
- + /* Do a sanity check of the granularity */
- + if ((tscGranularity == 0) ||
- + (tscGranularity > 30) ||
- + (busFreq < 50*Mega) ||
- + (busFreq > 1*Giga) ||
- + /* The following is useful to force a panic to print diagnostic info */
- + PE_parse_boot_argn("-tscpanic", &boot_arg, sizeof(boot_arg)))
- + {
- + printf("\n\n");
- + printf(" >>> The real-time clock was not properly initialized on your system!\n");
- + printf(" Contact Voodoo Software for further information.\n");
- + kTscPanicOn = 1; /* Later when the console is initialized, this will show up, and we'll halt */
- + if (tscGranularity == 0) tscGranularity = 1; /* to avoid divide-by-zero in the following few lines */
- + }
- - prfsts = rdmsr64(IA32_PERF_STS);
- - tscGranularity = (uint32_t)bitfield(prfsts, 44, 40);
- - N_by_2_bus_ratio = (prfsts & bit(46)) != 0;
- }
- + break;
- }
- if (busFreq != 0) {
- busFCvtt2n = ((1 * Giga) << 32) / busFreq;
- busFCvtn2t = 0xFFFFFFFFFFFFFFFFULL / busFCvtt2n;
- } else {
- - panic("tsc_init: EFI not supported!\n");
- + /* Instead of panicking, set a default FSB frequency */
- + busFreq = 133*Mega;
- + kprintf("rtclock_init: Setting fsb to %u MHz\n", (uint32_t) (busFreq/Mega));
- +
- }
- kprintf(" BUS: Frequency = %6d.%06dMHz, "
- diff -Naur -x BUILD -x .DS_Store -x '*.orig' -x '*.swp' -x '*.rej' xnu-2050.7.9/osfmk/i386/tsc.h xnu-2050.7.9-sinetek/osfmk/i386/tsc.h
- --- xnu-2050.7.9/osfmk/i386/tsc.h 2010-04-21 21:25:23.000000000 -0400
- +++ xnu-2050.7.9-sinetek/osfmk/i386/tsc.h 2012-12-31 10:39:54.000000000 -0500
- @@ -44,6 +44,11 @@
- #define IA32_PERF_STS 0x198
- #define SLOW_TSC_THRESHOLD 1000067800 /* TSC is too slow for regular nanotime() algorithm */
- +/* mercurysquad: MSRs for AMD support (getting bus ratio) */
- +#define AMD_PERF_STS 0xC0010042 /* AMD's version of the MSR */
- +#define AMD_PSTATE0_STS 0xC0010064 /* K10/phenom class AMD cpus */
- +#define AMD_COFVID_STS 0xC0010071 /* This might be a better MSR for K10? */
- +
- #ifndef ASSEMBLER
- extern uint64_t busFCvtt2n;
- extern uint64_t busFCvtn2t;
- @@ -53,6 +58,7 @@
- extern uint64_t tscGranularity;
- extern uint64_t bus2tsc;
- extern uint64_t busFreq;
- +extern uint32_t kTscPanicOn;
- extern uint32_t flex_ratio;
- extern uint32_t flex_ratio_min;
- extern uint32_t flex_ratio_max;
- diff -Naur -x BUILD -x .DS_Store -x '*.orig' -x '*.swp' -x '*.rej' xnu-2050.7.9/osfmk/kern/opemu.c xnu-2050.7.9-sinetek/osfmk/kern/opemu.c
- --- xnu-2050.7.9/osfmk/kern/opemu.c 1969-12-31 19:00:00.000000000 -0500
- +++ xnu-2050.7.9-sinetek/osfmk/kern/opemu.c 2012-12-31 10:38:11.000000000 -0500
- @@ -0,0 +1,742 @@
- +#include <stdint.h>
- +#include "opemu.h"
- +/* ** SINETEK **
- +* This is an emulator for the SSSE3 instruction set.
- +* It is executed as a part of the XNU kernel as a trap.
- +*
- +* Information about SSSE3: there are 32 instructions.
- +* A few of these use MMX registers and are therefore just like XMM.
- +*/
- +
- +#ifndef TESTCASE
- +#include <kern/sched_prim.h>
- +#endif
- +
- +#if 0
- +#define printf(...)
- +#endif
- +
- +#ifndef TESTCASE
- +void print_buffer(uint8_t *buffer);
- +void print_buffer(uint8_t *buffer)
- +{
- + int i;
- + printf("DEBUG: emu: buffer data ");
- + for(i = 0; i < 15; ++i) {
- + kprintf("%02x ", buffer[i]);
- + }
- + kprintf("\n");
- +}
- +
- +void print_debug(uint8_t *buffer, x86_saved_state_t *saved_state);
- +void print_debug(uint8_t *buffer, x86_saved_state_t *saved_state)
- +{
- + if(is_saved_state64(saved_state)) {
- + x86_saved_state64_t *regs;
- + regs = saved_state64(saved_state);
- + kprintf("DEBUG: emu64: eip=%016llx\n", regs->isf.rip);
- + } else {
- + x86_saved_state32_t *regs;
- + regs = saved_state32(saved_state);
- + kprintf("DEBUG: emu32: eip=%08x\n", regs->eip);
- + }
- + print_buffer(buffer);
- +}
- +
- +void opemu_trap(
- + x86_saved_state_t *saved_state)
- +{
- + /* instructions are at most 15ish bytes
- + * can we just dereference something instead?
- + */
- + uint8_t buffered_code[15];
- +
- + if(is_saved_state64(saved_state)) {
- + x86_saved_state64_t *regs;
- + regs = saved_state64(saved_state);
- +
- + //kprintf("DEBUG: emu64: eip=%016llx\n", regs->isf.rip);
- + user_addr_t pc = regs->isf.rip;
- + copyin(pc, (char*)buffered_code, 15);
- + //print_buffer(buffered_code);
- + regs->isf.rip += opemu(buffered_code, saved_state);
- + //kprintf("returning from opemu %eip=%08x\n", regs->isf.rip);
- + } else {
- + x86_saved_state32_t *regs;
- + regs = saved_state32(saved_state);
- +
- + //kprintf("DEBUG: emu32: eip=%08x\n", regs->eip);
- + user_addr_t pc = regs->eip;
- + copyin(pc, (char*)buffered_code, 15);
- + //print_buffer(buffered_code);
- + int opsize = (int) opemu(buffered_code, saved_state);
- + regs->eip += opsize;
- + //kprintf("returning from opemu %eip=%08x\n", regs->eip);
- + }
- +
- + thread_exception_return();
- + /* NOTREACHED */
- +}
- +
- +// forward declaration for sysenter handler of mach;
- +void mach_call_munger(x86_saved_state_t *state);
- +void unix_syscall(x86_saved_state_t *);
- +uint64_t opemu(uint8_t *code, x86_saved_state_t *saved_state)
- +{
- + // size of the instruction in bytes. will serve for adjusting
- + // the return address;
- + int ins_size = 1;
- + XMM Xsrc, Xdst, Xres;
- + MM Msrc, Mdst, Mres;
- +
- + if(code[0] == 0x0F && code[1] == 0x34) {
- + // sysenter, TODO remove redundancy regs load
- + // edx return address
- + // ecx return stack
- + x86_saved_state32_t *regs;
- + regs = saved_state32(saved_state);
- + regs->eip = regs->edx;
- + regs->uesp = regs->ecx;
- +
- + if((signed int)regs->eax < 0) {
- + // printf("mach call\n");
- + mach_call_munger(saved_state);
- + } else {
- + // printf("unix call\n");
- + unix_syscall(saved_state);
- + }
- + /* NEVER REACHES */
- + } else if(code[0] == 0xFF) {
- + // Instruction 0xFFFF, used as a debugging aid. (2-byte NOP)
- + if(code[1] != 0xFF) goto invalid;
- + ins_size = 2;
- + } else if(
- + (code[0] == 0x66 && code[1] == 0x0F && code[2] == 0x38) ||
- + ((code[0] == 0x66 && code[2] == 0x0F && code[3] == 0x38)) ) {
- + // Instruction would be of type XMM (128-bit).
- + XMM *src, *dst, *rs;
- + unsigned int NSRC, NDST;
- + src = &Xsrc;
- + dst = &Xdst;
- + rs = &Xres;
- + ins_size = 5;
- + uint8_t opcode = code[3];
- +
- + /* In long mode, there is a possible 0x40->0x4f prefix
- + * used to handle the higher xmm registers.
- + */
- +
- + InterpretSSSE3Operands(&code[4], &NSRC, &NDST);
- + if(code[1] & 0x40) {
- + if(code[1] & 0x44) NDST += 8;
- + if(code[1] & 0x41) NSRC += 8;
- + opcode = code[4];
- + ins_size += 1;
- + }
- + getxmm(src, NSRC);
- + getxmm(dst, NDST);
- +
- + switch(opcode) {
- + case 0x00: pshufb128(src,dst,rs); break;
- + case 0x01: phaddw128(src,dst,rs); break;
- + case 0x02: phaddd128(src,dst,rs); break;
- + case 0x03: phaddsw128(src,dst,rs); break;
- + case 0x04: pmaddubsw128(src,dst,rs); break;
- + case 0x05: phsubw128(src,dst,rs); break;
- + case 0x06: phsubd128(src,dst,rs); break;
- + case 0x07: phsubsw128(src,dst,rs); break;
- + case 0x08: psignb128(src,dst,rs); break;
- + case 0x09: psignw128(src,dst,rs); break;
- + case 0x0A: psignd128(src,dst,rs); break;
- + case 0x0B: pmulhrsw128(src,dst,rs); break;
- + case 0x1C: pabsb128(src,rs); break;
- + case 0x1D: pabsw128(src,rs); break;
- + case 0x1E: pabsd128(src,rs); break;
- + default: goto invalid; break;
- + }
- + movxmm(rs, NDST);
- +
- + } else if(code[0] == 0x0F && code[1] == 0x38) {
- + // Instruction would be of type MMX (64-bit).
- + MM *src, *dst, *rs;
- + unsigned int NSRC, NDST; // reg 0 to 7 possible.
- + src = &Msrc;
- + dst = &Mdst;
- + rs = &Mres;
- + ins_size = 4;
- +
- + InterpretSSSE3Operands(&code[3], &NSRC, &NDST);
- + getmm(src, NSRC);
- + getmm(dst, NDST);
- +
- + switch(code[2]) {
- + case 0x00: pshufb64(src,dst,rs); break;
- + case 0x01: phaddw64(src,dst,rs); break;
- + case 0x02: phaddd64(src,dst,rs); break;
- + case 0x03: phaddsw64(src,dst,rs); break;
- + case 0x04: pmaddubsw64(src,dst,rs); break;
- + case 0x05: phsubw64(src,dst,rs); break;
- + case 0x06: phsubd64(src,dst,rs); break;
- + case 0x07: phsubsw64(src,dst,rs); break;
- + case 0x08: psignb64(src,dst,rs); break;
- + case 0x09: psignw64(src,dst,rs); break;
- + case 0x0A: psignd64(src,dst,rs); break;
- + case 0x0B: pmulhrsw64(src,dst,rs); break;
- + case 0x1C: pabsb64(src,rs); break;
- + case 0x1D: pabsw64(src,rs); break;
- + case 0x1E: pabsd64(src,rs); break;
- + default: goto invalid; break;
- + }
- + movmm(rs, NDST);
- +
- + } else if(code[0] == 0x0F && code[1] == 0x3A &&
- + code[2] == 0x0F) {
- + // Not groupable with the other ones. (64-bit).
- + MM *src, *dst, *rs;
- + unsigned int NSRC, NDST; // reg 0 to 7 possible.
- + src = &Msrc;
- + dst = &Mdst;
- + rs = &Mres;
- + ins_size = 5;
- +
- + InterpretSSSE3Operands(&code[3], &NSRC, &NDST);
- + getmm(src, NSRC);
- + getmm(dst, NDST);
- + palignr64(src,dst,rs,code[4]);
- + movmm(rs, NDST);
- +
- + } else if(
- + (code[0] == 0x66 && code[1] == 0x0F &&
- + code[2] == 0x3A && code[3] == 0x0F) ||
- + ((code[0] == 0x66 && code[2] == 0x0F &&
- + code[3] == 0x3A && code[4] == 0x0F) )
- + ) {
- + // Not groupable with the other ones. (128-bit).
- + XMM *src, *dst, *rs;
- + unsigned int NSRC, NDST;
- + src = &Xsrc;
- + dst = &Xdst;
- + rs = &Xres;
- + ins_size = 6;
- + uint8_t operand = code[5];
- + uint8_t modrm = code[4];
- +
- + /* In long mode, there is a possible 0x40->0x4f prefix
- + * used to handle the higher xmm registers.
- + */
- +
- + InterpretSSSE3Operands(&code[4], &NSRC, &NDST);
- + if(code[1] & 0x40) {
- + if(code[1] & 0x44) NDST += 8;
- + if(code[1] & 0x41) NSRC += 8;
- + modrm = code[5];
- + operand = code[6];
- + ins_size += 1;
- + }
- +
- + InterpretSSSE3Operands(&modrm, &NSRC, &NDST);
- + getxmm(src, NSRC);
- + getxmm(dst, NDST);
- + palignr128(src,dst,rs,operand);
- + movxmm(rs, NDST);
- +
- + } else {
- +invalid:
- + // Invalid opcode, report it
- + kprintf("EMU: invop\n");
- + printf("EMU: invop\n");
- + print_debug(code, saved_state);
- + }
- +
- +
- + return ins_size;
- +}
- +#endif
- +
- +/** interpret ModRM byte
- +* [2:0] -- source operand
- +* [5:4] -- destination operand
- +*/
- +inline void InterpretSSSE3Operands(uint8_t *ModRM, unsigned int *src,
- + unsigned int *dst)
- +{
- + *src = *ModRM & 0x7;
- + *dst = (*ModRM >> 3) & 0x7;
- +}
- +
- +/* get value from the xmm register i */
- +inline void getxmm(XMM *v, unsigned int i)
- +{
- + switch(i) {
- + case 0:
- + asm __volatile__ ("movdqu %%xmm0, %0" : "=m" (*v->a8));
- + break;
- + case 1:
- + asm __volatile__ ("movdqu %%xmm1, %0" : "=m" (*v->a8));
- + break;
- + case 2:
- + asm __volatile__ ("movdqu %%xmm2, %0" : "=m" (*v->a8));
- + break;
- + case 3:
- + asm __volatile__ ("movdqu %%xmm3, %0" : "=m" (*v->a8));
- + break;
- + case 4:
- + asm __volatile__ ("movdqu %%xmm4, %0" : "=m" (*v->a8));
- + break;
- + case 5:
- + asm __volatile__ ("movdqu %%xmm5, %0" : "=m" (*v->a8));
- + break;
- + case 6:
- + asm __volatile__ ("movdqu %%xmm6, %0" : "=m" (*v->a8));
- + break;
- + case 7:
- + asm __volatile__ ("movdqu %%xmm7, %0" : "=m" (*v->a8));
- + break;
- + case 8:
- + asm __volatile__ ("movdqu %%xmm8, %0" : "=m" (*v->a8));
- + break;
- + case 9:
- + asm __volatile__ ("movdqu %%xmm9, %0" : "=m" (*v->a8));
- + break;
- + case 10:
- + asm __volatile__ ("movdqu %%xmm10, %0" : "=m" (*v->a8));
- + break;
- + case 11:
- + asm __volatile__ ("movdqu %%xmm11, %0" : "=m" (*v->a8));
- + break;
- + case 12:
- + asm __volatile__ ("movdqu %%xmm12, %0" : "=m" (*v->a8));
- + break;
- + case 13:
- + asm __volatile__ ("movdqu %%xmm13, %0" : "=m" (*v->a8));
- + break;
- + case 14:
- + asm __volatile__ ("movdqu %%xmm14, %0" : "=m" (*v->a8));
- + break;
- + case 15:
- + asm __volatile__ ("movdqu %%xmm15, %0" : "=m" (*v->a8));
- + break;
- + }
- +}
- +
- +/* get value from the mm register i */
- +inline void getmm(MM *v, unsigned int i)
- +{
- + switch(i) {
- + case 0:
- + asm __volatile__ ("movq %%mm0, %0" : "=m" (*v->a8));
- + break;
- + case 1:
- + asm __volatile__ ("movq %%mm1, %0" : "=m" (*v->a8));
- + break;
- + case 2:
- + asm __volatile__ ("movq %%mm2, %0" : "=m" (*v->a8));
- + break;
- + case 3:
- + asm __volatile__ ("movq %%mm3, %0" : "=m" (*v->a8));
- + break;
- + case 4:
- + asm __volatile__ ("movq %%mm4, %0" : "=m" (*v->a8));
- + break;
- + case 5:
- + asm __volatile__ ("movq %%mm5, %0" : "=m" (*v->a8));
- + break;
- + case 6:
- + asm __volatile__ ("movq %%mm6, %0" : "=m" (*v->a8));
- + break;
- + case 7:
- + asm __volatile__ ("movq %%mm7, %0" : "=m" (*v->a8));
- + break;
- + }
- +}
- +
- +/* move value over to xmm register i */
- +inline void movxmm(XMM *v, unsigned int i)
- +{
- + switch(i) {
- + case 0:
- + asm __volatile__ ("movdqu %0, %%xmm0" :: "m" (*v->a8) );
- + break;
- + case 1:
- + asm __volatile__ ("movdqu %0, %%xmm1" :: "m" (*v->a8) );
- + break;
- + case 2:
- + asm __volatile__ ("movdqu %0, %%xmm2" :: "m" (*v->a8) );
- + break;
- + case 3:
- + asm __volatile__ ("movdqu %0, %%xmm3" :: "m" (*v->a8) );
- + break;
- + case 4:
- + asm __volatile__ ("movdqu %0, %%xmm4" :: "m" (*v->a8) );
- + break;
- + case 5:
- + asm __volatile__ ("movdqu %0, %%xmm5" :: "m" (*v->a8) );
- + break;
- + case 6:
- + asm __volatile__ ("movdqu %0, %%xmm6" :: "m" (*v->a8) );
- + break;
- + case 7:
- + asm __volatile__ ("movdqu %0, %%xmm7" :: "m" (*v->a8) );
- + break;
- + case 8:
- + asm __volatile__ ("movdqu %0, %%xmm8" :: "m" (*v->a8) );
- + break;
- + case 9:
- + asm __volatile__ ("movdqu %0, %%xmm9" :: "m" (*v->a8) );
- + break;
- + case 10:
- + asm __volatile__ ("movdqu %0, %%xmm10" :: "m" (*v->a8) );
- + break;
- + case 11:
- + asm __volatile__ ("movdqu %0, %%xmm11" :: "m" (*v->a8) );
- + break;
- + case 12:
- + asm __volatile__ ("movdqu %0, %%xmm12" :: "m" (*v->a8) );
- + break;
- + case 13:
- + asm __volatile__ ("movdqu %0, %%xmm13" :: "m" (*v->a8) );
- + break;
- + case 14:
- + asm __volatile__ ("movdqu %0, %%xmm14" :: "m" (*v->a8) );
- + break;
- + case 15:
- + asm __volatile__ ("movdqu %0, %%xmm15" :: "m" (*v->a8) );
- + break;
- + }
- +}
- +
- +/* move value over to mm register i */
- +inline void movmm(MM *v, unsigned int i)
- +{
- + switch(i) {
- + case 0:
- + asm __volatile__ ("movq %0, %%mm0" :: "m" (*v->a8) );
- + break;
- + case 1:
- + asm __volatile__ ("movq %0, %%mm1" :: "m" (*v->a8) );
- + break;
- + case 2:
- + asm __volatile__ ("movq %0, %%mm2" :: "m" (*v->a8) );
- + break;
- + case 3:
- + asm __volatile__ ("movq %0, %%mm3" :: "m" (*v->a8) );
- + break;
- + case 4:
- + asm __volatile__ ("movq %0, %%mm4" :: "m" (*v->a8) );
- + break;
- + case 5:
- + asm __volatile__ ("movq %0, %%mm5" :: "m" (*v->a8) );
- + break;
- + case 6:
- + asm __volatile__ ("movq %0, %%mm6" :: "m" (*v->a8) );
- + break;
- + case 7:
- + asm __volatile__ ("movq %0, %%mm7" :: "m" (*v->a8) );
- + break;
- + }
- +}
- +
- +/***************************************/
- +/** SSSE3 instructions implementation **/
- +/***************************************/
- +
- +#define SATSW(x) ((x > 32767)? 32767 : ((x < -32768)? -32768 : x) )
- +
- +
- +
- +/** complex byte shuffle **/
- +void pshufb128(XMM *src, XMM *dst, XMM *res)
- +{
- + int i;
- + for(i = 0; i < 16; ++i)
- + res->a8[i] = (src->a8[i] < 0) ? 0 :
- + dst->a8[src->a8[i] & 0xF];
- +}
- +
- +void pshufb64(MM *src, MM *dst, MM *res)
- +{
- + int i;
- + for(i = 0; i < 8; ++i)
- + res->a8[i] = (src->a8[i] < 0) ? 0 :
- + dst->a8[src->a8[i] & 0x7];
- +}
- +
- +/** packed horizontal add word **/
- +void phaddw128(XMM *src, XMM *dst, XMM *res)
- +{
- + int i;
- + for(i = 0; i < 4; ++i)
- + res->a16[i] = dst->a16[2*i] + dst->a16[2*i+1];
- + for(i = 0; i < 4; ++i)
- + res->a16[i+4] = src->a16[2*i] + src->a16[2*i+1];
- +}
- +
- +void phaddw64(MM *src, MM *dst, MM *res)
- +{
- + res->a16[0] = dst->a16[0] + dst->a16[1];
- + res->a16[1] = dst->a16[2] + dst->a16[3];
- + res->a16[2] = src->a16[0] + src->a16[1];
- + res->a16[3] = src->a16[2] + src->a16[3];
- +}
- +
- +/** packed horizontal add double **/
- +void phaddd128(XMM *src, XMM *dst, XMM *res)
- +{
- + int i;
- + for(i = 0; i < 2; ++i) {
- + res->a32[i ] = dst->a32[2*i] + dst->a32[2*i+1];
- + }
- + for(i = 0; i < 2; ++i)
- + res->a32[i+2] = src->a32[2*i] + src->a32[2*i+1];
- +}
- +
- +void phaddd64(MM *src, MM *dst, MM *res)
- +{
- + res->a32[0] = dst->a32[0] + dst->a32[1];
- + res->a32[1] = src->a32[0] + src->a32[1];
- +}
- +
- +/** packed horizontal add and saturate word **/
- +void phaddsw128(XMM *src, XMM *dst, XMM *res)
- +{
- + int i;
- + for(i = 0; i < 4; ++i)
- + res->a16[i] = SATSW( dst->a16[2*i] + dst->a16[2*i+1] );
- + for(i = 0; i < 4; ++i)
- + res->a16[i+4] = SATSW( src->a16[2*i] + src->a16[2*i+1] );
- +}
- +
- +void phaddsw64(MM *src, MM *dst, MM *res)
- +{
- + res->a16[0] = SATSW( dst->a16[0] + dst->a16[1] );
- + res->a16[1] = SATSW( dst->a16[2] + dst->a16[3] );
- + res->a16[2] = SATSW( src->a16[0] + src->a16[1] );
- + res->a16[3] = SATSW( src->a16[2] + src->a16[3] );
- +}
- +
- +/** multiply and add packed signed and unsigned bytes **/
- +void pmaddubsw128(XMM *src, XMM *dst, XMM *res)
- +{
- + int i;
- + int16_t tmp[16];
- + for(i=0; i<16; ++i) {
- + tmp[i] = src->a8[i] * dst->ua8[i];
- + }
- + for(i=0; i<8; ++i) {
- + res->a16[i] = SATSW( tmp[2*i] + tmp[2*i+1] );
- + }
- +}
- +
- +void pmaddubsw64(MM *src, MM *dst, MM *res)
- +{
- + int i;
- + int16_t tmp[8];
- + for(i=0; i<8; ++i) {
- + tmp[i] = src->a8[i] * dst->ua8[i];
- + }
- + for(i=0; i<4; ++i) {
- + res->a16[i] = SATSW( tmp[2*i] + tmp[2*i+1] );
- + }
- +}
- +
- +/** packed horizontal subtract word **/
- +void phsubw128(XMM *src, XMM *dst, XMM *res)
- +{
- + int i;
- + for(i = 0; i < 4; ++i)
- + res->a16[i] = dst->a16[2*i] - dst->a16[2*i+1];
- + for(i = 0; i < 4; ++i)
- + res->a16[i+4] = src->a16[2*i] - src->a16[2*i+1];
- +}
- +
- +void phsubw64(MM *src, MM *dst, MM *res)
- +{
- + res->a16[0] = dst->a16[0] - dst->a16[1];
- + res->a16[1] = dst->a16[2] - dst->a16[3];
- + res->a16[2] = src->a16[0] - src->a16[1];
- + res->a16[3] = src->a16[2] - src->a16[3];
- +}
- +
- +/** packed horizontal subtract double **/
- +void phsubd128(XMM *src, XMM *dst, XMM *res)
- +{
- + int i;
- + for(i = 0; i < 2; ++i)
- + res->a32[i ] = dst->a32[2*i] - dst->a32[2*i+1];
- + for(i = 0; i < 2; ++i)
- + res->a32[i+2] = src->a32[2*i] - src->a32[2*i+1];
- +}
- +
- +void phsubd64(MM *src, MM *dst, MM *res)
- +{
- + res->a32[0] = dst->a32[0] - dst->a32[1];
- + res->a32[1] = src->a32[0] - src->a32[1];
- +}
- +
- +/** packed horizontal subtract and saturate word **/
- +void phsubsw128(XMM *src, XMM *dst, XMM *res)
- +{
- + int i;
- + for(i = 0; i < 4; ++i)
- + res->a16[i] = SATSW( dst->a16[2*i] - dst->a16[2*i+1] );
- + for(i = 0; i < 4; ++i)
- + res->a16[i+4] = SATSW( src->a16[2*i] - src->a16[2*i+1] );
- +}
- +
- +void phsubsw64(MM *src, MM *dst, MM *res)
- +{
- + res->a16[0] = SATSW( dst->a16[0] - dst->a16[1] );
- + res->a16[1] = SATSW( dst->a16[2] - dst->a16[3] );
- + res->a16[2] = SATSW( src->a16[0] - src->a16[1] );
- + res->a16[3] = SATSW( src->a16[2] - src->a16[3] );
- +}
- +
- +/** packed sign byte **/
- +void psignb128(XMM *src, XMM *dst, XMM *res)
- +{
- + int i;
- + for(i = 0; i < 16; ++i) {
- + if(src->a8[i] < 0) res->a8[i] = -dst->a8[i];
- + else if(src->a8[i] == 0) res->a8[i] = 0;
- + else res->a8[i] = dst->a8[i];
- + }
- +}
- +
- +void psignb64(MM *src, MM *dst, MM *res)
- +{
- + int i;
- + for(i = 0; i < 8; ++i) {
- + if(src->a8[i] < 0) res->a8[i] = -dst->a8[i];
- + else if(src->a8[i] == 0) res->a8[i] = 0;
- + else res->a8[i] = dst->a8[i];
- + }
- +}
- +
- +/** packed sign word **/
- +void psignw128(XMM *src, XMM *dst, XMM *res)
- +{
- + int i;
- + for(i = 0; i < 8; ++i) {
- + if(src->a16[i] < 0) res->a16[i] = -dst->a16[i];
- + else if(src->a16[i] == 0) res->a16[i] = 0;
- + else res->a16[i] = dst->a16[i];
- + }
- +}
- +
- +void psignw64(MM *src, MM *dst, MM *res)
- +{
- + int i;
- + for(i = 0; i < 4; ++i) {
- + if(src->a16[i] < 0) res->a16[i] = -dst->a16[i];
- + else if(src->a16[i] == 0) res->a16[i] = 0;
- + else res->a16[i] = dst->a16[i];
- + }
- +}
- +
- +/** packed sign double **/
- +void psignd128(XMM *src, XMM *dst, XMM *res)
- +{
- + int i;
- + for(i = 0; i < 4; ++i) {
- + if(src->a32[i] < 0) res->a32[i] = -dst->a32[i];
- + else if(src->a32[i] == 0) res->a32[i] = 0;
- + else res->a32[i] = dst->a32[i];
- + }
- +}
- +
- +void psignd64(MM *src, MM *dst, MM *res)
- +{
- + int i;
- + for(i = 0; i < 2; ++i) {
- + if(src->a32[i] < 0) res->a32[i] = -dst->a32[i];
- + else if(src->a32[i] == 0) res->a32[i] = 0;
- + else res->a32[i] = dst->a32[i];
- + }
- +}
- +
- +/** packed multiply high with round and scale word **/
- +void pmulhrsw128(XMM *src, XMM *dst, XMM *res)
- +{
- + int i;
- + for(i = 0; i < 8; ++i)
- + res->a16[i] = (((dst->a16[i] * src->a16[i] >> 14) + 1) >> 1);
- +}
- +
- +void pmulhrsw64(MM *src, MM *dst, MM *res)
- +{
- + int i;
- + for(i = 0; i < 4; ++i)
- + res->a16[i] = (((dst->a16[i] * src->a16[i] >> 14) + 1) >> 1);
- +}
- +
- +/** packed absolute value byte **/
- +void pabsb128(XMM *src, XMM *res)
- +{
- + int i;
- + for(i = 0; i < 16; ++i)
- + if(src->a8[i] < 0) res->a8[i] = -src->a8[i];
- + else res->a8[i] = src->a8[i];
- +}
- +
- +void pabsb64(MM *src, MM *res)
- +{
- + int i;
- + for(i = 0; i < 8; ++i)
- + if(src->a8[i] < 0) res->a8[i] = -src->a8[i];
- + else res->a8[i] = src->a8[i];
- +}
- +
- +/** packed absolute value word **/
- +void pabsw128(XMM *src, XMM *res)
- +{
- + int i;
- + for(i = 0; i < 8; ++i)
- + if(src->a16[i] < 0) res->a16[i] = -src->a16[i];
- + else res->a16[i] = src->a16[i];
- +}
- +
- +void pabsw64(MM *src, MM *res)
- +{
- + int i;
- + for(i = 0; i < 4; ++i)
- + if(src->a16[i] < 0) res->a16[i] = -src->a16[i];
- + else res->a16[i] = src->a16[i];
- +}
- +
- +/** packed absolute value double **/
- +void pabsd128(XMM *src, XMM *res)
- +{
- + int i;
- + for(i = 0; i < 4; ++i)
- + if(src->a32[i] < 0) res->a32[i] = -src->a32[i];
- + else res->a32[i] = src->a32[i];
- +}
- +
- +void pabsd64(MM *src, MM *res)
- +{
- + int i;
- + for(i = 0; i < 2; ++i)
- + if(src->a32[i] < 0) res->a32[i] = -src->a32[i];
- + else res->a32[i] = src->a32[i];
- +}
- +
- +/** packed align right **/
- +void palignr128(XMM *src, XMM *dst, XMM *res, uint8_t IMM)
- +{
- + int n = IMM * 8;
- + __uint128_t low, high;
- + low = src->ua128;
- + high = dst->ua128;
- + res->ua128 = (low >> n) + (high << (128-n));
- +}
- +
- +void palignr64(MM *src, MM *dst, MM *res, uint8_t IMM)
- +{
- + int n = IMM * 8;
- + __uint128_t t;
- + t = src->ua64 | ((__uint128_t)dst->ua64 << 64);
- + t >>= n;
- + res->ua64 = t;
- +}
- +
- +
- diff -Naur -x BUILD -x .DS_Store -x '*.orig' -x '*.swp' -x '*.rej' xnu-2050.7.9/osfmk/kern/opemu.h xnu-2050.7.9-sinetek/osfmk/kern/opemu.h
- --- xnu-2050.7.9/osfmk/kern/opemu.h 1969-12-31 19:00:00.000000000 -0500
- +++ xnu-2050.7.9-sinetek/osfmk/kern/opemu.h 2012-12-31 10:38:11.000000000 -0500
- @@ -0,0 +1,81 @@
- +#ifndef OPEMU_H
- +#define OPEMU_H
- +#include <stdint.h>
- +
- +#ifndef TESTCASE
- +#include <mach/thread_status.h>
- +#endif
- +
- +union XMM_u {
- +int8_t a8[16];
- +int16_t a16[8];
- +int32_t a32[4];
- +int64_t a64[2];
- +__int128_t a128;
- +uint8_t ua8[16];
- +uint16_t ua16[8];
- +uint32_t ua32[4];
- +uint64_t ua64[2];
- +__uint128_t ua128;
- +};
- +typedef union XMM_u XMM;
- +
- +union MM_u {
- +int8_t a8[8];
- +int16_t a16[4];
- +int32_t a32[2];
- +int64_t a64;
- +uint8_t ua8[8];
- +uint16_t ua16[4];
- +uint32_t ua32[2];
- +uint64_t ua64;
- +};
- +typedef union MM_u MM;
- +
- +#ifndef TESTCASE
- +void opemu_trap(x86_saved_state_t *saved_state);
- +uint64_t opemu(uint8_t *code, x86_saved_state_t *saved_state);
- +#endif
- +inline void getxmm(XMM *v, unsigned int i);
- +inline void getmm(MM *v, unsigned int i);
- +inline void movxmm(XMM *v, unsigned int i);
- +inline void movmm(MM *v, unsigned int i);
- +inline void InterpretSSSE3Operands(uint8_t *ModRM,
- + unsigned int *src, unsigned int *dst);
- +
- +/** All 32 SSSE3 instructions **/
- +void pshufb128(XMM *src, XMM *dst, XMM *res);
- +void pshufb64(MM *src, MM *dst, MM *res);
- +void phaddw128(XMM *src, XMM *dst, XMM *res);
- +void phaddw64(MM *src, MM *dst, MM *res);
- +void phaddd128(XMM *src, XMM *dst, XMM *res);
- +void phaddd64(MM *src, MM *dst, MM *res);
- +void phaddsw128(XMM *src, XMM *dst, XMM *res);
- +void phaddsw64(MM *src, MM *dst, MM *res);
- +void pmaddubsw128(XMM *src, XMM *dst, XMM *res);
- +void pmaddubsw64(MM *src, MM *dst, MM *res);
- +void phsubw128(XMM *src, XMM *dst, XMM *res);
- +void phsubw64(MM *src, MM *dst, MM *res);
- +void phsubd128(XMM *src, XMM *dst, XMM *res);
- +void phsubd64(MM *src, MM *dst, MM *res);
- +void phsubsw128(XMM *src, XMM *dst, XMM *res);
- +void phsubsw64(MM *src, MM *dst, MM *res);
- +void psignb128(XMM *src, XMM *dst, XMM *res);
- +void psignb64(MM *src, MM *dst, MM *res);
- +void psignw128(XMM *src, XMM *dst, XMM *res);
- +void psignw64(MM *src, MM *dst, MM *res);
- +void psignd128(XMM *src, XMM *dst, XMM *res);
- +void psignd64(MM *src, MM *dst, MM *res);
- +void pmulhrsw128(XMM *src, XMM *dst, XMM *res);
- +void pmulhrsw64(MM *src, MM *dst, MM *res);
- +void pabsb128(XMM *src, XMM *res);
- +void pabsb64(MM *src, MM *res);
- +void pabsw128(XMM *src, XMM *res);
- +void pabsw64(MM *src, MM *res);
- +void pabsd128(XMM *src, XMM *res);
- +void pabsd64(MM *src, MM *res);
- +void palignr128(XMM *src, XMM *dst, XMM *res, uint8_t IMM);
- +void palignr64(MM *src, MM *dst, MM *res, uint8_t IMM);
- +
- +#endif
- +
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement