#!/bin/bash # # Script (ssdtPRGen.sh) to create ssdt-pr.dsl for Apple Power Management Support. # # Version 0.9 - Copyright (c) 2012 by RevoGirl # # Version 21.5 - Copyright (c) 2014-2017 by Pike # # Readme......: https://github.com/Piker-Alpha/ssdtPRGen.sh/blob/master/README.md # # Change log..: https://github.com/Piker-Alpha/ssdtPRGen.sh/blob/master/CHANGELOG.md # # Contributors: https://github.com/Piker-Alpha/ssdtPRGen.sh/blob/master/CONTRIBUTORS.md # # Bug reports.: https://github.com/Piker-Alpha/ssdtPRGen.sh/issues # # Please provide clear steps to reproduce the bug, the terminal output # of the script (the log data) and the resulting SSDT.dsl Thank you! # # set -x # Used for tracing errors (can be used anywhere in the script). #================================= GLOBAL VARS ================================== # # Script version info. # gScriptVersion=21.5 # # GitHub branch to pull data from (master or Beta). # gGitHubBranch="Beta" # # Github download URL. # gGitHubContentURL="https://raw.githubusercontent.com/Piker-Alpha/ssdtPRGen.sh/${gGitHubBranch}" # # Change this to 1 if you want to use the Github project directory instead of ~/Library/ssdtPRGen # let gDeveloperMode=0 # # The script expects '0.5' but non-US localizations use '0,5' so we export # LC_NUMERIC here (for the duration of the ssdtPRGen.sh) to prevent errors. # export LC_NUMERIC="en_US.UTF-8" # # Prevent non-printable/control characters (see issue #180). # unset GREP_OPTIONS unset GREP_COLORS unset GREP_COLOR # # Change this to 1 if you want to enable custom mode by default: # # Note: Custom mode will look for ~/Desktop/DSDT/APIC.aml and use that instead # of the ACPI tables (extracted during normal mode) from the host computer. # # _getProcessorNames - will use hardcoded processor names (not ioreg extracted). # _extractAcpiTables – will not extract ACPI tables. # let gCustomMode=0 # # Initial xcpm mode. Default value is -1 (uninitialised). # let gXcpm=-1 # # Change this when your CPU is stuck in Low Frequency Mode! # # 1 - Injects one extra Turbo P-State at he top with max-Turbo frequency + 1 MHz. # 2 - Injects N extra Turbo P-States at the bottom. # 3 - Injects both of them. # let gCPUWorkArounds=0 # # Ask for confirmation before copying the new SSDT to the target location. # let gAutoCopy=1 # # This is the target location that ssdt.aml will be copied to. # # Note: Do no change this - will be updated automatically for Clover/RevoBoot! # gDestinationPath="/Extra/" # # This is the filename used for the copy process # gDestinationFile="ssdt.aml" # # A value of 1 will make this script call iasl (compiles ssdt_pr.dsl) # # Note: Will be set to 0 when we failed to locate a copy of iasl! # let gCallIasl=1 # # Open generated SSDT on request (default value is 2). # # 0 = don't open the generated SSDT. # 1 = open the generated SSDT in the editor of your choice. # 2 = ask for confirmation before opening the generated SSDT in the editor of your choice. # let gCallOpen=2 # 0 = no debug injection/debug statements executed. # 1 = inject debug data. # 3 = inject debug data and execute _debugPrint statements. # let gDebug=1 # # Get user id # let gID=$(id -u) # # Lowest possible idle frequency (user configurable). Also known as Low Frequency Mode. # let gBaseFrequency=1600 # # Custom ACPI processor label (initialised by _updateProcessorNames). # gProcLabel="" gProcessorNames="" # # Uncomment/change this for dry runs. # # gProcessorNames=("C000" "C001" "C002" "C003" "C100" "C101" "C102" "C103") # gProcessorNames=("C000" "C001" "C002" "C003" "C004" "C005" "C006" "C007" "C008" "C009" "C00A" "C00B") # gProcessorNames=("C000" "C001" "C002" "C003" "C004" "C005" "C006" "C007" "C008" "C009" "C00A" "C00B" "C00C" "C00D" "C00E" "C00F" \ # "C100" "C101" "C102" "C103" "C104" "C105" "C106" "C107" "C108" "C109" "C10A" "C10B" "C10C" "C10D" "C10E" "C10F") # # The Processor scope will be initialised by _initProcessorScope). # gScope="" # # Legacy RevoBoot status (default value is 0). # let gIsLegacyRevoBoot=0 # # Change this to 0 if you don't want additional styling (bold/underlined). # let gExtraStyling=1 # # Global variable used by some functions to return a value to the callee. # let gFunctionReturn=0 # # Global variable used for the used/target board-id. # gBoardID="" # # Global variable used for the used/target board-id. # gModelID="" # # Number of logical processors. # let gLogicalCPUs=0 # # Number of physical processors. # let gPhysicalCPUs=1 # # Initialised in _getScriptArguments and used in . # let gTargetProcessorType=0 # # Number of logical cores per ACPI processor scope (initialised in main). # let gLogicalCPUsPerScope=0 # # Clock frequency (uninitialised). # let gFrequency=-1 # # Set to 1 if _PR scope is found in the DSDT. # let gScopePRFound=0 # # For future use! # # Note: Set this to 0 if you want to inject ACPI Processor (...) {} declarations intead of External () objects. # let gInjectExternalObjects=1 # # Output styling. # STYLE_RESET="" STYLE_BOLD="" STYLE_UNDERLINED="" # # Other global variables. # gRevision='0x000'${gScriptVersion:0:2}${gScriptVersion:3:1}'00' # # Path and filename setup. # gHome=$(echo $HOME) gPath="${gHome}/Library/ssdtPRGen" gDataPath="${gPath}/Data" gToolPath="${gPath}/Tools" gSsdtID="ssdt" gSsdtPR="${gPath}/${gSsdtID}.dsl" gACPITablePath="${gPath}/ACPI" # # Default override path for -mode custom # # Note: Path used to convert APIC/DSDT.aml to data format. # gOverridePath="${gHome}/Desktop" let gDesktopCPU=1 let gMobileCPU=2 let gServerCPU=3 let gSystemType=0 let gACST_CPU0=13 let gACST_CPU1=7 gTargetMacModel="" let USER_DEFINED=1 let SANDY_BRIDGE=2 let IVY_BRIDGE=4 let HASWELL=8 let BROADWELL=16 let SKYLAKE=32 let KABYLAKE=64 # # Array with configuration files (used to show version information). # gProcessorDataConfigFiles=("User Defined" "Sandy Bridge" "Ivy Bridge" "Haswell" "Broadwell" "Skylake" "Kaby Lake") # # Global variable used as target cpu/bridge type. # let gBridgeType=-1 let gTypeCPU=0 let gProcessorStartIndex=0 let gLfm=0 let gTdp=0 gProcessorData="Unknown CPU" gProcessorNumber="" gBusFrequency=100 # # Set to 1 after _setDestinationPath mounted the EFI partition. # let gUnmountEFIPartition=0 gProductName=$(sw_vers -productName) gProductVersion="$(sw_vers -productVersion)" gBuildVersion=$(sw_vers -buildVersion) let gOSVersion=$(echo $gProductVersion | tr -d '.') # # Maximum Turbo Clock Speed (user configurable) # let gMaxOCFrequency=6300 let MAX_TURBO_FREQUENCY_ERROR=2 let MAX_TDP_ERROR=3 let TARGET_CPU_ERROR=4 let PROCESSOR_NUMBER_ERROR=5 let PROCESSOR_LABEL_LENGTH_ERROR=6 let PROCESSOR_NAMES_ERROR=7 let PROCESSOR_DECLARATION_ERROR=8 let FILE_NOT_FOUND_ERROR=9 let LFM_ERROR=10 # # First OS version number that no longer requires extra Low Frequency Mode P-States. # # Note: For future use (when we figured out what we need). # let LFM_REQUIRED_OS=1091 # # Setup supported byte encodings # # Note: value is number of characters that we read. # let AML_SINGLE_BYTE_ENCODING=2 let AML_DUAL_BYTE_ENCODING=4 let AML_TRIPLE_BYTE_ENCODING=6 let AML_QUAD_BYTE_ENCODING=8 # # Setup used AML encoding values. # AML_SCOPE_OPCODE=10 AML_DEVICE_OPCODE=5b82 AML_PROCESSOR_SCOPE_OPCODE=5b83 # #-------------------------------------------------------------------------------- # function _PRINT_MSG() { local message=$1 if [[ $gExtraStyling -eq 1 ]]; then if [[ $message =~ 'Aborting ...' ]]; then local message=$(echo $message | sed -e 's/^Aborting ...//') local messageType='Aborting ...' else local messageType=$(echo $message | sed -e 's/:.*//g') if [[ $messageType =~ ^"\n" ]]; then local messageTypeStripped=$(echo $messageType | sed -e 's/^[\n]*//') else local messageTypeStripped=$messageType fi local message=":"$(echo $message | sed -e "s/^[\n]*${messageTypeStripped}://") fi printf "${STYLE_BOLD}${messageType}${STYLE_RESET}$message\n" else printf "${message}\n" fi } # #-------------------------------------------------------------------------------- # function _ABORT() { _PRINT_MSG "Aborting ...\nDone.\n\n" exit $1 } # #-------------------------------------------------------------------------------- # function _printHeader() { echo '/*' > "$gSsdtPR" echo ' * Intel ACPI Component Architecture' >> "$gSsdtPR" echo ' * AML Disassembler version 20140210-00 [Feb 10 2014]' >> "$gSsdtPR" echo ' * Copyright (c) 2000 - 2014 Intel Corporation' >> "$gSsdtPR" echo ' * ' >> "$gSsdtPR" echo ' * Original Table Header:' >> "$gSsdtPR" echo ' * Signature "SSDT"' >> "$gSsdtPR" echo ' * Length 0x0000036A (874)' >> "$gSsdtPR" echo ' * Revision 0x01' >> "$gSsdtPR" echo ' * Checksum 0x00' >> "$gSsdtPR" echo ' * OEM ID "APPLE "' >> "$gSsdtPR" echo ' * OEM Table ID "CpuPm"' >> "$gSsdtPR" printf ' * OEM Revision '$gRevision' (%d)\n' $gRevision >> "$gSsdtPR" echo ' * Compiler ID "INTL"' >> "$gSsdtPR" echo ' * Compiler Version 0x20140210 (538182160)' >> "$gSsdtPR" echo ' */' >> "$gSsdtPR" echo '' >> "$gSsdtPR" echo 'DefinitionBlock ("'$gSsdtID'.aml", "SSDT", 1, "APPLE ", "CpuPm", '$gRevision')' >> "$gSsdtPR" echo '{' >> "$gSsdtPR" } # #-------------------------------------------------------------------------------- # function _printExternalObjects() { # # Local variable definition. # local index local scopeIndex local maxCoresPerScope # # Local variable initialisation. # let index=0 let scopeIndex=1 # # Loop through all processor scopes. # for scope in "${gScope[@]}" do let maxCoresPerScope=($gLogicalCPUsPerScope*$scopeIndex) # # Are we done yet? # if [[ $index -eq $gLogicalCPUs ]]; then # # Yes. Bail out early. # return fi # # Are we targeting a multi-processor configuration? # if [[ $gPhysicalCPUs -gt 1 ]]; then # # Yes. Add a comment about the target device scope. # echo ' /* Device('${scope}') */' >> "$gSsdtPR" fi # # Inject External () object for each logical processor in this processor scope. # while [ $index -lt $maxCoresPerScope ]; do echo ' External ('${scope}'.'${gProcessorNames[$index]}', DeviceObj)' >> "$gSsdtPR" # # Next logical processor. # let index+=1 done # # Next processor scope. # let scopeIndex+=1 done } # #-------------------------------------------------------------------------------- # function _getPBlockAddress() { # # Get Processor Control Block (P_BLK) address from offset: 152/0x98 in FACP.aml # local data=$(xxd -s 152 -l 4 -ps "${gPath}/facp.aml") # # Convert data to Little Endian # local pblockAddress="0x${data:6:2}${data:4:2}${data:2:2}${data:0:2}" # # Increase P_BLK address with 16 # let pblockAddress+=0x10 # # Return P_BLK address + 16 # echo $(printf "0x%08x" $pblockAddress) } # #-------------------------------------------------------------------------------- # function _printProcessorDefinitions() { # # Local variable definition. # local index local scopeIndex local maxCoresPerScope local pBlockAddress=$(_getPBlockAddress) # # Local variable initialisation. # let index=0 let scopeIndex=1 # # Loop through all processor scopes. # for scope in "${gScope[@]}" do let maxCoresPerScope=($gLogicalCPUsPerScope*$scopeIndex) # # Do we have a device name? # if [[ $scope =~ ^"\_SB_." ]]; then local scopeName=$(echo $scope | sed -e 's/^\\_SB_\.//') echo ' Scope(\_SB_)' >> "$gSsdtPR" echo ' {' >> "$gSsdtPR" echo ' Device ('$scopeName')' >> "$gSsdtPR" echo ' {' >> "$gSsdtPR" echo ' Name (_HID, "ACPI0004")' >> "$gSsdtPR" else echo ' Scope('$scope')' >> "$gSsdtPR" echo ' {' >> "$gSsdtPR" fi # # Inject Processor () object for each logical processor in this processor scope. # while [ $index -lt $maxCoresPerScope ]; do if [[ $scope =~ ^"\_SB_." ]]; then echo '' >> "$gSsdtPR" echo ' Processor ('${gProcessorNames[$index]}', '$index', '$pBlockAddress', Zero)' >> "$gSsdtPR" echo ' {' >> "$gSsdtPR" echo ' Name (_HID, "ACPI0007")' >> "$gSsdtPR" echo ' Name (_STA, 0x0F)' >> "$gSsdtPR" echo ' }' >> "$gSsdtPR" else echo " Processor ("${gProcessorNames[$index]}", "$index", "$pBlockAddress", 0x06) {}" >> "$gSsdtPR" fi # # Next logical processor. # let index+=1 done if [[ $scope =~ ^"\_SB_." ]]; then echo ' }' >> "$gSsdtPR" fi echo ' }' >> "$gSsdtPR" # # # if [[ $scopeIndex -lt ${#gScope[@]} ]]; then echo '' >> "$gSsdtPR" fi # # Next processor scope. # let scopeIndex+=1 done # # Done. # } # #-------------------------------------------------------------------------------- # function _injectDebugInfo() { # # Local variable definitions/initialisation. # local turboStates=$1 local maxTurboFrequency=$2 local packageLength=$3 echo ' Method (_INI, 0, NotSerialized)' >> "$gSsdtPR" echo ' {' >> "$gSsdtPR" echo ' Store ("ssdtPRGen version.....: '$gScriptVersion' / '$gProductName' '$gProductVersion' ('$gBuildVersion')", Debug)' >> "$gSsdtPR" echo ' Store ("custom mode...........: '$gCustomMode'", Debug)' >> "$gSsdtPR" echo ' Store ("host processor........: '$gBrandString'", Debug)' >> "$gSsdtPR" echo ' Store ("target processor......: '$gProcessorNumber'", Debug)' >> "$gSsdtPR" echo ' Store ("number of processors..: '$gPhysicalCPUs'", Debug)' >> "$gSsdtPR" echo ' Store ("baseFrequency.........: '$gBaseFrequency'", Debug)' >> "$gSsdtPR" echo ' Store ("frequency.............: '$frequency'", Debug)' >> "$gSsdtPR" echo ' Store ("busFrequency..........: '$gBusFrequency'", Debug)' >> "$gSsdtPR" echo ' Store ("logicalCPUs...........: '$gLogicalCPUs'", Debug)' >> "$gSsdtPR" echo ' Store ("maximum TDP...........: '$gTdp'", Debug)' >> "$gSsdtPR" echo ' Store ("packageLength.........: '$packageLength'", Debug)' >> "$gSsdtPR" echo ' Store ("turboStates...........: '$turboStates'", Debug)' >> "$gSsdtPR" echo ' Store ("maxTurboFrequency.....: '$maxTurboFrequency'", Debug)' >> "$gSsdtPR" # # CPU workarounds requested? # if [[ $gCPUWorkArounds -gt 0 ]]; then echo ' Store ("CPU Workarounds.......: '$gCPUWorkArounds'", Debug)' >> "$gSsdtPR" fi # # XCPM mode initialised? # if [[ $gXcpm -ne -1 ]]; then echo ' Store ("machdep.xcpm.mode.....: '$gXcpm'", Debug)' >> "$gSsdtPR" fi # # Do we have more than one ACPI processor scope? # if [[ "${#gScope[@]}" -gt 1 ]]; then echo ' Store ("number of ACPI scopes.: '${#gScope[@]}'", Debug)' >> "$gSsdtPR" fi echo ' }' >> "$gSsdtPR" echo '' >> "$gSsdtPR" } # #-------------------------------------------------------------------------------- # function _printScopeStart() { # # Local variable definitions. # local turboStates local packageLength local maxTurboFrequency local lowFrequencyPStates local useWorkArounds local maxTDP local extraR local extraF # # Local variable initialisation. # let scopeIndex=$1 let turboStates=$2 let packageLength=$3 let maxTurboFrequency=$4 let useWorkArounds=0 let index=($gLogicalCPUsPerScope*$scopeIndex) # # Have we injected External () objects? # if [[ $scopeIndex -eq 0 && $gInjectExternalObjects -ne 1 ]]; then # # No. Inject ACPI Processor (...) {} declarations. # _printProcessorDefinitions fi echo '' >> "$gSsdtPR" echo ' Scope ('${gScope[${scopeIndex}]}'.'${gProcessorNames[$index]}')' >> "$gSsdtPR" echo ' {' >> "$gSsdtPR" if (( $scopeIndex == 0 && $gDebug & 1 )) then _injectDebugInfo $turboStates $maxTurboFrequency $packageLength fi # # Do we need to create additional (Low Frequency) P-States? # if [ $gBridgeType -ne $SANDY_BRIDGE ]; then let lowFrequencyPStates=0 # # Do we need to add additional (Low Frequency) P-States for Ivy Bridge? # if (( $gBridgeType == $IVY_BRIDGE && $gCPUWorkArounds & 2 )); then let lowFrequencyPStates=($gBaseFrequency/100)-7 if [[ $lowFrequencyPStates -lt 0 ]]; then let lowFrequencyPStates=$(echo ${lowFrequencyPStates#-}) printf "lowFrequencyPStates: $lowFrequencyPStates\n" fi fi let packageLength=($packageLength+$lowFrequencyPStates) if [[ $lowFrequencyPStates -gt 0 ]]; then if [[ $lowFrequencyPStates -gt 1 ]]; then printf " Name (APLF, 0x%02x)\n" $lowFrequencyPStates >> "$gSsdtPR" else printf " Name (APLF, One)\n" >> "$gSsdtPR" fi else # Prevent optimization warning. echo " Name (APLF, Zero)" >> "$gSsdtPR" fi if [[ $gBridgeType -eq $IVY_BRIDGE && ($gCPUWorkArounds -eq 1 || $gCPUWorkArounds -eq 3) ]]; then let useWorkArounds=1 fi fi # # Check number of Turbo states (for IASL optimization). # if [ $turboStates -eq 0 ]; then # TODO: Remove this when CPUPM for IB works properly! if (( $useWorkArounds )); then echo ' Name (APSN, One)' >> "$gSsdtPR" else echo ' Name (APSN, Zero)' >> "$gSsdtPR" fi else # TODO: Remove this when CPUPM for IB works properly! if (( $useWorkArounds )); then let turboStates+=1 fi printf " Name (APSN, 0x%02X)\n" $turboStates >> "$gSsdtPR" fi # TODO: Remove this when CPUPM for IB works properly! if (( $useWorkArounds )); then let packageLength+=1 fi printf " Name (APSS, Package (0x%02X)\n" $packageLength >> "$gSsdtPR" echo ' {' >> "$gSsdtPR" # TODO: Remove this when CPUPM for IB works properly! if (( $useWorkArounds )); then let extraF=($maxTurboFrequency+1) # # Is the global TDP a floating-point number? # if [[ $gTdp =~ "." ]]; then # # Yes, convert it and calculate maximum TDP. # let tdp=$(echo "$gTdp" | sed -e 's/\.//g') let maxTDP=($tdp*100) else # # No. Calculate maximum TDP. # let maxTDP=($gTdp*1000) fi let extraR=($maxTurboFrequency/$gBusFrequency)+1 if [ $gBusFrequency -eq 100 ]; then echo ' /* CPU Workaround #1 */' >> "$gSsdtPR" printf " Package (0x06) { 0x%04X, 0x%06X, 0x0A, 0x0A, 0x%02X00, 0x%02X00 },\n" $extraF $maxTDP $extraR $extraR >> "$gSsdtPR" else echo " /* Workaround for AppleIntelCPUPowerManagement mode */" >> "$gSsdtPR" printf " Package (0x06) { 0x%04X, 0x%06X, 0x0A, 0x0A, 0x00%02X, 0x00%02X },\n" $extraF $maxTDP $extraR $extraR >> "$gSsdtPR" fi fi } # #-------------------------------------------------------------------------------- # function _printPackages() { # # Local variable definitions/initialisation. # local maxNonTurboFrequency=$1 local turboStates=$2 local frequency=$3 # # Local variable definitions. # local tdp local maxTDP local minRatio local p1Ratio local ratio local powerRatio local multipliedBusFrequency # # Is the global TDP a floating-point number? # if [[ $gTdp =~ "." ]]; then # # Yes, convert it and calculate maximum TDP. # let tdp=$(echo "$gTdp" | sed -e 's/\.//g') let maxTDP=($tdp*100) else # # No. Calculate maximum TDP. # let tdp=$gTdp let maxTDP=(tdp*1000) fi # # Local variable initialisation. # let minRatio=($gBaseFrequency/$gBusFrequency) let p0Ratio=($maxNonTurboFrequency/$gBusFrequency) let ratio=($frequency/$gBusFrequency) let powerRatio=($p0Ratio-1) let multipliedBusFrequency=($gBusFrequency*10) case "$gBusFrequency" in 133) let multipliedBusFrequency+=3 ;; 166) let multipliedBusFrequency+=6 ;; esac # # Do we need to add additional (Low Frequency) P-States for Ivy Bridge? # if (( $gBridgeType == $IVY_BRIDGE && $gCPUWorkArounds & 2 )); then let minRatio=7 fi if (( $turboStates )); then echo ' /* High Frequency Modes (turbo) */' >> "$gSsdtPR" fi while [ $ratio -ge $minRatio ]; do if [ $frequency -eq $gBaseFrequency ]; then echo ' /* Low Frequency Mode */' >> "$gSsdtPR" fi if [ $frequency -eq $maxNonTurboFrequency ]; then echo ' /* High Frequency Modes (non-turbo) */' >> "$gSsdtPR" fi if (( $ratio == $minRatio && $gBridgeType == $IVY_BRIDGE && $gCPUWorkArounds & 2 )); then echo ' /* CPU Workaround #2 */' >> "$gSsdtPR" fi printf " Package (0x06) { 0x%04X, " $frequency >> "$gSsdtPR" if [ $frequency -lt $maxNonTurboFrequency ]; then if [ $gBusFrequency -eq 100 ]; then power=$(echo "scale=6;m=((1.1-(($p0Ratio-$powerRatio)*0.00625))/1.1);(($powerRatio/$p0Ratio)*(m*m)*$maxTDP);" | bc | sed -e 's/.[0-9A-F]*$//') let powerRatio-=1 else let ratioFactor=($ratio*30)/$p0Ratio; power=$(echo "scale=6;(($ratioFactor*$ratioFactor*$ratioFactor*$maxTDP)/27000);" | bc | sed -e 's/.[0-9A-F]*$//') let powerRatio-=1 fi else power=$maxTDP fi if [ $frequency -ge $gBaseFrequency ]; then printf "0x%06X, " $power >> "$gSsdtPR" else printf ' Zero, ' >> "$gSsdtPR" fi if [ $gBusFrequency -eq 100 ]; then printf "0x0A, 0x0A, 0x%02X00, 0x%02X00 }" $ratio $ratio >> "$gSsdtPR" else printf "0x0A, 0x0A, 0x00%02X, 0x00%02X }" $ratio $ratio >> "$gSsdtPR" fi let ratio-=1 let frequency=$(printf "%.f\n" $(echo "scale=1;((($multipliedBusFrequency/10)*$ratio)+0.5)" | bc)) if [ $ratio -ge $minRatio ]; then echo ',' >> "$gSsdtPR" else echo '' >> "$gSsdtPR" fi done echo ' })' >> "$gSsdtPR" } # #-------------------------------------------------------------------------------- # function _printMethodDSM() { if [[ ($gBridgeType -ge $IVY_BRIDGE && $gBusFrequency -eq 100) || $gXcpm -eq 1 ]]; then # # New stand-alone version of Method _DSM - Copyright (c) 2009 by Master Chief # echo '' >> "$gSsdtPR" echo ' Method (_DSM, 4, NotSerialized)' >> "$gSsdtPR" echo ' {' >> "$gSsdtPR" if [[ $gDebug -eq 1 ]]; then local debugScopeName=$(echo $scope | sed -e 's/^\\//') echo ' Store ("Method '$debugScopeName'.'${gProcessorNames[0]}'._DSM Called", Debug)' >> "$gSsdtPR" echo '' >> "$gSsdtPR" fi echo ' If (LEqual (Arg2, Zero))' >> "$gSsdtPR" echo ' {' >> "$gSsdtPR" echo ' Return (Buffer (One)' >> "$gSsdtPR" echo ' {' >> "$gSsdtPR" echo ' 0x03' >> "$gSsdtPR" echo ' })' >> "$gSsdtPR" echo ' }' >> "$gSsdtPR" echo '' >> "$gSsdtPR" # # This property is required to get X86Platform[Plugin/Shim].kext loaded. # echo ' Return (Package (0x02)' >> "$gSsdtPR" echo ' {' >> "$gSsdtPR" echo ' "plugin-type",' >> "$gSsdtPR" echo ' One' >> "$gSsdtPR" echo ' })' >> "$gSsdtPR" echo ' }' >> "$gSsdtPR" echo ' }' >> "$gSsdtPR" elif [[ $gBridgeType -gt $SANDY_BRIDGE ]]; then echo ' }' >> "$gSsdtPR" fi } # #-------------------------------------------------------------------------------- # function _debugPrint() { if (( $gDebug & 2 )); then printf "$@" fi } # #-------------------------------------------------------------------------------- # function _printScopeACST() { # # Local variable definition. # local C1 C2 C3 C6 C7 local hintCode local pkgLength local targetCPU local numberOfCStates local targetCStates # # Intel values for Sandy / Ivy Bridge processors # # C-state : Power : SB Latency : IB Latency #---------:---------:------------:------------ # C1 : 0x3e8 : 0x01 : 0x03 # C3 : 0x1f4 : 0x50 : 0xcd # C6 : 0x15e : 0x68 : 0xf5 # C7 : 0xc8 : 0x6d : 0xf5 # # Note: C-state latency in uS and C-state power in mW. # local latency_C1=Zero local latency_C2=0x43 local latency_C3=0xCD local latency_C6=0xF5 local latency_C7=0xF5 # # Local variable initialisation. # let C1=0 let C2=0 let C3=0 let C6=0 let C7=0 let pkgLength=2 let numberOfCStates=0 # # Are we injecting C-States for CPU1? # if [ $1 -eq 1 ]; then let targetCPU=1 else let targetCPU=0 fi echo '' >> "$gSsdtPR" echo ' Method (ACST, 0, NotSerialized)' >> "$gSsdtPR" echo ' {' >> "$gSsdtPR" if (( $gDebug )); then local debugScopeName=$(echo $scope | sed -e 's/^\\//') echo ' Store ("Method '$debugScopeName'.'${gProcessorNames[$targetCPU]}'.ACST Called", Debug)' >> "$gSsdtPR" fi # # Are we injecting C-States for CPU1? # if [ $targetCPU -eq 1 ]; then # Yes (also used by CPU2, CPU3 and greater). let targetCStates=$gACST_CPU1 latency_C1=0x03E8 latency_C2=0x94 latency_C3=0xC6 else # # C-States override for Mobile processors (CPU0 only) # if (($gTypeCPU == $gMobileCPU)); then echo 'Adjusting C-States for detected (mobile) processor' let gACST_CPU0=29 fi let targetCStates=$gACST_CPU0 latency_C1=Zero latency_C2=0x43 latency_C3=0xCD latency_C6=0xF5 latency_C7=0xF5 fi if (( $gDebug )); then echo ' Store ("'${gProcessorNames[$targetCPU]}' C-States : '$targetCStates'", Debug)' >> "$gSsdtPR" echo '' >> "$gSsdtPR" fi _debugPrint "targetCStates: $targetCStates\n" # # Checks to determine which C-State(s) we should inject. # if (($targetCStates & 1)); then _debugPrint "Adding C1\n" let C1=1 let numberOfCStates+=1 let pkgLength+=1 fi if (($targetCStates & 2)); then _debugPrint "Adding C2\n" let C2=1 let numberOfCStates+=1 let pkgLength+=1 fi if (($targetCStates & 4)); then _debugPrint "Adding C3\n" let C3=1 let numberOfCStates+=1 let pkgLength+=1 fi if (($targetCStates & 8)); then _debugPrint "Adding C6\n" let C6=1 let numberOfCStates+=1 let pkgLength+=1 fi if ((($targetCStates & 16) == 16)); then _debugPrint "Adding C7\n" let C7=1 let numberOfCStates+=1 let pkgLength+=1 fi let hintCode=0x00 echo " /* Low Power Modes for ${gProcessorNames[$1]} */" >> "$gSsdtPR" printf " Return (Package (0x%02x)\n" $pkgLength >> "$gSsdtPR" echo ' {' >> "$gSsdtPR" echo ' One,' >> "$gSsdtPR" printf " 0x%02x,\n" $numberOfCStates >> "$gSsdtPR" echo ' Package (0x04)' >> "$gSsdtPR" echo ' {' >> "$gSsdtPR" echo ' ResourceTemplate ()' >> "$gSsdtPR" echo ' {' >> "$gSsdtPR" echo ' Register (FFixedHW,' >> "$gSsdtPR" echo ' 0x01, // Bit Width' >> "$gSsdtPR" echo ' 0x02, // Bit Offset' >> "$gSsdtPR" printf " 0x%016x, // Address\n" $hintCode >> "$gSsdtPR" echo ' 0x01, // Access Size' >> "$gSsdtPR" echo ' )' >> "$gSsdtPR" echo ' },' >> "$gSsdtPR" echo ' One,' >> "$gSsdtPR" echo ' '$latency_C1',' >> "$gSsdtPR" echo ' 0x03E8' >> "$gSsdtPR" if (($C2)); then let hintCode+=0x10 echo ' },' >> "$gSsdtPR" echo '' >> "$gSsdtPR" echo ' Package (0x04)' >> "$gSsdtPR" echo ' {' >> "$gSsdtPR" echo ' ResourceTemplate ()' >> "$gSsdtPR" echo ' {' >> "$gSsdtPR" echo ' Register (FFixedHW,' >> "$gSsdtPR" echo ' 0x01, // Bit Width' >> "$gSsdtPR" echo ' 0x02, // Bit Offset' >> "$gSsdtPR" printf " 0x%016x, // Address\n" $hintCode >> "$gSsdtPR" echo ' 0x03, // Access Size' >> "$gSsdtPR" echo ' )' >> "$gSsdtPR" echo ' },' >> "$gSsdtPR" echo ' 0x02,' >> "$gSsdtPR" echo ' '$latency_C2',' >> "$gSsdtPR" echo ' 0x01F4' >> "$gSsdtPR" fi if (($C3)); then let hintCode+=0x10 local power_C3=0x01F4 # # Is this for CPU1? # if (($1)); then if [[ ${gModelID:0:7} == "iMac13," ]]; then local power_C3=0x15E latency_C3=0xA9 else local power_C3=0xC8 let hintCode+=0x10 fi fi echo ' },' >> "$gSsdtPR" echo '' >> "$gSsdtPR" echo ' Package (0x04)' >> "$gSsdtPR" echo ' {' >> "$gSsdtPR" echo ' ResourceTemplate ()' >> "$gSsdtPR" echo ' {' >> "$gSsdtPR" echo ' Register (FFixedHW,' >> "$gSsdtPR" echo ' 0x01, // Bit Width' >> "$gSsdtPR" echo ' 0x02, // Bit Offset' >> "$gSsdtPR" printf " 0x%016x, // Address\n" $hintCode >> "$gSsdtPR" echo ' 0x03, // Access Size' >> "$gSsdtPR" echo ' )' >> "$gSsdtPR" echo ' },' >> "$gSsdtPR" echo ' 0x03,' >> "$gSsdtPR" echo ' '$latency_C3',' >> "$gSsdtPR" echo ' '$power_C3 >> "$gSsdtPR" fi if (($C6)); then let hintCode+=0x10 echo ' },' >> "$gSsdtPR" echo '' >> "$gSsdtPR" echo ' Package (0x04)' >> "$gSsdtPR" echo ' {' >> "$gSsdtPR" echo ' ResourceTemplate ()' >> "$gSsdtPR" echo ' {' >> "$gSsdtPR" echo ' Register (FFixedHW,' >> "$gSsdtPR" echo ' 0x01, // Bit Width' >> "$gSsdtPR" echo ' 0x02, // Bit Offset' >> "$gSsdtPR" printf " 0x%016x, // Address\n" $hintCode >> "$gSsdtPR" echo ' 0x03, // Access Size' >> "$gSsdtPR" echo ' )' >> "$gSsdtPR" echo ' },' >> "$gSsdtPR" echo ' 0x06,' >> "$gSsdtPR" echo ' '$latency_C6',' >> "$gSsdtPR" echo ' 0x015E' >> "$gSsdtPR" fi if (($C7)); then # # If $hintCode is already 0x30 then use 0x31 otherwise 0x30 # if [ $hintCode -eq 48 ]; then let hintCode+=0x01 else let hintCode+=0x10 fi echo ' },' >> "$gSsdtPR" echo '' >> "$gSsdtPR" echo ' Package (0x04)' >> "$gSsdtPR" echo ' {' >> "$gSsdtPR" echo ' ResourceTemplate ()' >> "$gSsdtPR" echo ' {' >> "$gSsdtPR" echo ' Register (FFixedHW,' >> "$gSsdtPR" echo ' 0x01, // Bit Width' >> "$gSsdtPR" echo ' 0x02, // Bit Offset' >> "$gSsdtPR" printf " 0x%016x, // Address\n" $hintCode >> "$gSsdtPR" echo ' 0x03, // Access Size' >> "$gSsdtPR" echo ' )' >> "$gSsdtPR" echo ' },' >> "$gSsdtPR" echo ' 0x07,' >> "$gSsdtPR" echo ' '$latency_C7',' >> "$gSsdtPR" echo ' 0xC8' >> "$gSsdtPR" fi echo ' }' >> "$gSsdtPR" echo ' })' >> "$gSsdtPR" echo ' }' >> "$gSsdtPR" # # Do we need to add a closing bracket? # # Note: The injected _DSM method will otherwise take care of it. # if [[ $gBridgeType -le $SANDY_BRIDGE && $gXcpm -ne 1 ]]; then echo ' }' >> "$gSsdtPR" fi } # #-------------------------------------------------------------------------------- # function _printScopeCPUn() { # # Local variable definition. # local index local scopeIndex local bspIndex local apIndex # # Local variable initialisation. # let index=1 let scopeIndex=$1 let bspIndex=$gLogicalCPUsPerScope*$scopeIndex let apIndex=$bspIndex+1 local scope=${gScope[$scopeIndex]} while [ $index -lt $gLogicalCPUsPerScope ]; do echo '' >> "$gSsdtPR" echo ' Scope ('${scope}'.'${gProcessorNames[${apIndex}]}')' >> "$gSsdtPR" echo ' {' >> "$gSsdtPR" echo ' Method (APSS, 0, NotSerialized)' >> "$gSsdtPR" echo ' {' >> "$gSsdtPR" if (( $gDebug )); then local debugScopeName=$(echo $scope | sed -e 's/^\\//') echo ' Store ("Method '$debugScopeName'.'${gProcessorNames[${apIndex}]}'.APSS Called", Debug)' >> "$gSsdtPR" echo '' >> "$gSsdtPR" fi echo ' Return ('${scope}'.'${gProcessorNames[${bspIndex}]}'.APSS)' >> "$gSsdtPR" echo ' }' >> "$gSsdtPR" # # IB CPUPM tries to parse/execute CPUn.ACST (see debug data) and thus we add # this method, conditionally, since SB CPUPM doesn't seem to care about it. # if [ $gBridgeType -ge $IVY_BRIDGE ]; then if [ $index -eq 1 ]; then _printScopeACST 1 else echo '' >> "$gSsdtPR" local processorName=${gProcessorNames[$bspIndex+1]} echo ' Method (ACST, 0, NotSerialized) { Return ('$scope'.'$processorName'.ACST ()) }' >> "$gSsdtPR" fi fi echo ' }' >> "$gSsdtPR" let index+=1 let apIndex+=1 done # # Next processor scope. # let scopeIndex+=1 if [[ $scopeIndex -eq ${#gScope[@]} ]]; then echo '}' >> "$gSsdtPR" fi # # Done. # } # #-------------------------------------------------------------------------------- # function _getModelID() { # # Grab 'compatible' property from ioreg (stripped with sed / RegEX magic). # gModelID=$(ioreg -p IODeviceTree -d 2 -k compatible | grep compatible | sed -e 's/ *["=<>]//g' -e 's/compatible//') } # #-------------------------------------------------------------------------------- # function _getBoardID() { # # Grab 'board-id' property from ioreg (stripped with sed / RegEX magic). # gBoardID=$(ioreg -p IODeviceTree -d 2 -k board-id | grep board-id | sed -e 's/ *["=<>]//g' -e 's/board-id//') } # #-------------------------------------------------------------------------------- # function _getProcessorNames() { # # Local variable definition/initialisation. # local threadCount local processorLabels local processorModelSpecified=$1 if [[ $gCustomMode -eq 0 ]]; then # # Note: -k clock-frequency filters out the inactive cores. # local acpiNames=$(ioreg -p IODeviceTree -c IOACPIPlatformDevice -k cpu-type -k clock-frequency | egrep name | sed -e 's/ *[-|="]//g') processorLabels=($acpiNames) fi # # Target processor model specified with -p argument? # if [[ $gTargetProcessorType -eq 0 ]]; then # # No. Get processor model from the host computer. # _getCPUNumberFromBrandString $gTargetProcessorType # # Get CPU data of the host computer. # _getCPUDataByProcessorNumber # # Set thread count to that of the host computer. # let threadCount=${#processorLabels[@]} else # # Yes. Get CPU data based on the specified processor model. # _getCPUDataByProcessorNumber # # Target processor model located? # if [[ $gTypeCPU -gt 0 ]]; then # # Set thread count to that of the target processor. # let threadCount=${gProcessorData[6]} # let gLogicalCPUs=$threadCount*$gPhysicalCPUs fi fi # # Check if -l argument is used. # if [[ $gLogicalCPUs -eq 0 ]]; then let gLogicalCPUs=$threadCount*$gPhysicalCPUs else let threadCount=$gLogicalCPUs/$gPhysicalCPUs fi # # Check if -cpus argument is used. # #if [[ $gPhysicalCPUs -gt 1 ]]; # then let gLogicalCPUsPerScope=$threadCount # else # let gLogicalCPUsPerScope=$threadCount/${#gScope[@]} # fi _initProcessorScope # # Custom ACPI Processor labels defined? # if [[ ${#gProcessorNames[@]} -eq 0 ]]; then # # No. Is argument -mode custom used? # if [[ $gCustomMode -eq 0 ]]; then # # No. Is argument -acpi used? # if [[ ${#gProcLabel} -eq 0 ]]; then # # No. Use the ACPI Processor declarations from the host computer. # gProcessorNames=($acpiNames) gProcLabel=${gProcessorNames[0]} else # # # printf "YES-1\n" fi else # # Yes. Argument -mode custom is used. printf "YES-2\n" # _initProcessorScope fi fi _debugPrint "Number of Scopes: ${#gScope[@]}\n" if [[ $gPhysicalCPUs -lt ${#gScope[@]} ]]; then let gPhysicalCPUs+=1 fi # # Do we have two or more logical processor cores? # if [[ ${#gProcessorNames[@]} -lt 2 ]]; then # # No. Bail out with error. # _exitWithError $PROCESSOR_NAMES_ERROR fi } # #-------------------------------------------------------------------------------- # function _getPackageLength() { # # Local variable definition/initialisation. # local data=$1 local pkgLengthByte=0 local start=0 local packageLength=0 # # Called with a AML Scope object? # if [[ ${data:0:2} == $AML_SCOPE_OPCODE ]]; then # Yes. let start=$AML_SINGLE_BYTE_ENCODING else # No. Must be a Processor declaration. let start=$AML_DUAL_BYTE_ENCODING fi # # The package length is encoded as a series of 1 to 4 bytes with the most significant # two bits of byte zero indicating how many following bytes are in the encoding. # The next two bits are only used in one-byte encodings, which allows for one-byte # encodings on a length up to 0x3F. Longer encodings, which do not use these two bits, # have a maximum length of the following: # # 0x0FFF for two-byte encodings. # 0x0FFFFF for three-byte encodings. # 0x0FFFFFFFFF for four-byte encodings. # # # Get package length from given data. # let pkgLengthByte="0x"${1:${start}:2} # # Mask the first byte – the one after the opcode byte(s) – with 0x3f. # let maskedByte=$((0x${data:${start}:2} & 0x3f)) if [[ $pkgLengthByte -gt 192 ]]; then _debugPrint 'Four-byte encoding detected (maximum length 0x0FFFFFFFFF/68719476735)\n' printf -v packageLength '0x%2%2s%2s%x' "${data:${start}+6:2}" "${data:${start}+4:2}" "${data:${start}+2:2}" $maskedByte elif [[ $pkgLengthByte -gt 128 ]]; then _debugPrint 'Three-byte encoding detected (maximum length 0x0FFFFF/1048575)\n' printf -v packageLength '0x%2s%2s%x' "${data:${start}+4:2}" "${data:${start}+2:2}" $maskedByte elif [[ $pkgLengthByte -gt 64 ]]; then _debugPrint 'Two-byte encoding detected (maximum length 0x0FFF/4095)\n' printf -v packageLength '0x%2s%x' "${data:${start}+2:2}" $maskedByte else _debugPrint 'One-byte encoding detected (maximum length 0x3F/77)\n' packageLength=$maskedByte fi _debugPrint "pkgLengthByte: 0x%x/${pkgLengthByte}\n" $pkgLengthByte _debugPrint "packageLength: ${packageLength}/%d\n" $packageLength let gFunctionReturn=$packageLength } # #-------------------------------------------------------------------------------- # function _checkForProcessorDeclarations() { # # Local variable definitions/initialisation. # local status=0 local targetData=$1 local deviceName=$2 local isACPI10Compliant=$3 local processorID local processorLabel local processorIsEnabled local processorDeclarationLenth local overrideProcessorEnableState local variableList=(16,18,20,22,24,30 6,8,10,12,14,20 8,10,12,14,16,22) let overrideProcessorEnableState=0 let enabledProcessorsPerScope=0 for varList in "${variableList[@]}" do # # Save default (0) delimiter. # local ifs=$IFS # # Change delimiter to a comma character. # IFS="," # # Split vars. # local vars=(${varList}) # # Restore the default (0) delimiter. # IFS=$ifs # # # local deviceObjectData=($(echo "${targetData}" | egrep -o "${AML_PROCESSOR_SCOPE_OPCODE}[0-9a-f]{${vars[5]}}06")) # # The above grep pattern may fail, in which case we fall back to a previously used grep pattern. # See also: https://github.com/Piker-Alpha/ssdtPRGen.sh/issues/215 # if [[ ${#deviceObjectData[@]} -eq 1 ]]; then local deviceObjectData=($(echo "${targetData}" | egrep -o "${AML_PROCESSOR_SCOPE_OPCODE}[0-9a-f]{${vars[5]}}")) fi if [[ $deviceObjectData ]]; then # # # if [[ ${#deviceName} -gt 0 ]]; then # _debugPrint "Device ($gScope/$deviceName): \n" _debugPrint "Device ($deviceName): \n" fi for processorDeclaration in "${deviceObjectData[@]}" do # # Get ProcessorID. # processorID="${processorDeclaration:${vars[4]}:2}" # # Check APIC data to see if this (logical) processor is enabled. # _isEnabledProcessor "${processorID}" # # Assign local variable with the return value. # processorIsEnabled=$? # # Processor enabled (first check)? # if [[ $processorIsEnabled -eq 0 && $enabledProcessorsPerScope -lt $gLogicalCPUsPerScope ]]; then # # Override the enabled state. # overrideProcessorEnableState=1 _debugPrint "Overriding processor enable state (now enabled)!\n" else overrideProcessorEnableState=0 fi #printf "overrideProcessorEnableState: $overrideProcessorEnableState\n" # # Is the (logical) processor enabled? # if [[ $processorIsEnabled -eq 1 || $overrideProcessorEnableState -eq 1 ]]; then # # Yes it is (may be overriden). Check shell for invocation of sh ssdtPRGen.sh (see issue #279). # if [[ $BASH =~ "/bin/bash" ]]; then processorLabel=$(echo -e "\x${processorDeclaration:${vars[0]}:2}\x${processorDeclaration:${vars[1]}:2}\x${processorDeclaration:${vars[2]}:2}\x${processorDeclaration:${vars[3]}:2}") else processorLabel=$(echo "\x${processorDeclaration:${vars[0]}:2}\x${processorDeclaration:${vars[1]}:2}\x${processorDeclaration:${vars[2]}:2}\x${processorDeclaration:${vars[3]}:2}") fi _debugPrint "processorID: ${processorID} $processorLabel\n" gProcessorNames[$gProcessorStartIndex]=$processorLabel # # # let gProcessorStartIndex+=1 # # Keep track of the number of enabled (logical) processors. # #printf "enabledProcessorsPerScope: ${enabledProcessorsPerScope}\n" let enabledProcessorsPerScope+=1 #printf "enabledProcessorsPerScope: ${enabledProcessorsPerScope}\n" fi # # Did we collact all the required (logical) processors? # if [[ $enabledProcessorsPerScope -eq $gLogicalCPUsPerScope ]]; then # # Yes. We're done here. # #printf "break\n" break; fi done printf "\n" fi done return $gProcessorStartIndex } # #-------------------------------------------------------------------------------- # function _getACPIProcessorScope() { # # Local variable definitions/initialisation. # local filename="$1" local basename=$(basename "${filename%.*}") local variableList=(10,6,40 12,8,42 24,20,40 14,10,44) local varList local scopeLength local index local scopeIndex # # Local variable initialisation. # let index=0 let scopeIndex=0 # # Convert (example) 'C000' to '43303030' # local processorNameBytes=$(echo -n ${gProcessorNames[0]} | xxd -ps) # # Loop through all Name (_HID, ACPI0004) objects. # for varList in "${variableList[@]}" do # # Save default (0) delimiter. # local ifs=$IFS # # Change delimiter to a comma character. # IFS="," # # Split vars. # local vars=(${varList}) # # Up index of variableList. # let index+=1 # # Restore the default (0) delimiter. # IFS=$ifs # # Check for (a) Device(s) with a _HID object value of 'ACPI0004' in the DSDT. # local matchingData=$(egrep -o "${AML_DEVICE_OPCODE}[0-9a-f]{${vars[0]}}085f4849440d414350493030303400" "$filename") # # Example: # 5b824d9553434b30085f4849440d414350493030303400 (N times) # 0123456789 123456789 123456789 123456789 12345 # if [[ $matchingData ]]; then local hidObjectList=($matchingData) local let objectCount=${#hidObjectList[@]} if [ $objectCount -gt 0 ]; then _debugPrint "${objectCount} Name (_HID, \"ACPI0004\") object(s) found in ${basename}\n" _debugPrint "matchingData:\n$matchingData\n" fi # # Loop through all Name (_HID, ACPI0004) objects. # for hidObjectData in "${hidObjectList[@]}" do # # Get the name of the device. # local deviceName=$(echo ${hidObjectData:${vars[1]}:8} | xxd -r -p) _debugPrint "Searching for ACPI Processor declarations in Device($deviceName) {}\n" # # Get the length of the device scope. # _getPackageLength $hidObjectData let scopeLength=$gFunctionReturn _debugPrint "scopeLength: $scopeLength\n" # # Convert number of bytes to number of characters. # let scopeLength*=2 # echo $scopeLength # # Lower scopeLength with the number of bytes that we used for this match. # let scopeLength-=${vars[2]} # echo $scopeLength # # Initialise string. # local repetitionString="" # # Prevent "egrep: invalid repetition count(s)" # if [[ $scopeLength -gt 255 ]]; then while [ $scopeLength -gt 255 ]; do local repetitionString+="[0-9a-f]{255}" let scopeLength-=255 done fi repetitionString+="[0-9a-f]{${scopeLength}}" # echo $repetitionString # # Extract the whole Device () {} scope. # local deviceObjectData=$(egrep -o "${hidObjectData}${repetitionString}" "$filename" | tr -d '\n') # # We should now have something like this (example): # # Device (SCK0) # { # Name (_HID, "ACPI0004") # Processor (C000, 0x00, 0x00000410, 0x06) # { # Name (_HID, "ACPI0007") # } # # 5b823053434b30085f4849440d4143504930303034005b831a43303030001004000006085f4849440d414350493030303700 # 0123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 # # Check for ACPI Processor () {} declarations. # _checkForProcessorDeclarations $deviceObjectData $deviceName 0 # # Check return status. # # if [[ $? -eq ${#gProcessorNames[@]} ]]; if [[ $? -eq $gLogicalCPUs ]]; then # # Update the global processor scope. # gScope[$scopeIndex]="\_SB_.${deviceName}" # # Next scope. # let scopeIndex+=1 # # Done. # return 1 else # # # if [ $? -lt ${#gProcessorNames[@]} ]; then # # Update the global processor scope. # gScope[$scopeIndex]="\_SB_.${deviceName}" # # Next scope. # let scopeIndex+=1 _debugPrint "gScope : ${#gScope[@]}\n" _debugPrint "gProcessorStartIndex: $gProcessorStartIndex\n" _debugPrint "gLogicalCPUs : $gLogicalCPUs\n" _debugPrint "gProcessorNames : ${#gProcessorNames[@]}\n" let nextTargetCores=${#gProcessorNames[@]}-$gProcessorStartIndex _debugPrint "Searching for ${nextTargetCores} additional Processor declaration ...\n" fi fi done fi done return 0 } # #-------------------------------------------------------------------------------- # function _getProcessorScope() { # # Local variable definitions/initialisation. # local index=0 local filename="$1" local scopeLength=0 local basename=$(basename "${filename%.*}") # # Target Scopes ('\_PR_', '\_PR', '_PR_', '_PR', '\_SB_', '\_SB', '_SB_', '_SB') # local grepPatternList=('5c5f50525f' '5c5f5052' '5f50525f' '5f5052' '5c5f53425f' '5c5f5342' '5f53425f' '5f5342') # # Loop through the target pattern list. # for grepPattern in "${grepPatternList[@]}" do # # Up scope index counter. # let index+=1; # # Setup array with supported type of byte encodings. # local byteEncodingList=($AML_SINGLE_BYTE_ENCODING $AML_DUAL_BYTE_ENCODING $AML_TRIPLE_BYTE_ENCODING $AML_QUAD_BYTE_ENCODING) for typeEncoding in "${byteEncodingList[@]}" do # # "528310[0-9a-f]{2}${grepPattern}" # "528310[0-9a-f]{4}${grepPattern}" # "528310[0-9a-f]{6}${grepPattern}" # "528310[0-9a-f]{8}${grepPattern}" # local data=$(egrep -o "${AML_PROCESSOR_SCOPE_OPCODE}${AML_SCOPE_OPCODE}[0-9a-f]{${typeEncoding}}${grepPattern}" "$filename") let patternLengthCorrection=0 if [[ ${#data} -eq 0 ]]; then # # "10[0-9a-f]{2}${grepPattern}" # "10[0-9a-f]{4}${grepPattern}" # "10[0-9a-f]{6}${grepPattern}" # "10[0-9a-f]{8}${grepPattern}" # local data=$(egrep -o "${AML_SCOPE_OPCODE}[0-9a-f]{${typeEncoding}}${grepPattern}" "$filename") let patternLengthCorrection=2 fi if [[ $data ]]; then local scopeObjectList=($data) # # Get number of target objects to check. # let objectCount=${#scopeObjectList[@]} # # Get Scope name from current pattern. # local scopeName=$(echo -n $grepPattern | xxd -ps -r) if [[ $objectCount -gt 0 ]]; then if [ $typeEncoding -eq $AML_SINGLE_BYTE_ENCODING ]; then local scopeDots="."; else local scopeDots=".."; fi _debugPrint $objectCount" Scope ("$scopeName") {"$scopeDots"} object(s) found in ${basename}\n" if [[ $index -lt 5 && $scopeName =~ "PR" ]]; then let gScopePRFound=1 fi fi # # Loop through all Scope (...) objects. # for scopeObjectData in "${scopeObjectList[@]}" do _debugPrint "scopeObjectData: $scopeObjectData\n" # # Get the length of the Scope. # _getPackageLength $scopeObjectData let scopeLength=$gFunctionReturn _debugPrint "scopeLength: $scopeLength\n" # echo $scopeLength # # Convert number of bytes to number of characters. # let scopeLength*=2 # echo $scopeLength # # Get number of characters in grep pattern. # let grepPatternLength="${#AML_SCOPE_OPCODE}+$typeEncoding+${#grepPattern}-${patternLengthCorrection}" # # Lower scopeLength with the number of characters that we used for the match. # let scopeLength-=$grepPatternLength _debugPrint "scopeLength: $scopeLength (egrep pattern length: $grepPatternLength)\n" # # Initialise string. # local repetitionString="" # # Prevent "egrep: invalid repetition count(s)" # if [[ $scopeLength -gt 255 ]]; then while [ $scopeLength -gt 255 ]; do local repetitionString+="[0-9a-f]{255}" let scopeLength-=255 done fi repetitionString+="[0-9a-f]{${scopeLength}}" # echo $repetitionString # # Extract the whole Scope() {}. # local scopeObjectData=$(egrep -o "${scopeObjectData}${repetitionString}" "$filename" | tr -d '\n') # echo "scopeObjectData: $scopeObjectData" _debugPrint "scopeObjectData length ${#scopeObjectData} (includes egrep pattern)\n" if [[ $scopeObjectData ]]; then # # Check for target scope in $scopeObjectData, there is no device name ("") # and $(($index < 5)) informs it about the ACPI 1.0 compliance (true/false). # _checkForProcessorDeclarations $scopeObjectData "" $(($index < 5)) # # Check return status (0 is SUCCESS). # # if [[ $? -eq 0 ]]; # if [[ $? -eq ${#gProcessorNames[@]} ]]; if [[ $? -eq $gLogicalCPUs ]]; then # # Reinitialise scopeLength (lowered for the repetitionString). # let scopeLength="${#scopeObjectData}" printf "Scope ("$scopeName") {"$scopeLength" bytes} with ACPI Processor declarations found in ${basename} (ACPI 1.0 compliant)\n" # # Construct processor scope name. # if [[ $scopeName =~ ^[\\] ]]; then gScope=$scopeName else # # Without the leading '\' the IASL compiler fails with: # # Error 4085 - Object not found or not accessible from scope ^ (_PR_.CPU0.APSS) # Error 4085 - Object not found or not accessible from scope ^ (_PR_.CPU1.ACST) # gScope='\'$scopeName fi return else _debugPrint 'Scope ('$scopeName') {'$scopeLength' bytes} without ACPI Processor declarations ...\n\n' fi fi done fi done done } # #-------------------------------------------------------------------------------- # function _getEnabledProcessors() { # # Check APIC structure type 00 for enabled processors. # gEnabledProcessors=($(egrep -o '0008[0-9a-f]{4}01000000' "/tmp/APIC.dat")) # # Note: Here is an explanation of the data: # # 0008000001000000 # ^^ = APIC structure type (Processor Local APIC). # # 0008000001000000 # ^^ = APIC structure length (8). # # 0008000001000000 # ^^ = ACPI Processor ID. # # 0008000001000000 # ^^ = APIC ID. # # 0008000001000000 # ^^^^^^^^ = APIC flags (enabled processors = 01 / disabled = 00). # # Do we have the minimum number (2) of logical processors? # if [[ ${#gEnabledProcessors[@]} -lt 2 ]]; then # # No. Error out. # _PRINT_MSG "Error: Not enough enabled processors found in: ${gOverridePath}/APIC.aml!" _ABORT fi } # #-------------------------------------------------------------------------------- # function _isEnabledProcessor() { local processorID local targetProcessorID=$1 # # Loop through the array with enabled processors. # for processorID in "${gEnabledProcessors[@]}" do # # Is this the processorID we are looking for? # if [[ ${processorID:4:2} == $targetProcessorID ]]; then # # Yes. Check APIC flags to see if the processor is enabled. # if [[ ${processorID:8:8} == "01000000" ]]; then # # Processor enabled. # return 1 fi fi done # # ProcessorID not found, or procesor not enabled. # return 0 } # #-------------------------------------------------------------------------------- # function _convertACPIFiles() { # # Is argument -mode custom used? # if [[ $gCustomMode -eq 1 ]]; then # # Yes. Use override path for ACPI files. # local path="${gOverridePath}" else # # ACPI table path specified (argument -extract)? # if [[ $gExtractionPath ]]; then # # Yes. Use given path. # local path="${gExtractionPath}" else # # No. Use default path (~/Library/ssdtPRGen/ACPI) # local path="${gACPITablePath}" fi fi # # Is argument -developer 1 used, and not -extract [some path]? # if [[ $gDeveloperMode -eq 1 ]] && [[ ! $gExtractionPath ]]; then # # Yes. Fixup ACPI table path. # local path="${gPath}/ACPI" fi # # Check SSDT(-n).AML files for scope SCK0. # targetDataFiles=(`grep -l SCK0 ${gPath}/ACPI/SSDT*.aml`) # # Loop through all matchingFilenames. # for match in "${targetDataFiles[@]}" do _debugPrint "matchingFilename: ${match[@]}\n" # # Convert AML file to postscript format. # local filename=$(basename $match) xxd -c 256 -ps "${match}" | tr -d '\n' > "/tmp/${filename%.*}.dat" done # # Check for required file DSDT.aml # if [[ -f "${path}/DSDT.aml" ]]; then # # Convert the override DSDT.aml file to postscript format. # xxd -c 256 -ps "${path}/DSDT.aml" | tr -d '\n' > "/tmp/DSDT.dat" else # # # _PRINT_MSG "Error: ${path}/DSDT.aml not found!" _ABORT fi # # Check for required file APIC.aml # if [[ -f "${path}/APIC.aml" ]]; then # # # xxd -c 256 -ps "${path}/APIC.aml" | tr -d '\n' > "/tmp/APIC.dat" else # # # _PRINT_MSG "Error: ${path}/APIC.aml not found!" _ABORT fi } # #-------------------------------------------------------------------------------- # function _initProcessorScope() { # # Local variable declarations. # local filename="/tmp/DSDT.dat" local basename=$(basename "${filename%.*}") local processorDeclarationsFound # # Local variable initialisation. # let processorDeclarationsFound=0 # # Loop through all matching files. # for filename in "${targetDataFiles[@]}" do # # Setup file- and basename. # basename=$(basename "${filename}") filename="/tmp/${basename%.*}.dat" _debugPrint "_getACPIProcessorScope: ${filename}\n" # # Check for Device()s with enclosed Name (_HID, "ACPI0004") objects in SSDT(-*).dat # _getACPIProcessorScope "${filename}" if [ $? -eq 1 ]; then _debugPrint "_getACPIProcessorScope: Done.\n" break fi done # # Processor declarationsa found? # if [[ $gScope == "" ]]; then # # No. Check for Device()s with enclosed Name (_HID, "ACPI0004") objects in DSDT.dat # filename="/tmp/DSDT.dat" basename=$(basename "${filename%.*}") _getACPIProcessorScope "$filename" fi # # Did we find any with Processor declarations? # if [[ $gScope != "" ]]; then # # Yes. We're done searching for the processor scope/declarations. # return else # # Note: This is not necessarily an error! # _debugPrint "Name (_HID, \"ACPI0004\") NOT found in ${basename}\n" fi # # Search for ACPI v1.0 compliant scopes (like _PR and _PR_). # _getProcessorScope "${filename}" # # Do we have a scope with processor declarations in it? # if [[ $gScope != "" ]]; then # # Yes. We're done searching for the processor scope/declarations. # return else # # Additional check for processor declarations with child objects. # if [[ $(egrep -o '5b83[0-9a-f]{2}04' "$filename") ]]; then printf 'ACPI Processor {.} Declaration(s) found in ${basename}\n' let processorDeclarationsFound=1 else # # Check for processor declarations without child objects. # if [[ $(egrep -o '5b830b' "$filename") ]]; then printf 'ACPI Processor {} Declaration(s) found in ${basename}\n' let processorDeclarationsFound=1 fi fi # # Check for processor declarations with RootChar in DSDT. # local data=$(egrep -o '5b83[0-9a-f]{2}5c2e[0-9a-f]{8}' "$filename") if [[ $data ]]; then printf "ACPI Processor {...} Declaration(s) with RootChar ('\\\') found in ${basename}" gScope="\\"$(echo ${data:10:8} | xxd -r -p) if [[ $gScope == "\_PR_" ]]; then echo ' (ACPI 1.0 compliant)' elif [[ $gScope == "\_SB_" ]]; then echo ' (none ACPI 1.0 compliant)' else echo ' - ERROR: Invalid Scope Used!' fi return fi # # Check for processor declarations with DualNamePrefix in the DSDT. # local data=$(egrep -o '5b83[0-9a-f]{2}2e[0-9a-f]{8}' "$filename") if [[ $data ]]; then printf "ACPI Processor {...} Declaration(s) with DualNamePrefix ('.') found in ${basename}" gScope="\\"$(echo ${data:8:8} | xxd -r -p) if [[ $gScope == "\_PR_" ]]; then echo ' (ACPI 1.0 compliant)' elif [[ $gScope == "\_SB_" ]]; then echo ' (none ACPI 1.0 compliant)' else echo ' - ERROR: Invalid Scope Used!' fi return fi # # Check for processor declarations with MultiNamePrefix (without leading backslash) in the DSDT. # local data=$(egrep -o '5b83[0-9a-f]{2}2f[0-9a-f]{2}' "$filename") if [[ $data ]]; then printf "ACPI Processor {...} Declaration(s) with MultiNamePrefix ('/') found in ${basename}" let scopeLength=("0x"${data:8:2})*4*2 local data=$(egrep -o '5b83[0-9a-f]{2}2f[0-9a-f]{'$scopeLength'}' "$filename") partOne=$(echo ${data:10:8} | xxd -r -p) partTwo=$(echo ${data:18:8} | xxd -r -p) gScope="\\${partOne}.${partTwo}" if [[ $gScope =~ "\_PR_" ]]; then echo ' (ACPI 1.0 compliant)' elif [[ $gScope =~ "\_SB_" ]]; then echo ' (none ACPI 1.0 compliant)' else echo ' - ERROR: Invalid Scope Used!' fi return fi # # Check for processor declarations with MultiNamePrefix (with leading backslash) in the DSDT. # local data=$(egrep -o '5b83[0-9a-f]{2}5c2f[0-9a-f]{2}' "$filename") if [[ $data ]]; then printf "ACPI Processor {...} Declaration(s) with MultiNamePrefix ('/') found in ${basename}" let scopeLength=("0x"${data:10:2})*4*2 local data=$(egrep -o '5b83[0-9a-f]{2}5c2f[0-9a-f]{'$scopeLength'}' "$filename") partOne=$(echo ${data:12:8} | xxd -r -p) partTwo=$(echo ${data:20:8} | xxd -r -p) gScope="\\${partOne}.${partTwo}" if [[ $gScope =~ "\_PR_" ]]; then echo ' (ACPI 1.0 compliant)' elif [[ $gScope =~ "\_SB_" ]]; then echo ' (none ACPI 1.0 compliant)' else echo ' - ERROR: Invalid Scope Used!' fi return fi # # Check for processor declarations with ParentPrefixChar in the DSDT. # local data=$(egrep -o '5b83[0-9a-f]{2}5e[0-9a-f]{8}' "$filename") if [[ $data ]]; then printf "ACPI Processor {...} Declaration(s) with ParentPrefixChar ('^') found in ${basename}\n" gScope=$(echo ${data:6:2} | xxd -r -p) # ioreg -w0 -p IOACPIPlane -c IOACPIPlatformDevice -n _SB -r > ~/Library/ssdtPRGen/dsdt2.txt if [[ $gScope =~ "^" ]]; then printf "Searching for Parent Scope ... " else echo ' - ERROR: Invalid Scope Used!' fi return fi fi # # Did we find a Scope (_PR) {} object in the DSDT? # # Note: We end up here if all patterns failed to match anything but the _PR scope. # if [[ $gScopePRFound -eq 1 ]]; then gScope="\_PR" else gScope="\_SB" fi _PRINT_MSG "\nWarning: No ACPI Processor declarations found in ${basename}!\n\t Using assumed Scope ("$gScope") {}\n" } # #-------------------------------------------------------------------------------- # function _getCPUtype() { # # Grab 'cpu-type' property from ioreg (stripped with sed / RegEX magic). # local grepStr=$(ioreg -p IODeviceTree -n "${gProcessorNames[0]}"@0 -k cpu-type | grep cpu-type | sed -e 's/["cputype" ,<>|=-]//g') # Swap bytes with help of ${str:pos:num} # echo ${grepStr:2:2}${grepStr:0:2} } # #-------------------------------------------------------------------------------- # function _getCPUModel() { # # Return the hexadecimal value of machdep.cpu.model # echo 0x$(sysctl machdep.cpu.model | awk '{ printf("%X", $2) }') } # #-------------------------------------------------------------------------------- # function _getCPUSignature() { # # Return the hexadecimal value of machdep.cpu.signature # echo 0x$(sysctl machdep.cpu.signature | awk '{ printf("%X", $2) }') } # #-------------------------------------------------------------------------------- # function _getSystemType() { # # Grab 'system-type' property from ioreg (stripped with sed / RegEX magic). # # Note: This property is checked (cmpb $0x02) in X86PlatformPlugin::configResourceCallback # echo `ioreg -p IODeviceTree -d 2 -k system-type | grep system-type | sed -e 's/ *[-="<0a-z>]//g'` } # #-------------------------------------------------------------------------------- # function _checkForExecutableFile() { local targetFile=$1 # # Check target file. # if [ ! -f "${gToolPath}/${targetFile}" ]; then # # Not there. Do we have the ZIP file? # if [ ! -f "${gToolPath}/${targetFile}.zip" ]; then # # No. Download it from the Github repository. # _PRINT_MSG "Notice: Downloading ${targetFile}.zip ..." curl -o "${gPath}/${targetFile}.zip" --silent "${gGitHubContentURL}/Tools/${targetFile}.zip" # # Unzip ZIP file. # _debugPrint "Unzipping ${targetFile}.zip ..." unzip -qu "${gPath}/${targetFile}.zip" -d "${gToolPath}/" # # Remove downloaded ZIP file. # _debugPrint 'Cleanups ..' rm "${gPath}/${targetFile}.zip" else # # Unzip ZIP file. # _debugPrint "Unzipping ${targetFile}.zip ..." unzip -qu "${gToolPath}/${targetFile}.zip" -d "${gToolPath}/" fi fi # # Check executing bit. # _debugPrint "Setting executing bit of ${targetFile} ...\n" if [ ! -x "${gToolPath}/${targetFile}" ]; then # # Set executing bit. # printf "Fixing executing bit of ${targetFile} ...\n" chmod +x "${gToolPath}/${targetFile}" fi _debugPrint "_checkForExecutableFile(${targetFile}) Done.\n" } # #-------------------------------------------------------------------------------- # function _findIasl() { # # Do we have to call IASL? # if [[ $gCallIasl -eq 1 ]]; then # # Yes. Do a quick lookup of IASL. # local iasl="$(type -p iasl)" # # Now we have to check if the file is still there. # if [ -x "${iasl}" ]; then # # Yes it is. Let's use it. # gIasl="${iasl}" # # Done (no need to download it from the Github repository). # return fi # # IASL should be there after the first run, but may have been removed since. # _checkForExecutableFile "iasl" fi gIasl="${gToolPath}/iasl" } # #-------------------------------------------------------------------------------- # function _extractAcpiTables() { # # extractACPITables should be there after the first run, but may have been removed since. # _checkForExecutableFile "extractACPITables" # # Do we have a given path for ACPI table extraction? # if [[ $gExtractionPath ]]; then # # Yes. Use given target path for extractACPITables v0.6 and greater. # export SSDTPRGEN_EXTRACTION_PATH="${gExtractionPath}" else # # No. Use default ACPI table path. # export SSDTPRGEN_EXTRACTION_PATH="${gPath}/ACPI" fi # # Does the target directory exist? # if [[ ! -d "${SSDTPRGEN_EXTRACTION_PATH}" ]]; then # # No. We need to create it. # mkdir -p "${SSDTPRGEN_EXTRACTION_PATH}" fi # # About to extract the ACPI tables. # _debugPrint 'Extracting ACPI tables ... ' "${gToolPath}/extractACPITables" _debugPrint 'Done.\n' } # #-------------------------------------------------------------------------------- # function _checkSourceFilename { # # Check for RevoBoot (legacy) setup on root volume. # if [[ -d "/Extra/ACPI" && -d "/Extra/EFI" ]]; then let gIsLegacyRevoBoot=1 if [[ $gDestinationPath != "/Extra/ACPI/" ]]; then gDestinationPath="/Extra/ACPI/" _debugPrint "ACPI target directory changed to: ${gDestinationPath}\n" fi if [[ "$gDestinationFile" != "ssdt_pr.aml" ]]; then gSsdtID="ssdt_pr" gSsdtPR="${gPath}/${gSsdtID}.dsl" gDestinationFile="ssdt_pr.aml" _debugPrint "ACPI target filename changed to: ${gDestinationFile}\n" fi fi } # #-------------------------------------------------------------------------------- # function _setDestinationPath { # # Check for mounted EFI volume. # if [ ! -d /Volumes/EFI ]; then # # Not there. # echo 'Creating temporarily mount point: /Volumes/EFI' sudo mkdir /Volumes/EFI printf 'Mounting EFI partition...\n' # # TODO: Get target disk from diskutil list # sudo mount_hfs /dev/disk0s1 /Volumes/EFI let gUnmountEFIPartition=1 fi # # Check for RevoBoot (legacy) setup on EFI volume. # if [ -d /Volumes/EFI/Extra/ACPI ]; then # # Update destination path. # gDestinationPath="/Volumes/EFI/Extra/ACPI/" _debugPrint "ACPI target directory changed to: ${gDestinationPath}" if [[ "$gDestinationFile" != "ssdt_pr.aml" ]]; then gSsdtID="ssdt_pr" gSsdtPR="/Volumes/EFI/Extra/ACPI/${gSsdtID}.dsl" gDestinationFile="ssdt_pr.aml" _debugPrint "ACPI target filename changed to: ${gDestinationFile}\n" fi else # # Check for the new RevoBoot EFI edition. # if [ -d /Volumes/EFI/RevoEFI/ACPI ]; then gDestinationPath="/Volumes/EFI/RevoEFI/ACPI/" _debugPrint "ACPI target directory changed to: ${gDestinationPath}\n" return fi # # Clover checks... must be checked or will be removed!!! # if [ -d /Volumes/EFI/Clover/ACPI/patched ]; then gDestinationPath="/Volumes/EFI/CLOVER/ACPI/patched/" _debugPrint "ACPI target directory changed to: ${gDestinationPath}\n" else # # Check for older versions of Clover. # if [ -d /EFI/ACPI/patched ]; then gDestinationPath="/EFI/ACPI/patched/" echo 'ACPI target directory changed to: '$gDestinationPath fi fi fi } # #-------------------------------------------------------------------------------- # function _getCPUNumberFromBrandString { # # Save default (0) delimiter # local ifs=$IFS # # Change delimiter to a space character # IFS=" " # # Split brandstring (pulled in by _showSystemData) into array (data) # local data=($gBrandString) # # Teststrings # # local data=("Intel(R)" "Xeon(R)" "CPU" "E3-1220" "@" "2.5GHz") # local data=("Intel(R)" "Xeon(R)" "CPU" "E3-1220" "v2" "@" "2.5GHz") # local data=("Intel(R)" "Xeon(R)" "CPU" "E3-1220" "v3" "@" "2.5GHz") # local data=("Intel(R)" "Xeon(R)" "CPU" "E3-1220" "0" "@" "2.5GHz") # local data=("Intel(R)" "Core(TM)" "i5-4670K" "CPU" "@" "3.40GHz") # # # Example from a MacBookPro10,2 # # echo "${data[0]}" # Intel(R) # echo "${data[1]}" # Core(TM) # echo "${data[2]}" # i5-3210M # echo "${data[3]}" # CPU # echo "${data[4]}" # @ # echo "${data[5]}" # 2.50GHz # # or: "Intel(R) Xeon(R) CPU E3-1230 V2 @ 3.30GHz" # # echo "${data[0]}" # Intel(R) # echo "${data[1]}" # Xeon(R) # echo "${data[2]}" # CPU # echo "${data[3]}" # E3-12XX # echo "${data[4]}" # V2 # echo "${data[5]}" # @ # echo "${data[6]}" # 3.30GHz # # Restore the default (0) delimiter. # IFS=$ifs let length=${#data[@]} if (( length > 7 )); then echo 'Warning: The brandstring has an unexpected length!' fi # # Is this a Xeon processor model? # if [[ "${data[1]}" == "Xeon(R)" ]]; then # # Yes. Check for lower/upper case 'v' or '0' for OEM processors. # if [[ "${data[4]}" =~ "v" || "${data[4]}" =~ "V" ]]; then # # Use a lowercase 'v' because that is what we use in our data. # gProcessorNumber="${data[3]} v${data[4]:1:1}" elif [[ "${data[4]}" == "0" ]]; then # # OEM CPU's have been reported to use a "0" instead of "v2" # and thus let's use that to make our data match the CPU. # # -target argument used? # if [[ $gBridgeType -gt 0 ]]; then # # Yes. Check target processor model (represented here as 'gBridgeType'). # case "$gBridgeType" in $SANDY_BRIDGE) gProcessorNumber="${data[3]}" ;; $IVY_BRIDGE) gProcessorNumber="${data[3]} v2" ;; esac else # # No. Check Processor model. # case $(_getCPUModel) in 0x2A|0x2C|0x2D) gProcessorNumber="${data[3]}" ;; 0x3A|0x3B|0x3E) gProcessorNumber="${data[3]} v2" ;; esac fi fi else # # Is this a Pentium processor model? # if [[ "${data[1]}" == "Pentium(R)" ]]; then # # Yes. Use fourth value from brandstring ("Intel(R) Pentium(R) CPU G3420 @ 3.20GHz") # gProcessorNumber="${data[3]}" else # # No. Use third value from brandstring for all other processor models. # gProcessorNumber="${data[2]}" fi fi } # #-------------------------------------------------------------------------------- # function _checkForConfigFile { # # Check given file. # if [ ! -f "${gDataPath}/${1}" ]; then # # Not there. # return 1 fi # # Do we have a local Data directory? # if [ -d "Data" ]; then # # Yes. Compare the files. # if [[ $(cmp -s "${gDataPath}/${1}" "Data/${1}") ]]; then return 2 fi fi # # Check file length. # if [[ $(wc -c "${gDataPath}/${1}" | awk '{print $1}') -lt 100 ]]; then rm "${gDataPath}/$1" return 3 fi return 0 } # #-------------------------------------------------------------------------------- # function _checkForConfigFileUpdate { # # New update available for download? # case "$1" in 0) if [[ $gLatestDataVersion_Model -gt $gModelDataVersion ]]; then return 1 fi ;; 1) let gCPUDataVersion=-1 ;; 2) if [[ $gLatestDataVersion_SandyBridge -gt $gSandyBridgeCPUDataVersion ]]; then return 1 else let gCPUDataVersion=$gSandyBridgeCPUDataVersion fi ;; 4) if [[ $gLatestDataVersion_IvyBridge -gt $gIvyBridgeCPUDataVersion ]]; then return 1 else let gCPUDataVersion=$gIvyBridgeCPUDataVersion fi ;; 8) if [[ $gLatestDataVersion_Haswell -gt $gHaswellCPUDataVersion ]]; then return 1 else let gCPUDataVersion=$gHaswellCPUDataVersion fi ;; 16) if [[ $gLatestDataVersion_Broadwell -gt $gBroadwellCPUDataVersion ]]; then return 1 else let gCPUDataVersion=$gBroadwellCPUDataVersion fi ;; 32) if [[ $gLatestDataVersion_Skylake -gt $gSkylakeCPUDataVersion ]]; then return 1 else let gCPUDataVersion=$gSkylakeCPUDataVersion fi ;; 64) if [[ $gLatestDataVersion_KabyLake -gt $gKabyLakeCPUDataVersion ]]; then return 1 else let gCPUDataVersion=$gKabyLakeCPUDataVersion fi ;; esac return 0 } # #-------------------------------------------------------------------------------- # function _getCPUDataByProcessorNumber { # # Local function definition # function __searchList() { local data local cpuData # # Save default (0) delimiter. # local ifs=$IFS let cpuType=0 case $1 in 1) local cpuSpecLists=("gUserDefinedCPUList[@]") ;; 2) local cpuSpecLists=("gDesktopSandyBridgeCPUList[@]" "gMobileSandyBridgeCPUList[@]" "gServerSandyBridgeCPUList[@]") ;; 4) local cpuSpecLists=("gDesktopIvyBridgeCPUList[@]" "gMobileIvyBridgeCPUList[@]" "gServerIvyBridgeCPUList[@]") ;; 8) local cpuSpecLists=("gDesktopHaswellCPUList[@]" "gMobileHaswellCPUList[@]" "gServerHaswellCPUList[@]") ;; 16) local cpuSpecLists=("gDesktopBroadwellCPUList[@]" "gMobileBroadwellCPUList[@]" "gServerBroadwellCPUList[@]") ;; 32) local cpuSpecLists=("gDesktopSkylakeCPUList[@]" "gMobileSkylakeCPUList[@]" "gServerSkylakeCPUList[@]") ;; 64) local cpuSpecLists=("gDesktopKabyLakeCPUList[@]" "gMobileKabyLakeCPUList[@]" "gServerKabyLakeCPUList[@]") ;; esac for cpuList in "${cpuSpecLists[@]}" do let cpuType+=1 local targetCPUList=("${!cpuList}") for cpuData in "${targetCPUList[@]}" do # # Change delimiter to comma character. # IFS="," # # Split vars. # data=($cpuData) if [[ "${data[0]}" == "${gProcessorNumber}" ]]; then # # Make processor data globally available. # gProcessorData=($cpuData) let gTypeCPU=$cpuType # # Is gBridgeType still uninitialised i.e. is argument -target not used? # if [[ $gBridgeType -eq -1 ]]; then if [[ "${#data[@]}" -ge 8 ]]; then let gBridgeType="${data[7]}" else let gBridgeType=$1 fi fi # # Do we have a custom BCLK/bus frequency? # if [[ "${#data[@]}" -eq 9 ]]; then let gBusFrequency="${data[8]}" fi # # Restore the default (0) delimiter. # IFS=$ifs _debugPrint "Processor data found for the Intel ${gProcessorNumber}\n" return 1 fi done done # # Restore the default (0) delimiter. # IFS=$ifs return 0 } let arrayIndex=0 let targetBridgeType=1 # # From here on we check/download/load the processor data file(s). # for dataFile in "${gProcessorDataConfigFiles[@]}" do _checkForConfigFile "${dataFile}.cfg" # # File not found? # if [[ $? -gt 0 ]]; then # # No. Download it. # _PRINT_MSG "Notice: Downloading ${dataFile}.cfg ..." curl -o "${gDataPath}/${dataFile}.cfg" --silent $(echo "${gGitHubContentURL}/Data/${dataFile}.cfg" | sed 's/ /%20/g') fi source "${gDataPath}/${dataFile}.cfg" _checkForConfigFileUpdate $targetBridgeType # # New update available? # if [[ $? -gt 0 ]]; then # # Yes. Download it. # _PRINT_MSG "Notice: Downloading Update of ${dataFile}.cfg ..." curl -o "${gDataPath}/${dataFile}.cfg" --silent $(echo "${gGitHubContentURL}/Data/${dataFile}.cfg" | sed 's/ /%20/g') source "${gDataPath}/${dataFile}.cfg" fi _debugPrint "Checking ${dataFile} processor data ...\n" __searchList $targetBridgeType # # Target processor data located? # if [[ $gTypeCPU -gt 0 ]]; then # # Yes. Show version information (helping me to debug issues). # _PRINT_MSG "Version: models.cfg v${gModelDataVersion} / ${gProcessorDataConfigFiles[($arrayIndex)]}.cfg v${gCPUDataVersion}\n" return fi # # Next # let arrayIndex+=1 let "targetBridgeType <<= 1" done # # No. The processor data was not found (error out). # _exitWithError $PROCESSOR_NUMBER_ERROR $2 } # #-------------------------------------------------------------------------------- # function _showLowPowerStates() { # # Local function definition # function __print() { local mask=1 local cStates=$1 printf "Injected C-States for ${gProcessorNames[$2]} (" # # Haswell : C0, C1, C1E, C2E, C3, C4, C6 and C7 # Haswell-ULT: C0, C1, C1E, C2E, C3, C4, C6, C7, C8, C9 and C10 # for state in C1 C2 C3 C6 C7 C8 C9 C10 do if (($cStates & $mask)); then if (($mask > 1)); then printf "," fi printf "$state" fi let mask=$(($mask << 1)) done echo ')' } # # Local function callers # __print $gACST_CPU0 0 if [ $gBridgeType -ge $IVY_BRIDGE ]; then __print $gACST_CPU1 1 fi } # #-------------------------------------------------------------------------------- # function _checkPlatformSupport() { # # Local function definition # function __searchList() { local data=`awk '/'${1}'<\/key>.*/,/<\/array>/' /System/Library/CoreServices/PlatformSupport.plist` local matched=`echo $data | egrep -o $2` if [ ${#matched} -gt 1 ]; then return 1 fi return 0 } # # This check is required for Snow Leopard compatibility! # if [ -f /System/Library/CoreServices/PlatformSupport.plist ]; then __searchList 'SupportedModelProperties' $gModelID if [ $? == 0 ]; then _PRINT_MSG 'Warning: Model identifier ('$gModelID') not found in..: /S*/L*/CoreServices/PlatformSupport.plist\n' fi __searchList 'SupportedBoardIds' $gBoardID if [ $? == 0 ]; then _PRINT_MSG 'Warning: board-id ('$gBoardID') not found in: /S*/L*/CoreServices/PlatformSupport.plist\n' fi else _PRINT_MSG 'Warning: /S*/L*/C*/PlatformSupport.plist not found (normal for Snow Leopard)!' fi # # Check for FrequencyVectors in plist. # if [ $gBridgeType -ge $HASWELL ]; then local plist="/System/Library/Extensions/IOPlatformPluginFamily.kext/Contents/PlugIns/X86PlatformPlugin.kext/Contents/Resources/${gBoardID}.plist" if [ -e "$plist" ]; then local freqVectorMatched=$(grep -c 'FrequencyVectors' "$plist") if [ $freqVectorMatched -eq 0 ]; then _PRINT_MSG "Warning..: FrequencyVectors missing in ${gBoardID}.plist" printf "\t Download https://github.com/Piker-Alpha/freqVectorsEdit.sh to fix this\n" fi else _PRINT_MSG "Warning: File ${gBoardID}.plist Not Found!" fi fi } # #-------------------------------------------------------------------------------- # function _checkSMCKeys() { # # TODO: Check SMC keys to see if they are there and properly initialized! # # Note: Do not dump SMC keys with HWSensors/iStat or other SMC plug-ins installed! # local filename="/System/Library/Extensions/FakeSMC.kext/Contents/Info.plist" local data=`grep -so '[a-zA-Z]*' $filename | sed -e 's///' -e 's/<\/key>//g'` local status=`echo $data | grep -oe 'DPLM'` if [ $status == 'DPLM' ]; then # DPLM [{lim] (bytes 00 00 00 00 00) # CPU, Idle, IGPU, EGPU and Memory P-State limits echo "SMC key 'DPLM' found (OK)" fi set -x local status=`echo $data | grep -oe 'MSAL'` if [ $status == 'MSAL' ]; then # MSAL [hex_] (bytes 4b) echo "SMC key 'MSAL' found (OK)" fi } # #-------------------------------------------------------------------------------- # function _checkForXCPM() { # # Is XCPM mode still uninitialised? # if [[ $gXcpm -eq -1 ]]; then # # Check OS version (the 'machdep.xcpm' class is introduced in 10.8.5) # if [[ $gOSVersion -gt 1084 ]]; then # # Yes. Update global variable. # let gXcpm=$(/usr/sbin/sysctl -n machdep.xcpm.mode) # # Is XCPM mode active/ -x 1 argument used? # if [[ $gXcpm -eq 1 && $gCPUWorkArounds -gt 0 ]]; then # # Yes. Disable Ivy Bridge workarounds. # let gCPUWorkArounds=0 # # Is the target processor an Ivy Bridge one? # if [[ $gBridgeType == $IVY_BRIDGE ]]; then # # Yes. Inform the user about the change. # printf "\nXCPM mode detected (Ivy Bridge workarounds disabled)\n\n" fi fi fi fi # # Is this a multiprocessor system using XCPM mode? # if [[ $gPhysicalCPUs -gt 1 && $gXcpm -eq 1 ]]; then # # Yes. Inform user to use inter-processor interrupt power management. # _PRINT_MSG "\n\nWarning: You must use the -xcpm_ipi boot argument instead of -xcpm on multiprocessor systems.\n\n\n" fi } # #-------------------------------------------------------------------------------- # function _initSandyBridgeSetup() { # # Global variable (re)initialisation. # gSystemType=2 gACST_CPU0=29 # C1, C3, C6 and C7 gACST_CPU1=7 # C1, C2 and C3 # # Overrides are set below. # case $gBoardID in Mac-942B5BF58194151B) gSystemType=1 gTargetMacModel="iMac12,1" gACST_CPU0=13 # C1, C3 and C6 gACST_CPU1=7 # C1, C2 and C3 ;; Mac-942B59F58194171B) gSystemType=1 gTargetMacModel="iMac12,2" gACST_CPU0=13 # C1, C3 and C6 gACST_CPU1=7 # C1, C2 and C3 ;; Mac-8ED6AF5B48C039E1) gSystemType=1 gTargetMacModel="Macmini5,1" gACST_CPU0=13 # C1, C3 and C6 gACST_CPU1=7 # C1, C2 and C3 ;; Mac-4BC72D62AD45599E) gSystemType=1 gTargetMacModel="Macmini5,2" gACST_CPU0=13 # C1, C3, C6 and C7 gACST_CPU1=7 # C1, C2 and C3 ;; Mac-7BA5B2794B2CDB12) gSystemType=1 gTargetMacModel="Macmini5,3" gACST_CPU0=13 # C1, C3, C6 and C7 gACST_CPU1=7 # C1, C2 and C3 ;; Mac-94245B3640C91C81) gTargetMacModel="MacBookPro8,1" ;; Mac-94245A3940C91C80) gTargetMacModel="MacBookPro8,2" ;; Mac-942459F5819B171B) gTargetMacModel="MacBookPro8,3" ;; Mac-C08A6BB70A942AC2) gTargetMacModel="MacBookAir4,1" ;; Mac-742912EFDBEE19B3) gTargetMacModel="MacBookAir4,2" ;; esac } # #-------------------------------------------------------------------------------- # function _initIvyBridgeSetup() { # # Global variable (re)initialisation. # gSystemType=2 gACST_CPU0=29 # C1, C3, C6 and C7 gACST_CPU1=7 # C1, C2 and C3 # # Overrides are set below. # case $gBoardID in Mac-00BE6ED71E35EB86) gSystemType=1 gTargetMacModel="iMac13,1" gACST_CPU0=13 # C1, C3 and C6 gACST_CPU1=7 # C1, C2 and C3 ;; Mac-FC02E91DDD3FA6A4) gSystemType=1 gTargetMacModel="iMac13,2" gACST_CPU0=13 # C1, C3 and C6 gACST_CPU1=7 # C1, C2 and C3 ;; Mac-031AEE4D24BFF0B1) gSystemType=1 gTargetMacModel="Macmini6,1" gACST_CPU0=13 # C1, C3 and C6 gACST_CPU1=7 # C1, C2 and C3 ;; Mac-F65AE981FFA204ED) gSystemType=1 gTargetMacModel="Macmini6,2" gACST_CPU0=13 # C1, C3 and C6 gACST_CPU1=7 # C1, C2 and C3 ;; Mac-4B7AC7E43945597E) gTargetMacModel="MacBookPro9,1" ;; Mac-6F01561E16C75D06) gTargetMacModel="MacBookPro9,2" ;; Mac-C3EC7CD22292981F) gTargetMacModel="MacBookPro10,1" ;; Mac-AFD8A9D944EA4843) gTargetMacModel="MacBookPro10,2" ;; Mac-66F35F19FE2A0D05) gTargetMacModel="MacBookAir5,1" ;; Mac-2E6FAB96566FE58C) gTargetMacModel="MacBookAir5,2" ;; Mac-F60DEB81FF30ACF6) gSystemType=3 gTargetMacModel="MacPro6,1" gACST_CPU0=13 # C1, C3, C6 gACST_CPU1=13 # C1, C3, C6 ;; esac } # #-------------------------------------------------------------------------------- # function _initHaswellSetup() { # # Global variable (re)initialisation. # gSystemType=2 gACST_CPU0=29 # C1, C3, C6 and C7 gACST_CPU1=7 # C1, C2 and C3 # # Overrides are set below. # case $gBoardID in Mac-031B6874CF7F642A) gSystemType=1 gTargetMacModel="iMac14,1" ;; Mac-27ADBB7B4CEE8E61) gSystemType=1 gTargetMacModel="iMac14,2" ;; Mac-77EB7D7DAF985301) gSystemType=1 gTargetMacModel="iMac14,3" ;; Mac-189A3D4F975D5FFC) gTargetMacModel="MacBookPro11,1" gACST_CPU0=253 # C1, C3, C6, C7, C8, C9 and C10 gACST_CPU1=31 # C1, C2, C3, C6 and C7 ;; Mac-3CBD00234E554E41) gTargetMacModel="MacBookPro11,2" gACST_CPU0=253 # C1, C3, C6, C7, C8, C9 and C10 gACST_CPU1=31 # C1, C2, C3, C6 and C7 ;; Mac-2BD1B31983FE1663) gTargetMacModel="MacBookPro11,3" gACST_CPU0=253 # C1, C3, C6, C7, C8, C9 and C10 gACST_CPU1=31 # C1, C2, C3, C6 and C7 ;; Mac-06F11FD93F0323C5) gTargetMacModel="MacBookPro11,4" ;; Mac-06F11F11946D27C5) gTargetMacModel="MacBookPro11,5" ;; Mac-35C1E88140C3E6CF) gTargetMacModel="MacBookAir6,1" ;; Mac-7DF21CB3ED6977E5) gTargetMacModel="MacBookAir6,2" ;; Mac-35C5E08120C7EEAF) gSystemType=1 gTargetMacModel="Macmini7,1" ;; Mac-F60DEB81FF30ACF6) gSystemType=3 gTargetMacModel="MacPro6,1" gACST_CPU0=13 # C1, C3, C6 gACST_CPU1=13 # C1, C3, C6 ;; esac } # #-------------------------------------------------------------------------------- # function _initBroadwellSetup() { # # Global variable (re)initialisation. # gSystemType=2 gACST_CPU0=253 # C1, C3, C6, C7, C8, C9 and C10 gACST_CPU1=31 # C1, C2, C3, C6 and C7 # # Overrides are set below. # case $gBoardID in Mac-E43C1C25D4880AD6) gTargetMacModel="MacBookPro12,1" ;; Mac-9F18E312C5C2BF0B) gTargetMacModel="MacBookAir7,1" ;; Mac-937CB26E2E02BB01) gTargetMacModel="MacBookAir7,2" ;; Mac-BE0E8AC46FE800CC) gTargetMacModel="MacBook8,1" ;; Mac-A369DDC4E67F1C45) gSystemType=1 gTargetMacModel="iMac16,1" ;; Mac-FFE5EF870D7BA81A) # Retina 4K, 21.5-inch, Core i5 3.1GHz gSystemType=1 gTargetMacModel="iMac16,2" ;; Mac-F60DEB81FF30ACF6) gSystemType=3 gTargetMacModel="MacPro6,1" gACST_CPU0=13 # C1, C3, C6 gACST_CPU1=13 # C1, C3, C6 ;; esac } # #-------------------------------------------------------------------------------- # function _initSkylakeSetup() { # # Global variable (re)initialisation. # gSystemType=2 gACST_CPU0=253 # C1, C3, C6, C7, C8, C9 and C10 gACST_CPU1=31 # C1, C2, C3, C6 and C7 # # Overrides are set below. # case $gBoardID in Mac-9AE82516C7C6B903) # Retina, 12-inch, Intel Core m3/m3 gTargetMacModel="MacBook9,1" ;; Mac-65CE76090165799A) # Retina 5K, 27-inch, Intel Core i7 4.0GHz gSystemType=1 gTargetMacModel="iMac17,1" ;; Mac-B809C3757DA9BB8D) # Retina 5K, 27-inch, Intel Core i5 3.3GHz gSystemType=1 gTargetMacModel="iMac17,1" ;; Mac-DB15BD556843C820) # Retina 5K, 27-inch, Intel Core i5 3.2GHz gSystemType=1 gTargetMacModel="iMac17,1" ;; Mac-473D31EABEB93F9B) # Retina MacBook Pro (Late 2016) gSystemType=2 gTargetMacModel="MacBookPro13,1" ;; Mac-66E35819EE2D0D05) # Retina MacBook Pro (Late 2016) gSystemType=2 gTargetMacModel="MacBookPro13,2" ;; Mac-A5C67F76ED83108C) # Retina MacBook Pro (Late 2016) gSystemType=2 gTargetMacModel="MacBookPro13,3" ;; esac } # #-------------------------------------------------------------------------------- # function _initKabyLakeSetup() { # # Global variable (re)initialisation. # gSystemType=2 gACST_CPU0=253 # C1, C3, C6, C7, C8, C9 and C10 gACST_CPU1=31 # C1, C2, C3, C6 and C7 # # Overrides are set below. # case $gBoardID in Mac-B4831CEBD52A0C4C) gTargetMacModel="MacBookPro14,1" ;; Mac-CAD6701F7CEA0921) gTargetMacModel="MacBookPro14,2" ;; Mac-551B86E5744E2388) gTargetMacModel="MacBookPro14,3" ;; Mac-EE2EBD4B90B839A8) gTargetMacModel="MacBook10,1" ;; Mac-4B682C642B45593E) gSystemType=1 gTargetMacModel="iMac18,1" ;; Mac-77F17D7DA9285301) gSystemType=1 gTargetMacModel="iMac18,2" ;; Mac-BE088AF8C5EB4FA2) gSystemType=1 gTargetMacModel="iMac18,3" ;; esac } # #-------------------------------------------------------------------------------- # function _exitWithError() { case "$1" in 2) _PRINT_MSG "\nError: 'MaxTurboFrequency' must be in the range of $frequency-$gMaxOCFrequency ..." _ABORT 2 ;; 3) _PRINT_MSG "\nError: -t [TDP] must be in the range of 11.5 - 150 Watt ..." _ABORT 3 ;; 4) _PRINT_MSG "\nError: 'BridgeType' must be 0, 1, 2 or 3 ..." _ABORT 4 ;; 5) printf "\e[A\e[K" _PRINT_MSG "\nError: Unknown processor model ..." if [[ $2 -eq 0 ]]; then printf " Visit http://ark.intel.com to gather the required data:\n" printf " Processor Number\n" printf " TDP\n" printf " Low Frequency Mode (use AppleIntelInfo.kext)\n" printf " Base Frequency\n" printf " Max Turbo Frequency\n" printf " Cores\n" printf " Threads\n" fi _ABORT 5 ;; 6) _PRINT_MSG "\nError: Processor label length is less than 3 ..." _ABORT 6 ;; 7) _PRINT_MSG "\nError: Processor name(s) not found ..." _ABORT 7 ;; 8) _PRINT_MSG "\nError: Processor Declarations not found ..." _ABORT 8 ;; 9) _PRINT_MSG "\nError: File not found ..." _ABORT 9 ;; 10) _PRINT_MSG "\nError: Low Frequency Mode is 0 ..." _ABORT 10 ;; *) _ABORT 1 ;; esac } # #-------------------------------------------------------------------------------- # function _confirmUnsupported() { _PRINT_MSG "$1" read -p "Do you want to continue (y/n)? " unsupportedConfirmed case "$unsupportedConfirmed" in y|Y) return ;; *) exit 1 ;; esac } # #-------------------------------------------------------------------------------- # function _invalidArgumentError() { _PRINT_MSG "\nError: Invalid argument detected: ${1} (check ssdtPRGen.sh -h)" _ABORT } # #-------------------------------------------------------------------------------- # function _showSupportedBoardIDsAndModels() { # # Save default (0) delimiter. # local ifs=$IFS # # Setup a local variable pointing to a list with supported model data. # case "$1" in 'Sandy Bridge') local modelDataList="gSandyBridgeModelData[@]" ;; 'Ivy Bridge') local modelDataList="gIvyBridgeModelData[@]" ;; Haswell) local modelDataList="gHaswellModelData[@]" ;; Broadwell) local modelDataList="gBroadwellModelData[@]" ;; Skylake) local modelDataList="gSkylakeModelData[@]" ;; 'Kaby Lake') local modelDataList="gKabyLakeModelData[@]" ;; esac # # Split 'modelDataList' into array. # local targetList=("${!modelDataList}") printf "${STYLE_BOLD}$1${STYLE_RESET}\n" if [[ "${#targetList[@]}" -gt 1 ]]; then # # Change delimiter to a colon character. # IFS=":" # # Loop through target list. # for modelData in "${targetList[@]}" do # # Split 'modelData' into array. # local data=($modelData) echo "${data[0]} / ${data[1]}" done else echo "Mac-XXXXXXXXXXXXXXXX / Undefined" fi # # Restore the default (0) delimiter. # IFS=$ifs # # Print extra newline for a cleaner layout. # printf "\n" } # #-------------------------------------------------------------------------------- # function _checkLibraryDirectory() { # # Download Versions.cfg so that we can check for new updates. # curl -o "${gDataPath}/Versions.cfg" --silent "${gGitHubContentURL}/Data/Versions.cfg" # # Load versions numbers. # source "${gDataPath}/Versions.cfg" # # Are we running in the Github project directory? # if [ $gDeveloperMode -eq 1 ] && [ -d .git ] && [ -f .gitIgnore ] && [ -f CHANGELOG.md ] && [ -f CONTRIBUTORS.md ] && [ -f README.md ] && [ -d Data ] && [ -f Data/Broadwell.cfg ] && [ -f Data/Haswell.cfg ] && [ -f "Data/Ivy bridge.cfg" ] && [ -f "Data/Kaby lake.cfg" ] && [ -f Data/Models.cfg ] && [ -f Data/Restrictions.cfg ] && [ -f "Data/Sandy Bridge.cfg" ] && [ -f Data/Skylake.cfg ] && [ -f Data/Versions.cfg ] && [ -d Tools ] && [ -f Tools/extractACPITables.zip ] && [ -f Tools/iasl.zip ] && [ -f Tools/Makefile ] && [ -f ssdtPRGen.sh ]; then # # Yes. Update path info. # gPath="$(pwd)" gDataPath="${gPath}/Data" gToolPath="${gPath}/Tools" gSsdtPR="${gPath}/${gSsdtID}.dsl" # # Write preferences with path info for extractACPITables v0.7 and greater. # defaults write com.wordpress.pikeralpha ssdtPRGenData $gDataPath defaults write com.wordpress.pikeralpha ssdtPRGenTools $gToolPath else # # Do we have the required Data directory? # if [ ! -d "${gDataPath}" ]; then mkdir -p "${gDataPath}" fi # # # _checkForConfigFile "Models.cfg" # # Is the return value of _checkForConfigFile 1? # if [[ $? -eq 1 ]]; then curl -o "${gDataPath}/Models.cfg" --silent "${gGitHubContentURL}/Data/Models.cfg" fi fi # # Load model data. # source "${gDataPath}/Models.cfg" } # #-------------------------------------------------------------------------------- # function _showSystemData { printf "\n${STYLE_BOLD}System information${STYLE_RESET}: $gProductName $gProductVersion ($gBuildVersion)\n" # # Show brandstring (this helps me to debug stuff). # gBrandString=$(echo `sysctl machdep.cpu.brand_string` | sed -e 's/machdep.cpu.brand_string: //') printf "${STYLE_BOLD}Brandstring${STYLE_RESET}: \"${gBrandString}\"\n\n" if [[ $gTargetProcessorType -eq 0 && "${gBrandString}" == "Genuine Intel(R) CPU 0000" ]]; then _PRINT_MSG "Error:\tUnable to determine CPU model!\n\tUse -p argument for Engineering Samples!" _ABORT fi } # #-------------------------------------------------------------------------------- # function _getScriptArguments() { local currentPath=$(pwd) # # Are we fired up with arguments? # if [ $# -gt 0 ]; then # # Yes. Do we have a single (-h or -help) argument? # local argument=$(echo "$1" | tr '[:upper:]' '[:lower:]') if [[ $# -eq 1 && "$argument" == "-h" || "$argument" == "-help" ]]; then printf "\n${STYLE_BOLD}Usage:${STYLE_RESET} ./ssdtPRGen.sh [-abcdefghiklmnoprsutwx]\n" printf " -${STYLE_BOLD}a${STYLE_RESET}cpi Processor name (example: CPU0, C000)\n" printf " -${STYLE_BOLD}bclk${STYLE_RESET} frequency (base clock frequency)\n" printf " -${STYLE_BOLD}b${STYLE_RESET}oard-id (example: Mac-F60DEB81FF30ACF6)\n" printf " -${STYLE_BOLD}cpus${STYLE_RESET} number of physical processors [1-4]\n" printf " -${STYLE_BOLD}d${STYLE_RESET}ebug output [0-3]\n" printf " 0 = no debug injection/debug output\n" printf " 1 = inject debug statements in: ${gSsdtID}.dsl\n" printf " 2 = show debug output\n" printf " 3 = both\n" printf " -${STYLE_BOLD}developer${STYLE_RESET} mode [0-1]\n" printf " 0 = disabled – Use files from: ${gPath}\n" printf " 1 = enabled – Use files from: ${currentPath}\n" printf " -${STYLE_BOLD}extract${STYLE_RESET} ACPI tables to [target path]\n" printf " -${STYLE_BOLD}f${STYLE_RESET}requency (clock frequency)\n" printf " -${STYLE_BOLD}h${STYLE_RESET}elp info (this)\n" printf " -${STYLE_BOLD}lfm${STYLE_RESET}ode, lowest idle frequency\n" printf " -${STYLE_BOLD}l${STYLE_RESET}ogical processors [2-128]\n" printf " -${STYLE_BOLD}mode${STYLE_RESET} script mode [normal/custom]:\n" printf " normal – Use ACPI/IOREG data from the host computer\n" printf " custom – Use ACPI data from: ${gOverridePath/APIC.aml}\n" printf " – : ${gOverridePath/DSDT.aml}\n" printf " -${STYLE_BOLD}m${STYLE_RESET}odel (example: MacPro6,1)\n" printf " -${STYLE_BOLD}o${STYLE_RESET}pen the previously generated SSDT\n" printf " -${STYLE_BOLD}p${STYLE_RESET}rocessor model (example: 'E3-1285L v3')\n" printf " -${STYLE_BOLD}show${STYLE_RESET} supported board-id and model combinations:\n" printf " Sandy Bridge\n" printf " Ivy Bridge\n" printf " Haswell\n" printf " Broadwell\n" printf " Skylake\n" printf " Kabylake\n" printf " -${STYLE_BOLD}target${STYLE_RESET} CPU type:\n" printf " 0 = Sandy Bridge\n" printf " 1 = Ivy Bridge\n" printf " 2 = Haswell\n" printf " 3 = Broadwell\n" printf " 4 = Skylake\n" printf " 5 = Kabylake\n" printf " -${STYLE_BOLD}turbo${STYLE_RESET} maximum (turbo) frequency:\n" printf " 6300 for Sandy Bridge and Ivy Bridge\n" printf " 8000 for Haswell, Broadwell and greater\n" printf " -${STYLE_BOLD}t${STYLE_RESET}dp [11.5 - 150]\n" printf " -${STYLE_BOLD}c${STYLE_RESET}ompatibility workarounds:\n" printf " 0 = no workarounds\n" printf " 1 = inject extra (turbo) P-State at the top with maximum (turbo) frequency + 1 MHz\n" printf " 2 = inject extra P-States at the bottom\n" printf " 3 = both\n" printf " -${STYLE_BOLD}x${STYLE_RESET}cpm mode [0-1]:\n" printf " 0 = XCPM mode disabled\n" printf " 1 = XCPM mode enabled\n\n" # # Stop script (success). # exit 0 fi if [[ $# -eq 1 && "$argument" == "-show" ]]; then printf "\nSupported board-id / model combinations for:\n" echo -e "--------------------------------------------\n" _showSupportedBoardIDsAndModels "Kaby Lake" _showSupportedBoardIDsAndModels "Skylake" _showSupportedBoardIDsAndModels "Broadwell" _showSupportedBoardIDsAndModels "Haswell" _showSupportedBoardIDsAndModels "Ivy Bridge" _showSupportedBoardIDsAndModels "Sandy Bridge" # # Stop script (success). # exit 0 fi if [[ $# -eq 2 && "$argument" == "-show" ]]; then printf "\nSupported board-id / model combinations for:\n" echo -e "--------------------------------------------\n" case "$(echo $2 | tr '[:lower:]' '[:upper:]')" in SANDY* ) _showSupportedBoardIDsAndModels "Sandy Bridge" ;; IVY* ) _showSupportedBoardIDsAndModels "Ivy Bridge" ;; HASWELL ) _showSupportedBoardIDsAndModels "Haswell" ;; BROADWELL) _showSupportedBoardIDsAndModels "Broadwell" ;; SKYLAKE) _showSupportedBoardIDsAndModels "Skylake" ;; KABYLAKE) _showSupportedBoardIDsAndModels "Kaby Lake" ;; esac # # Stop script (success). # exit 0 else _showSystemData # # Figure out what arguments are used. # while [ "$1" ]; do # # Store lowercase value of $1 in $flag # local flag=$(echo "$1" | tr '[:upper:]' '[:lower:]') # # Is this a valid flag? # # Note 'uro' was only added to support '-turbo' # if [[ "${flag}" =~ ^[-abcdefghiklmnoprsutvwx]+$ ]]; then # # Yes. Figure out what flag it is. # case "${flag}" in -a|-acpi) shift if [[ "$1" =~ ^[a-zA-Z0-9]+$ ]]; then if [ ${#1} -eq 4 ]; then gProcLabel=$(echo "$1" | tr '[:lower:]' '[:upper:]') _PRINT_MSG "Override value: (-acpi) label for ACPI Processors, now using '${gProcLabel}'!" else _exitWithError $PROCESSOR_LABEL_LENGTH_ERROR fi else _invalidArgumentError "-a $1" fi ;; -bclk) shift if [[ "$1" =~ ^[0-9]+$ ]]; then if [[ $1 < 167 ]]; then _PRINT_MSG "Override value: (-bclk) frequency, now using: ${1} MHz!" let gBusFrequency=$1 else _invalidArgumentError "-bclk $1 (use 100, 133 or 166)" fi else _invalidArgumentError "-bclk $1" fi ;; -b) shift if [[ "$1" =~ ^Mac-[0-9A-F]+$ ]]; then if [[ $gBoardID != "$1" ]]; then gBoardID=$1 _PRINT_MSG "Override value: (-b) board-id, now using: ${gBoardID}!" fi else _invalidArgumentError "-b $1" fi ;; -cpus) shift if [[ "$1" =~ ^[1-4]+$ ]]; then # # Sanity checking. # if [[ $1 -gt 0 && $1 -lt 5 ]]; then let gPhysicalCPUs=$1 _PRINT_MSG "Override value: (-cpus) number of processors, now using: ${1}!" else _invalidArgumentError "-cpus $1" fi else _invalidArgumentError "-cpus $1" fi ;; -developer) shift if [[ "$1" =~ ^[01]+$ ]]; then if [[ $gDeveloperMode -ne $1 ]]; then let gDeveloperMode=$1 _PRINT_MSG "Override value: (-developer) mode, now using: ${gDebug}!" fi else _invalidArgumentError "-developer $1" fi ;; -d) shift if [[ "$1" =~ ^[0123]+$ ]]; then if [[ $gDebug -ne $1 ]]; then let gDebug=$1 _PRINT_MSG "Override value: (-d) debug mode, now using: ${gDebug}!" fi else _invalidArgumentError "-d $1" fi ;; -extract) shift if [[ "$1" == "." || "$1" == " " ]]; then # # Get current path for extractACPITables v0.6 and greater. # gExtractionPath="${currentPath}" else # # Use given path for extractACPITables v0.6 and greater. # gExtractionPath="${1}" fi ;; -f) shift if [[ "$1" =~ ^[0-9]+$ ]]; then _PRINT_MSG "Override value: (-f) clock frequency, now using: ${1} MHz!" let gFrequency=$1 else _invalidArgumentError "-f $1" fi ;; -lfm) shift let gLfm=$1 _PRINT_MSG "Override value: (-lfm) low frequency mode, now using: ${gLfm}!" ;; -l) shift if [[ "$1" =~ ^[0-9]+$ ]]; then # # Sanity checking. # if [[ $1 -gt 1 && $1 -lt 129 ]]; then let gLogicalCPUs=$1 _PRINT_MSG "Override value: (-l) number of logical processors, now using: ${gLogicalCPUs}!" else _invalidArgumentError "-l $1" fi else _invalidArgumentError "-l $1" fi ;; -mode) shift argument=$(echo "$1" | tr '[:upper:]' '[:lower:]') if [[ "$argument" == "normal" ]]; then if [[ $gCustomMode -eq 0 ]]; then _PRINT_MSG "Override value: (-mode) ignored, script mode is already set to normal!" else _PRINT_MSG "Override value: (-mode) script mode changed to normal!" let gCustomMode=0 fi elif [[ "$argument" == "custom" ]]; then if [[ $gCustomMode -eq 1 ]]; then _PRINT_MSG "Override value: (-mode) ignored, script mode is already set to custom!" else _PRINT_MSG "Override value: (-mode) script mode changed to custom!" let gCustomMode=1 fi else _invalidArgumentError "-mode $1" fi ;; -m) shift if [[ "$1" =~ ^[a-zA-Z,0-9]+$ ]]; then if [[ "$gModelID" != "$1" ]]; then _PRINT_MSG "Override value: (-m) model, now using: ${1}!" gModelID="$1" fi else _invalidArgumentError "-m $1" fi ;; -o|-open) shift if [ -e "$gSsdtPR" ]; then open -e "$gSsdtPR" else _exitWithError $FILE_NOT_FOUND_ERROR fi exit 0 ;; -p) shift if [[ "$1" =~ ^[a-zA-Z0-9\ \-]+$ ]]; then if [ "$gProcessorNumber" != "$1" ]; then let gTargetProcessorType=1 # # Sandy Bridge checks. # if [[ ${1:0:4} == "i3-2" || ${1:0:4} == "i5-2" || ${1:0:4} == "i7-2" ]]; then let gTargetProcessorType=2 fi # # Ivy Bridge checks. # if [[ ${1:0:4} == "i3-3" || ${1:0:4} == "i5-3" || ${1:0:4} == "i7-3" ]]; then let gTargetProcessorType=4 fi # # Haswell/Haswell-E checks. # if [[ ${1:0:4} == "i3-4" || ${1:0:4} == "i5-4" || ${1:0:4} == "i7-4" || ${1:0:4} == "i7-5" ]]; then let gTargetProcessorType=5 fi # # Skylake checks. # if [[ ${1:0:4} == "i5-6" || ${1:0:4} == "i7-6" ]]; then let gTargetProcessorType=5 fi # # Xeon check. # if [[ ${1:0:1} == "E" ]]; then let gTargetProcessorType=7 fi # # Set processor model override and inform user about the change. # if [ $gTargetProcessorType -gt 0 ]; then gProcessorNumber=$1 _PRINT_MSG "Override value: (-p) processor model, now using: ${gProcessorNumber}!" else gProcessorNumber="" fi fi else _invalidArgumentError "-p $1" fi ;; -target) shift if [[ "$1" =~ ^[012345]+$ ]]; then local detectedBridgeType=$gBridgeType case "$1" in 0) local bridgeType=$SANDY_BRIDGE local bridgeTypeString="Sandy Bridge" ;; 1) local bridgeType=$IVY_BRIDGE local bridgeTypeString="Ivy Bridge" ;; 2) local bridgeType=$HASWELL local bridgeTypeString="Haswell" ;; 3) local bridgeType=$BROADWELL local bridgeTypeString="Broadwell" ;; 4) local bridgeType=$SKYLAKE local bridgeTypeString="Skylake" ;; 5) local bridgeType=$KABYLAKE local bridgeTypeString="Kaby Lake" ;; esac if [[ $detectedBridgeType -ne $((2 << $1)) ]]; then let gBridgeType=$bridgeType _PRINT_MSG "Override value: (-target) CPU, now using: ${bridgeTypeString}!" fi else _exitWithError $TARGET_CPU_ERROR fi ;; -turbo) shift if [[ "$1" =~ ^[0-9]+$ ]]; then # # Sanity checking. # if [[ $1 -gt $gMaxOCFrequency ]]; then _exitWithError $MAX_TURBO_FREQUENCY_ERROR else _PRINT_MSG "Override value: (-turbo) maximum (turbo) frequency, now using: ${1} MHz!" let gMaxTurboFrequency=$1 fi else _invalidArgumentError "-turbo $1" fi ;; -t|-tdp) shift if [[ "$1" =~ ^[0-9]+$ ]]; then # # Sanity checking. # if [[ $1 -lt 11 || $1 -gt 150 ]]; then _exitWithError $MAX_TDP_ERROR else let gTdp=$1 _PRINT_MSG "Override value: (-t) maximum TDP, now using: ${gTdp} Watt!" fi elif [[ "$1" =~ ^[0-9\.]*$ ]]; then # # Sanity checking. # if [[ $1 < "11.5" || $1 > "150" ]]; then _exitWithError $MAX_TDP_ERROR else gTdp="$1" _PRINT_MSG "Override value: (-t) maximum TDP, now using: ${gTdp} Watt!" fi else _invalidArgumentError "-t $1" fi ;; -c) shift if [[ "$1" =~ ^[0123]+$ ]]; then if [[ $gCPUWorkArounds -ne $1 ]]; then let gCPUWorkArounds=$1 _PRINT_MSG "Override value: (-c) CPU workarounds, now set to: ${1}!" fi # # Running on Sandy Bridge platform? # if [[ $gBridgeType -eq $SANDY_BRIDGE ]]; then # # Yes. Change it to Ivy Bridge. # gBridgeType=$IVY_BRIDGE _PRINT_MSG "Override value: CPU type changed, now using: Ivy Bridge!" fi else _invalidArgumentError "-c $1" fi ;; -x|-xcpm) shift if [[ "$1" =~ ^[01]+$ ]]; then let gXcpm=$1 _PRINT_MSG "Override value: (-x) XCPM mode, now set to: ${1}!" else _invalidArgumentError "-x $1" fi ;; *) _invalidArgumentError "$1" ;; esac else _invalidArgumentError "$1" fi shift; done; fi echo '' else _showSystemData fi } # #-------------------------------------------------------------------------------- # function _checkLFMCompatibility() { _checkForConfigFile "Restrictions.cfg" if [[ $? -eq 1 ]]; then _PRINT_MSG "Notice: Downloading Restrictions.cfg ..." curl -o "${gDataPath}/Restrictions.cfg" --silent "${gGitHubContentURL}/Data/Restrictions.cfg" fi source "${gDataPath}/Restrictions.cfg" for boardID in "${gBoardIDsWithLFMRestrictions[@]}" do if [[ "$boardID" == "$gBoardID" ]]; then _PRINT_MSG "\nNotice: The LFM frequency in $gBoardID.plist is set to 1300 MHz!" printf "\tThis restriction can be lifted with help of freqVectorsEdit.sh from:\n" printf "\thttps://github.com/Piker-Alpha/freqVectorsEdit.sh\n\n" return fi done } # #-------------------------------------------------------------------------------- # function main() { # # Local variable definitions. # local turboStates local assumedTDP local maxTurboFrequency local modelSpecified let assumedTDP=0 let maxTurboFrequency=0 printf "\n${STYLE_BOLD}ssdtPRGen.sh${STYLE_RESET} v0.9 Copyright (c) 2011-2012 by † RevoGirl\n" echo ' v6.6 Copyright (c) 2013 by † Jeroen' printf " v$gScriptVersion Copyright (c) 2013-$(date "+%Y") by Pike R. Alpha\n" echo '-----------------------------------------------------------' printf "${STYLE_BOLD}Bugs${STYLE_RESET} > https://github.com/Piker-Alpha/ssdtPRGen.sh/issues <\n" _checkSourceFilename _checkLibraryDirectory _getScriptArguments "$@" # # Fired up with -mode custom? # if [[ $gCustomMode -eq 0 ]]; then # # No. Extract ACPI data from host computer. # _extractAcpiTables fi # # Convert APIC.aml and DSDT.aml into data files. # _convertACPIFiles _getEnabledProcessors _getProcessorNames # # # if [[ $gCustomMode -eq 1 ]]; then # # Yes. Show some basic info (in case we need the log). # _PRINT_MSG "\nNotice: Custom mode enabled" printf "\tSkipping ACPI table extraction from host computer!\n\tGetting enabled Processors from...: ${gOverridePath}/APIC.aml\n" printf "\tGetting Processor declaration from: ${gOverridePath}/DSDT.aml\n" printf "\tUsed ACPI processor labels: " # # Check number of logical processors. Less/equal than 8? # if [[ ${#gProcessorNames[@]} -le 8 ]]; then # # Yes. Use the same line. # echo -e "${gProcessorNames[@]}\n" else # # No. Use (a) new line(s) to show the processor names. # let nameCount=0 # # Use (a) new line(s) to show the processor names. # printf "\n\t–" # # loop through all processorNames. # for processorName in "${gProcessorNames[@]}" do if [[ $nameCount -eq $gLogicalCPUsPerScope ]]; then printf "\n\t–" fi printf " ${processorName}" let nameCount+=1 done fi printf "\n\n" fi # # Set local variable from global function variable. # let modelSpecified=$gTargetProcessorType # # Model override (-m) argument used? # if [[ $gModelID == "" ]]; then # # No. Get model from ioreg. # _getModelID fi # # Check if -c argument wasn't used. # # Note: Only happens if we failed to locate the processor data! # if [[ $gBridgeType -eq -1 ]]; then local model=$(_getCPUModel) case $model in # Sandy Bridge 0x2A) let gTdp=95 let gBridgeType=2 ;; # Sandy Bridge Xeon 0x2D) let assumedTDP=1 let gTdp=130 let gBridgeType=2 ;; # Ivy Bridge, Ivy Bridge EX and Ivy Bridge Xeon 0x3A|0x3B|0x3E) let assumedTDP=1 let gTdp=77 let gBridgeType=4 ;; # Haswell 0x3C) let assumedTDP=1 let gTdp=84 let gBridgeType=8 let gMaxOCFrequency=8000 ;; # Haswell SVR 0x3F) let assumedTDP=1 let gTdp=130 let gBridgeType=8 ;; # Haswell ULT 0x45) let assumedTDP=1 let gTdp=15 let gBridgeType=8 ;; *) _confirmUnsupported 'Error: Unknown/unsupported processor model detected!\n' ;; esac fi # # Board-id override (-b) argument used? # if [[ $gBoardID == "" ]]; then # # No. Get board-id from ioreg. # _getBoardID fi _checkLFMCompatibility case $gBridgeType in 2) local bridgeTypeString="Sandy Bridge" ;; 4) local bridgeTypeString="Ivy Bridge" ;; 8) local bridgeTypeString="Haswell" ;; 16) local bridgeTypeString="Broadwell" ;; 32) local bridgeTypeString="Skylake" ;; 64) local bridgeTypeString="Kaby Lake" ;; *) local bridgeTypeString="Unknown" ;; esac local cpu_type=$(_getCPUtype) local currentSystemType=$(_getSystemType) local cpuSignature=$(_getCPUSignature) echo "Generating ${gSsdtID}.dsl for a '${gModelID}' with board-id [${gBoardID}]" # # Intel Core processor model? # if [ $modelSpecified -eq 1 ]; then echo "Intel $gProcessorNumber processor [$cpuSignature] setup [0x${cpu_type}]" else echo "$bridgeTypeString Core $gProcessorNumber processor [$cpuSignature] setup [0x${cpu_type}]" fi # # gTypeCPU is greater than 0 when the processor is found in one of the CPU lists # if [ $gTypeCPU -gt 0 ]; then # # -t argument used? # if [[ "$gTdp" > "0" ]]; then echo "With a maximum TDP of '$gTdp' Watt, as specified by argument: -t ${gTdp}" else # # No. Get TDP from CPU data. # gTdp=${gProcessorData[1]} echo 'With a maximum TDP of '$gTdp' Watt, as specified by Intel' if [[ $assumedTDP -eq 1 ]]; then echo "With a maximum TDP of ${gTdp} Watt - assumed/undetected CPU may require override value!" fi fi # # Check if -lfm argument was used. # if [[ $gLfm -gt 0 ]]; then # # Yes. Use override value. # let lfm=$gLfm else # # No. Get LFM from CPU data. # let lfm=${gProcessorData[2]} fi # # Check if -f argument is used. # if [[ $gFrequency -gt 0 ]]; then # # Yes. Use override frequency. # let frequency=$gFrequency else # # No. Get clock frequency from CPU data. # let frequency=${gProcessorData[3]} fi # # Check if -turbo argument is used. # if [[ $gMaxTurboFrequency -gt 0 ]]; then let maxTurboFrequency=$gMaxTurboFrequency else let maxTurboFrequency=${gProcessorData[4]} fi # # Sanity check. # if [ $maxTurboFrequency == 0 ]; then let maxTurboFrequency=$frequency fi # # Check if -l argument is used. # if [ $gLogicalCPUs -eq 0 ]; then # # No. Get thread count (logical cores) from CPU data. # let gLogicalCPUs=${gProcessorData[6]} fi # # Restore the default (0) delimiter. # IFS=$ifs # # Check Low Frequency Mode (may be 0 aka still unknown) # if [ $lfm -gt 0 ]; then let gBaseFrequency=$lfm else _PRINT_MSG "\nWarning: Low Frequency Mode is 0 (unknown/unconfirmed)" if [ $gTypeCPU == $gMobileCPU ]; then echo -e " Now using 1200 MHz for Mobile processor\n" let gBaseFrequency=1200 else echo -e " Now using 1600 MHz for Server/Desktop processors\n" let gBaseFrequency=1600 fi fi # # Check Ivy Bridge, XCPM mode and if -c argument is used. # if [[ $gBridgeType -eq $IVY_BRIDGE && $gXcpm -eq -1 && $gCPUWorkArounds -eq 0 ]]; then if [[ $gOSVersion -gt 10100 ]]; then let gCPUWorkArounds=3; else let gCPUWorkArounds=2; fi fi else printf "Processor NOT matched, checking required arguments!\n" # # Check if -lfm argument was used. # if [[ $gLfm -eq 0 ]]; then _exitWithError $LFM_ERROR fi # # Check if -t argument was used. # if [[ $gTdp -eq 0 ]]; then _exitWithError $MAX_TDP_ERROR fi # # No CPU data found. Check if -l argument is used. # if [ $gLogicalCPUs -eq 0 ]; then # # No. Get thread count (logical cores) from the running system. # let gLogicalCPUs=$(sysctl machdep.cpu.thread_count | awk '{ print $2 }') fi # # Check if -f argument is used. # if [ $gFrequency -eq -1 ]; then # # No. Get the clock frequency from the running system. # let frequency=$(sysctl hw.cpufrequency | awk '{ print($2) / 1000000 }') let gFrequency=frequency _PRINT_MSG "Warning: Core Frequency is unknown, now using $gFrequency MHz from sysctl hw.cpufrequency!" else let frequency=$gFrequency fi # # Check if -turbo argument is used. # if [[ $gMaxTurboFrequency -gt 0 ]]; then let maxTurboFrequency=$gMaxTurboFrequency else let maxTurboFrequency=$frequency let gMaxTurboFrequency=$frequency _PRINT_MSG "Warning: Maximum Turbo Frequency is unknown, now using $gMaxTurboFrequency MHz from Core Frequency!" fi let gCoreCount=$(sysctl machdep.cpu.core_count | awk '{ print $2 }') printf "${gProcessorNumber},${gTdp},${gLfm},${gFrequency},${gMaxTurboFrequency},${gCoreCount},${gLogicalCPUs}\n" fi echo "Number logical CPU's: $gLogicalCPUs (Core Frequency: $frequency MHz)" # if [ $gLogicalCPUs -gt "${#gProcessorNames[@]}" ]; # then # _updateProcessorNames $gLogicalCPUs # fi # # Check maxTurboFrequency # if [ $maxTurboFrequency -eq 0 ]; then _exitWithError $MAX_TURBO_FREQUENCY_ERROR fi # # Get number of Turbo states. # # let turboStates=$(printf "%.f" $(echo "scale=1;((($maxTurboFrequency - $frequency) / $gBusFrequency)+0.5)" | bc)) let turboStates=$(echo "(($maxTurboFrequency - $frequency) / $gBusFrequency)" | bc) # # # Check number of Turbo states. # if [ $turboStates -lt 0 ]; then let turboStates=0 fi # # Report number of Turbo States # if [ $turboStates -gt 0 ]; then let minTurboFrequency=($frequency+$gBusFrequency) echo "Number of Turbo States: $turboStates ($minTurboFrequency-$maxTurboFrequency MHz)" else echo "Number of Turbo States: 0" fi local packageLength=$(echo "((($maxTurboFrequency - $gBaseFrequency)+$gBusFrequency) / $gBusFrequency)" | bc) echo "Number of P-States: $packageLength ($gBaseFrequency-$maxTurboFrequency MHz)" _printHeader # # Check if -cpus argument is used. # if [[ $gPhysicalCPUs -gt 1 ]]; then let gLogicalCPUsPerScope=$gLogicalCPUs/$gPhysicalCPUs else let gLogicalCPUsPerScope=$gLogicalCPUs/${#gScope[@]} if [[ 0 -eq 1 ]]; then exit -1 fi fi # # Do we need to inject External () objects? # if [[ $gInjectExternalObjects -eq 1 ]]; then # # Yes. Inject External () objects for all processor declarations. # _printExternalObjects fi _checkForXCPM case "$gBridgeType" in $SANDY_BRIDGE) local cpuTypeString="06" _initSandyBridgeSetup ;; $IVY_BRIDGE) local cpuTypeString="07" _initIvyBridgeSetup ;; $HASWELL) local cpuTypeString="08" _initHaswellSetup ;; $BROADWELL) local cpuTypeString="09" _initBroadwellSetup ;; $SKYLAKE) local cpuTypeString="09" _initSkylakeSetup ;; $KABYLAKE) local cpuTypeString="09" _initKabyLakeSetup ;; esac let scopeIndex=0 # # Loop through all processor scopes. # for scope in "${gScope[@]}" do # # Are we done yet? # if [[ $gLogicalCPUsPerScope*$scopeIndex -ge $gLogicalCPUs ]]; then # # Yes. Add closing bracket to the end of the injected data. # echo '}' >> "$gSsdtPR" # # Break out the do loop. # break; else # # No. Continue. # _printScopeStart $scopeIndex $turboStates $packageLength $maxTurboFrequency _printPackages $frequency $turboStates $maxTurboFrequency _printScopeACST 0 if [ $scopeIndex -eq 0 ]; then _printMethodDSM else if [ $gBridgeType -ge $IVY_BRIDGE ]; then echo ' }' >> "$gSsdtPR" fi fi _printScopeCPUn $scopeIndex let scopeIndex+=1 fi done # # Is this a MacPro6,1 model? # if [[ $gModelID == 'MacPro6,1' ]]; then # # Yes. Use the correct string/value for the cpu-type suggestion. # local cpuTypeString="0a" fi _showLowPowerStates _checkPlatformSupport # # Some Sandy Bridge/Ivy Bridge CPUPM specific configuration checks # if [[ $gBridgeType -ne $HASWELL ]]; then if [[ ${cpu_type:0:2} != $cpuTypeString ]]; then _PRINT_MSG "Warning: 'cpu-type' may be set improperly (0x${cpu_type} instead of 0x${cpuTypeString}${cpu_type:2:2})" printf "\t - Clover users should read https://clover-wiki.zetam.org/Configuration/CPU#cpu_type" fi if [[ $gSystemType -eq 0 ]]; then _PRINT_MSG "\nWarning: 'board-id' [${gBoardID}] is not supported by ${bridgeTypeString} power management" else if [ "${gTargetMacModel}" == "" ]; then _confirmUnsupported "\nError: board-id [${gBoardID}] not supported by ${bridgeTypeString} – check SMBIOS data / use the -target option\n" elif [ "$gTargetMacModel" != "$gModelID" ]; then _confirmUnsupported 'Warning: board-id ['$gBoardID'] and model ['$gModelID'] mismatch – check SMBIOS data\n' fi fi fi if [ $currentSystemType -ne $gSystemType ]; then _PRINT_MSG "Warning: 'system-type' may be set improperly ($currentSystemType instead of $gSystemType)" printf "\t - Clover users should read https://clover-wiki.zetam.org/Configuration/ACPI#acpi_smartups" fi _findIasl if [[ $gCallIasl -eq 1 && -f "$gSsdtPR" ]]; then # # Compile ssdt_pr.dsl # printf "\n${STYLE_BOLD}Compiling:${STYLE_RESET} ssdt_pr.dsl" "$gIasl" "$gSsdtPR" let iaslStatus=$? if [ $iaslStatus -ne 0 ]; then _PRINT_MSG "Error: IASL status: ${iaslStatus} (Failed)\n" fi # # Copy ssdt_pr.aml to /Extra/ssdt.aml (example) # if [[ $iaslStatus -eq 0 && $gAutoCopy -eq 1 ]]; then if [[ -f "${gPath}/${gSsdtID}.aml" && -d "${gDestinationPath}" ]]; then echo "" read -p "Do you want to copy ${gPath}/${gSsdtID}.aml to ${gDestinationPath}${gDestinationFile}? (y/n)? " choice case "$choice" in y|Y ) if [[ $gIsLegacyRevoBoot -eq 0 ]]; then _setDestinationPath fi # # Check write permissions. # if [ -w "${gDestinationPath}${gDestinationFile}" ]; then cp "${gPath}/${gSsdtID}.aml" "${gDestinationPath}${gDestinationFile}" else sudo cp "${gPath}/${gSsdtID}.aml" "${gDestinationPath}${gDestinationFile}" fi # # Check if we need to unmount the EFI volume. # if [[ $gIsLegacyRevoBoot -eq 0 && $gUnmountEFIPartition ]]; then _debugPrint "Unmounting EFI partition...\n" sudo umount -f /Volumes/EFI # # Check return status for Success. # # Note: Without this check we may end up removing the whole freaking EFI directory! # if [[ $? -eq 0 ]]; then read -p "Do you want to remove the temporarily mount point (y/n)? " choice2 case "$choice2" in y|Y ) # # You fool: don't use rm commands in a script! # # read -p "Do you want to remove the temporarily mount point (y/n)?" choice3 # case "$choice3" in # y|Y ) _debugPrint "Removing temporarily mount point...\n" sudo rm -r /Volumes/EFI # ;; # esac ;; esac fi fi sudo -k ;; esac fi fi fi # # Ask for confirmation before opening the new SSDT.dsl? # if [[ $gCallOpen -eq 2 && -f "$gSsdtPR" ]]; then # # Yes. Ask for confirmation. # read -p "Do you want to open ${gSsdtID}.dsl (y/n)? " openAnswer case "$openAnswer" in y|Y ) # # Ok. Override default behaviour. # let gCallOpen=1 ;; esac fi # # Should we open the new SSDT.dsl? # if [[ $gCallOpen -eq 1 ]]; then # # Yes. Open SSDT.dsl in TextEdit. # open -e "$gSsdtPR" fi } #==================================== START ===================================== clear main "$@" exit 0 #================================================================================