diff --git a/distrib/sets/lists/minix-base/md.evbarm b/distrib/sets/lists/minix-base/md.evbarm index 41499b2af..79abb865b 100644 --- a/distrib/sets/lists/minix-base/md.evbarm +++ b/distrib/sets/lists/minix-base/md.evbarm @@ -16,12 +16,12 @@ ./etc/system.conf.d/usbd minix-base ./service/bmp085 minix-base ./service/cat24c256 minix-base -./service/omap_emmc minix-base -./service/rpi_emmc minix-base ./service/fb minix-base ./service/gpio minix-base ./service/i2c minix-base ./service/lan8710a minix-base +./service/mailbox minix-base +./service/omap_emmc minix-base ./service/omap_mmc minix-base ./service/rpi_mmc minix-base ./service/random minix-base diff --git a/etc/system.conf b/etc/system.conf index a0099f008..da39a7391 100644 --- a/etc/system.conf +++ b/etc/system.conf @@ -539,18 +539,6 @@ service edfictl ipc ALL; }; -service rpi_emmc -{ - system - PRIVCTL - IRQCTL - PADCONF - ; - irq - 52 # MMCSD1INT - ; -}; - service omap_emmc { system diff --git a/minix/drivers/storage/ramdisk/Makefile b/minix/drivers/storage/ramdisk/Makefile index 03dc26d24..a797ebc26 100644 --- a/minix/drivers/storage/ramdisk/Makefile +++ b/minix/drivers/storage/ramdisk/Makefile @@ -98,6 +98,8 @@ PROGRAMS+= rpi_mmc dir.rpi_mmc:= minix/drivers/storage/mmc/rpi PROGRAMS+= omap_mmc dir.omap_mmc:= minix/drivers/storage/mmc/omap +PROGRAMS+= mailbox +dir.mailbox:= minix/drivers/system/mailbox .endif # ${MACHINE_ARCH} == "earm" .if ${LDSTATIC} == "-dynamic" diff --git a/minix/drivers/storage/ramdisk/proto b/minix/drivers/storage/ramdisk/proto index 5a6ef92e9..211fa75e1 100644 --- a/minix/drivers/storage/ramdisk/proto +++ b/minix/drivers/storage/ramdisk/proto @@ -31,6 +31,7 @@ d--755 0 0 #ifdef __arm__ rpi_mmc ---755 0 0 rpi_mmc omap_mmc ---755 0 0 omap_mmc + mailbox ---755 0 0 mailbox #endif mfs ---755 0 0 mfs procfs ---755 0 0 procfs diff --git a/minix/drivers/system/Makefile b/minix/drivers/system/Makefile index 00033c6be..e652c891e 100644 --- a/minix/drivers/system/Makefile +++ b/minix/drivers/system/Makefile @@ -6,5 +6,6 @@ SUBDIR+= gpio SUBDIR+= log SUBDIR+= random +SUBDIR+= mailbox .include diff --git a/minix/drivers/system/mailbox/Makefile b/minix/drivers/system/mailbox/Makefile new file mode 100644 index 000000000..6ce4a2533 --- /dev/null +++ b/minix/drivers/system/mailbox/Makefile @@ -0,0 +1,15 @@ +# Makefile for the mailbox driver. +PROG= mailbox +SRCS= mbox.c main.c + +FILES=${PROG}.conf +FILESNAME=${PROG} +FILESDIR= /service + +DPADD+= ${LIBCHARDRIVER} ${LIBSYS} +LDADD+= -lchardriver -lsys + +# This is a system driver. +CPPFLAGS+= -D_SYSTEM=1 + +.include diff --git a/minix/drivers/system/mailbox/mailbox.conf b/minix/drivers/system/mailbox/mailbox.conf new file mode 100644 index 000000000..9d19cd70a --- /dev/null +++ b/minix/drivers/system/mailbox/mailbox.conf @@ -0,0 +1,11 @@ +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 new file mode 100644 index 000000000..655bfcab7 --- /dev/null +++ b/minix/drivers/system/mailbox/main.c @@ -0,0 +1,111 @@ +#include +#include +#include + +#include "mbox.h" + +#define NR_DEVS 1 /* number of minor devices */ +#define MAILBOX_DEV 0 /* minor device for /dev/mailbox */ + +/* SEF functions and variables. */ +static void sef_local_startup(void); +static int sef_cb_init_fresh(int type, sef_init_info_t *info); + +static ssize_t m_read(devminor_t minor, u64_t position, endpoint_t endpt, + cp_grant_id_t grant, size_t size, int flags, cdev_id_t id); +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); +static int m_open(devminor_t minor, int access, endpoint_t user_endpt); +static int m_select(devminor_t, unsigned int, endpoint_t); + +/* Entry points to this driver. */ +static struct chardriver m_dtab = { + .cdr_open = m_open, /* open device */ + .cdr_read = m_read, /* read from device */ + .cdr_write = m_write, /* write to device (seeding it) */ + .cdr_select = m_select, /* select hook */ +}; + +/*===========================================================================* + * main * + *===========================================================================*/ +int main(void) +{ + /* SEF local startup. */ + sef_local_startup(); + + /* Call the generic receive loop. */ + chardriver_task(&m_dtab); + + return(OK); +} + +/*===========================================================================* + * sef_local_startup * + *===========================================================================*/ +static void sef_local_startup() +{ + /* Register init callbacks. */ + sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_restart(sef_cb_init_fresh); + + /* Let SEF perform startup. */ + sef_startup(); +} + +/*===========================================================================* + * sef_cb_init_fresh * + *===========================================================================*/ +static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) +{ + /* Initialize the random driver. */ + static struct k_randomness krandom; + int i, s; + + mailbox_init(); + + /* Announce we are up! */ + chardriver_announce(); + + return(OK); +} + +static ssize_t m_read(devminor_t minor, u64_t position, endpoint_t endpt, + cp_grant_id_t grant, size_t size, int flags, cdev_id_t id) +{ + /* Read from one of the driver's minor devices. */ + size_t offset, chunk; + int r; + + if (minor != MAILBOX_DEV) + return(EIO); +} + +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; + + if (minor != MAILBOX_DEV) + return(EIO); +} + +static int m_open(devminor_t minor, int access, endpoint_t user_endpt) +{ + if (minor < 0 || minor >= NR_DEVS) + return(ENXIO); +} + +static int m_select(devminor_t minor, unsigned int ops, endpoint_t endpt) +{ + /* mailbox device is always writable; it's infinitely readable + * once seeded, and doesn't block when it's not, so all operations + * are instantly possible. we ignore CDEV_OP_ERR. + */ + int ready_ops = 0; + if (minor != MAILBOX_DEV) + return(EIO); + return ops & (CDEV_OP_RD | CDEV_OP_WR); +} \ No newline at end of file diff --git a/minix/drivers/system/mailbox/mbox.c b/minix/drivers/system/mailbox/mbox.c new file mode 100644 index 000000000..c00bac647 --- /dev/null +++ b/minix/drivers/system/mailbox/mbox.c @@ -0,0 +1,110 @@ +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "mbox.h" + +struct mailbox_t mailbox = { + .read = 0x00, + .res1 = 0x04, + .res2 = 0x08, + .res3 = 0x0c, + .peek = 0x10, + .sender = 0x14, + .status = 0x18, + .config = 0x1c, + .write = 0x20 +}; + +struct mailbox_t *gmailbox; + +uint32_t mbox_base; +/* + * Define a structure to be used for logging + */ +static struct log log = { + .name = "mailbox", + .log_level = LEVEL_INFO, + .log_func = default_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; +} + +static uint32_t read32(vir_bytes reg) +{ + assert(reg >= 0 && reg <= sizeof (struct mailbox_t)); + return mbox_base + reg; +} + +void mailbox_init() +{ + uint32_t value; + value = 0; + struct minix_mem_range mr; + + mr.mr_base = MBOX_BASE; + mr.mr_limit = MBOX_BASE + sizeof (struct mailbox_t); + + /* grant ourself rights to map the register memory */ + if (sys_privctl(SELF, SYS_PRIV_ADD_MEM, &mr) != 0) { + panic("Unable to request permission to map memory"); + } + + /* Set the base address to use */ + mbox_base = + (uint32_t) vm_map_phys(SELF, (void *) MBOX_BASE, + sizeof (struct mailbox_t)); + + if (mbox_base == (uint32_t) MAP_FAILED) + panic("Unable to map MMC memory"); + + gmailbox = &mailbox; +} + +uint32_t mbox_read(uint8_t chan) +{ + uint32_t data = 0; + while (1) { + while (read32(gmailbox->status) & MAILBOX_EMPTY) { + log_debug(&log, "status: 0x%x\n", read32(gmailbox->status)); + //mem barrier + } + data = read32(gmailbox->read); + + log_debug(&log, "received data %d\n", data); + + if (((uint8_t) data & 0xf) == chan) { + return (data & ~0xf); + } + } +} + +void mbox_write(uint8_t chan, uint32_t data) +{ + while (read32(gmailbox->status) & MAILBOX_FULL) ; + + write32(gmailbox->write, (data & ~0xf) | (uint32_t) (chan & 0xf)); +} + +void mbox_flush(void) +{ + spin_t spin; + while (!(read32(gmailbox->status) & MAILBOX_EMPTY)) { + spin_init(&spin, 20000); + while (1) { + if(spin_check(&spin) == FALSE) + break; + } + } +} \ No newline at end of file diff --git a/minix/drivers/system/mailbox/mbox.h b/minix/drivers/system/mailbox/mbox.h new file mode 100644 index 000000000..624371287 --- /dev/null +++ b/minix/drivers/system/mailbox/mbox.h @@ -0,0 +1,139 @@ +#ifndef _MBOX_H_ +#define _MBOX_H_ + +#define MBOX_BASE (0x3f000000 + 0xb880) + +struct mailbox_t { + vir_bytes read; + vir_bytes res1; + vir_bytes res2; + vir_bytes res3; + vir_bytes peek; + vir_bytes sender; + vir_bytes status; + vir_bytes config; + vir_bytes write; +}; + +enum mail_chan { + MBOX_POWER, + MBOX_FRAMEBUFFER, + MBOX_UART, + MBOX_VCHIQ, + MBOX_LEDS, + MBOX_BUTTONS, + MBOX_TOUCH, + MBOX_NUSED, + MBOX_PROP, + MBOX_REVPROP +}; + +void mailbox_init(); + +uint32_t mbox_read(uint8_t chan); + +void mbox_write(uint8_t chan, uint32_t data); + +void mbox_flush(); + + +#define MAILBOX_FULL 0x80000000 +#define MAILBOX_EMPTY 0x40000000 +#define MBX_TAG_GET_BOARD_MODEL 0x00010001 +#define MBX_TAG_GET_BOARD_REVISION 0x00010002 + +// Timers interrupt control registers +#define CORE0_TIMER_IRQCNTL 0x40000040 +#define CORE1_TIMER_IRQCNTL 0x40000044 +#define CORE2_TIMER_IRQCNTL 0x40000048 +#define CORE3_TIMER_IRQCNTL 0x4000004C + +// Where to route timer interrupt to, IRQ/FIQ +// Setting both the IRQ and FIQ bit gives an FIQ +#define TIMER0_IRQ 0x01 +#define TIMER1_IRQ 0x02 +#define TIMER2_IRQ 0x04 +#define TIMER3_IRQ 0x08 +#define TIMER0_FIQ 0x10 +#define TIMER1_FIQ 0x20 +#define TIMER2_FIQ 0x40 +#define TIMER3_FIQ 0x80 + +// Mailbox interrupt control registers +#define CORE0_MBOX_IRQCNTL 0x40000050 +#define CORE1_MBOX_IRQCNTL 0x40000054 +#define CORE2_MBOX_IRQCNTL 0x40000058 +#define CORE3_MBOX_IRQCNTL 0x4000005C + +// Where to route mailbox interrupt to, IRQ/FIQ +// Setting both the IRQ and FIQ bit gives an FIQ +#define MBOX0_IRQ 0x01 +#define MBOX1_IRQ 0x02 +#define MBOX2_IRQ 0x04 +#define MBOX3_IRQ 0x08 +#define MBOX0_FIQ 0x10 +#define MBOX1_FIQ 0x20 +#define MBOX2_FIQ 0x40 +#define MBOX3_FIQ 0x80 + +// IRQ & FIQ +#define CORE0_IRQ_SOURCE 0x40000060 +#define CORE1_IRQ_SOURCE 0x40000064 +#define CORE2_IRQ_SOURCE 0x40000068 +#define CORE3_IRQ_SOURCE 0x4000006C +#define CORE0_FIQ_SOURCE 0x40000070 +#define CORE1_FIQ_SOURCE 0x40000074 +#define CORE2_FIQ_SOURCE 0x40000078 +#define CORE3_FIQ_SOURCE 0x4000007C + +// Interrupt source bits +// IRQ and FIQ are the same +// GPU bits can be set +#define INT_SRC_TIMER0 0x00000001 +#define INT_SRC_TIMER1 0x00000002 +#define INT_SRC_TIMER2 0x00000004 +#define INT_SRC_TIMER3 0x00000008 +#define INT_SRC_MBOX0 0x00000010 +#define INT_SRC_MBOX1 0x00000020 +#define INT_SRC_MBOX2 0x00000040 +#define INT_SRC_MBOX3 0x00000080 +#define INT_SRC_GPU 0x00000100 +#define INT_SRC_PMU 0x00000200 + +// Mailbox write +#define CORE0_MBOX0_SET 0x40000080 +#define CORE0_MBOX1_SET 0x40000084 +#define CORE0_MBOX2_SET 0x40000088 +#define CORE0_MBOX3_SET 0x4000008C +#define CORE1_MBOX0_SET 0x40000090 +#define CORE1_MBOX1_SET 0x40000094 +#define CORE1_MBOX2_SET 0x40000098 +#define CORE1_MBOX3_SET 0x4000009C +#define CORE2_MBOX0_SET 0x400000A0 +#define CORE2_MBOX1_SET 0x400000A4 +#define CORE2_MBOX2_SET 0x400000A8 +#define CORE2_MBOX3_SET 0x400000AC +#define CORE3_MBOX0_SET 0x400000B0 +#define CORE3_MBOX1_SET 0x400000B4 +#define CORE3_MBOX2_SET 0x400000B8 +#define CORE3_MBOX3_SET 0x400000BC + +// Mailbox write (Read & Write) +#define CORE0_MBOX0_RDCLR 0x400000C0 +#define CORE0_MBOX1_RDCLR 0x400000C4 +#define CORE0_MBOX2_RDCLR 0x400000C8 +#define CORE0_MBOX3_RDCLR 0x400000CC +#define CORE1_MBOX0_RDCLR 0x400000D0 +#define CORE1_MBOX1_RDCLR 0x400000D4 +#define CORE1_MBOX2_RDCLR 0x400000D8 +#define CORE1_MBOX3_RDCLR 0x400000DC +#define CORE2_MBOX0_RDCLR 0x400000E0 +#define CORE2_MBOX1_RDCLR 0x400000E4 +#define CORE2_MBOX2_RDCLR 0x400000E8 +#define CORE2_MBOX3_RDCLR 0x400000EC +#define CORE3_MBOX0_RDCLR 0x400000F0 +#define CORE3_MBOX1_RDCLR 0x400000F4 +#define CORE3_MBOX2_RDCLR 0x400000F8 +#define CORE3_MBOX3_RDCLR 0x400000FC + +#endif /* _MBOX_H_ */ \ No newline at end of file