Skip to content

Latest commit

 

History

History
102 lines (73 loc) · 12 KB

chapter3.adoc

File metadata and controls

102 lines (73 loc) · 12 KB

IOPMP Tables and Configuration Protection

The spec offers several IOPMP configurations to accommodate varied platforms. Users can choose one that best fits their design requirements, such as area, power consumption, latency, throughput, flexibility, and portability.

SRCMD Table and MDCFG Table

When a IOPMP receives a transaction with RRID s, IOPMP first lookups SRCMD table to find out all the memory domains associated to requestor s. An IOPMP instance can support up to 65,535 requestors, the actual number of requestor can be implementation-defined and is indicated in HWCFG1 register. The SRCMD table defines the mapping from a transaction requestor to its associated MDs. The mapping can be in one of three formats specified in HWCFG0.srcmd_fmt and described in SRCMD Table Formats.

When the associated memory domains are retrieved, an IOPMP finds the entries. The MDCFG defines which memory domain every entry belongs to. An entry can belong to at most one memory domain, but a memory domain can own zero or more entries. MDCFG can be in one of three formats, specified in HWCFG0.mdcfg_fmt and described in MDCFG Table Formats.

After retrieving all related entries, an IOPMP checks the transaction according to them.

SRCMD Table Formats

Format 0 and 2 of the SRCMD Table use a bit map to associate every RRID with memory domains. Format 1 is a simplified version that uses the RRID as the memory domain index. That is, the RRIDs and MD indexes are one-to-one mapping.

SRCMD Table Format 0

In Format 0, the SRCMD table is an array and indexed by RRID. Every entry in the array is a set of registers. The register SRCMD_EN(s) must be implemented for the existing RRID s. If SPS extension described in Appendix A3 is supported, SRCMD_R(s) and SRCMD_W(s) are implemented. Every bit in the 31-bit field SRCMD_EN(s).md indicates a memory domain. If the number of MDs is more than 31, the register SRCMD_ENH(s) and the field SRCMD_ENH(s).mdh can be implemented to support up to 63 memory domains. On the other hand, SPS also includes the registers SRCMD_RH(s) and SRCMD_WH(s), and the fields SRCMD_RH(s).mdh and SRCMD_WH(s).mdh. Besides, the bit SRCMD_EN(s).l is used to lock the set of registers indexed by RRID s.

For easier description, in the following, we denote SRCMD(s) a 64-bit register representing the concatenation of SRCMD_ENH(s) for the higher word and SRCMD_EN(s) for the lower word. Field SRCMD(s).md is the concatenation of SRCMD_ENH(s).mdh and SRCMD_EN(s).md, and bit SRCMD(s).l is bit SRCMD_EN(s).l.

Field SRCMD(s).md is a bitmapped field with up to 63 bits and is implemented from the lowest bit. Bit md[j] in SRCMD(s) indicates if MD j is associated with RRID s. For unimplemented memory domains, the corresponding bits should be read-only zero. An IOPMP supports up to 63 memory domains. For a system requiring more memory domains than 63, please refer to Appendix A2.

SRCMD Table Format 1

The bitmap implementation of Format 1 facilitates the sharing of regions between RRIDs. It is specifically tailored for scenarios where there are minimal to no shared regions. In this format, each RRID is exactly associated with a single MD, eliminating the necessity for SRCMD table lookups. Each RRID i is directly associated with MD i, resulting in advantages in terms of area, latency, and system complexity. However, duplication of entries occurs when shared regions are required, representing a potential drawback. In the format, the SRCMD table and MDLCK(H) registers are not implemented. Thus, the SPS extension is not supported as well.

SRCMD Table Format 2

This format also has a physical SRCMD table of an array, like Format 0, but the array is indexed by the memory domain index. For MD i, SRCMD_PERM(i) and SRCMD_PERMH(i) are implemented at the same addresses as SRCMD_EN(i) and SRCMD_ENH(i). That is, there is no SRCMD_EN(H) in the format. There is no SRCMD_R(H) and SRCMD_W(H) as well.

SRCMD_PERM(m).r[s] indicates the read permission and instruction fetch permission of RRID s belongs to the memory domain m. SRCMD_PERM(m).w[s] indicates write permission of RRID s belongs to the memory domain m. SRCMD_PERM(m).r and SRCMD_PERM(m).w are adjacent. That is, SRCMD_PERM(m).r[s] and SRCMD_PERM(m).w[s] are located at the bits (s * 2) and (s * 2 + 1), respectively. For RRID indexed higher than 15, SRCMD_PERMH(m) is used. IOPMP looks at permissions in SRCMD_PERM(H) and ENTRY_CFG.r/w/x. As long as one of them grants the transaction under checking, it is legal. If one wants to use only SRCMD_PERM(H), all ENTRY_CFG.r/w/x can be wired to zero.

MDCFG Table Formats

The MDCFG table is used to map a memory domain to its own entries. It can be viewed as a partition of all entries in the IOPMP. Its three formats aim to fit different design targets.

MDCFG Table Format 0

In the format, every memory domain m has a register, MDCFG(m). Field MDCFG(m).t indicates the top index of IOPMP entry belonging to the memory domain m. An entry with index j belongs to MD m if MDCFG(m-1).tj < MDCFG(m).t, where m > 0. MD 0 owns the IOPMP entries with index j < MDCFG(0).t. MDCFG(m+1).t should be programmed larger than or equal to MDCFG(m).t. The IOPMP behavior of improperly programming them is implementation-dependent as long as (1) an entry must belong to at most one memory domain and (2) the index of an entry in a lower-indexed memory domain should be lower than that in a higher-indexed memory domain.

Note

