blob: 9d06ea9c47ae29435eaea9ef21b890b7421c4693 [file] [log] [blame] [edit]
/*
* Copyright 2023 The Hafnium Authors.
*
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file or at
* https://opensource.org/licenses/BSD-3-Clause.
*/
#pragma once
#include <stdint.h>
#include "hf/addr.h"
#include "hf/memiter.h"
#include "hf/string.h"
#include "vmapi/hf/ffa.h"
#define MANIFEST_INVALID_ADDRESS UINT64_MAX
#define MANIFEST_INVALID_ID UINT32_MAX
#define SP_RTX_BUF_NAME_SIZE 10
/** FF-A manifest memory and device regions attributes. */
#define MANIFEST_REGION_ATTR_READ (UINT32_C(1) << 0)
#define MANIFEST_REGION_ATTR_WRITE (UINT32_C(1) << 1)
#define MANIFEST_REGION_ATTR_EXEC (UINT32_C(1) << 2)
#define MANIFEST_REGION_ATTR_SECURITY (UINT32_C(1) << 3)
#define MANIFEST_REGION_ALL_ATTR_MASK \
(MANIFEST_REGION_ATTR_READ | MANIFEST_REGION_ATTR_WRITE | \
MANIFEST_REGION_ATTR_EXEC | MANIFEST_REGION_ATTR_SECURITY)
#define MANIFEST_POWER_MANAGEMENT_CPU_OFF_SUPPORTED (UINT32_C(1) << 0)
#define MANIFEST_POWER_MANAGEMENT_NONE_MASK (UINT32_C(0))
#define MANIFEST_POWER_MANAGEMENT_ALL_MASK \
MANIFEST_POWER_MANAGEMENT_CPU_OFF_SUPPORTED
/* Highest possible value for the boot-order field. */
#define DEFAULT_BOOT_ORDER 0xFFFF
#define DEFAULT_BOOT_GP_REGISTER UINT32_C(-1)
enum run_time_el {
EL1 = 0,
S_EL0,
S_EL1,
SUPERVISOR_MODE,
SECURE_USER_MODE,
SECURE_SUPERVISOR_MODE,
EL0
};
enum execution_state { AARCH64 = 0, AARCH32 };
enum xlat_granule { PAGE_4KB = 0, PAGE_16KB, PAGE_64KB };
/**
* Refer section 7.3 of the FF-A v1.3 ALP2 specification.
*/
enum abort_action {
/** Keep vCPU in STOPPED state. */
ACTION_STOP = 0,
/** Transition vCPU to NULL state. */
ACTION_DESTROY = 1,
/** Transition vCPU to STARTING state. */
ACTION_RESTART = 2,
/** SPMC aborts itself and informs SPMD. */
ACTION_PROPAGATE = 3,
/**
* SPMC takes implementation defined action if not specified explicitly.
*/
ACTION_IMP_DEF,
/** No other actions supported. */
};
struct sri_interrupts_policy {
/**
* When the partition is in waiting state at the moment one
* of its interrupts fires, the SPMC will trigger an SRI
* to the scheduler to explicitly provide CPU cycles, such that
* the interrupt can be handled.
*/
bool intr_while_waiting : 1;
/**
* If the SP is trying to go into a waiting state and it has
* pending interrupts, leave interrupts pended and trigger
* SRI to the scheduler of the system to explicitly provide
* CPU cycles at a later instance, such that the interrupt
* can be handled.
*/
bool intr_pending_entry_wait : 1;
uint8_t mbz : 6;
};
/**
* Properties of the DMA capable device upstream of an SMMU as specified in the
* memory region description of the partition manifest.
*/
struct dma_device_properties {
/** SMMU ID - optional */
uint32_t smmu_id;
/** IMPDEF id tracking DMA peripheral device - optional */
uint8_t dma_device_id;
/** Count of Stream IDs assigned to device - optional */
uint8_t stream_count;
/** List of Stream IDs assigned to device - optional */
uint32_t stream_ids[PARTITION_MAX_STREAMS_PER_DEVICE];
};
/**
* Partition Memory region as described in FFA v1.2 spec, Table 5.2 along with
* an implementation defined struct to track the properties of a DMA capable
* device that has access to this memory region.
*/
struct memory_region {
struct string description;
/**
* Specify PA, VA for S-EL0 partitions or IPA
* for S-EL1 partitions - optional.
*/
uintptr_t base_address;
/** True if `load-address-relative-offset` was specified. */
bool is_relative;
/** Page count - mandatory */
uint32_t page_count;
/** Memory attributes - mandatory */
uint32_t attributes;
/** DMA device properties - optional */
struct dma_device_properties dma_prop;
/** Instruction and data access permissions for DMA device - optional */
uint32_t dma_access_permissions;
};
/**
* Interrupts attibutes encoding in the manifest:
* Field Bit(s)
* ---------------------------
* Priority 7:0
* Security_State 8
* Config(Edge/Level) 9
* Type(SPI/PPI/SGI) 11:10
* Reserved 31:12
*/
#define INT_INFO_ATTR_PRIORITY_SHIFT 0
#define INT_INFO_ATTR_SEC_STATE_SHIFT 8
#define INT_INFO_ATTR_CONFIG_SHIFT 9
#define INT_INFO_ATTR_TYPE_SHIFT 10
struct interrupt_info {
uint32_t id;
uint32_t attributes;
bool mpidr_valid;
uint64_t mpidr;
};
/**
* Partition Device region as described in FFA v1.2 spec, Table 5.3 along with
* few implementation defined fields.
*/
struct device_region {
/** Device base PA - mandatory */
uintptr_t base_address;
/** Page count - mandatory */
uint32_t page_count;
/** Memory attributes - mandatory */
uint32_t attributes;
/** List of physical interrupt ID's and their attributes - optional */
struct interrupt_info interrupts[PARTITION_MAX_INTERRUPTS_PER_DEVICE];
/** Count of physical interrupts - optional */
uint8_t interrupt_count;
/** DMA device properties - optional */
struct dma_device_properties dma_prop;
/** Exclusive access to an endpoint - optional */
bool exclusive_access;
/** Name of Device region - optional */
struct string name;
};
/**
* RX/TX buffer, reference to memory-region entries that describe RX/TX
* buffers in partition manifest.
*/
struct rx_tx {
bool available;
uint32_t rx_phandle;
uint32_t tx_phandle;
struct memory_region *rx_buffer;
struct memory_region *tx_buffer;
};
struct vm_availability_messages {
bool vm_created : 1;
bool vm_destroyed : 1;
uint32_t mbz : 30;
};
static_assert(sizeof(struct vm_availability_messages) == sizeof(uint32_t),
"vm_availability_messages must have same size as uint32_t");
/**
* Partition manifest as described in FF-A v1.0 spec section 3.1
*/
struct ffa_partition_manifest {
/** FF-A expected version - mandatory */
enum ffa_version ffa_version;
/** UUID - at least one UUID mandatory */
uint16_t uuid_count;
struct ffa_uuid uuids[PARTITION_MAX_UUIDS];
/** Partition id - optional */
ffa_id_t id;
/** Aux ids for mem transactions - optional */
ffa_id_t aux_id;
/* NOTE: optional name field maps to VM debug_name field */
/** mandatory */
ffa_vcpu_count_t execution_ctx_count;
/** EL1 or secure EL1, secure EL0 - mandatory */
enum run_time_el run_time_el;
/** AArch32 / AArch64 - mandatory */
enum execution_state execution_state;
/** optional */
uintpaddr_t load_addr;
/** optional */
size_t ep_offset;
/** 4/16/64KB - optional */
enum xlat_granule xlat_granule;
/** Register id from w0/x0-w3/x3 - optional. */
uint32_t gp_register_num;
/**
* Flags the presence of the optional IMPDEF node to define Partition's
* Boot Info.
*/
bool boot_info;
/** optional */
uint16_t boot_order;
/** Optional RX/TX buffers */
struct rx_tx rxtx;
/** mandatory - direct/indirect msg or both */
uint16_t messaging_method;
/** mandatory - action in response to non secure interrupt */
uint8_t ns_interrupts_action;
/** optional - managed exit signaled through vIRQ */
bool me_signal_virq;
/** optional - receipt of notifications. */
bool notification_support;
/** optional - request the scheduler cycles to handle interrupts. */
struct sri_interrupts_policy sri_policy;
/**
* optional - VM availability messages bitfield.
*/
struct vm_availability_messages vm_availability_messages;
/**
* optional - power management messages bitfield.
*
* See [1] power-management-messages manifest field.
*
* The Hafnium supported combinations for a MP SP are:
* Bit 0 - relay PSCI cpu off message to the SP.
* Bit 3 - relay PSCI cpu on to the SP.
*
* [1]
* https://trustedfirmware-a.readthedocs.io/en/latest/components/ffa-manifest-binding.html#partition-properties
*/
uint32_t power_management;
/** optional */
bool has_primary_scheduler;
/** optional - tuples SEPID/SMMUID/streamId */
uint32_t stream_ep_ids[1];
/** Memory regions */
uint16_t mem_region_count;
struct memory_region mem_regions[PARTITION_MAX_MEMORY_REGIONS];
/** Device regions */
uint16_t dev_region_count;
struct device_region dev_regions[PARTITION_MAX_DEVICE_REGIONS];
/** DMA device count. */
uint8_t dma_device_count;
/** optional - action in response to Other-Secure interrupt */
uint8_t other_s_interrupts_action;
/** optional - SP lifecycle supported. */
bool lifecycle_support;
/** optional - Action in response to FFA_ABORT if SP lifecycle
* supported.
*/
uint8_t abort_action;
};