|  | // Copyright 2019 The Fuchsia Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | library fuchsia.sysmem; | 
|  |  | 
|  | using zx; | 
|  |  | 
|  | /// SecureMem | 
|  | /// | 
|  | /// The client is sysmem.  The server is securemem driver. | 
|  | /// | 
|  | /// TEE - Trusted Execution Environment. | 
|  | /// | 
|  | /// REE - Rich Execution Environment. | 
|  | /// | 
|  | /// Enables sysmem to call the securemem driver to get any secure heaps | 
|  | /// configured via the TEE (or via the securemem driver), and set any physical | 
|  | /// secure heaps configured via sysmem. | 
|  | /// | 
|  | /// Presently, dynamically-allocated secure heaps are configured via sysmem, as | 
|  | /// it starts quite early during boot and can successfully reserve contiguous | 
|  | /// physical memory.  Presently, fixed-location secure heaps are configured via | 
|  | /// TEE, as the plumbing goes from the bootloader to the TEE.  However, this | 
|  | /// protocol intentionally doesn't care which heaps are dynamically-allocated | 
|  | /// and which are fixed-location. | 
|  | protocol SecureMem { | 
|  | /// Gets the physical address and length of any secure heap whose physical | 
|  | /// range is configured via the TEE. | 
|  | /// | 
|  | /// Presently, these will be fixed physical addresses and lengths, with the | 
|  | /// location plumbed via the TEE. | 
|  | /// | 
|  | /// This is preferred over RegisterHeap() when there isn't any special | 
|  | /// heap-specific per-VMO setup or teardown required. | 
|  | /// | 
|  | /// The physical range must be secured/protected by the TEE before the | 
|  | /// securemem driver responds to this request with success. | 
|  | /// | 
|  | /// Sysmem should only call this once.  Returning zero heaps is not a | 
|  | /// failure. | 
|  | /// | 
|  | /// Errors: | 
|  | ///  * ZX_ERR_BAD_STATE - called more than once. | 
|  | ///  * ZX_ERR_INTERNAL - generic internal error (such as in communication | 
|  | ///    with TEE which doesn't generate zx_status_t errors). | 
|  | ///  * other errors are possible, such as from communication failures or | 
|  | ///    server propagation of zx_status_t failures | 
|  | GetPhysicalSecureHeaps() -> (PhysicalSecureHeaps heaps) error zx.status; | 
|  |  | 
|  | /// This request from sysmem to the securemem driver lets the TEE know the | 
|  | /// physical memory address and length of any secure heap whose location is | 
|  | /// configured/established via sysmem. | 
|  | /// | 
|  | /// Only sysmem can call this because only sysmem is handed the client end | 
|  | /// of a FIDL channel serving this protocol, via RegisterSecureMem().  The | 
|  | /// securemem driver is the server end of this protocol. | 
|  | /// | 
|  | /// Presently, these physical ranges will be dynamically-allocated by sysmem | 
|  | /// early during boot. | 
|  | /// | 
|  | /// The heap ID is included in case that's relevant to the securemem driver, | 
|  | /// for more informative log messages, and for consistency with | 
|  | /// GetPhysicalSecureHeaps(). | 
|  | /// | 
|  | /// The securemem driver must configure all the provided ranges as secure | 
|  | /// with the TEE before responding to this message with success. | 
|  | /// | 
|  | /// For heaps configured via sysmem, both the HeapType and heap location are | 
|  | /// configured via sysmem, and ZX_ERR_INVALID_ARGS will be the result if the | 
|  | /// securemem driver determines that the number of heaps or HeapType(s) are | 
|  | /// not what's supported by the securemem driver.  Typically these aspects | 
|  | /// are essentially fixed for a given device, so this error would typically | 
|  | /// imply a configuration or plumbing problem. | 
|  | /// | 
|  | /// Sysmem should only call this once. | 
|  | /// | 
|  | /// Errors: | 
|  | ///  * ZX_ERR_BAD_STATE - called more than once | 
|  | ///  * ZX_ERR_INVALID_ARGS - unexpected heap count or unexpected heap | 
|  | ///  * ZX_ERR_INTERNAL - generic internal error (such as in communication | 
|  | ///    with TEE which doesn't generate zx_status_t errors). | 
|  | ///  * other errors are possible, such as from communication failures or | 
|  | ///    server propagation of zx_status_t failures | 
|  | SetPhysicalSecureHeaps(PhysicalSecureHeaps heaps) -> () error zx.status; | 
|  | }; | 
|  |  | 
|  | struct PhysicalSecureHeap { | 
|  | /// This must be a HeapType that is secure/protected. | 
|  | HeapType heap; | 
|  | /// Must be at least PAGE_SIZE aligned. | 
|  | uint64 physical_address; | 
|  | /// Must be at least PAGE_SIZE aligned. | 
|  | uint64 size_bytes; | 
|  | }; | 
|  |  | 
|  | // Sysmem uses layout=Simple, which requires picking a specific array size. | 
|  | // Each heap consumes ~24 bytes on the stack, so we limit to a number that | 
|  | // exceeds the needs of any current use case (1 heap in each direction so far), | 
|  | // without over-alias stack space (24 bytes * 32 == 768 bytes). | 
|  | const uint32 MAX_HEAPS_COUNT = 32; | 
|  |  | 
|  | // In this struct we use array instead of vector because layout=Simple. | 
|  | struct PhysicalSecureHeaps { | 
|  | /// Must be <= MAX_HEAPS_COUNT. | 
|  | uint32 heaps_count; | 
|  | /// Only the first heaps_count are meaningful.  The rest are ignored. | 
|  | array<PhysicalSecureHeap>:MAX_HEAPS_COUNT heaps; | 
|  | }; |