• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 #include <common/debug.h>
9 #include <errno.h>
10 #include <inttypes.h>
11 #include <platform_def.h>
12 #include <stddef.h>
13 #include <trusty/arm_ffa.h>
14 #include <trusty/ffa_helpers.h>
15 
16 #define NS_DRAM0_BITMAP_SIZE DIV_ROUND_UP_2EVAL(NS_DRAM0_SIZE, PAGE_SIZE * 8)
17 static uint8_t trusty_shmem_shared[NS_DRAM0_BITMAP_SIZE];
18 static uint8_t trusty_shmem_secure[NS_DRAM0_BITMAP_SIZE];
19 
read_bit(uint8_t * bit_mask,size_t bit_num)20 static bool read_bit(uint8_t *bit_mask, size_t bit_num)
21 {
22 	size_t i = bit_num / 8;
23 	size_t m = 1U << (bit_num % 8);
24 	return !!(bit_mask[i] & m);
25 }
26 
write_bit(uint8_t * bit_mask,size_t bit_num,bool val)27 static void write_bit(uint8_t *bit_mask, size_t bit_num, bool val)
28 {
29 	size_t i = bit_num / 8;
30 	size_t m = 1U << (bit_num % 8);
31 	if (val) {
32 		bit_mask[i] |= m;
33 	} else {
34 		bit_mask[i] &= ~m;
35 	}
36 }
37 
mem_set_shared(bool shared,bool secure,unsigned long long base_pa,size_t size)38 static int mem_set_shared(bool shared, bool secure, unsigned long long base_pa,
39 			  size_t size)
40 {
41 	unsigned long long page;
42 	size_t i;
43 
44 	assert((size % PAGE_SIZE) == 0);
45 
46 	if (base_pa < NS_DRAM0_BASE ||
47 	    (base_pa - NS_DRAM0_BASE) + size > NS_DRAM0_SIZE) {
48 		NOTICE("%s(%d, %d, 0x%llx, 0x%zx) invalid address range\n",
49 		       __func__, shared, secure, base_pa, size);
50 		return -EINVAL;
51 	}
52 	for (page = (base_pa - NS_DRAM0_BASE) / PAGE_SIZE, i = 0;
53 	     i < size / PAGE_SIZE; page++, i++) {
54 		bool was_shared = read_bit(trusty_shmem_shared, page);
55 		bool was_secure = read_bit(trusty_shmem_secure, page);
56 		assert(!was_secure || was_shared);
57 		if (was_shared == shared) {
58 			/* already shared or reclaimed */
59 			NOTICE("%s(%d, %d, 0x%llx, 0x%zx) already set\n",
60 			       __func__, shared, secure, base_pa, size);
61 			goto err;
62 		}
63 		assert(was_secure == (secure && !shared));
64 		write_bit(trusty_shmem_shared, page, shared);
65 		if (secure) {
66 			/*
67 			 * For emulator testing purposes the memory
68 			 * is marked as secure, and communicated to
69 			 * Trusty as such, even though it is not.
70 			 */
71 			write_bit(trusty_shmem_secure, page, shared);
72 		}
73 	}
74 	return 0;
75 
76 err:
77 	while (i > 0) {
78 		i--;
79 		page--;
80 		write_bit(trusty_shmem_shared, page, !shared);
81 		if (secure) {
82 			write_bit(trusty_shmem_secure, page, !shared);
83 		}
84 	}
85 	return -EBUSY;
86 }
87 
88 
plat_mem_set_shared(struct ffa_mtd * mtd,bool shared)89 int plat_mem_set_shared(struct ffa_mtd *mtd, bool shared)
90 {
91 	struct ffa_comp_mrd *comp = trusty_ffa_mtd_get_comp_mrd(mtd);
92 	size_t count = comp->address_range_count;
93 	struct ffa_cons_mrd *cons_mrd;
94 	int ret = 0;
95 	size_t i;
96 	bool secure;
97 
98 	secure = trusty_ffa_should_be_secure(mtd);
99 
100 	for (i = 0, cons_mrd = comp->address_range_array; i < count;
101 	     i++, cons_mrd++) {
102 		ret = mem_set_shared(shared, secure, cons_mrd->address,
103 				     cons_mrd->page_count * PAGE_SIZE);
104 		if (ret) {
105 			goto err;
106 		}
107 	}
108 
109 	if (secure) {
110 		mtd->memory_region_attributes &= ~FFA_MEM_ATTR_NONSECURE;
111 	}
112 	return 0;
113 
114 err:
115 	NOTICE("%s: %zu/%zu: failed to set shared %d secure %d for %"
116 	       PRIx64 " (%x)\n",
117 	       __func__, i, count, shared, secure, cons_mrd->address,
118 	       cons_mrd->page_count);
119 	while (i > 0) {
120 		i--;
121 		cons_mrd--;
122 		if (mem_set_shared(!shared, secure, cons_mrd->address,
123 				   cons_mrd->page_count * PAGE_SIZE)) {
124 			/* Failed to revert change */
125 			panic();
126 		}
127 	}
128 	return ret;
129 }
130