[MAJOR] Full functionality of mailbox driver

This commit is contained in:
Korobov Nikita
2017-07-08 19:31:09 +03:00
parent ef69c49d79
commit 88661079be
9 changed files with 125 additions and 18 deletions

View File

@@ -11,6 +11,7 @@
./etc/system.conf.d/gpio minix-base
./etc/system.conf.d/i2c minix-base
./etc/system.conf.d/lan8710a minix-base
./etc/system.conf.d/mailbox minix-base
./etc/system.conf.d/sht21 minix-base
./etc/system.conf.d/tsl2550 minix-base
./etc/system.conf.d/usbd minix-base
@@ -20,7 +21,7 @@
./service/gpio minix-base
./service/i2c minix-base
./service/lan8710a minix-base
./service/mailbox minix-base
./service/mailbox minix-base
./service/omap_emmc minix-base
./service/omap_mmc minix-base
./service/rpi_mmc minix-base

View File

@@ -550,3 +550,14 @@ service omap_emmc
28 # MMCSD1INT
;
};
service mailbox
{
system
PRIVCTL # 4
IRQCTL # 19
;
irq
33
;
};

View File

@@ -220,6 +220,9 @@ do
des="keyboard input $n"
dev=kbd$n
;;
15,0)
dev=mailbox
;;
64,64)
des="mouse input multiplexer"
dev=mousemux

View File

@@ -26,6 +26,7 @@ RAMDISK_DEVICES="
c1d4 c1d4p0 c1d4p0s0 c1d5 c1d5p0 c1d5p0s0
c1d6 c1d6p0 c1d6p0s0 c1d7 c1d7p0 c1d7p0s0
fd0 fd1 fd0p0 fd1p0
mailbox
pci
ttyc1 ttyc2 ttyc3 tty00 tty01 tty02 tty03
"
@@ -354,6 +355,9 @@ do
# Logging device.
makedev ${dev} c 15 0 ${uname} ${gname} ${permissions}
;;
mailbox)
makedev ${dev} c 16 0 ${uname} ${gname} ${permissions}
;;
pc[0-3]|at[0-3]|qd[0-3]|ps[0-3]|pat[0-3]|qh[0-3]|PS[0-3])
# Obsolete density locked floppy disk drive n.
drive=`expr ${dev} : '.*\\(.\\)'`

View File

@@ -2,9 +2,8 @@
PROG= mailbox
SRCS= mbox.c main.c
FILES=${PROG}.conf
FILESNAME=${PROG}
FILESDIR= /service
FILESDIR= /etc/system.conf.d
DPADD+= ${LIBCHARDRIVER} ${LIBSYS}
LDADD+= -lchardriver -lsys

View File

@@ -1,11 +0,0 @@
service gpio
{
system
PRIVCTL # 4
IRQCTL # 19
;
irq
33
;
};

View File

