[PATCH 3/6] staging: vc04_services: Convert pointers in shared state to offsets

Michael Zoran mzoran at crowfest.net
Wed Oct 19 01:36:17 PDT 2016


>From 83c2e1776ee3d2595d6d1f4f5d815c62cc7e6552 Mon Sep 17 00:00:00 2001
From: Michael Zoran <mzoran at crowfest.net>
Date: Sun, 16 Oct 2016 08:12:06 -0700
Subject: [PATCH 3/6] staging: vc04_services: Convert pointers in shared
state
 to offsets

The arm processor core and the GPU have a shared data structure.
This structure contains pointers to base linux kernel objects such as
events.  The size of the pointer changes between 32 bit and 64 bit,
so it is necessary to convert these pointers to offsets from the
beginning of the state structure.

Luckly, the GPU does not interpret these pointers/offsets,
but this change is necessary to keep the structure the same since
the GPU code is outside the scope of the linux kernel
and can't be easily changed.

Signed-off-by: Michael Zoran <mzoran at crowfest.net>
---
 .../vc04_services/interface/vchiq_arm/vchiq_core.c | 54 +++++++++++---
--------
 .../vc04_services/interface/vchiq_arm/vchiq_core.h |  3 +-
 2 files changed, 30 insertions(+), 27 deletions(-)

diff --git
a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
index 05954f9..3aa5cc4 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
@@ -406,22 +406,24 @@ vchiq_set_conn_state(VCHIQ_STATE_T *state,
VCHIQ_CONNSTATE_T newstate)
 }
 
 static inline void
-remote_event_create(REMOTE_EVENT_T *event)
+remote_event_create(VCHIQ_STATE_T *state, REMOTE_EVENT_T *event)
 {
 	event->armed = 0;
 	/* Don't clear the 'fired' flag because it may already have
been set
 	** by the other side. */
-	sema_init(event->event, 0);
+	sema_init((struct semaphore *)((char *)state + event->event),
0);
 }
 
 static inline int
