|
@@ -441,78 +441,87 @@ static int iwl_pcie_load_section(struct iwl_trans *trans, u8 section_num,
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-static int iwl_pcie_secure_set(struct iwl_trans *trans, int cpu)
|
|
|
+static int iwl_pcie_load_cpu_secured_sections(struct iwl_trans *trans,
|
|
|
+ const struct fw_img *image,
|
|
|
+ int cpu)
|
|
|
{
|
|
|
int shift_param;
|
|
|
- u32 address;
|
|
|
- int ret = 0;
|
|
|
+ u32 first_idx, last_idx;
|
|
|
+ int i, ret = 0;
|
|
|
|
|
|
if (cpu == 1) {
|
|
|
shift_param = 0;
|
|
|
- address = CSR_SECURE_BOOT_CPU1_STATUS_ADDR;
|
|
|
+ first_idx = 0;
|
|
|
+ last_idx = 2;
|
|
|
} else {
|
|
|
shift_param = 16;
|
|
|
- address = CSR_SECURE_BOOT_CPU2_STATUS_ADDR;
|
|
|
+ first_idx = 3;
|
|
|
+ last_idx = 5;
|
|
|
}
|
|
|
|
|
|
- /* set CPU to started */
|
|
|
- iwl_trans_set_bits_mask(trans,
|
|
|
- CSR_UCODE_LOAD_STATUS_ADDR,
|
|
|
- CSR_CPU_STATUS_LOADING_STARTED << shift_param,
|
|
|
- 1);
|
|
|
-
|
|
|
- /* set last complete descriptor number */
|
|
|
- iwl_trans_set_bits_mask(trans,
|
|
|
- CSR_UCODE_LOAD_STATUS_ADDR,
|
|
|
- CSR_CPU_STATUS_NUM_OF_LAST_COMPLETED
|
|
|
- << shift_param,
|
|
|
- 1);
|
|
|
-
|
|
|
- /* set last loaded block */
|
|
|
- iwl_trans_set_bits_mask(trans,
|
|
|
- CSR_UCODE_LOAD_STATUS_ADDR,
|
|
|
- CSR_CPU_STATUS_NUM_OF_LAST_LOADED_BLOCK
|
|
|
- << shift_param,
|
|
|
- 1);
|
|
|
+ for (i = first_idx; i <= last_idx; i++) {
|
|
|
+ if (!image->sec[i].data)
|
|
|
+ break;
|
|
|
+ if (i == first_idx + 1)
|
|
|
+ /* set CPU to started */
|
|
|
+ iwl_set_bits_prph(trans,
|
|
|
+ CSR_UCODE_LOAD_STATUS_ADDR,
|
|
|
+ LMPM_CPU_HDRS_LOADING_COMPLETED
|
|
|
+ << shift_param);
|
|
|
|
|
|
- /* image loading complete */
|
|
|
- iwl_trans_set_bits_mask(trans,
|
|
|
- CSR_UCODE_LOAD_STATUS_ADDR,
|
|
|
- CSR_CPU_STATUS_LOADING_COMPLETED
|
|
|
- << shift_param,
|
|
|
- 1);
|
|
|
-
|
|
|
- /* set FH_TCSR_0_REG */
|
|
|
- iwl_trans_set_bits_mask(trans, FH_TCSR_0_REG0, 0x00400000, 1);
|
|
|
-
|
|
|
- /* verify image verification started */
|
|
|
- ret = iwl_poll_bit(trans, address,
|
|
|
- CSR_SECURE_BOOT_CPU_STATUS_VERF_STATUS,
|
|
|
- CSR_SECURE_BOOT_CPU_STATUS_VERF_STATUS,
|
|
|
- CSR_SECURE_TIME_OUT);
|
|
|
- if (ret < 0) {
|
|
|
- IWL_ERR(trans, "secure boot process didn't start\n");
|
|
|
- return ret;
|
|
|
+ ret = iwl_pcie_load_section(trans, i, &image->sec[i]);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
}
|
|
|
+ /* image loading complete */
|
|
|
+ iwl_set_bits_prph(trans,
|
|
|
+ CSR_UCODE_LOAD_STATUS_ADDR,
|
|
|
+ LMPM_CPU_UCODE_LOADING_COMPLETED << shift_param);
|
|
|
|
|
|
- /* wait for image verification to complete */
|
|
|
- ret = iwl_poll_bit(trans, address,
|
|
|
- CSR_SECURE_BOOT_CPU_STATUS_VERF_COMPLETED,
|
|
|
- CSR_SECURE_BOOT_CPU_STATUS_VERF_COMPLETED,
|
|
|
- CSR_SECURE_TIME_OUT);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
|
|
|
- if (ret < 0) {
|
|
|
- IWL_ERR(trans, "Time out on secure boot process\n");
|
|
|
- return ret;
|
|
|
+static int iwl_pcie_load_cpu_sections(struct iwl_trans *trans,
|
|
|
+ const struct fw_img *image,
|
|
|
+ int cpu)
|
|
|
+{
|
|
|
+ int shift_param;
|
|
|
+ u32 first_idx, last_idx;
|
|
|
+ int i, ret = 0;
|
|
|
+
|
|
|
+ if (cpu == 1) {
|
|
|
+ shift_param = 0;
|
|
|
+ first_idx = 0;
|
|
|
+ last_idx = 1;
|
|
|
+ } else {
|
|
|
+ shift_param = 16;
|
|
|
+ first_idx = 2;
|
|
|
+ last_idx = 3;
|
|
|
}
|
|
|
|
|
|
+ for (i = first_idx; i <= last_idx; i++) {
|
|
|
+ if (!image->sec[i].data)
|
|
|
+ break;
|
|
|
+ ret = iwl_pcie_load_section(trans, i, &image->sec[i]);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
|
|
|
+ iwl_set_bits_prph(trans,
|
|
|
+ CSR_UCODE_LOAD_STATUS_ADDR,
|
|
|
+ (LMPM_CPU_UCODE_LOADING_COMPLETED |
|
|
|
+ LMPM_CPU_HDRS_LOADING_COMPLETED |
|
|
|
+ LMPM_CPU_UCODE_LOADING_STARTED) <<
|
|
|
+ shift_param);
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
|
|
|
const struct fw_img *image)
|
|
|
{
|
|
|
- int i, ret = 0;
|
|
|
+ int ret = 0;
|
|
|
|
|
|
IWL_DEBUG_FW(trans,
|
|
|
"working with %s image\n",
|
|
@@ -524,54 +533,46 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
|
|
|
/* configure the ucode to be ready to get the secured image */
|
|
|
if (image->is_secure) {
|
|
|
/* set secure boot inspector addresses */
|
|
|
- iwl_write32(trans, CSR_SECURE_INSPECTOR_CODE_ADDR, 0);
|
|
|
- iwl_write32(trans, CSR_SECURE_INSPECTOR_DATA_ADDR, 0);
|
|
|
+ iwl_write_prph(trans,
|
|
|
+ LMPM_SECURE_INSPECTOR_CODE_ADDR,
|
|
|
+ LMPM_SECURE_INSPECTOR_CODE_MEM_SPACE);
|
|
|
|
|
|
- /* release CPU1 reset if secure inspector image burned in OTP */
|
|
|
- iwl_write32(trans, CSR_RESET, 0);
|
|
|
- }
|
|
|
+ iwl_write_prph(trans,
|
|
|
+ LMPM_SECURE_INSPECTOR_DATA_ADDR,
|
|
|
+ LMPM_SECURE_INSPECTOR_DATA_MEM_SPACE);
|
|
|
|
|
|
- /* load to FW the binary sections of CPU1 */
|
|
|
- IWL_DEBUG_INFO(trans, "Loading CPU1\n");
|
|
|
- for (i = 0;
|
|
|
- i < IWL_UCODE_FIRST_SECTION_OF_SECOND_CPU;
|
|
|
- i++) {
|
|
|
- if (!image->sec[i].data)
|
|
|
- break;
|
|
|
- ret = iwl_pcie_load_section(trans, i, &image->sec[i]);
|
|
|
+ /* set CPU1 header address */
|
|
|
+ iwl_write_prph(trans,
|
|
|
+ LMPM_SECURE_UCODE_LOAD_CPU1_HDR_ADDR,
|
|
|
+ LMPM_SECURE_CPU1_HDR_MEM_SPACE);
|
|
|
+
|
|
|
+ /* load to FW the binary Secured sections of CPU1 */
|
|
|
+ ret = iwl_pcie_load_cpu_secured_sections(trans, image, 1);
|
|
|
if (ret)
|
|
|
return ret;
|
|
|
- }
|
|
|
|
|
|
- /* configure the ucode to start secure process on CPU1 */
|
|
|
- if (image->is_secure) {
|
|
|
- /* config CPU1 to start secure protocol */
|
|
|
- ret = iwl_pcie_secure_set(trans, 1);
|
|
|
+ } else {
|
|
|
+ /* load to FW the binary Non secured sections of CPU1 */
|
|
|
+ ret = iwl_pcie_load_cpu_sections(trans, image, 1);
|
|
|
if (ret)
|
|
|
return ret;
|
|
|
- } else {
|
|
|
- /* Remove all resets to allow NIC to operate */
|
|
|
- iwl_write32(trans, CSR_RESET, 0);
|
|
|
}
|
|
|
|
|
|
if (image->is_dual_cpus) {
|
|
|
- /* load to FW the binary sections of CPU2 */
|
|
|
- IWL_DEBUG_INFO(trans, "working w/ DUAL CPUs - Loading CPU2\n");
|
|
|
- for (i = IWL_UCODE_FIRST_SECTION_OF_SECOND_CPU;
|
|
|
- i < IWL_UCODE_SECTION_MAX; i++) {
|
|
|
- if (!image->sec[i].data)
|
|
|
- break;
|
|
|
- ret = iwl_pcie_load_section(trans, i, &image->sec[i]);
|
|
|
- if (ret)
|
|
|
- return ret;
|
|
|
- }
|
|
|
+ /* set CPU2 header address */
|
|
|
+ iwl_write_prph(trans,
|
|
|
+ LMPM_SECURE_UCODE_LOAD_CPU2_HDR_ADDR,
|
|
|
+ LMPM_SECURE_CPU2_HDR_MEM_SPACE);
|
|
|
|
|
|
- if (image->is_secure) {
|
|
|
- /* set CPU2 for secure protocol */
|
|
|
- ret = iwl_pcie_secure_set(trans, 2);
|
|
|
- if (ret)
|
|
|
- return ret;
|
|
|
- }
|
|
|
+ /* load to FW the binary sections of CPU2 */
|
|
|
+ if (image->is_secure)
|
|
|
+ ret = iwl_pcie_load_cpu_secured_sections(trans,
|
|
|
+ image,
|
|
|
+ 2);
|
|
|
+ else
|
|
|
+ ret = iwl_pcie_load_cpu_sections(trans, image, 2);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
/* release CPU reset */
|
|
@@ -580,6 +581,20 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
|
|
|
else
|
|
|
iwl_write32(trans, CSR_RESET, 0);
|
|
|
|
|
|
+ if (image->is_secure) {
|
|
|
+ /* wait for image verification to complete */
|
|
|
+ ret = iwl_poll_prph_bit(trans,
|
|
|
+ LMPM_SECURE_BOOT_CPU1_STATUS_ADDR,
|
|
|
+ LMPM_SECURE_BOOT_STATUS_SUCCESS,
|
|
|
+ LMPM_SECURE_BOOT_STATUS_SUCCESS,
|
|
|
+ LMPM_SECURE_TIME_OUT);
|
|
|
+
|
|
|
+ if (ret < 0) {
|
|
|
+ IWL_ERR(trans, "Time out on secure boot process\n");
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|