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 | |
02af6beb | 4 | * (C) COPYRIGHT 2012-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_ukk.h" | |
12 | #include "mali_osk.h" | |
13 | #include "mali_kernel_common.h" | |
14 | #include "mali_session.h" | |
15 | #include "mali_kernel_linux.h" | |
6fa3eb70 | 16 | #include "mali_memory.h" |
6fa3eb70 S |
17 | #include "ump_kernel_interface.h" |
18 | ||
02af6beb | 19 | static int mali_mem_ump_map(mali_mem_backend *mem_backend) |
6fa3eb70 S |
20 | { |
21 | ump_dd_handle ump_mem; | |
02af6beb S |
22 | mali_mem_allocation *alloc; |
23 | struct mali_session_data *session; | |
6fa3eb70 S |
24 | u32 nr_blocks; |
25 | u32 i; | |
26 | ump_dd_physical_block *ump_blocks; | |
27 | struct mali_page_directory *pagedir; | |
28 | u32 offset = 0; | |
6fa3eb70 S |
29 | _mali_osk_errcode_t err; |
30 | ||
02af6beb S |
31 | MALI_DEBUG_ASSERT_POINTER(mem_backend); |
32 | MALI_DEBUG_ASSERT(MALI_MEM_UMP == mem_backend->type); | |
33 | ||
34 | alloc = mem_backend->mali_allocation; | |
35 | MALI_DEBUG_ASSERT_POINTER(alloc); | |
36 | ||
37 | session = alloc->session; | |
6fa3eb70 | 38 | MALI_DEBUG_ASSERT_POINTER(session); |
6fa3eb70 | 39 | |
02af6beb | 40 | ump_mem = mem_backend->ump_mem.handle; |
6fa3eb70 S |
41 | MALI_DEBUG_ASSERT(UMP_DD_HANDLE_INVALID != ump_mem); |
42 | ||
43 | nr_blocks = ump_dd_phys_block_count_get(ump_mem); | |
44 | if (nr_blocks == 0) { | |
45 | MALI_DEBUG_PRINT(1, ("No block count\n")); | |
46 | return -EINVAL; | |
47 | } | |
48 | ||
02af6beb | 49 | ump_blocks = _mali_osk_malloc(sizeof(*ump_blocks) * nr_blocks); |
6fa3eb70 S |
50 | if (NULL == ump_blocks) { |
51 | return -ENOMEM; | |
52 | } | |
53 | ||
54 | if (UMP_DD_INVALID == ump_dd_phys_blocks_get(ump_mem, ump_blocks, nr_blocks)) { | |
55 | _mali_osk_free(ump_blocks); | |
56 | return -EFAULT; | |
57 | } | |
58 | ||
59 | pagedir = session->page_directory; | |
6fa3eb70 | 60 | |
02af6beb S |
61 | mali_session_memory_lock(session); |
62 | ||
63 | err = mali_mem_mali_map_prepare(alloc); | |
6fa3eb70 S |
64 | if (_MALI_OSK_ERR_OK != err) { |
65 | MALI_DEBUG_PRINT(1, ("Mapping of UMP memory failed\n")); | |
66 | ||
67 | _mali_osk_free(ump_blocks); | |
02af6beb | 68 | mali_session_memory_unlock(session); |
6fa3eb70 S |
69 | return -ENOMEM; |
70 | } | |
71 | ||
02af6beb S |
72 | for (i = 0; i < nr_blocks; ++i) { |
73 | u32 virt = alloc->mali_vma_node.vm_node.start + offset; | |
6fa3eb70 S |
74 | |
75 | MALI_DEBUG_PRINT(7, ("Mapping in 0x%08x size %d\n", ump_blocks[i].addr , ump_blocks[i].size)); | |
76 | ||
77 | mali_mmu_pagedir_update(pagedir, virt, ump_blocks[i].addr, | |
02af6beb | 78 | ump_blocks[i].size, MALI_MMU_FLAGS_DEFAULT); |
6fa3eb70 S |
79 | |
80 | offset += ump_blocks[i].size; | |
81 | } | |
82 | ||
02af6beb S |
83 | if (alloc->flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE) { |
84 | u32 virt = alloc->mali_vma_node.vm_node.start + offset; | |
6fa3eb70 S |
85 | |
86 | /* Map in an extra virtual guard page at the end of the VMA */ | |
87 | MALI_DEBUG_PRINT(6, ("Mapping in extra guard page\n")); | |
88 | ||
02af6beb | 89 | mali_mmu_pagedir_update(pagedir, virt, ump_blocks[0].addr, _MALI_OSK_MALI_PAGE_SIZE, MALI_MMU_FLAGS_DEFAULT); |
6fa3eb70 S |
90 | |
91 | offset += _MALI_OSK_MALI_PAGE_SIZE; | |
92 | } | |
02af6beb | 93 | mali_session_memory_unlock(session); |
6fa3eb70 | 94 | _mali_osk_free(ump_blocks); |
6fa3eb70 S |
95 | return 0; |
96 | } | |
97 | ||
02af6beb | 98 | static void mali_mem_ump_unmap(mali_mem_allocation *alloc) |
6fa3eb70 | 99 | { |
02af6beb S |
100 | struct mali_session_data *session; |
101 | MALI_DEBUG_ASSERT_POINTER(alloc); | |
102 | session = alloc->session; | |
103 | MALI_DEBUG_ASSERT_POINTER(session); | |
104 | mali_session_memory_lock(session); | |
105 | mali_mem_mali_map_free(session, alloc->psize, alloc->mali_vma_node.vm_node.start, | |
106 | alloc->flags); | |
107 | mali_session_memory_unlock(session); | |
6fa3eb70 S |
108 | } |
109 | ||
02af6beb | 110 | int mali_mem_bind_ump_buf(mali_mem_allocation *alloc, mali_mem_backend *mem_backend, u32 secure_id, u32 flags) |
6fa3eb70 S |
111 | { |
112 | ump_dd_handle ump_mem; | |
02af6beb S |
113 | int ret; |
114 | MALI_DEBUG_ASSERT_POINTER(alloc); | |
115 | MALI_DEBUG_ASSERT_POINTER(mem_backend); | |
116 | MALI_DEBUG_ASSERT(MALI_MEM_UMP == mem_backend->type); | |
6fa3eb70 S |
117 | |
118 | MALI_DEBUG_PRINT(3, | |
02af6beb S |
119 | ("Requested to map ump memory with secure id %d into virtual memory 0x%08X, size 0x%08X\n", |
120 | secure_id, alloc->mali_vma_node.vm_node.start, alloc->mali_vma_node.vm_node.size)); | |
6fa3eb70 | 121 | |
02af6beb | 122 | ump_mem = ump_dd_handle_create_from_secure_id(secure_id); |
6fa3eb70 | 123 | if (UMP_DD_HANDLE_INVALID == ump_mem) MALI_ERROR(_MALI_OSK_ERR_FAULT); |
02af6beb S |
124 | alloc->flags |= MALI_MEM_FLAG_DONT_CPU_MAP; |
125 | if (flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE) { | |
126 | alloc->flags |= MALI_MEM_FLAG_MALI_GUARD_PAGE; | |
6fa3eb70 S |
127 | } |
128 | ||
02af6beb | 129 | mem_backend->ump_mem.handle = ump_mem; |
6fa3eb70 | 130 | |
02af6beb | 131 | ret = mali_mem_ump_map(mem_backend); |
6fa3eb70 | 132 | if (0 != ret) { |
6fa3eb70 | 133 | ump_dd_reference_release(ump_mem); |
02af6beb | 134 | return _MALI_OSK_ERR_FAULT; |
6fa3eb70 | 135 | } |
02af6beb S |
136 | MALI_DEBUG_PRINT(3, ("Returning from UMP bind\n")); |
137 | return _MALI_OSK_ERR_OK; | |
6fa3eb70 S |
138 | } |
139 | ||
02af6beb | 140 | void mali_mem_unbind_ump_buf(mali_mem_backend *mem_backend) |
6fa3eb70 | 141 | { |
02af6beb S |
142 | ump_dd_handle ump_mem; |
143 | mali_mem_allocation *alloc; | |
144 | MALI_DEBUG_ASSERT_POINTER(mem_backend); | |
145 | MALI_DEBUG_ASSERT(MALI_MEM_UMP == mem_backend->type); | |
146 | ump_mem = mem_backend->ump_mem.handle; | |
147 | MALI_DEBUG_ASSERT(UMP_DD_HANDLE_INVALID != ump_mem); | |
6fa3eb70 | 148 | |
02af6beb S |
149 | alloc = mem_backend->mali_allocation; |
150 | MALI_DEBUG_ASSERT_POINTER(alloc); | |
151 | mali_mem_ump_unmap(alloc); | |
152 | ump_dd_reference_release(ump_mem); | |
6fa3eb70 S |
153 | } |
154 |