diff options
-rw-r--r-- | big-little/switcher/context/gic.c | 42 |
1 files changed, 28 insertions, 14 deletions
diff --git a/big-little/switcher/context/gic.c b/big-little/switcher/context/gic.c index 5ae13a7..7686feb 100644 --- a/big-little/switcher/context/gic.c +++ b/big-little/switcher/context/gic.c @@ -59,6 +59,24 @@ typedef struct { /* 0x18 */ volatile unsigned const int highest_pending; } cpu_interface; +static void wcpymem2io(void volatile *dest, void const *src, size_t count) +{ + unsigned long volatile *_dest = dest; + unsigned long *_src = src; + + while (count--) + *_dest++ = *_src++; +} + +static void wcpyio2mem(void *dest, void volatile const *src, size_t count) +{ + unsigned long *_src = src; + unsigned long volatile *_dest = dest; + + while (count--) + *_dest++ = *_src++; +} + /* * Saves the GIC CPU interface context * Requires 3 words of memory @@ -87,9 +105,9 @@ int save_gic_distributor_private(unsigned int *pointer, *pointer = id->enable.set[0]; ++pointer; - memcpy((void *)pointer, (const void *)id->priority, 8 << 2); + wcpyio2mem(pointer, id->priority, 8); pointer += 8; - memcpy((void *)pointer, (const void *)id->target, 8 << 2); + wcpyio2mem(pointer, id->target, 8); pointer += 8; /* Save just the PPI configurations (SGIs are not configurable) */ @@ -114,14 +132,14 @@ int save_gic_distributor_private(unsigned int *pointer, * and restoring the set/clear pending registers */ ptr = pointer; - memcpy((void *)pointer, (const void *)id->sgi_set_pending, 4 << 2); + wcpyio2mem(pointer, id->sgi_set_pending, 4); pointer += 8; /* * Clear the pending SGIs on this cpuif so that they don't * interfere with the wfi later on. */ - memcpy((void *)id->sgi_clr_pending, (const void *)ptr, 4 << 2); + wcpymem2io(id->sgi_clr_pending, ptr, 4); if (*pointer) { return -1; @@ -148,8 +166,7 @@ int save_gic_distributor_shared(unsigned int *pointer, /* Save rest of GIC configuration */ if (num_spis) { - memcpy((void *)pointer, (const void *)(id->target + 8), - (num_spis / 4) << 2); + wcpyio2mem(pointer, id->target + 8, num_spis / 4); pointer += num_spis / 4; } @@ -182,9 +199,9 @@ void restore_gic_distributor_private(unsigned int *pointer, id->enable.set[0] = *pointer; ++pointer; - memcpy((void *)id->priority, (const void *)pointer, 8 << 2); + wcpymem2io(id->priority, pointer, 8); pointer += 8; - memcpy((void *)id->target, (const void *)pointer, 8 << 2); + wcpymem2io(id->target, pointer, 8); pointer += 8; /* Restore just the PPI configurations (SGIs are not configurable) */ @@ -214,7 +231,7 @@ void restore_gic_distributor_private(unsigned int *pointer, } } - memcpy((void *)id->sgi_set_pending, (const void *)pointer, 4 << 2); + wcpymem2io(id->sgi_set_pending, pointer, 4); pointer += 4; id->pending.set[0] = *pointer; @@ -242,9 +259,7 @@ void restore_gic_distributor_shared(unsigned int *pointer, /* Restore rest of GIC configuration */ if (num_spis) { - - memcpy((void *)pointer, (const void *)(id->target + 8), - (num_spis / 4) << 2); + wcpyio2mem(pointer, id->target + 8, num_spis / 4); for (ctr = 0; ctr < num_spis / 4; ctr++) { if (!pointer[ctr]) @@ -259,8 +274,7 @@ void restore_gic_distributor_shared(unsigned int *pointer, } } - memcpy((void *)(id->target + 8), (const void *)pointer, - (num_spis / 4) << 2); + wcpymem2io(id->target + 8, pointer, num_spis / 4); } return; |