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

intel_uc_fw.h (8558B)


      1/* SPDX-License-Identifier: MIT */
      2/*
      3 * Copyright © 2014-2019 Intel Corporation
      4 */
      5
      6#ifndef _INTEL_UC_FW_H_
      7#define _INTEL_UC_FW_H_
      8
      9#include <linux/types.h>
     10#include "intel_uc_fw_abi.h"
     11#include "intel_device_info.h"
     12#include "i915_gem.h"
     13#include "i915_vma.h"
     14
     15struct drm_printer;
     16struct drm_i915_private;
     17struct intel_gt;
     18
     19/* Home of GuC, HuC and DMC firmwares */
     20#define INTEL_UC_FIRMWARE_URL "https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/i915"
     21
     22/*
     23 * +------------+---------------------------------------------------+
     24 * |   PHASE    |           FIRMWARE STATUS TRANSITIONS             |
     25 * +============+===================================================+
     26 * |            |               UNINITIALIZED                       |
     27 * +------------+-               /   |   \                         -+
     28 * |            |   DISABLED <--/    |    \--> NOT_SUPPORTED        |
     29 * | init_early |                    V                              |
     30 * |            |                 SELECTED                          |
     31 * +------------+-               /   |   \                         -+
     32 * |            |    MISSING <--/    |    \--> ERROR                |
     33 * |   fetch    |                    V                              |
     34 * |            |                 AVAILABLE                         |
     35 * +------------+-                   |   \                         -+
     36 * |            |                    |    \--> INIT FAIL            |
     37 * |   init     |                    V                              |
     38 * |            |        /------> LOADABLE <----<-----------\       |
     39 * +------------+-       \         /    \        \           \     -+
     40 * |            |    LOAD FAIL <--<      \--> TRANSFERRED     \     |
     41 * |   upload   |                  \           /   \          /     |
     42 * |            |                   \---------/     \--> RUNNING    |
     43 * +------------+---------------------------------------------------+
     44 */
     45
     46enum intel_uc_fw_status {
     47	INTEL_UC_FIRMWARE_NOT_SUPPORTED = -1, /* no uc HW */
     48	INTEL_UC_FIRMWARE_UNINITIALIZED = 0, /* used to catch checks done too early */
     49	INTEL_UC_FIRMWARE_DISABLED, /* disabled */
     50	INTEL_UC_FIRMWARE_SELECTED, /* selected the blob we want to load */
     51	INTEL_UC_FIRMWARE_MISSING, /* blob not found on the system */
     52	INTEL_UC_FIRMWARE_ERROR, /* invalid format or version */
     53	INTEL_UC_FIRMWARE_AVAILABLE, /* blob found and copied in mem */
     54	INTEL_UC_FIRMWARE_INIT_FAIL, /* failed to prepare fw objects for load */
     55	INTEL_UC_FIRMWARE_LOADABLE, /* all fw-required objects are ready */
     56	INTEL_UC_FIRMWARE_LOAD_FAIL, /* failed to xfer or init/auth the fw */
     57	INTEL_UC_FIRMWARE_TRANSFERRED, /* dma xfer done */
     58	INTEL_UC_FIRMWARE_RUNNING /* init/auth done */
     59};
     60
     61enum intel_uc_fw_type {
     62	INTEL_UC_FW_TYPE_GUC = 0,
     63	INTEL_UC_FW_TYPE_HUC
     64};
     65#define INTEL_UC_FW_NUM_TYPES 2
     66
     67/*
     68 * This structure encapsulates all the data needed during the process
     69 * of fetching, caching, and loading the firmware image into the uC.
     70 */
     71struct intel_uc_fw {
     72	enum intel_uc_fw_type type;
     73	union {
     74		const enum intel_uc_fw_status status;
     75		enum intel_uc_fw_status __status; /* no accidental overwrites */
     76	};
     77	const char *path;
     78	bool user_overridden;
     79	size_t size;
     80	struct drm_i915_gem_object *obj;
     81	/**
     82	 * @dummy: A vma used in binding the uc fw to ggtt. We can't define this
     83	 * vma on the stack as it can lead to a stack overflow, so we define it
     84	 * here. Safe to have 1 copy per uc fw because the binding is single
     85	 * threaded as it done during driver load (inherently single threaded)
     86	 * or during a GT reset (mutex guarantees single threaded).
     87	 */
     88	struct i915_vma_resource dummy;
     89	struct i915_vma *rsa_data;
     90
     91	/*
     92	 * The firmware build process will generate a version header file with major and
     93	 * minor version defined. The versions are built into CSS header of firmware.
     94	 * i915 kernel driver set the minimal firmware version required per platform.
     95	 */
     96	u16 major_ver_wanted;
     97	u16 minor_ver_wanted;
     98	u16 major_ver_found;
     99	u16 minor_ver_found;
    100
    101	u32 rsa_size;
    102	u32 ucode_size;
    103
    104	u32 private_data_size;
    105};
    106
    107#ifdef CONFIG_DRM_I915_DEBUG_GUC
    108void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
    109			       enum intel_uc_fw_status status);
    110#else
    111static inline void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
    112					     enum intel_uc_fw_status status)
    113{
    114	uc_fw->__status = status;
    115}
    116#endif
    117
    118static inline
    119const char *intel_uc_fw_status_repr(enum intel_uc_fw_status status)
    120{
    121	switch (status) {
    122	case INTEL_UC_FIRMWARE_NOT_SUPPORTED:
    123		return "N/A";
    124	case INTEL_UC_FIRMWARE_UNINITIALIZED:
    125		return "UNINITIALIZED";
    126	case INTEL_UC_FIRMWARE_DISABLED:
    127		return "DISABLED";
    128	case INTEL_UC_FIRMWARE_SELECTED:
    129		return "SELECTED";
    130	case INTEL_UC_FIRMWARE_MISSING:
    131		return "MISSING";
    132	case INTEL_UC_FIRMWARE_ERROR:
    133		return "ERROR";
    134	case INTEL_UC_FIRMWARE_AVAILABLE:
    135		return "AVAILABLE";
    136	case INTEL_UC_FIRMWARE_INIT_FAIL:
    137		return "INIT FAIL";
    138	case INTEL_UC_FIRMWARE_LOADABLE:
    139		return "LOADABLE";
    140	case INTEL_UC_FIRMWARE_LOAD_FAIL:
    141		return "LOAD FAIL";
    142	case INTEL_UC_FIRMWARE_TRANSFERRED:
    143		return "TRANSFERRED";
    144	case INTEL_UC_FIRMWARE_RUNNING:
    145		return "RUNNING";
    146	}
    147	return "<invalid>";
    148}
    149
    150static inline int intel_uc_fw_status_to_error(enum intel_uc_fw_status status)
    151{
    152	switch (status) {
    153	case INTEL_UC_FIRMWARE_NOT_SUPPORTED:
    154		return -ENODEV;
    155	case INTEL_UC_FIRMWARE_UNINITIALIZED:
    156		return -EACCES;
    157	case INTEL_UC_FIRMWARE_DISABLED:
    158		return -EPERM;
    159	case INTEL_UC_FIRMWARE_MISSING:
    160		return -ENOENT;
    161	case INTEL_UC_FIRMWARE_ERROR:
    162		return -ENOEXEC;
    163	case INTEL_UC_FIRMWARE_INIT_FAIL:
    164	case INTEL_UC_FIRMWARE_LOAD_FAIL:
    165		return -EIO;
    166	case INTEL_UC_FIRMWARE_SELECTED:
    167		return -ESTALE;
    168	case INTEL_UC_FIRMWARE_AVAILABLE:
    169	case INTEL_UC_FIRMWARE_LOADABLE:
    170	case INTEL_UC_FIRMWARE_TRANSFERRED:
    171	case INTEL_UC_FIRMWARE_RUNNING:
    172		return 0;
    173	}
    174	return -EINVAL;
    175}
    176
    177static inline const char *intel_uc_fw_type_repr(enum intel_uc_fw_type type)
    178{
    179	switch (type) {
    180	case INTEL_UC_FW_TYPE_GUC:
    181		return "GuC";
    182	case INTEL_UC_FW_TYPE_HUC:
    183		return "HuC";
    184	}
    185	return "uC";
    186}
    187
    188static inline enum intel_uc_fw_status
    189__intel_uc_fw_status(struct intel_uc_fw *uc_fw)
    190{
    191	/* shouldn't call this before checking hw/blob availability */
    192	GEM_BUG_ON(uc_fw->status == INTEL_UC_FIRMWARE_UNINITIALIZED);
    193	return uc_fw->status;
    194}
    195
    196static inline bool intel_uc_fw_is_supported(struct intel_uc_fw *uc_fw)
    197{
    198	return __intel_uc_fw_status(uc_fw) != INTEL_UC_FIRMWARE_NOT_SUPPORTED;
    199}
    200
    201static inline bool intel_uc_fw_is_enabled(struct intel_uc_fw *uc_fw)
    202{
    203	return __intel_uc_fw_status(uc_fw) > INTEL_UC_FIRMWARE_DISABLED;
    204}
    205
    206static inline bool intel_uc_fw_is_available(struct intel_uc_fw *uc_fw)
    207{
    208	return __intel_uc_fw_status(uc_fw) >= INTEL_UC_FIRMWARE_AVAILABLE;
    209}
    210
    211static inline bool intel_uc_fw_is_loadable(struct intel_uc_fw *uc_fw)
    212{
    213	return __intel_uc_fw_status(uc_fw) >= INTEL_UC_FIRMWARE_LOADABLE;
    214}
    215
    216static inline bool intel_uc_fw_is_loaded(struct intel_uc_fw *uc_fw)
    217{
    218	return __intel_uc_fw_status(uc_fw) >= INTEL_UC_FIRMWARE_TRANSFERRED;
    219}
    220
    221static inline bool intel_uc_fw_is_running(struct intel_uc_fw *uc_fw)
    222{
    223	return __intel_uc_fw_status(uc_fw) == INTEL_UC_FIRMWARE_RUNNING;
    224}
    225
    226static inline bool intel_uc_fw_is_overridden(const struct intel_uc_fw *uc_fw)
    227{
    228	return uc_fw->user_overridden;
    229}
    230
    231static inline void intel_uc_fw_sanitize(struct intel_uc_fw *uc_fw)
    232{
    233	if (intel_uc_fw_is_loaded(uc_fw))
    234		intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_LOADABLE);
    235}
    236
    237static inline u32 __intel_uc_fw_get_upload_size(struct intel_uc_fw *uc_fw)
    238{
    239	return sizeof(struct uc_css_header) + uc_fw->ucode_size;
    240}
    241
    242/**
    243 * intel_uc_fw_get_upload_size() - Get size of firmware needed to be uploaded.
    244 * @uc_fw: uC firmware.
    245 *
    246 * Get the size of the firmware and header that will be uploaded to WOPCM.
    247 *
    248 * Return: Upload firmware size, or zero on firmware fetch failure.
    249 */
    250static inline u32 intel_uc_fw_get_upload_size(struct intel_uc_fw *uc_fw)
    251{
    252	if (!intel_uc_fw_is_available(uc_fw))
    253		return 0;
    254
    255	return __intel_uc_fw_get_upload_size(uc_fw);
    256}
    257
    258void intel_uc_fw_init_early(struct intel_uc_fw *uc_fw,
    259			    enum intel_uc_fw_type type);
    260int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw);
    261void intel_uc_fw_cleanup_fetch(struct intel_uc_fw *uc_fw);
    262int intel_uc_fw_upload(struct intel_uc_fw *uc_fw, u32 offset, u32 dma_flags);
    263int intel_uc_fw_init(struct intel_uc_fw *uc_fw);
    264void intel_uc_fw_fini(struct intel_uc_fw *uc_fw);
    265size_t intel_uc_fw_copy_rsa(struct intel_uc_fw *uc_fw, void *dst, u32 max_len);
    266void intel_uc_fw_dump(const struct intel_uc_fw *uc_fw, struct drm_printer *p);
    267
    268#endif