Skip to content

ASoC: SOF: add ext manifest 4 firmware support - #3176

Closed
bardliao wants to merge 2 commits into
thesofproject:topic/sof-devfrom
bardliao:manifest4
Closed

bardliao wants to merge 2 commits into
thesofproject:topic/sof-devfrom
bardliao:manifest4

Conversation

@bardliao

@bardliao bardliao commented Sep 27, 2021 •

Copy link
Copy Markdown
Collaborator

SOF can support a new firmware extension manifest from ABI version 4. This
patch adds extension manifest 4 parser.

Signed-off-by: Rander Wang rander.wang@intel.com

@plbossart @ujfalusi I am not sure can we use bitfields in extension manifest struct. I will modify it if it is not suitable.

@bardliao
bardliao force-pushed the manifest4 branch 2 times, most recently from 76d1195 to 6194012 Compare September 29, 2021 05:25
@bardliao bardliao changed the title ASoC: SOF: add manifest 4 firmware support ASoC: SOF: add ext manifest 4 firmware support Sep 29, 2021
Comment thread include/sound/sof/ext_manifest4.h Resolved
Comment thread include/sound/sof/ext_manifest4.h Resolved

@plbossart plbossart left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confused on what parts are actually needed by the kernel.

Comment thread include/sound/sof/ext_manifest4.h Resolved
Comment thread include/sound/sof/ext_manifest4.h Resolved
Comment thread include/sound/sof/ext_manifest4.h Resolved
Comment thread include/sound/sof/ext_manifest4.h Resolved
Comment thread sound/soc/sof/loader.c Resolved
Comment thread sound/soc/sof/loader.c Resolved
@bardliao

Copy link
Copy Markdown
Collaborator Author

Confused on what parts are actually needed by the kernel.

Thanks @plbossart. I checked those elements and we don't need most of them.

Comment thread include/sound/sof/ext_manifest4.h Resolved
Comment thread include/sound/sof/ext_manifest4.h Resolved
Comment thread include/sound/sof/ext_manifest4.h Outdated
uint32_t ibs; /* input buffer size (bytes) */
uint32_t obs; /* output buffer size (bytes) */
uint32_t module_flags; /* flags, res for future use */
uint32_t cpc; /* cycles per single run */

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

single run of what? sorry the comment is quite vague, could you please elaborate?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

single run of what? sorry the comment is quite vague, could you please elaborate?

@RanderWang Could you comment on this?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is related to schedule. In each schedule period, each module is scheduled to process a batch of sample data, generally 1ms data. Here single run means the time span that each module used.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

then 'max cycles per scheduling period'?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

then 'max cycles per scheduling period'?

Updated, thanks

Comment thread sound/soc/sof/loader.c Resolved
Comment thread sound/soc/sof/loader.c Resolved
Comment thread include/sound/sof/ext_manifest4.h Resolved
Comment thread sound/soc/sof/loader.c Outdated
const struct sof_ext_manifest4_hdr *hdr;

hdr = (struct sof_ext_manifest4_hdr *)fw->data;
if (hdr->id == SOF_EXT_MAN4_MAGIC_NUMBER) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hdr->id is magic, right?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hdr->id is magic, right?

Yes, hdr->id is a magic number

Comment thread sound/soc/sof/loader.c Resolved
Comment thread include/sound/sof/ext_manifest4.h Outdated

struct sof_ext_manifest4_hdr {
u32 id;
u32 len;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Length of what?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Length of what?

length of extension manifest. I will add a comment here.

Comment thread sound/soc/sof/loader.c Outdated
fw_offset = hdr->len;

fw_header = (struct sof_man4_fw_binary_header *)(fw->data + fw_offset +
SOF_MAN4_FW_HDR_OFFSET);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have so many offsets that it is hard to follow, can you use hdr->len instead of fw_offset, it is only used here and then returned at the end.
between hdr->len and SOF_MAN4_FW_HDR_OFFSET we have grey area? 0x2000 is a lot of wasted space.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have so many offsets that it is hard to follow, can you use hdr->len instead of fw_offset, it is only used here and then returned at the end.

Will use hdr->len instead of fw_offset.

between hdr->len and SOF_MAN4_FW_HDR_OFFSET we have grey area? 0x2000 is a lot of wasted space.

I checked the firmware binary, there are some data followed by a lot of 0s in the SOF_MAN4_FW_HDR_OFFSET area. I believe that area is used by some struct.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This 0x2000 has been a constant for a long time: thesofproject/sof@8885b465df53

To test thesofproject/sof#4889 I ran the latest tools/sof_ri_info/sof_ri_info.py on all platform binaries since v1.7 and it parsed all of them. Example:

Reading SOF ri image sof-bin/v1.9.x/sof-v1.9/intel-signed/sof-tgl-h.ri
    File size 0x68300 (426752)
    0x0     Looking for Extended Manifest
    0x0     Extended Manifest (XMan)
    0x300   Looking for CSE Manifest
    0x300   CSE Manifest ($CPD)
    0x308   # of entries 3
    0x314   Reading CSE Manifest entry 0...
    0x32c   ... CSE Entry name ADSP.man file offset 0x35c length 1124
    ...
    0x2300  ADSP Manifest ($AM1)
    0x2334  Module Entry signature found ($AME)
    0x23a8  Module Entry signature found ($AME)
    Parsing finished

