summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--big-little/switcher/context/gic.c42
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;