artiq/soc/runtime/mailbox.c

79 lines
1.5 KiB
C

#include <stdlib.h>
#include <system.h>
#include <spr-defs.h>
#include <hw/common.h>
#include <generated/mem.h>
#include "mailbox.h"
#define KERNELCPU_MAILBOX MMPTR(MAILBOX_BASE)
static unsigned int last_transmission;
static void _flush_cpu_dcache(void)
{
unsigned long dccfgr;
unsigned long cache_set_size;
unsigned long cache_ways;
unsigned long cache_block_size;
unsigned long cache_size;
int i;
dccfgr = mfspr(SPR_DCCFGR);
cache_ways = 1 << (dccfgr & SPR_ICCFGR_NCW);
cache_set_size = 1 << ((dccfgr & SPR_DCCFGR_NCS) >> 3);
cache_block_size = (dccfgr & SPR_DCCFGR_CBS) ? 32 : 16;
cache_size = cache_set_size * cache_ways * cache_block_size;
for (i = 0; i < cache_size; i += cache_block_size)
mtspr(SPR_DCBIR, i);
}
void mailbox_send(void *ptr)
{
last_transmission = (unsigned int)ptr;
KERNELCPU_MAILBOX = last_transmission;
}
int mailbox_acknowledged(void)
{
unsigned int m;
m = KERNELCPU_MAILBOX;
return !m || (m != last_transmission);
}
void mailbox_send_and_wait(void *ptr)
{
mailbox_send(ptr);
while(!mailbox_acknowledged());
}
void *mailbox_receive(void)
{
unsigned int r;
r = KERNELCPU_MAILBOX;
if(r == last_transmission)
return NULL;
else {
if(r) {
_flush_cpu_dcache();
}
return (void *)r;
}
}
void *mailbox_wait_and_receive(void)
{
void *r;
while(!(r = mailbox_receive()));
return r;
}
void mailbox_acknowledge(void)
{
KERNELCPU_MAILBOX = 0;
}