Commit | Line | Data |
---|---|---|
6fa3eb70 S |
1 | /* |
2 | * This confidential and proprietary software may be used only as | |
3 | * authorised by a licensing agreement from ARM Limited | |
bdc132d7 | 4 | * (C) COPYRIGHT 2011-2015 ARM Limited |
6fa3eb70 S |
5 | * ALL RIGHTS RESERVED |
6 | * The entire notice above must be reproduced on all authorised | |
7 | * copies and copies may only be made to the extent permitted | |
8 | * by a licensing agreement from ARM Limited. | |
9 | */ | |
10 | ||
11 | #include "mali_kernel_common.h" | |
12 | #include "mali_osk.h" | |
bdc132d7 | 13 | #include "mali_ukk.h" |
6fa3eb70 S |
14 | #include "mali_uk_types.h" |
15 | #include "mali_mmu_page_directory.h" | |
16 | #include "mali_memory.h" | |
17 | #include "mali_l2_cache.h" | |
18 | ||
19 | static _mali_osk_errcode_t fill_page(mali_io_address mapping, u32 data); | |
20 | ||
21 | u32 mali_allocate_empty_page(mali_io_address *virt_addr) | |
22 | { | |
23 | _mali_osk_errcode_t err; | |
24 | mali_io_address mapping; | |
bdc132d7 | 25 | mali_dma_addr address; |
6fa3eb70 | 26 | |
bdc132d7 | 27 | if (_MALI_OSK_ERR_OK != mali_mmu_get_table_page(&address, &mapping)) { |
6fa3eb70 S |
28 | /* Allocation failed */ |
29 | MALI_DEBUG_PRINT(2, ("Mali MMU: Failed to get table page for empty pgdir\n")); | |
30 | return 0; | |
31 | } | |
32 | ||
bdc132d7 | 33 | MALI_DEBUG_ASSERT_POINTER(mapping); |
6fa3eb70 S |
34 | |
35 | err = fill_page(mapping, 0); | |
36 | if (_MALI_OSK_ERR_OK != err) { | |
37 | mali_mmu_release_table_page(address, mapping); | |
38 | MALI_DEBUG_PRINT(2, ("Mali MMU: Failed to zero page\n")); | |
39 | return 0; | |
40 | } | |
41 | ||
42 | *virt_addr = mapping; | |
43 | return address; | |
44 | } | |
45 | ||
bdc132d7 | 46 | void mali_free_empty_page(mali_dma_addr address, mali_io_address virt_addr) |
6fa3eb70 S |
47 | { |
48 | if (MALI_INVALID_PAGE != address) { | |
49 | mali_mmu_release_table_page(address, virt_addr); | |
50 | } | |
51 | } | |
52 | ||
bdc132d7 S |
53 | _mali_osk_errcode_t mali_create_fault_flush_pages(mali_dma_addr *page_directory, |
54 | mali_io_address *page_directory_mapping, | |
55 | mali_dma_addr *page_table, mali_io_address *page_table_mapping, | |
56 | mali_dma_addr *data_page, mali_io_address *data_page_mapping) | |
6fa3eb70 S |
57 | { |
58 | _mali_osk_errcode_t err; | |
59 | ||
60 | err = mali_mmu_get_table_page(data_page, data_page_mapping); | |
61 | if (_MALI_OSK_ERR_OK == err) { | |
62 | err = mali_mmu_get_table_page(page_table, page_table_mapping); | |
63 | if (_MALI_OSK_ERR_OK == err) { | |
64 | err = mali_mmu_get_table_page(page_directory, page_directory_mapping); | |
65 | if (_MALI_OSK_ERR_OK == err) { | |
66 | fill_page(*data_page_mapping, 0); | |
67 | fill_page(*page_table_mapping, *data_page | MALI_MMU_FLAGS_DEFAULT); | |
68 | fill_page(*page_directory_mapping, *page_table | MALI_MMU_FLAGS_PRESENT); | |
69 | MALI_SUCCESS; | |
70 | } | |
71 | mali_mmu_release_table_page(*page_table, *page_table_mapping); | |
72 | *page_table = MALI_INVALID_PAGE; | |
73 | } | |
74 | mali_mmu_release_table_page(*data_page, *data_page_mapping); | |
75 | *data_page = MALI_INVALID_PAGE; | |
76 | } | |
77 | return err; | |
78 | } | |
79 | ||
bdc132d7 S |
80 | void mali_destroy_fault_flush_pages( |
81 | mali_dma_addr *page_directory, mali_io_address *page_directory_mapping, | |
82 | mali_dma_addr *page_table, mali_io_address *page_table_mapping, | |
83 | mali_dma_addr *data_page, mali_io_address *data_page_mapping) | |
6fa3eb70 S |
84 | { |
85 | if (MALI_INVALID_PAGE != *page_directory) { | |
86 | mali_mmu_release_table_page(*page_directory, *page_directory_mapping); | |
87 | *page_directory = MALI_INVALID_PAGE; | |
88 | *page_directory_mapping = NULL; | |
89 | } | |
90 | ||
91 | if (MALI_INVALID_PAGE != *page_table) { | |
92 | mali_mmu_release_table_page(*page_table, *page_table_mapping); | |
93 | *page_table = MALI_INVALID_PAGE; | |
94 | *page_table_mapping = NULL; | |
95 | } | |
96 | ||
97 | if (MALI_INVALID_PAGE != *data_page) { | |
98 | mali_mmu_release_table_page(*data_page, *data_page_mapping); | |
99 | *data_page = MALI_INVALID_PAGE; | |
100 | *data_page_mapping = NULL; | |
101 | } | |
102 | } | |
103 | ||
104 | static _mali_osk_errcode_t fill_page(mali_io_address mapping, u32 data) | |
105 | { | |
106 | int i; | |
bdc132d7 | 107 | MALI_DEBUG_ASSERT_POINTER(mapping); |
6fa3eb70 | 108 | |
bdc132d7 S |
109 | for (i = 0; i < MALI_MMU_PAGE_SIZE / 4; i++) { |
110 | _mali_osk_mem_iowrite32_relaxed(mapping, i * sizeof(u32), data); | |
6fa3eb70 S |
111 | } |
112 | _mali_osk_mem_barrier(); | |
113 | MALI_SUCCESS; | |
114 | } | |
115 | ||
116 | _mali_osk_errcode_t mali_mmu_pagedir_map(struct mali_page_directory *pagedir, u32 mali_address, u32 size) | |
117 | { | |
118 | const int first_pde = MALI_MMU_PDE_ENTRY(mali_address); | |
119 | const int last_pde = MALI_MMU_PDE_ENTRY(mali_address + size - 1); | |
120 | _mali_osk_errcode_t err; | |
121 | mali_io_address pde_mapping; | |
bdc132d7 | 122 | mali_dma_addr pde_phys; |
6fa3eb70 S |
123 | int i; |
124 | ||
bdc132d7 S |
125 | if (last_pde < first_pde) |
126 | return _MALI_OSK_ERR_INVALID_ARGS; | |
6fa3eb70 | 127 | |
bdc132d7 S |
128 | for (i = first_pde; i <= last_pde; i++) { |
129 | if (0 == (_mali_osk_mem_ioread32(pagedir->page_directory_mapped, | |
130 | i * sizeof(u32)) & MALI_MMU_FLAGS_PRESENT)) { | |
6fa3eb70 S |
131 | /* Page table not present */ |
132 | MALI_DEBUG_ASSERT(0 == pagedir->page_entries_usage_count[i]); | |
133 | MALI_DEBUG_ASSERT(NULL == pagedir->page_entries_mapped[i]); | |
134 | ||
135 | err = mali_mmu_get_table_page(&pde_phys, &pde_mapping); | |
bdc132d7 | 136 | if (_MALI_OSK_ERR_OK != err) { |
6fa3eb70 S |
137 | MALI_PRINT_ERROR(("Failed to allocate page table page.\n")); |
138 | return err; | |
139 | } | |
140 | pagedir->page_entries_mapped[i] = pde_mapping; | |
141 | ||
142 | /* Update PDE, mark as present */ | |
bdc132d7 S |
143 | _mali_osk_mem_iowrite32_relaxed(pagedir->page_directory_mapped, i * sizeof(u32), |
144 | pde_phys | MALI_MMU_FLAGS_PRESENT); | |
6fa3eb70 S |
145 | |
146 | MALI_DEBUG_ASSERT(0 == pagedir->page_entries_usage_count[i]); | |
147 | pagedir->page_entries_usage_count[i] = 1; | |
148 | } else { | |
149 | pagedir->page_entries_usage_count[i]++; | |
150 | } | |
151 | } | |
152 | _mali_osk_write_mem_barrier(); | |
153 | ||
bdc132d7 | 154 | return _MALI_OSK_ERR_OK; |
6fa3eb70 S |
155 | } |
156 | ||
157 | MALI_STATIC_INLINE void mali_mmu_zero_pte(mali_io_address page_table, u32 mali_address, u32 size) | |
158 | { | |
159 | int i; | |
160 | const int first_pte = MALI_MMU_PTE_ENTRY(mali_address); | |
161 | const int last_pte = MALI_MMU_PTE_ENTRY(mali_address + size - 1); | |
162 | ||
163 | for (i = first_pte; i <= last_pte; i++) { | |
164 | _mali_osk_mem_iowrite32_relaxed(page_table, i * sizeof(u32), 0); | |
165 | } | |
166 | } | |
167 | ||
bdc132d7 S |
168 | static u32 mali_page_directory_get_phys_address(struct mali_page_directory *pagedir, u32 index) |
169 | { | |
170 | return (_mali_osk_mem_ioread32(pagedir->page_directory_mapped, | |
171 | index * sizeof(u32)) & ~MALI_MMU_FLAGS_MASK); | |
172 | } | |
173 | ||
174 | ||
6fa3eb70 S |
175 | _mali_osk_errcode_t mali_mmu_pagedir_unmap(struct mali_page_directory *pagedir, u32 mali_address, u32 size) |
176 | { | |
177 | const int first_pde = MALI_MMU_PDE_ENTRY(mali_address); | |
178 | const int last_pde = MALI_MMU_PDE_ENTRY(mali_address + size - 1); | |
179 | u32 left = size; | |
180 | int i; | |
181 | mali_bool pd_changed = MALI_FALSE; | |
182 | u32 pages_to_invalidate[3]; /* hard-coded to 3: max two pages from the PT level plus max one page from PD level */ | |
183 | u32 num_pages_inv = 0; | |
184 | mali_bool invalidate_all = MALI_FALSE; /* safety mechanism in case page_entries_usage_count is unreliable */ | |
185 | ||
186 | /* For all page directory entries in range. */ | |
187 | for (i = first_pde; i <= last_pde; i++) { | |
188 | u32 size_in_pde, offset; | |
189 | ||
190 | MALI_DEBUG_ASSERT_POINTER(pagedir->page_entries_mapped[i]); | |
191 | MALI_DEBUG_ASSERT(0 != pagedir->page_entries_usage_count[i]); | |
192 | ||
193 | /* Offset into page table, 0 if mali_address is 4MiB aligned */ | |
194 | offset = (mali_address & (MALI_MMU_VIRTUAL_PAGE_SIZE - 1)); | |
195 | if (left < MALI_MMU_VIRTUAL_PAGE_SIZE - offset) { | |
196 | size_in_pde = left; | |
197 | } else { | |
198 | size_in_pde = MALI_MMU_VIRTUAL_PAGE_SIZE - offset; | |
199 | } | |
200 | ||
201 | pagedir->page_entries_usage_count[i]--; | |
202 | ||
203 | /* If entire page table is unused, free it */ | |
204 | if (0 == pagedir->page_entries_usage_count[i]) { | |
205 | u32 page_phys; | |
206 | void *page_virt; | |
207 | MALI_DEBUG_PRINT(4, ("Releasing page table as this is the last reference\n")); | |
208 | /* last reference removed, no need to zero out each PTE */ | |
209 | ||
bdc132d7 | 210 | page_phys = MALI_MMU_ENTRY_ADDRESS(_mali_osk_mem_ioread32(pagedir->page_directory_mapped, i * sizeof(u32))); |
6fa3eb70 S |
211 | page_virt = pagedir->page_entries_mapped[i]; |
212 | pagedir->page_entries_mapped[i] = NULL; | |
bdc132d7 | 213 | _mali_osk_mem_iowrite32_relaxed(pagedir->page_directory_mapped, i * sizeof(u32), 0); |
6fa3eb70 S |
214 | |
215 | mali_mmu_release_table_page(page_phys, page_virt); | |
216 | pd_changed = MALI_TRUE; | |
217 | } else { | |
218 | MALI_DEBUG_ASSERT(num_pages_inv < 2); | |
219 | if (num_pages_inv < 2) { | |
220 | pages_to_invalidate[num_pages_inv] = mali_page_directory_get_phys_address(pagedir, i); | |
221 | num_pages_inv++; | |
222 | } else { | |
223 | invalidate_all = MALI_TRUE; | |
224 | } | |
225 | ||
226 | /* If part of the page table is still in use, zero the relevant PTEs */ | |
227 | mali_mmu_zero_pte(pagedir->page_entries_mapped[i], mali_address, size_in_pde); | |
228 | } | |
229 | ||
230 | left -= size_in_pde; | |
231 | mali_address += size_in_pde; | |
232 | } | |
233 | _mali_osk_write_mem_barrier(); | |
234 | ||
235 | /* L2 pages invalidation */ | |
236 | if (MALI_TRUE == pd_changed) { | |
237 | MALI_DEBUG_ASSERT(num_pages_inv < 3); | |
238 | if (num_pages_inv < 3) { | |
239 | pages_to_invalidate[num_pages_inv] = pagedir->page_directory; | |
240 | num_pages_inv++; | |
241 | } else { | |
242 | invalidate_all = MALI_TRUE; | |
243 | } | |
244 | } | |
245 | ||
246 | if (invalidate_all) { | |
247 | mali_l2_cache_invalidate_all(); | |
248 | } else { | |
249 | mali_l2_cache_invalidate_all_pages(pages_to_invalidate, num_pages_inv); | |
250 | } | |
251 | ||
252 | MALI_SUCCESS; | |
253 | } | |
254 | ||
255 | struct mali_page_directory *mali_mmu_pagedir_alloc(void) | |
256 | { | |
257 | struct mali_page_directory *pagedir; | |
bdc132d7 S |
258 | _mali_osk_errcode_t err; |
259 | mali_dma_addr phys; | |
6fa3eb70 S |
260 | |
261 | pagedir = _mali_osk_calloc(1, sizeof(struct mali_page_directory)); | |
bdc132d7 | 262 | if (NULL == pagedir) { |
6fa3eb70 S |
263 | return NULL; |
264 | } | |
265 | ||
bdc132d7 S |
266 | err = mali_mmu_get_table_page(&phys, &pagedir->page_directory_mapped); |
267 | if (_MALI_OSK_ERR_OK != err) { | |
6fa3eb70 S |
268 | _mali_osk_free(pagedir); |
269 | return NULL; | |
270 | } | |
271 | ||
bdc132d7 S |
272 | pagedir->page_directory = (u32)phys; |
273 | ||
6fa3eb70 S |
274 | /* Zero page directory */ |
275 | fill_page(pagedir->page_directory_mapped, 0); | |
276 | ||
277 | return pagedir; | |
278 | } | |
279 | ||
280 | void mali_mmu_pagedir_free(struct mali_page_directory *pagedir) | |
281 | { | |
282 | const int num_page_table_entries = sizeof(pagedir->page_entries_mapped) / sizeof(pagedir->page_entries_mapped[0]); | |
283 | int i; | |
284 | ||
285 | /* Free referenced page tables and zero PDEs. */ | |
286 | for (i = 0; i < num_page_table_entries; i++) { | |
bdc132d7 S |
287 | if (pagedir->page_directory_mapped && (_mali_osk_mem_ioread32( |
288 | pagedir->page_directory_mapped, | |
289 | sizeof(u32)*i) & MALI_MMU_FLAGS_PRESENT)) { | |
290 | mali_dma_addr phys = _mali_osk_mem_ioread32(pagedir->page_directory_mapped, | |
291 | i * sizeof(u32)) & ~MALI_MMU_FLAGS_MASK; | |
6fa3eb70 S |
292 | _mali_osk_mem_iowrite32_relaxed(pagedir->page_directory_mapped, i * sizeof(u32), 0); |
293 | mali_mmu_release_table_page(phys, pagedir->page_entries_mapped[i]); | |
294 | } | |
295 | } | |
296 | _mali_osk_write_mem_barrier(); | |
297 | ||
298 | /* Free the page directory page. */ | |
299 | mali_mmu_release_table_page(pagedir->page_directory, pagedir->page_directory_mapped); | |
300 | ||
301 | _mali_osk_free(pagedir); | |
302 | } | |
303 | ||
304 | ||
bdc132d7 S |
305 | void mali_mmu_pagedir_update(struct mali_page_directory *pagedir, u32 mali_address, |
306 | mali_dma_addr phys_address, u32 size, u32 permission_bits) | |
6fa3eb70 S |
307 | { |
308 | u32 end_address = mali_address + size; | |
bdc132d7 | 309 | u32 mali_phys = (u32)phys_address; |
6fa3eb70 S |
310 | |
311 | /* Map physical pages into MMU page tables */ | |
bdc132d7 | 312 | for (; mali_address < end_address; mali_address += MALI_MMU_PAGE_SIZE, mali_phys += MALI_MMU_PAGE_SIZE) { |
6fa3eb70 S |
313 | MALI_DEBUG_ASSERT_POINTER(pagedir->page_entries_mapped[MALI_MMU_PDE_ENTRY(mali_address)]); |
314 | _mali_osk_mem_iowrite32_relaxed(pagedir->page_entries_mapped[MALI_MMU_PDE_ENTRY(mali_address)], | |
bdc132d7 S |
315 | MALI_MMU_PTE_ENTRY(mali_address) * sizeof(u32), |
316 | mali_phys | permission_bits); | |
6fa3eb70 S |
317 | } |
318 | } | |
319 | ||
bdc132d7 | 320 | void mali_mmu_pagedir_diag(struct mali_page_directory *pagedir, u32 fault_addr) |
6fa3eb70 | 321 | { |
bdc132d7 S |
322 | #if defined(DEBUG) |
323 | u32 pde_index, pte_index; | |
324 | u32 pde, pte; | |
325 | ||
326 | pde_index = MALI_MMU_PDE_ENTRY(fault_addr); | |
327 | pte_index = MALI_MMU_PTE_ENTRY(fault_addr); | |
328 | ||
329 | ||
330 | pde = _mali_osk_mem_ioread32(pagedir->page_directory_mapped, | |
331 | pde_index * sizeof(u32)); | |
332 | ||
333 | ||
334 | if (pde & MALI_MMU_FLAGS_PRESENT) { | |
335 | u32 pte_addr = MALI_MMU_ENTRY_ADDRESS(pde); | |
336 | ||
337 | pte = _mali_osk_mem_ioread32(pagedir->page_entries_mapped[pde_index], | |
338 | pte_index * sizeof(u32)); | |
339 | ||
340 | MALI_DEBUG_PRINT(2, ("\tMMU: %08x: Page table present: %08x\n" | |
341 | "\t\tPTE: %08x, page %08x is %s\n", | |
342 | fault_addr, pte_addr, pte, | |
343 | MALI_MMU_ENTRY_ADDRESS(pte), | |
344 | pte & MALI_MMU_FLAGS_DEFAULT ? "rw" : "not present")); | |
345 | } else { | |
346 | MALI_DEBUG_PRINT(2, ("\tMMU: %08x: Page table not present: %08x\n", | |
347 | fault_addr, pde)); | |
348 | } | |
349 | #else | |
350 | MALI_IGNORE(pagedir); | |
351 | MALI_IGNORE(fault_addr); | |
352 | #endif | |
6fa3eb70 S |
353 | } |
354 | ||
355 | /* For instrumented */ | |
356 | struct dump_info { | |
357 | u32 buffer_left; | |
358 | u32 register_writes_size; | |
359 | u32 page_table_dump_size; | |
360 | u32 *buffer; | |
361 | }; | |
362 | ||
363 | static _mali_osk_errcode_t writereg(u32 where, u32 what, const char *comment, struct dump_info *info) | |
364 | { | |
365 | if (NULL != info) { | |
bdc132d7 | 366 | info->register_writes_size += sizeof(u32) * 2; /* two 32-bit words */ |
6fa3eb70 S |
367 | |
368 | if (NULL != info->buffer) { | |
369 | /* check that we have enough space */ | |
bdc132d7 | 370 | if (info->buffer_left < sizeof(u32) * 2) MALI_ERROR(_MALI_OSK_ERR_NOMEM); |
6fa3eb70 S |
371 | |
372 | *info->buffer = where; | |
373 | info->buffer++; | |
374 | ||
375 | *info->buffer = what; | |
376 | info->buffer++; | |
377 | ||
bdc132d7 | 378 | info->buffer_left -= sizeof(u32) * 2; |
6fa3eb70 S |
379 | } |
380 | } | |
381 | ||
382 | MALI_SUCCESS; | |
383 | } | |
384 | ||
bdc132d7 | 385 | static _mali_osk_errcode_t mali_mmu_dump_page(mali_io_address page, u32 phys_addr, struct dump_info *info) |
6fa3eb70 S |
386 | { |
387 | if (NULL != info) { | |
388 | /* 4096 for the page and 4 bytes for the address */ | |
389 | const u32 page_size_in_elements = MALI_MMU_PAGE_SIZE / 4; | |
390 | const u32 page_size_in_bytes = MALI_MMU_PAGE_SIZE; | |
391 | const u32 dump_size_in_bytes = MALI_MMU_PAGE_SIZE + 4; | |
392 | ||
393 | info->page_table_dump_size += dump_size_in_bytes; | |
394 | ||
395 | if (NULL != info->buffer) { | |
396 | if (info->buffer_left < dump_size_in_bytes) MALI_ERROR(_MALI_OSK_ERR_NOMEM); | |
397 | ||
398 | *info->buffer = phys_addr; | |
399 | info->buffer++; | |
400 | ||
401 | _mali_osk_memcpy(info->buffer, page, page_size_in_bytes); | |
402 | info->buffer += page_size_in_elements; | |
403 | ||
404 | info->buffer_left -= dump_size_in_bytes; | |
405 | } | |
406 | } | |
407 | ||
408 | MALI_SUCCESS; | |
409 | } | |
410 | ||
bdc132d7 | 411 | static _mali_osk_errcode_t dump_mmu_page_table(struct mali_page_directory *pagedir, struct dump_info *info) |
6fa3eb70 S |
412 | { |
413 | MALI_DEBUG_ASSERT_POINTER(pagedir); | |
414 | MALI_DEBUG_ASSERT_POINTER(info); | |
415 | ||
416 | if (NULL != pagedir->page_directory_mapped) { | |
417 | int i; | |
418 | ||
419 | MALI_CHECK_NO_ERROR( | |
bdc132d7 | 420 | mali_mmu_dump_page(pagedir->page_directory_mapped, pagedir->page_directory, info) |
6fa3eb70 S |
421 | ); |
422 | ||
423 | for (i = 0; i < 1024; i++) { | |
424 | if (NULL != pagedir->page_entries_mapped[i]) { | |
425 | MALI_CHECK_NO_ERROR( | |
bdc132d7 S |
426 | mali_mmu_dump_page(pagedir->page_entries_mapped[i], |
427 | _mali_osk_mem_ioread32(pagedir->page_directory_mapped, | |
428 | i * sizeof(u32)) & ~MALI_MMU_FLAGS_MASK, info) | |
6fa3eb70 S |
429 | ); |
430 | } | |
431 | } | |
432 | } | |
433 | ||
434 | MALI_SUCCESS; | |
435 | } | |
436 | ||
bdc132d7 | 437 | static _mali_osk_errcode_t dump_mmu_registers(struct mali_page_directory *pagedir, struct dump_info *info) |
6fa3eb70 S |
438 | { |
439 | MALI_CHECK_NO_ERROR(writereg(0x00000000, pagedir->page_directory, | |
bdc132d7 | 440 | "set the page directory address", info)); |
6fa3eb70 S |
441 | MALI_CHECK_NO_ERROR(writereg(0x00000008, 4, "zap???", info)); |
442 | MALI_CHECK_NO_ERROR(writereg(0x00000008, 0, "enable paging", info)); | |
443 | MALI_SUCCESS; | |
444 | } | |
445 | ||
bdc132d7 | 446 | _mali_osk_errcode_t _mali_ukk_query_mmu_page_table_dump_size(_mali_uk_query_mmu_page_table_dump_size_s *args) |
6fa3eb70 S |
447 | { |
448 | struct dump_info info = { 0, 0, 0, NULL }; | |
bdc132d7 | 449 | struct mali_session_data *session_data; |
6fa3eb70 | 450 | |
bdc132d7 S |
451 | session_data = (struct mali_session_data *)(uintptr_t)(args->ctx); |
452 | MALI_DEBUG_ASSERT_POINTER(session_data); | |
6fa3eb70 | 453 | MALI_DEBUG_ASSERT_POINTER(args); |
6fa3eb70 S |
454 | |
455 | MALI_CHECK_NO_ERROR(dump_mmu_registers(session_data->page_directory, &info)); | |
456 | MALI_CHECK_NO_ERROR(dump_mmu_page_table(session_data->page_directory, &info)); | |
457 | args->size = info.register_writes_size + info.page_table_dump_size; | |
458 | MALI_SUCCESS; | |
459 | } | |
460 | ||
bdc132d7 | 461 | _mali_osk_errcode_t _mali_ukk_dump_mmu_page_table(_mali_uk_dump_mmu_page_table_s *args) |
6fa3eb70 S |
462 | { |
463 | struct dump_info info = { 0, 0, 0, NULL }; | |
bdc132d7 | 464 | struct mali_session_data *session_data; |
6fa3eb70 S |
465 | |
466 | MALI_DEBUG_ASSERT_POINTER(args); | |
6fa3eb70 | 467 | |
bdc132d7 S |
468 | session_data = (struct mali_session_data *)(uintptr_t)(args->ctx); |
469 | MALI_DEBUG_ASSERT_POINTER(session_data); | |
6fa3eb70 S |
470 | |
471 | info.buffer_left = args->size; | |
bdc132d7 | 472 | info.buffer = (u32 *)(uintptr_t)args->buffer; |
6fa3eb70 | 473 | |
bdc132d7 | 474 | args->register_writes = (uintptr_t)info.buffer; |
6fa3eb70 S |
475 | MALI_CHECK_NO_ERROR(dump_mmu_registers(session_data->page_directory, &info)); |
476 | ||
bdc132d7 | 477 | args->page_table_dump = (uintptr_t)info.buffer; |
6fa3eb70 S |
478 | MALI_CHECK_NO_ERROR(dump_mmu_page_table(session_data->page_directory, &info)); |
479 | ||
480 | args->register_writes_size = info.register_writes_size; | |
481 | args->page_table_dump_size = info.page_table_dump_size; | |
482 | ||
483 | MALI_SUCCESS; | |
484 | } |