From 88661079be4df3bc4c27359d7fcc3d053dfb48c0 Mon Sep 17 00:00:00 2001 From: Korobov Nikita Date: Sat, 8 Jul 2017 19:31:09 +0300 Subject: [PATCH] [MAJOR] Full functionality of mailbox driver --- distrib/sets/lists/minix-base/md.evbarm | 3 +- etc/system.conf | 11 +++ minix/commands/DESCRIBE/DESCRIBE.sh | 3 + minix/commands/MAKEDEV/MAKEDEV.sh | 4 + minix/drivers/system/mailbox/Makefile | 3 +- minix/drivers/system/mailbox/mailbox.conf | 11 --- minix/drivers/system/mailbox/main.c | 99 ++++++++++++++++++++++- minix/drivers/system/mailbox/mbox.c | 8 +- minix/drivers/system/mailbox/mbox.h | 1 + 9 files changed, 125 insertions(+), 18 deletions(-) delete mode 100644 minix/drivers/system/mailbox/mailbox.conf diff --git a/distrib/sets/lists/minix-base/md.evbarm b/distrib/sets/lists/minix-base/md.evbarm index 79abb865b..b4a021b39 100644 --- a/distrib/sets/lists/minix-base/md.evbarm +++ b/distrib/sets/lists/minix-base/md.evbarm @@ -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 diff --git a/etc/system.conf b/etc/system.conf index da39a7391..3effc20c4 100644 --- a/etc/system.conf +++ b/etc/system.conf @@ -550,3 +550,14 @@ service omap_emmc 28 # MMCSD1INT ; }; + +service mailbox +{ + system + PRIVCTL # 4 + IRQCTL # 19 + ; + irq + 33 + ; +}; diff --git a/minix/commands/DESCRIBE/DESCRIBE.sh b/minix/commands/DESCRIBE/DESCRIBE.sh index e826052ab..139657e1c 100644 --- a/minix/commands/DESCRIBE/DESCRIBE.sh +++ b/minix/commands/DESCRIBE/DESCRIBE.sh @@ -220,6 +220,9 @@ do des="keyboard input $n" dev=kbd$n ;; + 15,0) + dev=mailbox + ;; 64,64) des="mouse input multiplexer" dev=mousemux diff --git a/minix/commands/MAKEDEV/MAKEDEV.sh b/minix/commands/MAKEDEV/MAKEDEV.sh index 81330b6fa..d905fca5c 100755 --- a/minix/commands/MAKEDEV/MAKEDEV.sh +++ b/minix/commands/MAKEDEV/MAKEDEV.sh @@ -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} : '.*\\(.\\)'` diff --git a/minix/drivers/system/mailbox/Makefile b/minix/drivers/system/mailbox/Makefile index 6ce4a2533..b5de736a4 100644 --- a/minix/drivers/system/mailbox/Makefile +++ b/minix/drivers/system/mailbox/Makefile @@ -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 diff --git a/minix/drivers/system/mailbox/mailbox.conf b/minix/drivers/system/mailbox/mailbox.conf deleted file mode 100644 index 9d19cd70a..000000000 --- a/minix/drivers/system/mailbox/mailbox.conf +++ /dev/null @@ -1,11 +0,0 @@ -service gpio -{ - system - PRIVCTL # 4 - IRQCTL # 19 - ; - irq - 33 - ; - -}; \ No newline at end of file diff --git a/minix/drivers/system/mailbox/main.c b/minix/drivers/system/mailbox/main.c index 655bfcab7..0ece60025 100644 --- a/minix/drivers/system/mailbox/main.c +++ b/minix/drivers/system/mailbox/main.c @@ -1,12 +1,17 @@ #include #include #include +#include #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) diff --git a/minix/drivers/system/mailbox/mbox.c b/minix/drivers/system/mailbox/mbox.c index c00bac647..c95e8f81f 100644 --- a/minix/drivers/system/mailbox/mbox.c +++ b/minix/drivers/system/mailbox/mbox.c @@ -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) diff --git a/minix/drivers/system/mailbox/mbox.h b/minix/drivers/system/mailbox/mbox.h index 624371287..9e3d0dbc2 100644 --- a/minix/drivers/system/mailbox/mbox.h +++ b/minix/drivers/system/mailbox/mbox.h @@ -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