[MAJOR] The mailbox driver works

The final commit about the mailbox driver.
It was debuged and tested. You can use it from this moment.
This commit is contained in:
Korobov Nikita
2017-07-14 03:27:12 +03:00
parent 25de27fbcb
commit 364990d9da
4 changed files with 40 additions and 39 deletions

View File

@@ -554,10 +554,12 @@ service omap_emmc
service mailbox
{
system
UMAP # 14
PRIVCTL # 4
IRQCTL # 19
;
irq
33
;
ipc ALL
};

View File

@@ -139,6 +139,7 @@ Where key is one of the following:
filter # Make /dev/filter
fbd # Make /dev/fbd
hello # Make /dev/hello
mailbox # Make /dev/mailbox
video # Make /dev/video
pci # Make /dev/pci
vnd0 vnd0p0 vnd0p0s0 .. # Make vnode disks /dev/vnd[0-7] and (sub)partitions
@@ -356,7 +357,7 @@ do
makedev ${dev} c 15 0 ${uname} ${gname} ${permissions}
;;
mailbox)
makedev ${dev} c 16 0 ${uname} ${gname} ${permissions}
makedev ${dev} c 22 0 ${uname} ${gname} 0666
;;
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.

View File

@@ -1,6 +1,8 @@
#include <minix/drivers.h>
#include <minix/chardriver.h>
#include <minix/type.h>
#include <minix/vm.h>
#include <sys/mman.h>
#include <minix/log.h>
#include "mbox.h"
@@ -23,6 +25,9 @@ static ssize_t m_write(devminor_t minor, u64_t position, endpoint_t endpt,
static int m_open(devminor_t minor, int access, endpoint_t user_endpt);
static int m_select(devminor_t, unsigned int, endpoint_t);
static u8_t* mboxbuffer_vir; /* Address of dss phys memory map */
static phys_bytes mboxbuffer_phys;
/* Entry points to this driver. */
static struct chardriver m_dtab = {
.cdr_open = m_open, /* open device */
@@ -82,6 +87,14 @@ static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
return(EPERM);
}
mbox_flush();
/* Configure mailbox buffer */
mboxbuffer_vir = (u8_t*) alloc_contig(0x1000, 0, &mboxbuffer_phys);
if (mboxbuffer_vir == (u8_t*) MAP_FAILED) {
panic("Unable to allocate contiguous memory for mailbox buffer\n");
}
/* Announce we are up! */
chardriver_announce();
@@ -98,8 +111,8 @@ static ssize_t m_read(devminor_t minor, u64_t position, endpoint_t endpt,
if (minor != MAILBOX_DEV)
return(EIO);
uint8_t *buf = (int8_t *)mbox_read(MBOX_PROP);
r = sys_safecopyto(endpt, grant, 0, (vir_bytes)buf, size);
mbox_read(MBOX_PROP);
r = sys_safecopyto(endpt, grant, 0, (vir_bytes)mboxbuffer_vir, size);
if (r != OK) {
log_warn(&log, "mailbox: sys_safecopyto failed for proc %d, grant %d\n",
endpt, grant);
@@ -108,17 +121,15 @@ static ssize_t m_read(devminor_t minor, u64_t position, endpoint_t endpt,
mbox_flush();
return(OK);
}
static int hook_id = 1;
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;
}
if (sys_irqenable(&hook_id) != OK)
log_warn(&log, "Failed to enable irq\n");
/* Wait for a task completion interrupt. */
message m;
@@ -141,6 +152,7 @@ static int wait_irq()
return -1;
break;
case HARDWARE:
log_debug(&log, "HARDWARE\n");
sys_setalarm(0, 0);
return 0;
}
@@ -156,31 +168,18 @@ static ssize_t m_write(devminor_t minor, u64_t position, endpoint_t endpt,
/* Write to one of the driver's minor devices. */
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);
r = sys_safecopyfrom(endpt, grant, 0, (vir_bytes)mboxbuffer_vir, size);
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)mboxbuffer_phys + 0x40000000);
if (wait_irq() < 0) {
log_warn(&log, "can't wait interrupt from mbox\n");

View File

@@ -37,14 +37,13 @@ static struct log log = {
static void write32(vir_bytes reg, uint32_t data)
{
assert(reg >= 0 && reg <= sizeof (struct mailbox_t));
uint32_t *addr = (uint32_t *)(mbox_base + reg);
*addr = data;
*(volatile uint32_t *)(mbox_base + reg) = data;
}
static uint32_t read32(vir_bytes reg)
{
assert(reg >= 0 && reg <= sizeof (struct mailbox_t));
return *(uint32_t *)(mbox_base + reg);
return *(volatile uint32_t *)(mbox_base + reg);
}
void mailbox_init()
@@ -54,7 +53,7 @@ void mailbox_init()
struct minix_mem_range mr;
mr.mr_base = MBOX_BASE;
mr.mr_limit = MBOX_BASE + sizeof (struct mailbox_t);
mr.mr_limit = MBOX_BASE + 0x1000;
/* grant ourself rights to map the register memory */
if (sys_privctl(SELF, SYS_PRIV_ADD_MEM, &mr) != 0) {
@@ -64,7 +63,7 @@ void mailbox_init()
/* Set the base address to use */
mbox_base =
(uint32_t) vm_map_phys(SELF, (void *) MBOX_BASE,
sizeof (struct mailbox_t));
0x1000);
if (mbox_base == (uint32_t) MAP_FAILED)
panic("Unable to map MMC memory");
@@ -78,10 +77,10 @@ uint32_t mbox_read(uint8_t chan)
{
uint32_t data = 0;
while (1) {
while (read32(gmailbox->status) & MAILBOX_EMPTY) {
while (read32(gmailbox->status) & MAILBOX_EMPTY)
log_debug(&log, "status: 0x%x\n", read32(gmailbox->status));
//mem barrier
}
log_info(&log, "0x%08x\n", read32(gmailbox->status));
data = read32(gmailbox->read);
log_debug(&log, "received data %d\n", data);
@@ -94,7 +93,7 @@ uint32_t mbox_read(uint8_t chan)
void mbox_write(uint8_t chan, uint32_t data)
{
while (read32(gmailbox->status) & MAILBOX_FULL) ;
while (read32(gmailbox->status) & MAILBOX_FULL);
write32(gmailbox->write, (data & ~0xf) | (uint32_t) (chan & 0xf));
}