blob: e11059ac8466daa7f9843e6c2fa2c6ba5ab3aefd [file] [log] [blame]
Tamas Bana9de4a62018-09-18 08:09:45 +01001/*
2 * Copyright (c) 2018, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8#include "boot_record.h"
9#include "tfm_boot_status.h"
10#include "target.h"
11#include <stdint.h>
12#include <string.h>
13
14/*!
15 * \var shared_memory_init_done
16 *
17 * \brief Indicates whether shared memory area was already initialized.
18 *
19 */
20static uint32_t shared_memory_init_done;
21
22/*!
23 * \def SHARED_MEMORY_UNINITIALZED
24 *
25 * \brief Indicates that shared memory is uninitialized.
26 */
27#define SHARED_MEMORY_UNINITIALZED (0u)
28
29/*!
30 * \def SHARED_MEMORY_INITIALZED
31 *
32 * \brief Indicates that shared memory was already initialized.
33 */
34#define SHARED_MEMORY_INITIALZED (1u)
35
36enum shared_memory_err_t
37boot_add_data_to_shared_area(uint8_t major_type,
38 uint8_t minor_type,
39 size_t size,
40 const uint8_t *data)
41{
42 struct shared_data_tlv_entry tlv_entry = {0};
43 struct shared_data_tlv_header *tlv_header;
44 uint8_t *next_tlv;
45 uintptr_t tlv_end, offset;
46
47 tlv_header = (struct shared_data_tlv_header *)BOOT_TFM_SHARED_DATA_BASE;
48
49 /* Check whether first time to call this function. If does then initialise
50 * shared data area.
51 */
52 if (shared_memory_init_done == SHARED_MEMORY_UNINITIALZED) {
53 memset((void *)BOOT_TFM_SHARED_DATA_BASE, 0, BOOT_TFM_SHARED_DATA_SIZE);
54 tlv_header->tlv_magic = SHARED_DATA_TLV_INFO_MAGIC;
55 tlv_header->tlv_tot_len = SHARED_DATA_HEADER_SIZE;
56 shared_memory_init_done = SHARED_MEMORY_INITIALZED;
57 }
58
59 /* Check whether TLV entry is already added.
60 * Get the boundaries of TLV section
61 */
62 tlv_end = BOOT_TFM_SHARED_DATA_BASE + tlv_header->tlv_tot_len;
63 offset = BOOT_TFM_SHARED_DATA_BASE + SHARED_DATA_HEADER_SIZE;
64
65 /* Iterates over the TLV section looks for the same entry if found then
66 * returns with error: SHARED_MEMORY_OVERWRITE
67 */
68 for(; offset < tlv_end; offset += tlv_entry.tlv_len) {
69 tlv_entry = *((struct shared_data_tlv_entry *)offset);
70 if (tlv_entry.tlv_major_type == major_type &&
71 tlv_entry.tlv_minor_type == minor_type ) {
72 return SHARED_MEMORY_OVERWRITE;
73 }
74 }
75
76 /* Add TLV entry */
77 tlv_entry.tlv_major_type = major_type;
78 tlv_entry.tlv_minor_type = minor_type;
79 tlv_entry.tlv_len = SHARED_DATA_ENTRY_SIZE(size);
80
81 /* Verify overflow of shared area */
82 if ((tlv_header->tlv_tot_len + tlv_entry.tlv_len) >
83 BOOT_TFM_SHARED_DATA_SIZE){
84 return SHARED_MEMORY_OVERFLOW;
85 }
86
87 next_tlv = (uint8_t *)tlv_header + tlv_header->tlv_tot_len;
88 memcpy(next_tlv, &tlv_entry, SHARED_DATA_ENTRY_HEADER_SIZE);
89
90 next_tlv += SHARED_DATA_ENTRY_HEADER_SIZE;
91 memcpy(next_tlv, data, size);
92
93 tlv_header->tlv_tot_len = tlv_header->tlv_tot_len + tlv_entry.tlv_len;
94
95 return SHARED_MEMORY_OK;
96}