mirror of
https://github.com/isometimes/rpi4-osdev
synced 2024-11-28 21:21:32 +00:00
40 lines
1.2 KiB
C
40 lines
1.2 KiB
C
|
#include "../include/io.h"
|
||
|
|
||
|
// The buffer must be 16-byte aligned as only the upper 28 bits of the address can be passed via the mailbox
|
||
|
volatile unsigned int __attribute__((aligned(16))) mbox[36];
|
||
|
|
||
|
enum {
|
||
|
VIDEOCORE_MBOX = (PERIPHERAL_BASE + 0x0000B880),
|
||
|
MBOX_READ = (VIDEOCORE_MBOX + 0x0),
|
||
|
MBOX_POLL = (VIDEOCORE_MBOX + 0x10),
|
||
|
MBOX_SENDER = (VIDEOCORE_MBOX + 0x14),
|
||
|
MBOX_STATUS = (VIDEOCORE_MBOX + 0x18),
|
||
|
MBOX_CONFIG = (VIDEOCORE_MBOX + 0x1C),
|
||
|
MBOX_WRITE = (VIDEOCORE_MBOX + 0x20),
|
||
|
MBOX_RESPONSE = 0x80000000,
|
||
|
MBOX_FULL = 0x80000000,
|
||
|
MBOX_EMPTY = 0x40000000
|
||
|
};
|
||
|
|
||
|
unsigned int mbox_call(unsigned char ch)
|
||
|
{
|
||
|
// 28-bit address (MSB) and 4-bit value (LSB)
|
||
|
unsigned int r = ((unsigned int)((long) &mbox) &~ 0xF) | (ch & 0xF);
|
||
|
|
||
|
// Wait until we can write
|
||
|
while (mmio_read(MBOX_STATUS) & MBOX_FULL);
|
||
|
|
||
|
// Write the address of our buffer to the mailbox with the channel appended
|
||
|
mmio_write(MBOX_WRITE, r);
|
||
|
|
||
|
while (1) {
|
||
|
// Is there a reply?
|
||
|
while (mmio_read(MBOX_STATUS) & MBOX_EMPTY);
|
||
|
|
||
|
// Is it a reply to our message?
|
||
|
if (r == mmio_read(MBOX_READ)) return mbox[1]==MBOX_RESPONSE; // Is it successful?
|
||
|
|
||
|
}
|
||
|
return 0;
|
||
|
}
|