10 Op_cache_clean_data = 0x00,
11 Op_cache_flush_data = 0x01,
12 Op_cache_inv_data = 0x02,
13 Op_cache_coherent = 0x03,
14 Op_cache_dma_coherent = 0x04,
15 Op_cache_dma_coherent_full = 0x05,
20 Op_mem_read_data = 0x10,
21 Op_mem_write_data = 0x11,
25 // ------------------------------------------------------------------------
29 #include "entry_frame.h"
32 #include "mem_space.h"
34 #include "outer_cache.h"
39 Mem_op::arm_mem_cache_maint(int op, void const *start, void const *end)
41 Context *c = current();
43 c->set_ignore_mem_op_in_progress(true);
47 case Op_cache_clean_data:
48 Mem_unit::clean_dcache(start, end);
51 case Op_cache_flush_data:
52 Mem_unit::flush_dcache(start, end);
55 case Op_cache_inv_data:
56 Mem_unit::inv_dcache(start, end);
59 case Op_cache_coherent:
60 Mem_unit::clean_dcache(start, end);
65 case Op_cache_dma_coherent:
67 Mem_space::Vaddr v = Virt_addr(Address(start));
68 Mem_space::Vaddr e = Virt_addr(Address(end));
70 Mem_unit::flush_dcache(v, e);
73 Mem_space::Size phys_size;
74 Mem_space::Phys_addr phys_addr;
77 if ( c->mem_space()->v_lookup(v, &phys_addr,
79 && (attrs & Mem_space::Page_user_accessible))
81 Outer_cache::flush(Virt_addr(phys_addr).value(),
82 Virt_addr(phys_addr).value()
83 + Virt_size(phys_size).value() - 1,
93 // We might not want to implement this one but single address outer
94 // cache flushing can be really slow
95 case Op_cache_dma_coherent_full:
96 Mem_unit::flush_dcache();
104 c->set_ignore_mem_op_in_progress(false);
108 Mem_op::arm_mem_access(Mword *r)
116 if (!current()->space()->is_user_memory(a, 1 << w))
122 if ((e = setjmp(pf_recovery)) == 0)
124 current()->recover_jmp_buf(&pf_recovery);
128 case Op_mem_read_data:
132 r[3] = *(unsigned char *)a;
135 r[3] = *(unsigned short *)a;
138 r[3] = *(unsigned int *)a;
145 case Op_mem_write_data:
149 *(unsigned char *)a = r[3];
152 *(unsigned short *)a = r[3];
155 *(unsigned int *)a = r[3];
167 WARN("Unresolved memory access, skipping\n");
169 current()->recover_jmp_buf(0);
172 extern "C" void sys_arm_mem_op()
174 Entry_frame *e = current()->regs();
175 if (EXPECT_FALSE(e->r[0] & 0x10))
176 Mem_op::arm_mem_access(e->r);
178 Mem_op::arm_mem_cache_maint(e->r[0], (void *)e->r[1], (void *)e->r[2]);