    SOF Binary sof-bin/v1.9.x/sof-v1.9/intel-signed/sof-tgl-h.ri size 0x68300

      Extended Manifest ver 1.0.0 length 768

      CSE Manifest ver 0x102 checksum 0x0 partition name ADSP

        ADSP.man (CSS Manifest) type 0x4 file offset 0x35c hdr_len 900 ver 0x21000 date 2021/09/23
          Rsvd0 0x1
          Modulus size (dwords) 96
            d3 72 92 99 4e b9 cd 67 ... 5d 62 4a 80 96 31 f8 b5 (TGL Intel prod key)
          Exponent size (dwords) 1
      ....
      ....

      cavs0015 (ADSP Manifest) file offset 0x2300 name ADSPFW build ver 1.9.0.1 feature mask 0xffff image flags 0x0
        HW buffers base address 0x0 length 0x0
        Load offset 0x30000


Comment thread sound/soc/sof/loader.c Resolved
Comment thread sound/soc/sof/loader.c Resolved
Comment thread sound/soc/sof/sof-priv.h Resolved
Comment thread include/sound/sof/ext_manifest4.h Resolved
Comment thread sound/soc/sof/loader.c Resolved

@kv2019i kv2019i left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I compare this to include/sound/sof/ext_manifest.h (for v3), this is quite specific (for example many fields for ROM only usage). I wonder if this should be hidden as a vendor manifest instead, e.g. Intel specific manifest.

If the amount of data SOF driver needs to get from manifest stays low, we could have a function interface to get data (like FW version and max IPC MSG size) and this could be coded in a vendor specific manifest structure.

Of course, if SOF core needs to get more data for IPC4 (like the module description data), then this become more complex. At minimum in this case, we should have clear documentation which of the manifest fields are relevant to driver and describe them better (like in include/sound/sof/ext_manifest.h -> all fields documented).

Comment thread include/sound/sof/ext_manifest4.h Resolved
Comment thread include/sound/sof/ext_manifest4.h Resolved

@kv2019i kv2019i left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Closer but still a few opens

Comment thread sound/soc/sof/loader.c Resolved
Comment thread sound/soc/sof/loader.c
dev_dbg(sdev->dev, " fw %s: header length %x, module num %d", fw_header->name,
fw_header->len, fw_header->num_module_entries);

fm_entry = (struct sof_man4_module *)((u8 *)fw_header + fw_header->len);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need fm_entry here yet, so this could be before L415. This is really the first place you need fm_entry. This will not impact the sizeof calculations (L401 et al, this just need to know the type).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bardliao , can you address @kv2019i's comment?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bardliao , can you address @kv2019i's comment?

Yes, I moved fm_entry = (struct sof_man4_module *)((u8 *)fw_header + fw_header->len); and the remaining calculation right before fm_config = (struct sof_man4_module_config *)(fm_entry + fw_header->num_module_entries);. Or are you suggesting that moving fm_entry only but not the remaining calculation?
Like

        remaining -= fw_header->len;