-remote_event_wait(REMOTE_EVENT_T *event)
+remote_event_wait(VCHIQ_STATE_T *state, REMOTE_EVENT_T *event)
 {
 	if (!event->fired) {
 		event->armed = 1;
 		dsb(sy);
 		if (!event->fired) {
-			if (down_interruptible(event->event) != 0) {
+			if (down_interruptible(
+					(struct semaphore *)
+					((char *)state + event-
>event)) != 0) {
 				event->armed = 0;
 				return 0;
 			}
@@ -435,26 +437,26 @@ remote_event_wait(REMOTE_EVENT_T *event)
 }
 
 static inline void
-remote_event_signal_local(REMOTE_EVENT_T *event)
+remote_event_signal_local(VCHIQ_STATE_T *state, REMOTE_EVENT_T *event)
 {
 	event->armed = 0;
-	up(event->event);
+	up((struct semaphore *)((char *)state + event->event));
 }
 
 static inline void
-remote_event_poll(REMOTE_EVENT_T *event)
+remote_event_poll(VCHIQ_STATE_T *state, REMOTE_EVENT_T *event)
 {
 	if (event->fired && event->armed)
-		remote_event_signal_local(event);
+		remote_event_signal_local(state, event);
 }
 
 void
 remote_event_pollall(VCHIQ_STATE_T *state)
 {
-	remote_event_poll(&state->local->sync_trigger);
-	remote_event_poll(&state->local->sync_release);
-	remote_event_poll(&state->local->trigger);
-	remote_event_poll(&state->local->recycle);
+	remote_event_poll(state, &state->local->sync_trigger);
+	remote_event_poll(state, &state->local->sync_release);
+	remote_event_poll(state, &state->local->trigger);
+	remote_event_poll(state, &state->local->recycle);
 }
 
 /* Round up message sizes so that any space at the end of a slot is
always big
@@ -535,7 +537,7 @@ request_poll(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T
*service, int poll_type)
 	wmb();
 
 	/* ... and ensure the slot handler runs. */
-	remote_event_signal_local(&state->local->trigger);
+	remote_event_signal_local(state, &state->local->trigger);
 }
 
 /* Called from queue_message, by the slot handler and application
threads,
@@ -976,7 +978,7 @@ queue_message_sync(VCHIQ_STATE_T *state,
VCHIQ_SERVICE_T *service,
 		(mutex_lock_interruptible(&state->sync_mutex) != 0))
 		return VCHIQ_RETRY;
 
-	remote_event_wait(&local->sync_release);
+	remote_event_wait(state, &local->sync_release);
 
 	rmb();
 
@@ -1995,7 +1997,7 @@ slot_handler_func(void *v)
 	while (1) {
 		DEBUG_COUNT(SLOT_HANDLER_COUNT);
 		DEBUG_TRACE(SLOT_HANDLER_LINE);
-		remote_event_wait(&local->trigger);
+		remote_event_wait(state, &local->trigger);
 
 		rmb();
 
@@ -2084,7 +2086,7 @@ recycle_func(void *v)
 	VCHIQ_SHARED_STATE_T *local = state->local;
 
 	while (1) {
-		remote_event_wait(&local->recycle);
+		remote_event_wait(state, &local->recycle);
 
 		process_free_queue(state);
 	}
@@ -2107,7 +2109,7 @@ sync_func(void *v)
 		int type;
 		unsigned int localport, remoteport;
 
-		remote_event_wait(&local->sync_trigger);
+		remote_event_wait(state, &local->sync_trigger);
 
 		rmb();
 
@@ -2406,24 +2408,24 @@ vchiq_init_state(VCHIQ_STATE_T *state,
VCHIQ_SLOT_ZERO_T *slot_zero,
 	state->data_use_count = 0;
 	state->data_quota = state->slot_queue_available - 1;
 
-	local->trigger.event = &state->trigger_event;
-	remote_event_create(&local->trigger);
+	local->trigger.event = offsetof(VCHIQ_STATE_T, trigger_event);
+	remote_event_create(state, &local->trigger);
 	local->tx_pos = 0;
 
-	local->recycle.event = &state->recycle_event;
-	remote_event_create(&local->recycle);
+	local->recycle.event = offsetof(VCHIQ_STATE_T, recycle_event);
+	remote_event_create(state, &local->recycle);
 	local->slot_queue_recycle = state->slot_queue_available;
 
-	local->sync_trigger.event = &state->sync_trigger_event;
-	remote_event_create(&local->sync_trigger);
+	local->sync_trigger.event = offsetof(VCHIQ_STATE_T,
sync_trigger_event);
+	remote_event_create(state, &local->sync_trigger);
 
-	local->sync_release.event = &state->sync_release_event;
-	remote_event_create(&local->sync_release);
+	local->sync_release.event = offsetof(VCHIQ_STATE_T,
sync_release_event);
+	remote_event_create(state, &local->sync_release);
 
 	/* At start-of-day, the slot is empty and available */
 	((VCHIQ_HEADER_T *)SLOT_DATA_FROM_INDEX(state, local-
>slot_sync))->msgid
 		= VCHIQ_MSGID_PADDING;
-	remote_event_signal_local(&local->sync_release);
+	remote_event_signal_local(state, &local->sync_release);
 
 	local->debug[DEBUG_ENTRIES] = DEBUG_MAX;
 
diff --git
a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h
b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h
index 9013bdb..1c2b1b5 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h
@@ -264,7 +264,8 @@ typedef struct vchiq_bulk_queue_struct {
 typedef struct remote_event_struct {
 	int armed;
 	int fired;
-	struct semaphore *event;
+	/* Contains offset from the beginning of the VCHIQ_STATE_T
structure */
+	u32 event;
 } REMOTE_EVENT_T;
 
 typedef struct opaque_platform_state_t *VCHIQ_PLATFORM_STATE_T;
-- 
2.9.3



More information about the linux-rpi-kernel mailing list