]> rtime.felk.cvut.cz Git - jailhouse.git/blobdiff - hypervisor/arch/arm/mmio.c
Merge remote-tracking branch 'kiszka/master'
[jailhouse.git] / hypervisor / arch / arm / mmio.c
index 04e4d731b3fe59fe1317d72c47c460f1e5036615..1098e8df57dbbca53ccad00de15ac4c4922652b8 100644 (file)
  */
 
 #include <jailhouse/mmio.h>
+#include <asm/bitops.h>
 #include <asm/irqchip.h>
 #include <asm/processor.h>
 #include <asm/smp.h>
 #include <asm/traps.h>
 
+unsigned int arch_mmio_count_regions(struct cell *cell)
+{
+       return irqchip_mmio_count_regions(cell) + smp_mmio_regions;
+}
+
 /* Taken from the ARM ARM pseudocode for taking a data abort */
 static void arch_inject_dabt(struct trap_context *ctx, unsigned long addr)
 {
@@ -55,45 +61,12 @@ static void arch_inject_dabt(struct trap_context *ctx, unsigned long addr)
        arm_write_sysreg(DFAR, addr);
 }
 
-void arm_mmio_perform_access(struct mmio_access *mmio)
-{
-       void *addr = (void *)mmio->address;
-
-       if (mmio->is_write)
-               switch (mmio->size) {
-               case 1:
-                       mmio_write8(addr, mmio->value);
-                       return;
-               case 2:
-                       mmio_write16(addr, mmio->value);
-                       return;
-               case 4:
-                       mmio_write32(addr, mmio->value);
-                       return;
-               }
-       else
-               switch (mmio->size) {
-               case 1:
-                       mmio->value = mmio_read8(addr);
-                       return;
-               case 2:
-                       mmio->value = mmio_read16(addr);
-                       return;
-               case 4:
-                       mmio->value = mmio_read32(addr);
-                       return;
-               }
-
-       printk("WARNING: Ignoring unsupported MMIO access size %d\n",
-              mmio->size);
-}
-
 int arch_handle_dabt(struct trap_context *ctx)
 {
+       enum mmio_result mmio_result;
        struct mmio_access mmio;
        unsigned long hpfar;
        unsigned long hdfar;
-       int ret         = TRAP_UNHANDLED;
        /* Decode the syndrome fields */
        u32 icc         = ESR_ICC(ctx->esr);
        u32 isv         = icc >> 24;
@@ -137,27 +110,25 @@ int arch_handle_dabt(struct trap_context *ctx)
        mmio.is_write = is_write;
        mmio.size = size;
 
-       ret = irqchip_mmio_access(&mmio);
-       if (ret == TRAP_UNHANDLED)
-               ret = arch_smp_mmio_access(&mmio);
-
-       if (ret == TRAP_HANDLED) {
-               /* Put the read value into the dest register */
-               if (!is_write) {
-                       if (sse)
-                               mmio.value = sign_extend(mmio.value, 8 * size);
-                       access_cell_reg(ctx, srt, &mmio.value, false);
-               }
+       mmio_result = mmio_handle_access(&mmio);
+       if (mmio_result == MMIO_ERROR)
+               return TRAP_FORBIDDEN;
+       if (mmio_result == MMIO_UNHANDLED)
+               goto error_unhandled;
 
-               arch_skip_instruction(ctx);
+       /* Put the read value into the dest register */
+       if (!is_write) {
+               if (sse)
+                       mmio.value = sign_extend(mmio.value, 8 * size);
+               access_cell_reg(ctx, srt, &mmio.value, false);
        }
 
-       if (ret != TRAP_UNHANDLED)
-               return ret;
+       arch_skip_instruction(ctx);
+       return TRAP_HANDLED;
 
 error_unhandled:
        panic_printk("Unhandled data %s at 0x%x(%d)\n",
                (is_write ? "write" : "read"), mmio.address, size);
 
-       return ret;
+       return TRAP_UNHANDLED;
 }