From 59f5fb2c6e38271426e8d511ffaae021f63db1c2 Mon Sep 17 00:00:00 2001 From: Lauchmelder Date: Sat, 22 Jan 2022 13:30:34 +0100 Subject: [PATCH] Added mailbox system --- include/gpio.h | 5 ++ include/mb.h | 6 +++ src/gpio.c | 2 - src/kernel.c | 17 +++++++ src/mb.c | 121 +++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 149 insertions(+), 2 deletions(-) create mode 100644 include/mb.h create mode 100644 src/mb.c diff --git a/include/gpio.h b/include/gpio.h index 82aa9e0..cffa6cb 100644 --- a/include/gpio.h +++ b/include/gpio.h @@ -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); diff --git a/include/mb.h b/include/mb.h new file mode 100644 index 0000000..1ebd1c6 --- /dev/null +++ b/include/mb.h @@ -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); \ No newline at end of file diff --git a/src/gpio.c b/src/gpio.c index 8aa129a..d72de80 100644 --- a/src/gpio.c +++ b/src/gpio.c @@ -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, diff --git a/src/kernel.c b/src/kernel.c index df0a016..58eec5e 100644 --- a/src/kernel.c +++ b/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)); diff --git a/src/mb.c b/src/mb.c new file mode 100644 index 0000000..f6092dc --- /dev/null +++ b/src/mb.c @@ -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; +} \ No newline at end of file