diff options
Diffstat (limited to 'src/mailbox.c')
-rw-r--r-- | src/mailbox.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/src/mailbox.c b/src/mailbox.c index 310b2b1..fcad179 100644 --- a/src/mailbox.c +++ b/src/mailbox.c | |||
@@ -7,7 +7,9 @@ | |||
7 | 7 | ||
8 | enum | 8 | enum |
9 | { | 9 | { |
10 | MAILBOX = 0xB880 // Mailbox address relative to MMIO base address. | 10 | MAILBOX = 0xB880, // Mailbox address relative to MMIO base address. |
11 | STATUS_EMPTY = 0x40000000, // Empty bit. | ||
12 | STATUS_FULL = 0x80000000, // Full bit. | ||
11 | }; | 13 | }; |
12 | 14 | ||
13 | typedef uint32_t Message; | 15 | typedef uint32_t Message; |
@@ -21,7 +23,7 @@ static inline Message msg_make(uint8_t channel, volatile const void* data) { | |||
21 | } | 23 | } |
22 | 24 | ||
23 | typedef struct Mailbox { | 25 | typedef struct Mailbox { |
24 | Message inbox; // 0x00 | 26 | Message inbox; // 0x00 |
25 | uint32_t unused_1; // 0x04 | 27 | uint32_t unused_1; // 0x04 |
26 | uint32_t unused_2; // 0x08 | 28 | uint32_t unused_2; // 0x08 |
27 | uint32_t unused_3; // 0x0C | 29 | uint32_t unused_3; // 0x0C |
@@ -29,15 +31,15 @@ typedef struct Mailbox { | |||
29 | uint32_t unused_5; // 0x14 | 31 | uint32_t unused_5; // 0x14 |
30 | uint32_t status; // 0x18 | 32 | uint32_t status; // 0x18 |
31 | uint32_t unused_6; // 0x1C | 33 | uint32_t unused_6; // 0x1C |
32 | Message outbox; // 0x20 | 34 | Message outbox; // 0x20 |
33 | } Mailbox; | 35 | } Mailbox; |
34 | 36 | ||
35 | static inline bool inbox_empty(const volatile Mailbox* pMailbox) { | 37 | static inline bool inbox_empty(const volatile Mailbox* pMailbox) { |
36 | return (pMailbox->status & 0x40000000) != 0; | 38 | return (pMailbox->status & STATUS_EMPTY) != 0; |
37 | } | 39 | } |
38 | 40 | ||
39 | static inline bool outbox_full(const volatile Mailbox* pMailbox) { | 41 | static inline bool outbox_full(const volatile Mailbox* pMailbox) { |
40 | return (pMailbox->status & 0x80000000) != 0; | 42 | return (pMailbox->status & STATUS_FULL) != 0; |
41 | } | 43 | } |
42 | 44 | ||
43 | static volatile Mailbox* pMailbox; | 45 | static volatile Mailbox* pMailbox; |
@@ -59,10 +61,15 @@ const Mail* mbox_read(uint8_t channel) { | |||
59 | return (const Mail*)((uintptr_t)msg & ~0xf); | 61 | return (const Mail*)((uintptr_t)msg & ~0xf); |
60 | } | 62 | } |
61 | 63 | ||
62 | void mbox_write(uint8_t channel, volatile const void* mail) { | 64 | uint32_t mbox_write(uint8_t channel, volatile const void* mail) { |
63 | // Wait until the outbox is clear. | 65 | // Wait until the outbox is clear. |
64 | while (outbox_full(pMailbox)); | 66 | while (outbox_full(pMailbox)); |
65 | // Send the mail. | 67 | // Send the mail. |
66 | pMailbox->outbox = msg_make(channel, mail); | 68 | pMailbox->outbox = msg_make(channel, mail); |
69 | // Wait for the response. | ||
70 | // Mailbox messages cannot be streamed anyway, so wait here so that the API | ||
71 | // does not allow the caller to write two messages in a row without waiting. | ||
72 | const Mail* response = mbox_read(channel); | ||
73 | return response->code; | ||
67 | } | 74 | } |
68 | 75 | ||