move stuff around

This commit is contained in:
Kai 2022-12-09 20:23:18 +00:00
parent c575adb838
commit 0e99e762ff
6 changed files with 177 additions and 11 deletions

View File

@ -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

View File

View File

@ -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
View 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
View 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