Added mailbox system

This commit is contained in:
Lauchmelder 2022-01-22 13:30:34 +01:00
parent c49ff2998d
commit 59f5fb2c6e
5 changed files with 149 additions and 2 deletions

View file

@ -1,5 +1,10 @@
#include "stdint.h"
enum
{
PERIPHERAL_BASE = 0xFE000000
};
// Functions for peeking/poking into memory
void poke(int64_t addr, uint32_t val);
uint32_t peek(int64_t addr);

6
include/mb.h Normal file
View file

@ -0,0 +1,6 @@
#pragma once
#include "stdint.h"
uint32_t get_vc_firmware_rev(void);
uint8_t* get_board_mac_address(uint8_t* buffer);

View file

@ -12,8 +12,6 @@ uint32_t peek(int64_t addr)
enum
{
PERIPHERAL_BASE = 0xFE000000,
GPFSEL0 = PERIPHERAL_BASE + 0x200000,
GPSET0 = PERIPHERAL_BASE + 0x20001C,
GPCLR0 = PERIPHERAL_BASE + 0x200028,

View file

@ -2,6 +2,7 @@
#include "convert.h"
#include "string.h"
#include "memory.h"
#include "mb.h"
void print_clippy();
char* get_user_input(char* buffer);
@ -10,12 +11,28 @@ void main()
{
extern long _start;
char buffer[1024];
uint8_t mac_address[6];
uart_init();
heap_init();
print_clippy();
uart_puts("Boot successful! \n");
uart_puts("Firmware revision: ");
uart_puts(utoa(get_vc_firmware_rev(), buffer, 10));
get_board_mac_address(mac_address);
uart_puts("\nMAC Address: ");
for(uint8_t i = 0; i < 6; i++)
{
uart_puts(utoa(mac_address[i], buffer, 16));
if(i != 5)
uart_puts(":");
}
uart_puts("\n");
uart_puts("\n");
uart_puts("Started execution at 0x");
uart_puts(ultoa((long)&_start, buffer, 16));

121
src/mb.c Normal file
View file

@ -0,0 +1,121 @@
#include "mb.h"
#include "gpio.h"
#include "memory.h"
#include "io.h"
#include "convert.h"
volatile uint32_t __attribute__((aligned(16))) mailbox[36];
enum
{
VIDEOCORE_MAILBOX = (PERIPHERAL_BASE + 0x0000B880),
MAILBOX_READ = (VIDEOCORE_MAILBOX + 0x0),
MAILBOX_POLL = (VIDEOCORE_MAILBOX + 0x10),
MAILBOX_SENDER = (VIDEOCORE_MAILBOX + 0x14),
MAILBOX_STATUS = (VIDEOCORE_MAILBOX + 0x18),
MAILBOX_CONFIG = (VIDEOCORE_MAILBOX + 0x1C),
MAILBOX_WRITE = (VIDEOCORE_MAILBOX + 0x20),
MAILBOX_RESPONSE = 0x80000000,
MAILBOX_FULL = 0x80000000,
MAILBOX_EMPTY = 0x40000000
};
struct BufferHeader
{
uint32_t size;
uint32_t status_code;
};
struct TagHeader
{
uint32_t identifier;
uint32_t buf_size;
uint32_t status_code;
};
uint32_t mailbox_call(uint8_t ch)
{
uint32_t r = ((uint32_t)((int64_t)&mailbox) & ~0xF) | (ch & 0xF);
while(peek(MAILBOX_STATUS) & MAILBOX_FULL);
poke(MAILBOX_WRITE, r);
for(;;)
{
while(peek(MAILBOX_STATUS) & MAILBOX_EMPTY);
if(r == peek(MAILBOX_READ))
return mailbox[1] == MAILBOX_RESPONSE;
}
return 0;
}
struct BufferHeader* alloc_buffer()
{
return (struct BufferHeader*)malloc();
}
void free_buffer(struct BufferHeader* ptr)
{
free((void*)ptr);
}
uint8_t* create_tag(uint8_t* ptr, uint32_t identifier, uint8_t* buffer, uint32_t size)
{
struct TagHeader* header = (struct TagHeader*)ptr;
header->identifier = identifier;
header->buf_size = size;
header->status_code = 0;
ptr = (uint8_t*)(header + 1);
for(uint32_t i = 0; i < size; i++)
{
*ptr++ = *buffer++;
}
uint8_t padding = size % 4;
if(padding)
ptr += 4 - padding;
return ptr;
}
uint32_t get_vc_firmware_rev(void)
{
mailbox[0] = 7 * sizeof(uint32_t); // buffer size
mailbox[1] = 0; // request code
mailbox[2] = 1; // tag identifier
mailbox[3] = sizeof(uint32_t); // tag buffer size
mailbox[4] = 0; // tag request code
mailbox[5] = 0; // tag content
mailbox[6] = 0; // end tag
mailbox_call(8);
return mailbox[5];
}
uint8_t* get_board_mac_address(uint8_t* buffer)
{
mailbox[0] = 8 * sizeof(uint32_t); // buffer size
mailbox[1] = 0; // request code
mailbox[2] = 0x00010003; // tag identifier
mailbox[3] = 6 * sizeof(uint8_t); // tag buffer size
mailbox[4] = 0; // tag request code
mailbox[5] = 0; // tag content
mailbox[6] = 0;
mailbox[7] = 0; // end tag
mailbox_call(8);
uint8_t* mac_address = (uint8_t*)(mailbox + 5);
for(uint8_t i = 0; i < 6; i++)
buffer[i] = mac_address[i];
return buffer;
}