startup and debug led
authorJohn Tsiombikas <nuclear@member.fsf.org>
Tue, 23 Oct 2018 12:04:50 +0000 (15:04 +0300)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Tue, 23 Oct 2018 12:04:50 +0000 (15:04 +0300)
Makefile
rpikern.ld
src/libc/stdint.h [new file with mode: 0644]
src/libc/string.c [new file with mode: 0644]
src/libc/string.h [new file with mode: 0644]
src/main.c [new file with mode: 0644]
src/startup.s

index 739bfdd..f61f340 100644 (file)
--- 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)
index 074a182..3843a15 100644 (file)
@@ -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 (file)
index 0000000..7050344
--- /dev/null
@@ -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 (file)
index 0000000..19de177
--- /dev/null
@@ -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 (file)
index 0000000..8754f71
--- /dev/null
@@ -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 (file)
index 0000000..47e23b6
--- /dev/null
@@ -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 <string.h>
+#include <stdint.h>
+
+#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;
+}
index ec157f6..30e2a66 100644 (file)
@@ -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: