[MAJOR] Full functionality of mailbox driver
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -550,3 +550,14 @@ service omap_emmc
|
||||
28 # MMCSD1INT
|
||||
;
|
||||
};
|
||||
|
||||
service mailbox
|
||||
{
|
||||
system
|
||||
PRIVCTL # 4
|
||||
IRQCTL # 19
|
||||
;
|
||||
irq
|
||||
33
|
||||
;
|
||||
};
|
||||
|
||||
@@ -220,6 +220,9 @@ do
|
||||
des="keyboard input $n"
|
||||
dev=kbd$n
|
||||
;;
|
||||
15,0)
|
||||
dev=mailbox
|
||||
;;
|
||||
64,64)
|
||||
des="mouse input multiplexer"
|
||||
dev=mousemux
|
||||
|
||||
@@ -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} : '.*\\(.\\)'`
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
service gpio
|
||||
{
|
||||
system
|
||||
PRIVCTL # 4
|
||||
IRQCTL # 19
|
||||
;
|
||||
irq
|
||||
33
|
||||
;
|
||||
|
||||
};
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user