Added bits/wordsize.h.
[tart.git] / platform / bcm2835 / mailbox.c
blob44fa3cf105136d24e326e8f0998aafaa475913d4
1 #include <mailbox.h>
2 #include <mmio.h>
3 #include <barrier.h>
4 #include <compiler.h>
5 #include <kernel/timer.h>
7 static void mailbox_write_timeout(timer_list_t *timer __UNUSED, timer_ticks_t now __UNUSED,
8 void *arg __UNUSED)
10 // arg is data | channel.
11 /* todo: panic(); */
12 for(;;);
15 static void mailbox_read_timeout(timer_list_t *timer __UNUSED, timer_ticks_t now __UNUSED,
16 void *arg __UNUSED)
18 // arg is channel.
19 /* todo: panic(); */
20 for(;;);
23 void mailbox_write(uint32_t data, uint8_t channel)
25 // Only accesses of different peripherals can get out of order,
26 // so we'll do a DMB at the start of each peripheral access.
28 // Interrupts that access peripherals would do a DMB at, both,
29 // the beginning and the end.
30 data_memory_barrier();
32 timer_list_t timer;
33 timer_setup(&timer, MAILBOX_TIMEOUT, 0, mailbox_write_timeout, 0);
35 while (mmio_reg_read(MAILBOX_BASE + MAILBOX_STATUS) & (1 << 31));
37 timer_delete(&timer);
38 mmio_reg_write(MAILBOX_BASE + MAILBOX_WRITE, data | channel);
41 uint32_t mailbox_read(uint8_t channel)
43 data_memory_barrier();
44 uint32_t data;
45 do {
46 timer_list_t timer;
47 timer_setup(&timer, MAILBOX_TIMEOUT, 0, mailbox_read_timeout, 0);
49 while (mmio_reg_read(MAILBOX_BASE + MAILBOX_STATUS) & (1 << 30));
51 timer_delete(&timer);
52 } while (((data = mmio_reg_read(MAILBOX_BASE)) & 0xF) != channel);
54 return data;