cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cpu-drivers.rst (10997B)


      1.. SPDX-License-Identifier: GPL-2.0
      2
      3===============================================
      4How to Implement a new CPUFreq Processor Driver
      5===============================================
      6
      7Authors:
      8
      9
     10	- Dominik Brodowski  <linux@brodo.de>
     11	- Rafael J. Wysocki <rafael.j.wysocki@intel.com>
     12	- Viresh Kumar <viresh.kumar@linaro.org>
     13
     14.. Contents
     15
     16   1.   What To Do?
     17   1.1  Initialization
     18   1.2  Per-CPU Initialization
     19   1.3  verify
     20   1.4  target/target_index or setpolicy?
     21   1.5  target/target_index
     22   1.6  setpolicy
     23   1.7  get_intermediate and target_intermediate
     24   2.   Frequency Table Helpers
     25
     26
     27
     281. What To Do?
     29==============
     30
     31So, you just got a brand-new CPU / chipset with datasheets and want to
     32add cpufreq support for this CPU / chipset? Great. Here are some hints
     33on what is necessary:
     34
     35
     361.1 Initialization
     37------------------
     38
     39First of all, in an __initcall level 7 (module_init()) or later
     40function check whether this kernel runs on the right CPU and the right
     41chipset. If so, register a struct cpufreq_driver with the CPUfreq core
     42using cpufreq_register_driver()
     43
     44What shall this struct cpufreq_driver contain?
     45
     46 .name - The name of this driver.
     47
     48 .init - A pointer to the per-policy initialization function.
     49
     50 .verify - A pointer to a "verification" function.
     51
     52 .setpolicy _or_ .fast_switch _or_ .target _or_ .target_index - See
     53 below on the differences.
     54
     55And optionally
     56
     57 .flags - Hints for the cpufreq core.
     58
     59 .driver_data - cpufreq driver specific data.
     60
     61 .get_intermediate and target_intermediate - Used to switch to stable
     62 frequency while changing CPU frequency.
     63
     64 .get - Returns current frequency of the CPU.
     65
     66 .bios_limit - Returns HW/BIOS max frequency limitations for the CPU.
     67
     68 .exit - A pointer to a per-policy cleanup function called during
     69 CPU_POST_DEAD phase of cpu hotplug process.
     70
     71 .suspend - A pointer to a per-policy suspend function which is called
     72 with interrupts disabled and _after_ the governor is stopped for the
     73 policy.
     74
     75 .resume - A pointer to a per-policy resume function which is called
     76 with interrupts disabled and _before_ the governor is started again.
     77
     78 .ready - A pointer to a per-policy ready function which is called after
     79 the policy is fully initialized.
     80
     81 .attr - A pointer to a NULL-terminated list of "struct freq_attr" which
     82 allow to export values to sysfs.
     83
     84 .boost_enabled - If set, boost frequencies are enabled.
     85
     86 .set_boost - A pointer to a per-policy function to enable/disable boost
     87 frequencies.
     88
     89
     901.2 Per-CPU Initialization
     91--------------------------
     92
     93Whenever a new CPU is registered with the device model, or after the
     94cpufreq driver registers itself, the per-policy initialization function
     95cpufreq_driver.init is called if no cpufreq policy existed for the CPU.
     96Note that the .init() and .exit() routines are called only once for the
     97policy and not for each CPU managed by the policy. It takes a ``struct
     98cpufreq_policy *policy`` as argument. What to do now?
     99
    100If necessary, activate the CPUfreq support on your CPU.
    101
    102Then, the driver must fill in the following values:
    103
    104+-----------------------------------+--------------------------------------+
    105|policy->cpuinfo.min_freq _and_	    |					   |
    106|policy->cpuinfo.max_freq	    | the minimum and maximum frequency	   |
    107|				    | (in kHz) which is supported by	   |
    108|				    | this CPU				   |
    109+-----------------------------------+--------------------------------------+
    110|policy->cpuinfo.transition_latency | the time it takes on this CPU to	   |
    111|				    | switch between two frequencies in	   |
    112|				    | nanoseconds (if appropriate, else	   |
    113|				    | specify CPUFREQ_ETERNAL)		   |
    114+-----------------------------------+--------------------------------------+
    115|policy->cur			    | The current operating frequency of   |
    116|				    | this CPU (if appropriate)		   |
    117+-----------------------------------+--------------------------------------+
    118|policy->min,			    |					   |
    119|policy->max,			    |					   |
    120|policy->policy and, if necessary,  |					   |
    121|policy->governor		    | must contain the "default policy" for|
    122|				    | this CPU. A few moments later,       |
    123|				    | cpufreq_driver.verify and either     |
    124|				    | cpufreq_driver.setpolicy or          |
    125|				    | cpufreq_driver.target/target_index is|
    126|				    | called with these values.		   |
    127+-----------------------------------+--------------------------------------+
    128|policy->cpus			    | Update this with the masks of the	   |
    129|				    | (online + offline) CPUs that do DVFS |
    130|				    | along with this CPU (i.e.  that share|
    131|				    | clock/voltage rails with it).	   |
    132+-----------------------------------+--------------------------------------+
    133
    134For setting some of these values (cpuinfo.min[max]_freq, policy->min[max]), the
    135frequency table helpers might be helpful. See the section 2 for more information
    136on them.
    137
    138
    1391.3 verify
    140----------
    141
    142When the user decides a new policy (consisting of
    143"policy,governor,min,max") shall be set, this policy must be validated
    144so that incompatible values can be corrected. For verifying these
    145values cpufreq_verify_within_limits(``struct cpufreq_policy *policy``,
    146``unsigned int min_freq``, ``unsigned int max_freq``) function might be helpful.
    147See section 2 for details on frequency table helpers.
    148
    149You need to make sure that at least one valid frequency (or operating
    150range) is within policy->min and policy->max. If necessary, increase
    151policy->max first, and only if this is no solution, decrease policy->min.
    152
    153
    1541.4 target or target_index or setpolicy or fast_switch?
    155-------------------------------------------------------
    156
    157Most cpufreq drivers or even most cpu frequency scaling algorithms
    158only allow the CPU frequency to be set to predefined fixed values. For
    159these, you use the ->target(), ->target_index() or ->fast_switch()
    160callbacks.
    161
    162Some cpufreq capable processors switch the frequency between certain
    163limits on their own. These shall use the ->setpolicy() callback.
    164
    165
    1661.5. target/target_index
    167------------------------
    168
    169The target_index call has two arguments: ``struct cpufreq_policy *policy``,
    170and ``unsigned int`` index (into the exposed frequency table).
    171
    172The CPUfreq driver must set the new frequency when called here. The
    173actual frequency must be determined by freq_table[index].frequency.
    174
    175It should always restore to earlier frequency (i.e. policy->restore_freq) in
    176case of errors, even if we switched to intermediate frequency earlier.
    177
    178Deprecated
    179----------
    180The target call has three arguments: ``struct cpufreq_policy *policy``,
    181unsigned int target_frequency, unsigned int relation.
    182
    183The CPUfreq driver must set the new frequency when called here. The
    184actual frequency must be determined using the following rules:
    185
    186- keep close to "target_freq"
    187- policy->min <= new_freq <= policy->max (THIS MUST BE VALID!!!)
    188- if relation==CPUFREQ_REL_L, try to select a new_freq higher than or equal
    189  target_freq. ("L for lowest, but no lower than")
    190- if relation==CPUFREQ_REL_H, try to select a new_freq lower than or equal
    191  target_freq. ("H for highest, but no higher than")
    192
    193Here again the frequency table helper might assist you - see section 2
    194for details.
    195
    1961.6. fast_switch
    197----------------
    198
    199This function is used for frequency switching from scheduler's context.
    200Not all drivers are expected to implement it, as sleeping from within
    201this callback isn't allowed. This callback must be highly optimized to
    202do switching as fast as possible.
    203
    204This function has two arguments: ``struct cpufreq_policy *policy`` and
    205``unsigned int target_frequency``.
    206
    207
    2081.7 setpolicy
    209-------------
    210
    211The setpolicy call only takes a ``struct cpufreq_policy *policy`` as
    212argument. You need to set the lower limit of the in-processor or
    213in-chipset dynamic frequency switching to policy->min, the upper limit
    214to policy->max, and -if supported- select a performance-oriented
    215setting when policy->policy is CPUFREQ_POLICY_PERFORMANCE, and a
    216powersaving-oriented setting when CPUFREQ_POLICY_POWERSAVE. Also check
    217the reference implementation in drivers/cpufreq/longrun.c
    218
    2191.8 get_intermediate and target_intermediate
    220--------------------------------------------
    221
    222Only for drivers with target_index() and CPUFREQ_ASYNC_NOTIFICATION unset.
    223
    224get_intermediate should return a stable intermediate frequency platform wants to
    225switch to, and target_intermediate() should set CPU to that frequency, before
    226jumping to the frequency corresponding to 'index'. Core will take care of
    227sending notifications and driver doesn't have to handle them in
    228target_intermediate() or target_index().
    229
    230Drivers can return '0' from get_intermediate() in case they don't wish to switch
    231to intermediate frequency for some target frequency. In that case core will
    232directly call ->target_index().
    233
    234NOTE: ->target_index() should restore to policy->restore_freq in case of
    235failures as core would send notifications for that.
    236
    237
    2382. Frequency Table Helpers
    239==========================
    240
    241As most cpufreq processors only allow for being set to a few specific
    242frequencies, a "frequency table" with some functions might assist in
    243some work of the processor driver. Such a "frequency table" consists of
    244an array of struct cpufreq_frequency_table entries, with driver specific
    245values in "driver_data", the corresponding frequency in "frequency" and
    246flags set. At the end of the table, you need to add a
    247cpufreq_frequency_table entry with frequency set to CPUFREQ_TABLE_END.
    248And if you want to skip one entry in the table, set the frequency to
    249CPUFREQ_ENTRY_INVALID. The entries don't need to be in sorted in any
    250particular order, but if they are cpufreq core will do DVFS a bit
    251quickly for them as search for best match is faster.
    252
    253The cpufreq table is verified automatically by the core if the policy contains a
    254valid pointer in its policy->freq_table field.
    255
    256cpufreq_frequency_table_verify() assures that at least one valid
    257frequency is within policy->min and policy->max, and all other criteria
    258are met. This is helpful for the ->verify call.
    259
    260cpufreq_frequency_table_target() is the corresponding frequency table
    261helper for the ->target stage. Just pass the values to this function,
    262and this function returns the of the frequency table entry which
    263contains the frequency the CPU shall be set to.
    264
    265The following macros can be used as iterators over cpufreq_frequency_table:
    266
    267cpufreq_for_each_entry(pos, table) - iterates over all entries of frequency
    268table.
    269
    270cpufreq_for_each_valid_entry(pos, table) - iterates over all entries,
    271excluding CPUFREQ_ENTRY_INVALID frequencies.
    272Use arguments "pos" - a ``cpufreq_frequency_table *`` as a loop cursor and
    273"table" - the ``cpufreq_frequency_table *`` you want to iterate over.
    274
    275For example::
    276
    277	struct cpufreq_frequency_table *pos, *driver_freq_table;
    278
    279	cpufreq_for_each_entry(pos, driver_freq_table) {
    280		/* Do something with pos */
    281		pos->frequency = ...
    282	}
    283
    284If you need to work with the position of pos within driver_freq_table,
    285do not subtract the pointers, as it is quite costly. Instead, use the
    286macros cpufreq_for_each_entry_idx() and cpufreq_for_each_valid_entry_idx().