diff --git a/Makefile b/Makefile index 8559ad6..056d7a2 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ clean: rm -rf $(cobj) $(gasmobj) $(deps) *.bin *.elf *.map run: $(KERNEL) - qemu-system-aarch64 -machine raspi3b -kernel $< + qemu-system-aarch64 -machine raspi3b -kernel $< -serial stdio debug: CFLAGS += $(DEBUG_FLAGS) debug: CXXFLAGS += $(DEBUG_FLAGS) diff --git a/hello.c b/hello.c index 75514e4..886bc59 100644 --- a/hello.c +++ b/hello.c @@ -1,7 +1,28 @@ #include "uart.h" +#include "mbox.h" int kernelmain(void) { init_uart(); + mbox[0] = 8 * 4; + mbox[1] = MBOX_REQUEST; + mbox[2] = MBOX_TAG_GETVCOREMEM; + mbox[3] = 8; + mbox[4] = 0; + mbox[5] = 0; + mbox[6] = 0; + mbox[7] = MBOX_TAG_LAST; + + if(mbox_call(MBOX_CH_PROP, mbox)){ + puts("videocore start at 0x"); + printhex(mbox[5]); + puts(" - "); + int mem = mbox[6]/1024/1024; + printdec(mem); + puts(" Mo\n"); + }else{ + puts("Error getting videocore mem\n"); + } + puts("Hello world\n"); return 0; } diff --git a/mbox.c b/mbox.c new file mode 100644 index 0000000..a80955c --- /dev/null +++ b/mbox.c @@ -0,0 +1,43 @@ +#include "mbox.h" + +// See at https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface +// For messsage description +// E.g. for Get firmware revision +// +// Tag: 0x00000001 +// Request: +// Length: 0 +// Response: +// Length: 4 +// Value: +// u32: firmware revision +// mbox[0] = 4 * 6 // total length in byte +// mbox[1] = MBOX_REQUEST +// mbox[2] = 0x00000001 +// mbox[3] = max(req_length, resp_length) -> 4 +// mbox[5] = 0 // 0 :request, 0x80000000: response +// mbox[6] = MBOX_TAG_LAST + + +// aligned on 16 mutiple so the 4 first bit can be used by the channel +// Should be allocated in the first 2^32bytes +volatile uint32_t __attribute__((aligned(16))) mbox[36]; + +int mbox_call(uint8_t ch, volatile uint32_t *box) { + // mbox is 16 aligned + uint32_t r = (uint64_t)box | (ch & 0xF); + while (*MBOX_STATUS & MBOX_FULL) { + asm volatile("nop"); + } + *MBOX_WRITE = r; + while (1) { + while (*MBOX_STATUS & MBOX_EMPTY) { + asm volatile("nop"); + } + if (r == *MBOX_READ) + /* is it a valid successful response? */ + return box[1] == MBOX_RESPONSE; + } + + return 0; +} diff --git a/mbox.h b/mbox.h new file mode 100644 index 0000000..4ca0017 --- /dev/null +++ b/mbox.h @@ -0,0 +1,42 @@ +#pragma once + +#include +#include "mmio.h" + +#define MBOX_READ ((volatile unsigned int*)(VCORE_MBOX+0x0)) +#define MBOX_POLL ((volatile unsigned int*)(VCORE_MBOX+0x10)) +#define MBOX_SENDER ((volatile unsigned int*)(VCORE_MBOX+0x14)) +#define MBOX_STATUS ((volatile unsigned int*)(VCORE_MBOX+0x18)) +#define MBOX_CONFIG ((volatile unsigned int*)(VCORE_MBOX+0x1C)) +#define MBOX_WRITE ((volatile unsigned int*)(VCORE_MBOX+0x20)) +#define MBOX_RESPONSE 0x80000000 +#define MBOX_FULL 0x80000000 +#define MBOX_EMPTY 0x40000000 + +#define MBOX_REQUEST 0 + +/* channels */ +#define MBOX_CH_POWER 0 +#define MBOX_CH_FB 1 +#define MBOX_CH_VUART 2 +#define MBOX_CH_VCHIQ 3 +#define MBOX_CH_LEDS 4 +#define MBOX_CH_BTNS 5 +#define MBOX_CH_TOUCH 6 +#define MBOX_CH_COUNT 7 +#define MBOX_CH_PROP 8 // Used for ARM to GPU + +/* tags */ +#define MBOX_TAG_GETSERIAL 0x00010004 +#define MBOX_TAG_GETARMMEM 0x00010005 +#define MBOX_TAG_GETVCOREMEM 0x00010006 +#define MBOX_TAG_GETCORETEMP 0x00030006 +#define MBOX_TAG_GETMAXCLK 0x00030004 +#define MBOX_TAG_GETCLK 0x00030047 +#define MBOX_TAG_SETCLK 0x00038002 +#define MBOX_TAG_LAST 0 + +extern volatile unsigned int mbox[36]; +//box should be 16 aligned. +//mbox could be used for this. +int mbox_call(uint8_t ch, volatile uint32_t *box); diff --git a/uart.c b/uart.c index 838708b..794dc5b 100644 --- a/uart.c +++ b/uart.c @@ -2,7 +2,6 @@ #include "uart.h" #include "gpio.h" -//#include "mbox.h" void init_uart(void ) diff --git a/utils.c b/utils.c new file mode 100644 index 0000000..d8158f7 --- /dev/null +++ b/utils.c @@ -0,0 +1,54 @@ +#include +#include "uart.h" + +// K&R inspirated + +void printhex(unsigned int d) +{ + char n; + for(int c=28;c>=0;c-=4) { + // get highest tetrad + n=(d>>c)&0xF; + // 0-9 => '0'-'9', 10-15 => 'A'-'F' + n+=n>9?0x37:0x30; + putc(n); + } +} + +int strlen(char s[]) +{ + int i=0; + while(s[i]!= '\0') { + ++i; + } + return i; +} + +void reverse(char s[]) +{ + int c, i, j; + for(i=0, j=strlen(s)-1; i0); + s[i]='\0'; + reverse(s); +} + +void printdec(unsigned int d) +{ + char s[16]; + itoa(d, s); + for(int i=0; i