@@ -1,12 +1,17 @@
#include <minix/drivers.h>
#include <minix/chardriver.h>
#include <minix/type.h>
#include <minix/log.h>
#include "mbox.h"
#define NR_DEVS 1 /* number of minor devices */
#define MAILBOX_DEV 0 /* minor device for /dev/mailbox */
#define SANE_TIMEOUT 500000 /* 500 ms */
#define MBOX_IRQ 33
/* SEF functions and variables. */
static void sef_local_startup(void);
static int sef_cb_init_fresh(int type, sef_init_info_t *info);
@@ -26,6 +31,12 @@ static struct chardriver m_dtab = {
.cdr_select = m_select, /* select hook */
};
static struct log log = {
.name = "mailbox",
.log_level = LEVEL_INFO,
.log_func = default_log
};
/*===========================================================================*
* main *
*===========================================================================*/
@@ -64,6 +75,13 @@ static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
mailbox_init();
int hook_id = 1;
if (sys_irqsetpolicy(MBOX_IRQ, 0, &hook_id) != OK) {
log_warn(&log, "mailbox: couldn't set IRQ policy %d\n",
MBOX_IRQ);
return(EPERM);
}
/* Announce we are up! */
chardriver_announce();
@@ -79,17 +97,96 @@ static ssize_t m_read(devminor_t minor, u64_t position, endpoint_t endpt,
if (minor != MAILBOX_DEV)
return(EIO);
return(OK);
}
static int wait_irq()
{
int hook_id = 1;
if (sys_irqenable(&hook_id) != OK) {
log_warn(&log, "Failed to enable irqenable irq\n");
return -1;
}
/* Wait for a task completion interrupt. */
message m;
int ipc_status;
int ticks = SANE_TIMEOUT * sys_hz() / 1000000;
if (ticks <= 0)
ticks = 1;
while (1) {
int rr;
sys_setalarm(ticks, 0);
if ((rr = driver_receive(ANY, &m, &ipc_status)) != OK) {
panic("driver_receive failed: %d", rr);
};
if (is_ipc_notify(ipc_status)) {
switch (_ENDPOINT_P(m.m_source)) {
case CLOCK:
/* Timeout. */
log_warn(&log, "TIMEOUT\n");
return -1;
break;
case HARDWARE:
sys_setalarm(0, 0);
return 0;
}
}
}
sys_setalarm(0, 0); /* cancel the alarm */
}
static ssize_t m_write(devminor_t minor, u64_t position, endpoint_t endpt,
cp_grant_id_t grant, size_t size, int flags, cdev_id_t id)
{
/* Write to one of the driver's minor devices. */
size_t offset, chunk;
int r;
uint32_t msg;
int8_t *buf;
if (minor != MAILBOX_DEV)
return(EIO);
r = sys_safecopyfrom(endpt, grant, 0, (vir_bytes)&msg,
sizeof (uint32_t));
if (r != OK) {
log_warn(&log, "mailbox: sys_safecopyfrom failed for proc %d,"
" grant %d\n", endpt, grant);
return r;
}
log_info(&log, "size of buffer %d\n", *(int *)msg);
buf = (int8_t *)calloc(*(int *)msg, sizeof (int8_t));
if (!buf) {
log_warn(&log, "can't allocate buffer\n");
return(ENOMEM);
}
r = sys_safecopyfrom(endpt, grant, 0, (vir_bytes)buf, *(int *)msg);
if (r != OK) {
log_warn(&log, "mailbox: sys_safecopyfrom failed for proc %d,"
" grant %d\n", endpt, grant);
return r;
}
mbox_write(MBOX_PROP, (uint32_t)buf);
if (wait_irq() < 0) {
log_warn(&log, "can't wait interrupt from mbox\n");
return(ETIME);
} else {
buf = (int8_t *)mbox_read(MBOX_PROP);
r = sys_safecopyto(endpt, grant, 0, (vir_bytes)buf, *(int *)msg);
if (r != OK) {
log_warn(&log, "mailbox: sys_safecopyto failed for proc %d, grant %d\n",
endpt, grant);
return r;
}
}
mbox_flush();
return(OK);
}
static int m_open(devminor_t minor, int access, endpoint_t user_endpt)

View File

@@ -37,14 +37,14 @@ static struct log log = {
static void write32(vir_bytes reg, uint32_t data)
{
assert(reg >= 0 && reg <= sizeof (struct mailbox_t));
uint32_t addr = mbox_base + reg;
addr = data;
uint32_t *addr = (uint32_t *)(mbox_base + reg);
*addr = data;
}
static uint32_t read32(vir_bytes reg)
{
assert(reg >= 0 && reg <= sizeof (struct mailbox_t));
return mbox_base + reg;
return *(uint32_t *)(mbox_base + reg);
}
void mailbox_init()
@@ -70,6 +70,8 @@ void mailbox_init()
panic("Unable to map MMC memory");
gmailbox = &mailbox;
write32(gmailbox->config, IRQ_EN);
}
uint32_t mbox_read(uint8_t chan)

View File

@@ -36,6 +36,7 @@ void mbox_write(uint8_t chan, uint32_t data);
void mbox_flush();
#define IRQ_EN (0x1 << 0)
#define MAILBOX_FULL 0x80000000
#define MAILBOX_EMPTY 0x40000000