aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware
diff options
context:
space:
mode:
authorMatt Fleming <matt@codeblueprint.co.uk>2016-02-29 11:58:18 -0500
committerMatt Fleming <matt@codeblueprint.co.uk>2016-09-09 11:07:45 -0400
commitc8c1a4c5e4ead0d2dcf0f0bcb8bdbdcf877fb3bb (patch)
tree49f0f6a37495aa1e88bec7a42974994d1131658f /drivers/firmware
parentdca0f971ea6fcf2f1bb78f7995adf80da9f4767f (diff)
efi/fake_mem: Refactor main two code chunks into functions
There is a whole load of generic EFI memory map code inside of the fake_mem driver which is better suited to being grouped with the rest of the generic EFI code for manipulating EFI memory maps. In preparation for that, this patch refactors the core code, so that it's possible to move entire functions later. Tested-by: Dave Young <dyoung@redhat.com> [kexec/kdump] Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> [arm] Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Cc: Leif Lindholm <leif.lindholm@linaro.org> Cc: Peter Jones <pjones@redhat.com> Cc: Borislav Petkov <bp@alien8.de> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Taku Izumi <izumi.taku@jp.fujitsu.com> Signed-off-by: Matt Fleming <matt@codeblueprint.co.uk>
Diffstat (limited to 'drivers/firmware')
-rw-r--r--drivers/firmware/efi/fake_mem.c229
1 files changed, 134 insertions, 95 deletions
diff --git a/drivers/firmware/efi/fake_mem.c b/drivers/firmware/efi/fake_mem.c
index 939eec47139f..446c669431c0 100644
--- a/drivers/firmware/efi/fake_mem.c
+++ b/drivers/firmware/efi/fake_mem.c
@@ -54,43 +54,151 @@ static int __init cmp_fake_mem(const void *x1, const void *x2)
54 return 0; 54 return 0;
55} 55}
56 56
57/**
58 * efi_fake_memmap_split_count - Count number of additional EFI memmap entries
59 * @md: EFI memory descriptor to split
60 * @range: Address range (start, end) to split around
61 *
62 * Returns the number of additional EFI memmap entries required to
63 * accomodate @range.
64 */
65static int efi_fake_memmap_split_count(efi_memory_desc_t *md, struct range *range)
66{
67 u64 m_start, m_end;
68 u64 start, end;
69 int count = 0;
70
71 start = md->phys_addr;
72 end = start + (md->num_pages << EFI_PAGE_SHIFT) - 1;
73
74 /* modifying range */
75 m_start = range->start;
76 m_end = range->end;
77
78 if (m_start <= start) {
79 /* split into 2 parts */
80 if (start < m_end && m_end < end)
81 count++;
82 }
83
84 if (start < m_start && m_start < end) {
85 /* split into 3 parts */
86 if (m_end < end)
87 count += 2;
88 /* split into 2 parts */
89 if (end <= m_end)
90 count++;
91 }
92
93 return count;
94}
95
96/**
97 * efi_fake_memmap_insert - Insert a fake memory region in an EFI memmap
98 * @old_memmap: The existing EFI memory map structure
99 * @buf: Address of buffer to store new map
100 * @mem: Fake memory map entry to insert
101 *
102 * It is suggested that you call efi_fake_memmap_split_count() first
103 * to see how large @buf needs to be.
104 */
105static void efi_fake_memmap_insert(struct efi_memory_map *old_memmap,
106 void *buf, struct fake_mem *mem)
107{
108 u64 m_start, m_end, m_attr;
109 efi_memory_desc_t *md;
110 u64 start, end;
111 void *old, *new;
112
113 /* modifying range */
114 m_start = mem->range.start;
115 m_end = mem->range.end;
116 m_attr = mem->attribute;
117
118 for (old = old_memmap->map, new = buf;
119 old < old_memmap->map_end;
120 old += old_memmap->desc_size, new += old_memmap->desc_size) {
121
122 /* copy original EFI memory descriptor */
123 memcpy(new, old, old_memmap->desc_size);
124 md = new;
125 start = md->phys_addr;
126 end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1;
127
128 if (m_start <= start && end <= m_end)
129 md->attribute |= m_attr;
130
131 if (m_start <= start &&
132 (start < m_end && m_end < end)) {
133 /* first part */
134 md->attribute |= m_attr;
135 md->num_pages = (m_end - md->phys_addr + 1) >>
136 EFI_PAGE_SHIFT;
137 /* latter part */
138 new += old_memmap->desc_size;
139 memcpy(new, old, old_memmap->desc_size);
140 md = new;
141 md->phys_addr = m_end + 1;
142 md->num_pages = (end - md->phys_addr + 1) >>
143 EFI_PAGE_SHIFT;
144 }
145
146 if ((start < m_start && m_start < end) && m_end < end) {
147 /* first part */
148 md->num_pages = (m_start - md->phys_addr) >>
149 EFI_PAGE_SHIFT;
150 /* middle part */
151 new += old_memmap->desc_size;
152 memcpy(new, old, old_memmap->desc_size);
153 md = new;
154 md->attribute |= m_attr;
155 md->phys_addr = m_start;
156 md->num_pages = (m_end - m_start + 1) >>
157 EFI_PAGE_SHIFT;
158 /* last part */
159 new += old_memmap->desc_size;
160 memcpy(new, old, old_memmap->desc_size);
161 md = new;
162 md->phys_addr = m_end + 1;
163 md->num_pages = (end - m_end) >>
164 EFI_PAGE_SHIFT;
165 }
166
167 if ((start < m_start && m_start < end) &&
168 (end <= m_end)) {
169 /* first part */
170 md->num_pages = (m_start - md->phys_addr) >>
171 EFI_PAGE_SHIFT;
172 /* latter part */
173 new += old_memmap->desc_size;
174 memcpy(new, old, old_memmap->desc_size);
175 md = new;
176 md->phys_addr = m_start;
177 md->num_pages = (end - md->phys_addr + 1) >>
178 EFI_PAGE_SHIFT;
179 md->attribute |= m_attr;
180 }
181 }
182}
183
57void __init efi_fake_memmap(void) 184void __init efi_fake_memmap(void)
58{ 185{
59 u64 start, end, m_start, m_end, m_attr;
60 struct efi_memory_map_data data; 186 struct efi_memory_map_data data;
61 int new_nr_map = efi.memmap.nr_map; 187 int new_nr_map = efi.memmap.nr_map;
62 efi_memory_desc_t *md; 188 efi_memory_desc_t *md;
63 phys_addr_t new_memmap_phy; 189 phys_addr_t new_memmap_phy;
64 void *new_memmap; 190 void *new_memmap;
65 void *old, *new;
66 int i; 191 int i;
67 192
68 if (!nr_fake_mem) 193 if (!nr_fake_mem)
69 return; 194 return;
70 195
71 /* count up the number of EFI memory descriptor */ 196 /* count up the number of EFI memory descriptor */
72 for_each_efi_memory_desc(md) { 197 for (i = 0; i < nr_fake_mem; i++) {
73 start = md->phys_addr; 198 for_each_efi_memory_desc(md) {
74 end = start + (md->num_pages << EFI_PAGE_SHIFT) - 1; 199 struct range *r = &fake_mems[i].range;
75 200
76 for (i = 0; i < nr_fake_mem; i++) { 201 new_nr_map += efi_fake_memmap_split_count(md, r);
77 /* modifying range */
78 m_start = fake_mems[i].range.start;
79 m_end = fake_mems[i].range.end;
80
81 if (m_start <= start) {
82 /* split into 2 parts */
83 if (start < m_end && m_end < end)
84 new_nr_map++;
85 }
86 if (start < m_start && m_start < end) {
87 /* split into 3 parts */
88 if (m_end < end)
89 new_nr_map += 2;
90 /* split into 2 parts */
91 if (end <= m_end)
92 new_nr_map++;
93 }
94 } 202 }
95 } 203 }
96 204
@@ -108,77 +216,8 @@ void __init efi_fake_memmap(void)
108 return; 216 return;
109 } 217 }
110 218
111 for (old = efi.memmap.map, new = new_memmap; 219 for (i = 0; i < nr_fake_mem; i++)
112 old < efi.memmap.map_end; 220 efi_fake_memmap_insert(&efi.memmap, new_memmap, &fake_mems[i]);
113 old += efi.memmap.desc_size, new += efi.memmap.desc_size) {
114
115 /* copy original EFI memory descriptor */
116 memcpy(new, old, efi.memmap.desc_size);
117 md = new;
118 start = md->phys_addr;
119 end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1;
120
121 for (i = 0; i < nr_fake_mem; i++) {
122 /* modifying range */
123 m_start = fake_mems[i].range.start;
124 m_end = fake_mems[i].range.end;
125 m_attr = fake_mems[i].attribute;
126
127 if (m_start <= start && end <= m_end)
128 md->attribute |= m_attr;
129
130 if (m_start <= start &&
131 (start < m_end && m_end < end)) {
132 /* first part */
133 md->attribute |= m_attr;
134 md->num_pages = (m_end - md->phys_addr + 1) >>
135 EFI_PAGE_SHIFT;
136 /* latter part */
137 new += efi.memmap.desc_size;
138 memcpy(new, old, efi.memmap.desc_size);
139 md = new;
140 md->phys_addr = m_end + 1;
141 md->num_pages = (end - md->phys_addr + 1) >>
142 EFI_PAGE_SHIFT;
143 }
144
145 if ((start < m_start && m_start < end) && m_end < end) {
146 /* first part */
147 md->num_pages = (m_start - md->phys_addr) >>
148 EFI_PAGE_SHIFT;
149 /* middle part */
150 new += efi.memmap.desc_size;
151 memcpy(new, old, efi.memmap.desc_size);
152 md = new;
153 md->attribute |= m_attr;
154 md->phys_addr = m_start;
155 md->num_pages = (m_end - m_start + 1) >>
156 EFI_PAGE_SHIFT;
157 /* last part */
158 new += efi.memmap.desc_size;
159 memcpy(new, old, efi.memmap.desc_size);
160 md = new;
161 md->phys_addr = m_end + 1;
162 md->num_pages = (end - m_end) >>
163 EFI_PAGE_SHIFT;
164 }
165
166 if ((start < m_start && m_start < end) &&
167 (end <= m_end)) {
168 /* first part */
169 md->num_pages = (m_start - md->phys_addr) >>
170 EFI_PAGE_SHIFT;
171 /* latter part */
172 new += efi.memmap.desc_size;
173 memcpy(new, old, efi.memmap.desc_size);
174 md = new;
175 md->phys_addr = m_start;
176 md->num_pages = (end - md->phys_addr + 1) >>
177 EFI_PAGE_SHIFT;
178 md->attribute |= m_attr;
179 }
180 }
181 }
182 221
183 /* swap into new EFI memmap */ 222 /* swap into new EFI memmap */
184 early_memunmap(new_memmap, efi.memmap.desc_size * new_nr_map); 223 early_memunmap(new_memmap, efi.memmap.desc_size * new_nr_map);