move stuff around
This commit is contained in:
parent
c575adb838
commit
0e99e762ff
26
Makefile
26
Makefile
@ -1,18 +1,22 @@
|
||||
CC := $(PREFIX)gcc
|
||||
AS := $(PREFIX)as
|
||||
OBJCPY := $(PREFIX)objcopy
|
||||
CC := $(PREFIX)gcc
|
||||
AS := $(PREFIX)as
|
||||
OBJCPY := $(PREFIX)objcopy
|
||||
boot.o: src/boot.S
|
||||
$(AS) -c src/boot.S -o boot.o
|
||||
|
||||
boot.o: boot.S
|
||||
$(AS) -c boot.S -o boot.o
|
||||
kernel.o: src/kernel.c
|
||||
$(CC) -ffreestanding -c src/kernel.c -o kernel.o -O2 -Wall -Wextra
|
||||
|
||||
os.elf: boot.o kernel.o src/linker.ld
|
||||
$(CC) -T src/linker.ld -o os.elf -ffreestanding -O2 -nostdlib boot.o kernel.o -lgcc
|
||||
|
||||
kernel.o: kernel.c
|
||||
$(CC) -ffreestanding -c kernel.c -o kernel.o -O2 -Wall -Wextra
|
||||
|
||||
os.elf: boot.o kernel.o linker.ld
|
||||
$(CC) -T linker.ld -o os.elf -ffreestanding -O2 -nostdlib boot.o kernel.o -lgcc
|
||||
|
||||
kernel8.img: os.elf
|
||||
$(OBJCPY) os.elf -O binary kernel8.img
|
||||
|
||||
.PHONY: image kernel
|
||||
image: kernel8.img
|
||||
|
||||
kernel: os.elf
|
||||
|
||||
clean:
|
||||
rm boot.o kernel.o os.elf kernel8.img
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "mmio.h"
|
||||
#include "uart.h"
|
||||
|
||||
volatile uint64_t** core_1 = (void*)0xE0;
|
||||
volatile uint64_t** core_2 = (void*)0xE8;
|
||||
@ -21,6 +23,25 @@ void _start_core_3(void* addr) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
void kernel_main(uint64_t dtb_ptr32, uint64_t x1, uint64_t x2, uint64_t x3) {
|
||||
uint32_t reg;
|
||||
char *board;
|
||||
|
||||
asm volatile ("mrs %x0, midr_el1" : "=r" (reg));
|
||||
|
||||
switch ((reg >> 4) & 0xFFF) {
|
||||
case 0xD03:
|
||||
board = "Raspberry Pi 3";
|
||||
MMIO_BASE = 0x3F000000;
|
||||
break;
|
||||
case 0xD08:
|
||||
board = "Raspberry Pi 4";
|
||||
MMIO_BASE = 0xFE000000;
|
||||
break;
|
||||
}
|
||||
uart_init();
|
||||
uart_puts(board);
|
||||
|
||||
return;
|
||||
}
|
22
src/mmio.h
Normal file
22
src/mmio.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef MMIO_H
|
||||
#define MMIO_H
|
||||
|
||||
static uint32_t MMIO_BASE;
|
||||
|
||||
static inline void mmio_write(uint32_t reg, uint32_t data)
|
||||
{
|
||||
*(volatile uint32_t*)(MMIO_BASE + reg) = data;
|
||||
}
|
||||
|
||||
|
||||
static inline uint32_t mmio_read(uint32_t reg)
|
||||
{
|
||||
return *(volatile uint32_t*)(MMIO_BASE + reg);
|
||||
}
|
||||
|
||||
static inline void delay(int32_t count)
|
||||
{
|
||||
asm volatile("__delay_%=: subs %[count], %[count], #1; bne __delay_%=\n"
|
||||
: "=r"(count): [count]"0"(count) : "cc");
|
||||
}
|
||||
#endif
|
119
src/uart.h
Normal file
119
src/uart.h
Normal file
@ -0,0 +1,119 @@
|
||||
#ifndef UART_H
|
||||
#define UART_H
|
||||
#include "mmio.h"
|
||||
|
||||
enum
|
||||
{
|
||||
// The offsets for reach register.
|
||||
GPIO_BASE = 0x200000,
|
||||
|
||||
// Controls actuation of pull up/down to ALL GPIO pins.
|
||||
GPPUD = (GPIO_BASE + 0x94),
|
||||
|
||||
// Controls actuation of pull up/down for specific GPIO pin.
|
||||
GPPUDCLK0 = (GPIO_BASE + 0x98),
|
||||
|
||||
// The base address for UART.
|
||||
UART0_BASE = (GPIO_BASE + 0x1000), // for raspi4 0xFE201000, raspi2 & 3 0x3F201000, and 0x20201000 for raspi1
|
||||
|
||||
// The offsets for reach register for the UART.
|
||||
UART0_DR = (UART0_BASE + 0x00),
|
||||
UART0_RSRECR = (UART0_BASE + 0x04),
|
||||
UART0_FR = (UART0_BASE + 0x18),
|
||||
UART0_ILPR = (UART0_BASE + 0x20),
|
||||
UART0_IBRD = (UART0_BASE + 0x24),
|
||||
UART0_FBRD = (UART0_BASE + 0x28),
|
||||
UART0_LCRH = (UART0_BASE + 0x2C),
|
||||
UART0_CR = (UART0_BASE + 0x30),
|
||||
UART0_IFLS = (UART0_BASE + 0x34),
|
||||
UART0_IMSC = (UART0_BASE + 0x38),
|
||||
UART0_RIS = (UART0_BASE + 0x3C),
|
||||
UART0_MIS = (UART0_BASE + 0x40),
|
||||
UART0_ICR = (UART0_BASE + 0x44),
|
||||
UART0_DMACR = (UART0_BASE + 0x48),
|
||||
UART0_ITCR = (UART0_BASE + 0x80),
|
||||
UART0_ITIP = (UART0_BASE + 0x84),
|
||||
UART0_ITOP = (UART0_BASE + 0x88),
|
||||
UART0_TDR = (UART0_BASE + 0x8C),
|
||||
|
||||
// The offsets for Mailbox registers
|
||||
MBOX_BASE = 0xB880,
|
||||
MBOX_READ = (MBOX_BASE + 0x00),
|
||||
MBOX_STATUS = (MBOX_BASE + 0x18),
|
||||
MBOX_WRITE = (MBOX_BASE + 0x20)
|
||||
};
|
||||
|
||||
volatile unsigned int __attribute__((aligned(16))) mbox[9] = {
|
||||
9*4, 0, 0x38002, 12, 8, 2, 3000000, 0 ,0
|
||||
};
|
||||
|
||||
void uart_init()
|
||||
{
|
||||
mmio_write(UART0_CR, 0x00000000);
|
||||
// Setup the GPIO pin 14 && 15.
|
||||
|
||||
// Disable pull up/down for all GPIO pins & delay for 150 cycles.
|
||||
mmio_write(GPPUD, 0x00000000);
|
||||
delay(150);
|
||||
|
||||
// Disable pull up/down for pin 14,15 & delay for 150 cycles.
|
||||
mmio_write(GPPUDCLK0, (1 << 14) | (1 << 15));
|
||||
delay(150);
|
||||
|
||||
// Write 0 to GPPUDCLK0 to make it take effect.
|
||||
mmio_write(GPPUDCLK0, 0x00000000);
|
||||
|
||||
// Clear pending interrupts.
|
||||
mmio_write(UART0_ICR, 0x7FF);
|
||||
|
||||
// Set integer & fractional part of baud rate.
|
||||
// Divider = UART_CLOCK/(16 * Baud)
|
||||
// Fraction part register = (Fractional part * 64) + 0.5
|
||||
// Baud = 115200.
|
||||
|
||||
// For Raspi3 and 4 the UART_CLOCK is system-clock dependent by default.
|
||||
// Set it to 3Mhz so that we can consistently set the baud rate
|
||||
unsigned int r = (((unsigned int)(&mbox) & ~0xF) | 8);
|
||||
// wait until we can talk to the VC
|
||||
while ( mmio_read(MBOX_STATUS) & 0x80000000 ) { }
|
||||
// send our message to property channel and wait for the response
|
||||
mmio_write(MBOX_WRITE, r);
|
||||
while ( (mmio_read(MBOX_STATUS) & 0x40000000) || mmio_read(MBOX_READ) != r ) { }
|
||||
|
||||
// Divider = 3000000 / (16 * 115200) = 1.627 = ~1.
|
||||
mmio_write(UART0_IBRD, 1);
|
||||
// Fractional part register = (.627 * 64) + 0.5 = 40.6 = ~40.
|
||||
mmio_write(UART0_FBRD, 40);
|
||||
|
||||
// Enable FIFO & 8 bit data transmission (1 stop bit, no parity).
|
||||
mmio_write(UART0_LCRH, (1 << 4) | (1 << 5) | (1 << 6));
|
||||
|
||||
// Mask all interrupts.
|
||||
mmio_write(UART0_IMSC, (1 << 1) | (1 << 4) | (1 << 5) | (1 << 6) |
|
||||
(1 << 7) | (1 << 8) | (1 << 9) | (1 << 10));
|
||||
|
||||
// Enable UART0, receive & transfer part of UART.
|
||||
mmio_write(UART0_CR, (1 << 0) | (1 << 8) | (1 << 9));
|
||||
}
|
||||
|
||||
void uart_putc(unsigned char c)
|
||||
{
|
||||
// Wait for UART to become ready to transmit.
|
||||
while ( mmio_read(UART0_FR) & (1 << 5) ) { }
|
||||
mmio_write(UART0_DR, c);
|
||||
}
|
||||
|
||||
unsigned char uart_getc()
|
||||
{
|
||||
// Wait for UART to have received something.
|
||||
while ( mmio_read(UART0_FR) & (1 << 4) ) { }
|
||||
return mmio_read(UART0_DR);
|
||||
}
|
||||
|
||||
void uart_puts(const char* str)
|
||||
{
|
||||
for (size_t i = 0; str[i] != '\0'; i ++)
|
||||
uart_putc((unsigned char)str[i]);
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user