Added mailbox system
This commit is contained in:
parent
c49ff2998d
commit
59f5fb2c6e
|
@ -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
6
include/mb.h
Normal 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);
|
|
@ -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,
|
||||
|
|
17
src/kernel.c
17
src/kernel.c
|
@ -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
121
src/mb.c
Normal 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;
|
||||
}
|
Loading…
Reference in a new issue