2017-01-18 08:05:53 -08:00
/*
* Copyright © 2016 - 2017 Intel Corporation
*
* Permission is hereby granted , free of charge , to any person obtaining a
* copy of this software and associated documentation files ( the " Software " ) ,
* to deal in the Software without restriction , including without limitation
* the rights to use , copy , modify , merge , publish , distribute , sublicense ,
* and / or sell copies of the Software , and to permit persons to whom the
* Software is furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice ( including the next
* paragraph ) shall be included in all copies or substantial portions of the
* Software .
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING
* FROM , OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE .
*
*/
2017-10-06 09:02:09 +00:00
# include <linux/types.h>
# include "intel_huc.h"
2017-01-18 08:05:53 -08:00
# include "i915_drv.h"
2017-12-06 13:53:10 +00:00
void intel_huc_init_early ( struct intel_huc * huc )
{
2018-03-01 22:15:45 +05:30
intel_huc_fw_init_early ( huc ) ;
2017-01-18 08:05:53 -08:00
}
2018-06-28 14:15:21 +00:00
int intel_huc_init_misc ( struct intel_huc * huc )
{
struct drm_i915_private * i915 = huc_to_i915 ( huc ) ;
intel_uc_fw_fetch ( i915 , & huc - > fw ) ;
return 0 ;
}
2017-01-18 08:05:57 -08:00
/**
2017-09-26 12:47:16 +05:30
* intel_huc_auth ( ) - Authenticate HuC uCode
* @ huc : intel_huc structure
*
* Called after HuC and GuC firmware loading during intel_uc_init_hw ( ) .
2017-01-18 08:05:57 -08:00
*
2017-09-26 12:47:16 +05:30
* This function pins HuC firmware image object into GGTT .
* Then it invokes GuC action to authenticate passing the offset to RSA
* signature through intel_guc_auth_huc ( ) . It then waits for 50 ms for
* firmware verification ACK and unpins the object .
2017-01-18 08:05:57 -08:00
*/
2017-12-06 13:53:16 +00:00
int intel_huc_auth ( struct intel_huc * huc )
2017-01-18 08:05:57 -08:00
{
2017-09-26 12:47:16 +05:30
struct drm_i915_private * i915 = huc_to_i915 ( huc ) ;
struct intel_guc * guc = & i915 - > guc ;
2017-01-18 08:05:57 -08:00
struct i915_vma * vma ;
2018-03-02 13:37:17 +00:00
u32 status ;
2017-01-18 08:05:57 -08:00
int ret ;
2017-01-20 20:23:46 +01:00
if ( huc - > fw . load_status ! = INTEL_UC_FIRMWARE_SUCCESS )
2017-12-06 13:53:16 +00:00
return - ENOEXEC ;
2017-01-20 20:23:46 +01:00
2017-01-18 08:05:57 -08:00
vma = i915_gem_object_ggtt_pin ( huc - > fw . obj , NULL , 0 , 0 ,
2018-07-27 16:11:45 +02:00
PIN_OFFSET_BIAS | i915 - > ggtt . pin_bias ) ;
2017-01-18 08:05:57 -08:00
if ( IS_ERR ( vma ) ) {
2017-12-06 13:53:16 +00:00
ret = PTR_ERR ( vma ) ;
DRM_ERROR ( " HuC: Failed to pin huc fw object %d \n " , ret ) ;
2018-03-02 13:37:17 +00:00
goto fail ;
2017-01-18 08:05:57 -08:00
}
2017-09-26 12:47:16 +05:30
ret = intel_guc_auth_huc ( guc ,
2018-03-13 17:32:49 -07:00
intel_guc_ggtt_offset ( guc , vma ) +
huc - > fw . rsa_offset ) ;
2017-01-18 08:05:57 -08:00
if ( ret ) {
DRM_ERROR ( " HuC: GuC did not ack Auth request %d \n " , ret ) ;
2018-03-02 13:37:17 +00:00
goto fail_unpin ;
2017-01-18 08:05:57 -08:00
}
/* Check authentication status, it should be done by now */
2019-03-25 14:49:39 -07:00
ret = __intel_wait_for_register ( & i915 - > uncore ,
2018-03-02 13:37:17 +00:00
HUC_STATUS2 ,
HUC_FW_VERIFIED ,
HUC_FW_VERIFIED ,
2 , 50 , & status ) ;
2017-01-18 08:05:57 -08:00
if ( ret ) {
2018-03-02 13:37:17 +00:00
DRM_ERROR ( " HuC: Firmware not verified %#x \n " , status ) ;
goto fail_unpin ;
2017-01-18 08:05:57 -08:00
}
i915_vma_unpin ( vma ) ;
2018-03-02 13:37:17 +00:00
return 0 ;
fail_unpin :
i915_vma_unpin ( vma ) ;
fail :
huc - > fw . load_status = INTEL_UC_FIRMWARE_FAIL ;
DRM_ERROR ( " HuC: Authentication failed %d \n " , ret ) ;
2017-12-06 13:53:16 +00:00
return ret ;
2017-01-18 08:05:57 -08:00
}
2018-03-14 20:04:29 +00:00
/**
* intel_huc_check_status ( ) - check HuC status
* @ huc : intel_huc structure
*
* This function reads status register to verify if HuC
* firmware was successfully loaded .
*
2018-10-17 19:52:45 +00:00
* Returns : 1 if HuC firmware is loaded and verified ,
* 0 if HuC firmware is not loaded and - ENODEV if HuC
* is not present on this platform .
2018-03-14 20:04:29 +00:00
*/
int intel_huc_check_status ( struct intel_huc * huc )
{
struct drm_i915_private * dev_priv = huc_to_i915 ( huc ) ;
2019-01-14 14:21:17 +00:00
intel_wakeref_t wakeref ;
2019-01-14 14:21:23 +00:00
bool status = false ;
2018-03-14 20:04:29 +00:00
if ( ! HAS_HUC ( dev_priv ) )
return - ENODEV ;
2019-01-14 14:21:23 +00:00
with_intel_runtime_pm ( dev_priv , wakeref )
status = I915_READ ( HUC_STATUS2 ) & HUC_FW_VERIFIED ;
2018-03-14 20:04:29 +00:00
return status ;
}