        if (remaining < fw_header->num_module_entries * sizeof(*fm_entry)) {
                dev_err(sdev->dev, "Invalid num_module_entries %d\n",
                        fw_header->num_module_entries);
                return -EINVAL;
        }
        fm_entry = (struct sof_man4_module *)((u8 *)fw_header + fw_header->len);
        fm_config = (struct sof_man4_module_config *)(fm_entry + fw_header->num_module_entries);

The reason I kept the remaining calculation right after pointer assignments was that I think it is more readable.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm good with this. Strictly speaking, you only consume/access the data when the pointer is dereferences (at L415), so in that sense more correctly place to adjust remaining would be L416. But I think this is now close enough and may be easier to read.

Comment thread sound/soc/sof/loader.c
memcpy(&module_entry->man4_module_entry, fm_entry, sizeof(*fm_entry));

if (fm_entry->cfg_count)
module_entry->bss_size = fm_config[fm_entry->cfg_offset].is_bytes;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are correct @bardliao , keep fm_config init in the original place.

This segment is difficult to follow as each fm_entry will also access fm_config, so you are consuming data from two places in the binary in this loop. So it's not so clear where to actually modify remaining as you are going back and forth in the blob. And you can do all the checks outside the loop either as you need to parse each fm_entry to see how many fm_config entries is has.

I think the current code is probably the best compromise.

kv2019i
kv2019i previously approved these changes Oct 29, 2021

@kv2019i kv2019i left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @bardliao , looks good now! I have one style related issue for snd_sof_fw_ext_man_parse() implementation, see code alternative in the comment. But that's not a blocking concern, so I'm ok to approve.

Comment thread sound/soc/sof/loader.c Resolved

@ujfalusi ujfalusi left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bardliao , I only have few points to clarify, other than that it looks pretty good.

Comment thread sound/soc/sof/loader.c
dev_dbg(sdev->dev, " fw %s: header length %x, module num %d", fw_header->name,
fw_header->len, fw_header->num_module_entries);

fm_entry = (struct sof_man4_module *)((u8 *)fw_header + fw_header->len);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bardliao , can you address @kv2019i's comment?

Comment thread sound/soc/sof/loader.c Resolved
kv2019i
kv2019i previously approved these changes Nov 2, 2021
Comment thread sound/soc/sof/loader.c
dev_dbg(sdev->dev, " fw %s: header length %x, module num %d", fw_header->name,
fw_header->len, fw_header->num_module_entries);

fm_entry = (struct sof_man4_module *)((u8 *)fw_header + fw_header->len);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm good with this. Strictly speaking, you only consume/access the data when the pointer is dereferences (at L415), so in that sense more correctly place to adjust remaining would be L416. But I think this is now close enough and may be easier to read.

ujfalusi
ujfalusi previously approved these changes Nov 4, 2021

@ujfalusi ujfalusi left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bardliao, looks good, thank you for the updates.

Comment thread include/sound/sof/ext_manifest4.h Resolved
Comment thread include/sound/sof/ext_manifest4.h Resolved
Comment thread include/sound/sof/ext_manifest4.h Resolved
Comment thread include/sound/sof/ext_manifest4.h Resolved
Comment thread include/sound/sof/ext_manifest4.h Resolved
Comment thread include/sound/sof/ext_manifest4.h Resolved
Comment thread sound/soc/sof/loader.c Resolved
@bardliao

bardliao commented Nov 5, 2021

Copy link
Copy Markdown
Collaborator Author

@plbossart I addressed all comments except the endianness issue. I need more discussion on the endianness issue.

@plbossart

Copy link
Copy Markdown
Member

@plbossart I addressed all comments except the endianness issue. I need more discussion on the endianness issue.

Sorry I wasn't asking for a change, it would be fine to just have a comment that this assumes little-endian order for compatibility with Windows firmware. That way upstream reviewers will know it's by-design and not a mistake.

@bardliao

bardliao commented Nov 8, 2021

Copy link
Copy Markdown
Collaborator Author

@plbossart I addressed all comments except the endianness issue. I need more discussion on the endianness issue.

Sorry I wasn't asking for a change, it would be fine to just have a comment that this assumes little-endian order for compatibility with Windows firmware. That way upstream reviewers will know it's by-design and not a mistake.

Oh, I see. Adding a sentence Note that not all items in the struct are 32 bits length, and we assume the firmware is little-endian. at the beginning of ext_manifest4.h now.

#define SOF_MAN4_DEFAULT_HASH_SHA256_LEN 32
#define SOF_MAN4_SEGMENT_NUM 3
#define SOF_MAN4_MODULE_PARAMS_NUM 4
#define SOF_MAN4_FW_HDR_OFFSET 0x2000

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bardliao the FW_HDR_OFFSET is not the same for cavs1.5 abd cavs1.8. Can we please abstract this?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bardliao the FW_HDR_OFFSET is not the same for cavs1.5 abd cavs1.8. Can we please abstract this?

Thanks @ranj063. I did some change, could you review it? Thanks.

#define SOF_MAN4_DEFAULT_HASH_SHA256_LEN 32
#define SOF_MAN4_SEGMENT_NUM 3
#define SOF_MAN4_MODULE_PARAMS_NUM 4
#define SOF_MAN4_FW_HDR_OFFSET 0x2000

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bardliao thanks but you didnt use the struct defined in the first patch?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bardliao thanks but you didnt use the struct defined in the first patch?

Yes, I did. See snd_sof_fw_ext_man4_parse

static int snd_sof_fw_ext_man4_parse(struct snd_sof_dev *sdev, const struct firmware *fw)
{
	struct snd_sof_pdata *sof_pdata = sdev->pdata;
	const struct sof_dev_desc *desc = sof_pdata->desc;
	const struct snd_sof_ext_man_pdata *ext_man_pdata = desc->ext_man_pdata;
...
	if (ext_man_pdata)
		fw_hdr_offset = ext_man_pdata->fw_hdr_offset;
	else
		fw_hdr_offset = SOF_MAN4_FW_HDR_OFFSET;
...
}

bardliao and others added 2 commits November 17, 2021 19:44
Some extension manifest datas are platform dependency. Add a new struct
allow us to define those datas for each platform.

Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
SOF can support a new firmware extension manifest from ABI version 4. This
patch adds extension manifest 4 parser.

Signed-off-by: Rander Wang <rander.wang@intel.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants