From 4cdb0feb633bc6181644704cea8f18368b5bcfd1 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Tue, 23 Oct 2018 15:04:50 +0300 Subject: [PATCH] startup and debug led --- Makefile | 9 +++--- rpikern.ld | 13 +++++--- src/libc/stdint.h | 12 +++++++ src/libc/string.c | 10 ++++++ src/libc/string.h | 6 ++++ src/main.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/startup.s | 34 ++++++++++++++++++++ 7 files changed, 167 insertions(+), 9 deletions(-) create mode 100644 src/libc/stdint.h create mode 100644 src/libc/string.c create mode 100644 src/libc/string.h create mode 100644 src/main.c diff --git a/Makefile b/Makefile index 739bfdd..f61f340 100644 --- a/Makefile +++ b/Makefile @@ -18,8 +18,9 @@ endif warn = -pedantic -Wall dbg = -g inc = -Isrc/libc -gccopt = -fpic -ffreestanding -nostdinc -arch = -mcpu=arm1176jzf-s +gccopt = -marm -fpic -ffreestanding -nostdinc +#arch = -mcpu=arm1176jzf-s +arch = -mcpu=cortex-a7 CFLAGS = $(arch) $(warn) $(opt) $(dbg) $(gccopt) $(inc) $(def) ASFLAGS = $(arch) $(dbg) $(inc) @@ -48,6 +49,6 @@ clean: cleandep: rm -f $(dep) -.PHONY: debug -debug: $(elf) +.PHONY: run +run: $(elf) qemu-system-arm $(QEMU_FLAGS) -kernel $(elf) diff --git a/rpikern.ld b/rpikern.ld index 074a182..3843a15 100644 --- a/rpikern.ld +++ b/rpikern.ld @@ -1,15 +1,18 @@ SECTIONS { . = 0x00008000; + _stacktop = .; _kern_start = .; - .startup : { KEEP(* (.startup)) } - .text : { * (.text); } - .rotdata : { * (.rodata); } - .data : { * (.data); } + .text : { + KEEP(* (.startup*)); + * (.text*); + } + .rodata ALIGN(4): { * (.rodata*); } + .data ALIGN(4): { * (.data*); } .bss ALIGN(4): { _bss_start = .; - * (.bss); + * (.bss*); . = ALIGN(4); _bss_end = .; } diff --git a/src/libc/stdint.h b/src/libc/stdint.h new file mode 100644 index 0000000..7050344 --- /dev/null +++ b/src/libc/stdint.h @@ -0,0 +1,12 @@ +#ifndef LIBC_STDINT_H_ +#define LIBC_STDINT_H_ + +typedef char int8_t; +typedef short int16_t; +typedef long int32_t; + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned long uint32_t; + +#endif /* LIBC_STDINT_H_ */ diff --git a/src/libc/string.c b/src/libc/string.c new file mode 100644 index 0000000..19de177 --- /dev/null +++ b/src/libc/string.c @@ -0,0 +1,10 @@ +#include "string.h" + +void *memset(void *ptr, int val, int size) +{ + unsigned char *p = ptr; + while(size--) { + *p++ = val; + } + return ptr; +} diff --git a/src/libc/string.h b/src/libc/string.h new file mode 100644 index 0000000..8754f71 --- /dev/null +++ b/src/libc/string.h @@ -0,0 +1,6 @@ +#ifndef LIBC_STRING_H_ +#define LIBC_STRING_H_ + +void *memset(void *ptr, int val, int size); + +#endif /* LIBC_STRING_H_ */ diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..47e23b6 --- /dev/null +++ b/src/main.c @@ -0,0 +1,92 @@ +/* mailbox registers (MB 0: input 1: output) + * function | MB 0 | MB 1 + * rd/wr | 00 | 20 ( upper 28: data, lower 4: channel ) + * peek | 10 | 30 + * sender | 14 | 34 + * status | 18 | 38 + * config | 1c | 3c + * + * channel 1: framebuffer + * channel 8: request + * + * read: read status reg loop while empty flag is set + * write: read status loop while full flag is set + */ +#include +#include + +#ifdef RPI1 +#define IOBASEADDR 0x20000000 +#else +#define IOBASEADDR 0x3f000000 +#endif + +#define phys2bus(addr) ((addr) | 0x40000000) +#define bus2phys(addr) ((addr) & 0x3fffffff) + +#define IOREG_ADDR(x) (IOBASEADDR | (x)) +#define REG_MB_READ *((volatile uint32_t*)IOREG_ADDR(0xb880)) +#define REG_MB_STAT *((volatile uint32_t*)IOREG_ADDR(0xb898)) +#define REG_MB_WRITE *((volatile uint32_t*)IOREG_ADDR(0xb8a0)) + +#define MB_STAT_FULL 0x80000000 +#define MB_STAT_EMPTY 0x40000000 + +#define MB_CHAN_FRAMEBUF 1 +#define MB_CHAN_PROP 8 + +#define PROP_CODE_REQ 0 +#define PROP_RESP_OK 0x80000000 + +#define PROP_TAG_END 0 +#define PROP_TAG_BLANKSCR 0x40002 + +int prop_blankscr(int onoff); + +uint32_t mb_read(int chan); +void mb_write(int chan, uint32_t val); + +int main(void) +{ + prop_blankscr(1); + + return 0; +} + +static uint32_t propbuf[64] __attribute__((aligned(16))); + +int prop_blankscr(int onoff) +{ + uint32_t *pb = propbuf; + + *pb++ = 0; + *pb++ = 0; + *pb++ = PROP_TAG_BLANKSCR; + *pb++ = 4; /* data size */ + *pb++ = PROP_CODE_REQ; + *pb++ = onoff ? 1 : 0; + *pb++ = PROP_TAG_END; + *pb++ = 0; /* padding */ + propbuf[0] = (char*)pb - (char*)propbuf; + + mb_write(MB_CHAN_PROP, (uint32_t)propbuf >> 4); + mb_read(MB_CHAN_PROP); + + return propbuf[1] == PROP_RESP_OK ? 0 : -1; +} + +uint32_t mb_read(int chan) +{ + uint32_t val; + do { + while(REG_MB_STAT & MB_STAT_EMPTY); + val = REG_MB_READ; + } while((val & 0xf) != chan); + return val >> 4; +} + +void mb_write(int chan, uint32_t val) +{ + while(REG_MB_STAT & MB_STAT_FULL); + REG_MB_WRITE = (val << 4) | chan; +} diff --git a/src/startup.s b/src/startup.s index ec157f6..30e2a66 100644 --- a/src/startup.s +++ b/src/startup.s @@ -1,8 +1,42 @@ + .extern main + .section .startup + .code 32 + + ldr sp, =_stacktop + + mov r0, #1 + bl dbgled + @ clear bss ldr r0, =_bss_start ldr r1, =_bss_size + cmp r1, #0 + beq 1f @ 0-sized bss, skip clear mov r2, #0 0: str r2, [r0], #4 subs r1, #4 bne 0b +1: + bl main + + mov r0, #0 + bl dbgled + +halt: wfe + b halt + +dbgled: + ldr r3, =0x3f200000 @ gpio base + ldr r2, =0x9000 @ gpio 24 and 25 -> output + str r2, [r3, #8] @ store to GPFSEL2 + ldr r2, =0x01000000 @ bit 24 + teq r0, #0 + streq r2, [r3, #0x1c] @ GPSET0 + strne r2, [r3, #0x28] @ GPCLR0 + lsl r2, #1 + strne r2, [r3, #0x1c] @ GPSET0 + streq r2, [r3, #0x28] @ GPCLR0 + bx lr + +@ vi:set filetype=armasm: -- 1.7.10.4