commit 787b4617ae6b72dd51af61f6833f8649102b534d Author: Mathieu Maret Date: Mon Mar 14 07:46:32 2022 +0100 Initial import with uart 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);