1 // © 2022 Qualcomm Innovation Center, Inc. All rights reserved.
2 //
3 // SPDX-License-Identifier: BSD-3-Clause
4 
5 #include <assert.h>
6 #include <hyptypes.h>
7 
8 #include <addrspace.h>
9 #include <atomic.h>
10 #include <gpt.h>
11 #include <memdb.h>
12 #include <memextent.h>
13 #include <rcu.h>
14 
15 #include <events/vdevice.h>
16 
17 #include "internal.h"
18 
19 vcpu_trap_result_t
vdevice_access_phys(paddr_t pa,size_t size,register_t * val,bool is_write)20 vdevice_access_phys(paddr_t pa, size_t size, register_t *val, bool is_write)
21 {
22 	vcpu_trap_result_t ret;
23 
24 	memdb_obj_type_result_t res = memdb_lookup(pa);
25 	if ((res.e != OK) || (res.r.type != MEMDB_TYPE_EXTENT)) {
26 		ret = VCPU_TRAP_RESULT_UNHANDLED;
27 		goto out;
28 	}
29 
30 	memextent_t *me = (memextent_t *)res.r.object;
31 	assert(me != NULL);
32 	vdevice_t *vdevice = atomic_load_consume(&me->vdevice);
33 	if (vdevice == NULL) {
34 		ret = VCPU_TRAP_RESULT_UNHANDLED;
35 		goto out;
36 	}
37 
38 	size_result_t offset_r = memextent_get_offset_for_pa(me, pa, size);
39 	if (offset_r.e != OK) {
40 		ret = VCPU_TRAP_RESULT_UNHANDLED;
41 		goto out;
42 	}
43 
44 	ret = trigger_vdevice_access_event(vdevice->type, vdevice, offset_r.r,
45 					   size, val, is_write);
46 
47 out:
48 	return ret;
49 }
50 
51 vcpu_trap_result_t
vdevice_access_ipa(vmaddr_t ipa,size_t size,register_t * val,bool is_write)52 vdevice_access_ipa(vmaddr_t ipa, size_t size, register_t *val, bool is_write)
53 {
54 	vcpu_trap_result_t ret;
55 
56 	addrspace_t *addrspace = addrspace_get_self();
57 	assert(addrspace != NULL);
58 
59 	rcu_read_start();
60 
61 	gpt_lookup_result_t lookup_ret =
62 		gpt_lookup(&addrspace->vdevice_gpt, ipa, size);
63 
64 	if (lookup_ret.size != size) {
65 		ret = VCPU_TRAP_RESULT_UNHANDLED;
66 	} else if (lookup_ret.entry.type == GPT_TYPE_VDEVICE) {
67 		vdevice_t *vdevice = lookup_ret.entry.value.vdevice;
68 		assert(vdevice != NULL);
69 		assert((ipa >= vdevice->ipa) &&
70 		       ((ipa + size - 1U) <=
71 			(vdevice->ipa + vdevice->size - 1U)));
72 
73 		ret = trigger_vdevice_access_event(vdevice->type, vdevice,
74 						   ipa - vdevice->ipa, size,
75 						   val, is_write);
76 	} else {
77 		assert(lookup_ret.entry.type == GPT_TYPE_EMPTY);
78 
79 		// FIXME:
80 		ret = trigger_vdevice_access_fixed_addr_event(ipa, size, val,
81 							      is_write);
82 	}
83 
84 	rcu_read_finish();
85 
86 	return ret;
87 }
88