caller.c 1.09 KB
Newer Older
Rahix's avatar
Rahix committed
1
2
3
4
#include <stdlib.h>
#include "sema.h"
#include "api/caller.h"

Rahix's avatar
Rahix committed
5
#define MXC_ASSERT_ENABLE
6
7
#include "mxc_assert.h"

Rahix's avatar
Rahix committed
8
void *_api_call_start(api_id_t id, uintptr_t size)
Rahix's avatar
Rahix committed
9
{
Rahix's avatar
Rahix committed
10
11
	while (SEMA_GetSema(_API_SEMAPHORE) == E_BUSY) {
	}
Rahix's avatar
Rahix committed
12

13
14
15
16
17
18
19
20
21
22
23
24
	if (API_CALL_MEM->call_flag != _API_FLAG_IDLE) {
		/*
		 * The only way this can happen is if a call was issued from an
		 * interrupt hander while another call is still happening.  This
		 * has to be prevented at all cost!
		 */
		mxc_assert(
			"API recalled during ongoing call!",
			__FILE__,
			__LINE__
		);
	}
Rahix's avatar
Rahix committed
25
26
27
28
29

	API_CALL_MEM->id = id;
	return API_CALL_MEM->buffer;
}

Rahix's avatar
Rahix committed
30
void *_api_call_transact(void *buffer)
Rahix's avatar
Rahix committed
31
32
33
34
35
36
37
38
39
40
41
42
{
	API_CALL_MEM->call_flag = _API_FLAG_CALLING;
	SEMA_FreeSema(_API_SEMAPHORE);

	/* Notify the dispather of the new call */
	__SEV();
	__WFE();

	while (1) {
		/* Wait for the dispather to return */
		__WFE();

Rahix's avatar
Rahix committed
43
44
		while (SEMA_GetSema(_API_SEMAPHORE) == E_BUSY) {
		}
Rahix's avatar
Rahix committed
45
46
47
48
49
50
51
52
53
54
55
		if (API_CALL_MEM->call_flag == _API_FLAG_RETURNED) {
			break;
		}
		SEMA_FreeSema(_API_SEMAPHORE);
	}

	API_CALL_MEM->call_flag = _API_FLAG_IDLE;
	SEMA_FreeSema(_API_SEMAPHORE);

	return API_CALL_MEM->buffer;
}