Hi

It seems that 'io_dev_open' is being called within 'check_fip' and 'check_enc_fip' during the retrieval of the image specification. Instead, you can register and open the enc and fip devices once during the setup phase [see example [1] for reference) and store their handles (fip_dev_handle and enc_dev_handle) 

These stored handles can then be used directly in the `check_fip` and `check_enc_fip` functions. Please let me know if you need any additional information or if I missed anything in your details.

[1]: https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/refs/heads/integration/plat/arm/common/arm_io_storage.c#72

Thanks,
Manish Badarkhe


From: 林觀明 via TF-A <tf-a@lists.trustedfirmware.org>
Sent: 18 January 2025 15:56
To: tf-a@lists.trustedfirmware.org <tf-a@lists.trustedfirmware.org>
Subject: [TF-A] question about encryption
 

Hi

I tried to turn on encryption in BL31.
And, I met some trouble.

Here is my code.

```
static struct plat_io_policy policies[] = {
    ...
    [BL31_IMAGE_ID] = {&enc_dev_handle, &bl31_uuid_spec, check_enc_fip}, 
    ....
    [ENC_IMAGE_ID] = {&fip_dev_handle, NULL, check_fip}
}

int plat_get_image_source(...) {
    ...
    policy = &policies[image_id];
    ret = policy->check[policy->image_spec];
    ...
}

static int check_fip(const uintptr_t spec)
{

        int ret;

        ret = io_dev_open(fip_dev_con, (uintptr_t)NULL, &fip_dev_handle);

         if (ret) {
                 ERROR("io_dev_open failed for FIP (%d)\n", ret);
                 return ret;
  }

         ret = io_dev_init(fip_dev_handle, fip_image_id);
         if (ret) {
                 ERROR("io_dev_init failed for FIP image id %lu (%d)\n",
                       fip_image_id, ret);
                 io_dev_close(fip_dev_handle);
         }
         return ret;
}

static int check_enc_fip(const uintptr_t spec)
{
  int result;
  uintptr_t local_image_handle;

 

  /* See if a Firmware Image Package is available */
  result = io_dev_open(enc_dev_con, (uintptr_t)NULL, &enc_dev_handle);
  if (result) {
    ERROR("io_dev_open failed for FIP (%d)\n", result);
    return result;
  }

  result = io_dev_init(enc_dev_handle, (uintptr_t)ENC_IMAGE_ID);
  if (result != 0)
    return result;
  return result;
}
```

 

But, I can't boot successfully.
Below is log.
```
INFO:    Image id=3 loaded: 0x40800000 - 0x4080e299
INFO:    BL2: Loading image id 5
WARNING: ===== allocate_dev_info 1 =====
WARNING: ==== -12 ====
ERROR:   io_dev_open failed for FIP (-12)
ERROR:   Image id 11 open failed with -12
WARNING: Failed to obtain reference to image id=11 (-12)
ERROR:   BL2: Failed to load image id 5 (-12)
```

And, I found root cause in `allocate_dev_info` and `free_dev_info` in `drivers/io/io_fip.c`
In `allocate_dev_info`, there is a count, `fip_dev_count`, increasing by 1 after calling `fip_dev_open`
There is a check. The value of MAX_FIP_DEVICES is 1.
```
if (fip_dev_count < (unsigned int)MAX_FIP_DEVICES) {
    unsigned int index = 0;

    result = find_first_fip_state(0, &index);
    assert(result == 0);
    /* initialize dev_info */
    dev_info_pool[index].funcs = &fip_dev_funcs;
    dev_info_pool[index].info =
        (uintptr_t)&state_pool[index];
    *dev_info = &dev_info_pool[index];
    ++fip_dev_count;
  }
```
And, in `fip_dev_close`, The `fip_dev_count` will be decreased by 1.

However, The root casue is it call fip_dev_open but not calling fip_dev_close.
It cause the `fip_dev_count` not be decreased by 1.

Now, I have two solution.
1. Increasing the MAX_FIP_DEVICES, it will be working.
2. Add the io_dev_close in `enc_dev_close` in `driver/io_/io_encrypted.c`. 
    And, it will call the fip_dev_close. It will be working.

Do you have any idea in this solution ? 
Which solution is more general ?

Thanks !