From 787b4617ae6b72dd51af61f6833f8649102b534d Mon Sep 17 00:00:00 2001 From: Mathieu Maret Date: Mon, 14 Mar 2022 07:46:32 +0100 Subject: [PATCH] Initial import with uart --- Makefile | 23 +++++++++++++++++++++++ config.txt | 8 ++++++++ crt0.S | 27 +++++++++++++++++++++++++++ gpio.h | 9 +++++++++ hello.c | 6 ++++++ mmio.h | 13 +++++++++++++ rpi3.ld | 32 ++++++++++++++++++++++++++++++++ uart.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ uart.h | 15 +++++++++++++++ 9 files changed, 178 insertions(+) create mode 100644 Makefile create mode 100644 config.txt create mode 100644 crt0.S create mode 100644 gpio.h create mode 100644 hello.c create mode 100644 mmio.h create mode 100644 rpi3.ld create mode 100644 uart.c create mode 100644 uart.h diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0986317 --- /dev/null +++ b/Makefile @@ -0,0 +1,23 @@ +#CROSS=aarch64-none-elf- +CROSS=aarch64-linux-gnu- +CC=$(CROSS)gcc +LD=$(CROSS)ld +CFLAGS=-Wall -Wextra -ffreestanding -march=armv8-a+crc -mcpu=cortex-a53 +LDSCRIPT=rpi3.ld + +OBJS=crt0.o uart.o hello.o + +all:kernel.bin + +kernel.elf: $(OBJS) $(LDSCRIPT) + $(LD) -o $@ $(OBJS) -T$(LDSCRIPT) -Map kernel.map + +kernel.bin: kernel.elf + $(CROSS)objcopy -O binay -B aarch64 $< $@ + +clean: + rm -rf $(OBJS) *.bin *.elf *.map + +run: kernel.bin + qemu-system-aarch64 -machine raspi3b -kernel $< + diff --git a/config.txt b/config.txt new file mode 100644 index 0000000..3c49fda --- /dev/null +++ b/config.txt @@ -0,0 +1,8 @@ +#bootloarder +uart_2ndstage=1 + +# 64bits +arm_64bit=1 + +# Kernel name +kernel=kernel.bin diff --git a/crt0.S b/crt0.S new file mode 100644 index 0000000..90ec9b4 --- /dev/null +++ b/crt0.S @@ -0,0 +1,27 @@ + .section .text.boot + .global __start + .type __start, %function + +__start: + //Use core 0 only + mrs x7, mpidr_el1 + and x7, x7, #3 + cbz x7, __start_master +0: wfe + b 0b + +__start_master: + //Setup stack pointer + ldr x2, = __stack_start + mov sp, x2 + + //Clear BSS + ldr w0, = __bss_start + ldr w1, = __bss_size +1: cbz x1, 2f + str xzr, [x0], #8 + sub x1, x1, #1 + cbnz x1, 1b +2: + bl kernelmain + b 0b diff --git a/gpio.h b/gpio.h new file mode 100644 index 0000000..899cc97 --- /dev/null +++ b/gpio.h @@ -0,0 +1,9 @@ +#pragma once + +#include "mmio.h" +// GPIO Function Select 1 +#define GPFSEL1 (*(volatile unsigned *)(GP_BASE + 0x04)) +// GPIO Pin Pull-up/down Enable +#define GPPUD (*(volatile unsigned *)(GP_BASE + 0x94)) +// GPIO Pin Pull-up/down Enable Clock 0 +#define GPPUDCLK0 (*(volatile unsigned *)(GP_BASE + 0x98)) diff --git a/hello.c b/hello.c new file mode 100644 index 0000000..6631ada --- /dev/null +++ b/hello.c @@ -0,0 +1,6 @@ +#include "uart.h" + +int kernelmain(void) { + init_uart(); + return 0; +} diff --git a/mmio.h b/mmio.h new file mode 100644 index 0000000..3f98913 --- /dev/null +++ b/mmio.h @@ -0,0 +1,13 @@ +#pragma once + +// IO mapping +#define IO_BASE 0x3f000000 + +// Mini-UART mapping +#define MU_BASE (IO_BASE + 0x215000) + +// GPIO mapping +#define GP_BASE (IO_BASE + 0x200000) + +// videocore mbox system +#define VCORE_MBOX (IO_BASE + 0x0000B880) diff --git a/rpi3.ld b/rpi3.ld new file mode 100644 index 0000000..7e6f591 --- /dev/null +++ b/rpi3.ld @@ -0,0 +1,32 @@ +MEMORY +{ + /* Load at a classic 64bit addr*/ + /* Could be replace by . = 0x8000; before .text*/ + RAM (rwx) : ORIGIN = 0x80000, LENGTH = 0x10000000 +} + +SECTIONS +{ + .text : { *(.text .text.*) } + .rodata : { *(.rodata .rodata.*) } + .data : { *(.data .data.*) } + + .bss (NOLOAD): + { + __bss_start = ALIGN(16); + *(.bss .bss.*) + __bss_end = ALIGN(16); + } + __end =.; + + . = ALIGN(16); + . += 0x1000; + __stack_start = .; + + /DISCARD/ : + { + *(.comment) *(.gnu) *(.note*) *(.eh_frame*) + } +} + +__bss_size = (__bss_end - __bss_start) >> 3; diff --git a/uart.c b/uart.c new file mode 100644 index 0000000..e3d1ca9 --- /dev/null +++ b/uart.c @@ -0,0 +1,45 @@ +#include + +#include "uart.h" +#include "gpio.h" +//#include "mbox.h" + + +void init_uart(void ) +{ + //Active waiting + while(UART0_FR & (1<<3)){} + + //Stop UART0 + UART0_CR = 0; + + //GPIO 14 and 15 in ALT0 + GPFSEL1 &= ~((7<<12)|(7<<15)); + GPFSEL1 |= (4<<12)|(4<<15); + GPPUD = 0; + for(uint8_t i = 0; i < 150; i++){ + asm volatile ("nop"); + } + GPPUDCLK0 = (1<<14)|(1<<5); + for(uint8_t i = 0; i < 150; i++){ + asm volatile ("nop"); + } + + //CLR INTR + GPPUDCLK0 = 0; + + // Setup for 115200bps @3Mhz + // 3000000 /(115200 * 16) = 1.627 + // 0.627 * 64 + 0.5 = 40.628 -> 40 + UART0_IBRD = 1; //int part + UART0_FBRD = 40; //fract part + UART0_LCRH = 0b11 <<5; //format 8n1 + UART0_CR = 0x301; //Active Tx, Rx & FIFO +} + +void putc(char c){ + //FIFO Full? + while(UART0_FR & (1<<5)){} + + UART0_DR = c; +} diff --git a/uart.h b/uart.h new file mode 100644 index 0000000..c0d4777 --- /dev/null +++ b/uart.h @@ -0,0 +1,15 @@ +#pragma once +#include "mmio.h" + +/* PL011 UART */ +#define UART0_DR (*(volatile unsigned *)(IO_BASE + 0x00201000)) +#define UART0_FR (*(volatile unsigned *)(IO_BASE + 0x00201018)) +#define UART0_IBRD (*(volatile unsigned *)(IO_BASE + 0x00201024)) +#define UART0_FBRD (*(volatile unsigned *)(IO_BASE + 0x00201028)) +#define UART0_LCRH (*(volatile unsigned *)(IO_BASE + 0x0020102C)) +#define UART0_CR (*(volatile unsigned *)(IO_BASE + 0x00201030)) +#define UART0_IMSC (*(volatile unsigned *)(IO_BASE + 0x00201038)) +#define UART0_ICR (*(volatile unsigned *)(IO_BASE + 0x00201044)) + +void init_uart(void); +void putc(char c);