For programmers, to ensure the portability, MDCFG(m).t should be increased monotonically for m during the runtime, that is, MDCFG(m).tMDCFG(m+1).t for any legal m. Programming or initializing MDCFGs may temporarily cause improper settings; however, these registers are typically not changed at a high frequency, and one could stall the IOPMP while programming them. Thus, the specification doesn’t impose too many requirements on the case.

MDCFG Table Format 1

There is no physical MDCFG table in the format. Each memory domain has exactly k entries, where k is implementation-dependent and non-programmable. The value of the read-only field HWCFG0.md_entry_num is the k value minus 1. The register MDCFGLCK should not be implemented.

For a particular case of k=1 (HWCFG0.md_entry_num=0), every memory domain has exactly one entry. One can skip the concept of the memory domain when using such an IOPMP.

MDCFG Table Format 2

This format is based on Format 1, except HWCFG0.md_entry_num is programmable. md_entry_num is locked when HWCFG0 is locked, a.k.a. HWCFG0.enable is 1.

IOPMP Models

For the sake of convenience of discussion, some highly used combinations of HWCFG0 have an alias name, which are srcmd_fmt=0 and mdcfg_fmt=0 as the full model, srcmd_fmt=0 and mdcfg_fmt=1 as the rapid-k model, where k = (md_entry_num + 1), srcmd_fmt=0 and mdcfg_fmt=2 as the dynamic-k model, where k = (md_entry_num + 1), srcmd_fmt=1 and mdcfg_fmt=0 as the isolation model, and srcmd_fmt=1 and mdcfg_fmt=1 as the compact-k model, where k = (md_entry_num + 1).

Configuration Protection

The term 'lock' refers to a hardware feature that renders one or more fields or registers nonprogrammable until the IOPMP is reset. This feature serves to maintain the integrity of essential configurations in the event of a compromise of secure software. In cases where a lock bit is programmable, it is expected to be reset to '0' and sticky to '1' upon receiving a write of '1'.

SRCMD Table Protection

The two fields MDLCK.md and MDLCKH.mdh have 63 bits together. Every bit is used to lock the association bits with a memory domain in the SRCMD table. In Format 0, for MD m≤31, MDLCK.md[m] looks SRCMD(s).md[m] for all existing RRID s. In Format 1, there is no MDLCK. In Format 2, MDLCK.md[m] locks both SRCMD_PERM(m).r and SRCMD_PERM(m).w. For MD m≥32, one should use MDLCKH.mdh to lock corresponding bits.

Bit MDLCK.l is a sticky to 1 and indicates if MDLCK and MDLCKH are locked.

MDLCK.md is optional, if not implemented, MDLCK.md should be wired to 0 and MDLCK.l should be wired to 1. MDLCKH is optional.

Besides, in Format 0, every SRCMD_EN(s) register has a bit l, which is used to lock registers SRCMD_EN(s), SRCMD_ENH(s), SRCMD_R(s), SRCMD_RH(s), SRCMD_W(s), and SRCMD_WH(s) if any.

Note

Locking SRCMD table in either way can prevent the table from being altered accidentally or maliciously. By locking the association of the MD containing the configuration regions of a component, one can prevent the component from being configured by unwanted RRIDs. To make it more secure, one can use another high-priority MD containing the same regions but no permission, let it be associated with all unwanted RRIDs, and then lock the two MDs' associations by MDLCK/MDLCKH. By adopting this approach, it is possible to safeguard the configuration from direct access by potentially compromised security software.

MDCFG Table Protection

Register MDCFGLCK is designed to partially or fully lock the MDCFG table for Format 0. MDCFGLCK consists of two fields: MDCFGLCK.l and MDCFGLCK.f. MDCFG(m) is locked if m< MDCFGLCK.f. MDCFGLCK.f is incremental-only. Any smaller value can not be written into it. The bit MDCFGLCK.l is used to lock MDCFGLCK.

Format 1 and 2 do not implement the register MDCFGLCK.

Note

If a MD is locked, while its preceding MD is not locked, it could lead to the potential addition or removal of unexpected entries within the locked MD. This can occur by manipulating the top index of the preceding unlocked MD. Thus, the specification asks that one MD is locked, all its preceding MDs should be locked.

Entry Protection

IOPMP entry protection is also related to the other IOPMP entries belonging to the same memory domain. For a MD, locked entries should be placed in the higher priority. Otherwise, when the secure monitor is compromised, one unlocked entry in higher priority can overwrite all the other locked or non-locked entries in lower priority. A register ENTRYLCK is define to indicate the number of nonprogrammable entries. ENTRYLCK register has two fields: ENTRYLCK.l and ENTRYLCK.f. Any IOPMP entry with index iENTRYLCK.f is not programmable. ENTRYLCK.f is initialized to 0 and can be increased only when written. Besides, ENTRYLCK.l is the lock to ENTRYLCK.f and itself. If ENTRYLCK is hardwired, ENTRYLCK.l should be wired to 1.

Prelocked Configurations

Prelocked configurations in the specification mean the fields or registers are locked right after reset. They are not programmable at all. In practice, they could be hardwired and/or implemented by read-only memory. The obvious benefits are saving gate counts, no programming mistakes, and no malicious modification. Every lock mechanism in this chapter can be optionally pre-locked. The non-zero reset value of MDCFGLCK.f reflects the pre-locked MDCFG(j), where j< MDCFGLCK.f. The non-zero reset value of ENTRYLCK.f reflects the existing pre-locked entries. SRCMD_EN/R/W(H) can have prelocked bits fully or partially based on presets of MDLCK.md and SRCMD_EN.l. Similarly, SRCMD_PERM(H) also can have prelocked bits fully or partially based on presets of MDLCK.md. The rest of the lock bits can be preset, too. They are ERR_CFG.l, MDLCK.l, MDCFGLCK.l, and ENTRYLCK.l.