| 184 | } |
| 185 | |
| 186 | int rt_varea_map_with_msg(rt_varea_t varea, struct rt_aspace_fault_msg *msg) |
| 187 | { |
| 188 | rt_aspace_t aspace; |
| 189 | int err = -RT_ERROR; |
| 190 | if (msg->response.status == MM_FAULT_STATUS_OK) |
| 191 | { |
| 192 | /** |
| 193 | * the page returned by handler is not checked |
| 194 | * cause no much assumption can make on it |
| 195 | */ |
| 196 | char *store = msg->response.vaddr; |
| 197 | rt_size_t store_sz = msg->response.size; |
| 198 | if ((char *)msg->fault_vaddr + store_sz > (char *)varea->start + varea->size) |
| 199 | { |
| 200 | LOG_W("%s: too much (0x%lx) of buffer on vaddr %p is provided", |
| 201 | __func__, store_sz, msg->fault_vaddr); |
| 202 | } |
| 203 | else |
| 204 | { |
| 205 | void *map; |
| 206 | rt_size_t attr; |
| 207 | void *v_addr = msg->fault_vaddr; |
| 208 | void *p_addr = store + PV_OFFSET; |
| 209 | |
| 210 | aspace = varea->aspace; |
| 211 | RT_ASSERT(aspace); |
| 212 | |
| 213 | attr = _get_effect_attr(aspace, varea); |
| 214 | map = rt_hw_mmu_map(aspace, v_addr, p_addr, store_sz, attr); |
| 215 | |
| 216 | if (!map) |
| 217 | { |
| 218 | LOG_W("%s: MMU mapping failed for va %p to %p of %lx", __func__, |
| 219 | msg->fault_vaddr, store + PV_OFFSET, store_sz); |
| 220 | } |
| 221 | else |
| 222 | { |
| 223 | rt_hw_tlb_invalidate_range(varea->aspace, v_addr, store_sz, ARCH_PAGE_SIZE); |
| 224 | err = RT_EOK; |
| 225 | } |
| 226 | } |
| 227 | } |
| 228 | else if (msg->response.status == MM_FAULT_STATUS_OK_MAPPED) |
| 229 | { |
| 230 | if (rt_hw_mmu_v2p(varea->aspace, msg->fault_vaddr) == ARCH_MAP_FAILED) |
| 231 | { |
| 232 | LOG_D("%s: no page is mapped on %p", __func__, msg->fault_vaddr); |
| 233 | } |
| 234 | err = RT_EOK; |
| 235 | } |
| 236 | else |
| 237 | { |
| 238 | LOG_W("%s: failed on va %p inside varea %p(%s)", __func__, msg->fault_vaddr, varea, |
| 239 | varea->mem_obj->get_name ? varea->mem_obj->get_name(varea) : "unknow"); |
| 240 | } |
| 241 | return err; |
| 242 | } |
| 243 |
no test coverage detected