CROSS ?= aarch64-linux-gnu-

SRC_DIR := src
BUILD_DIR := build
BOOT_DIR := boot

CC := $(CROSS)gcc
LD := $(CROSS)ld
OBJCOPY := $(CROSS)objcopy

CFLAGS := -Wall -Wextra -O2 -ffreestanding -nostdlib -nostartfiles
LDFLAGS := -nostdlib -T $(SRC_DIR)/link.ld

C_SRC := \
	$(SRC_DIR)/kernel.c \
	$(SRC_DIR)/drivers/led.c \
	$(SRC_DIR)/drivers/timer.c \
	$(SRC_DIR)/drivers/uart.c \
	$(SRC_DIR)/kernel/scheduler.c \
	$(SRC_DIR)/kernel/sync.c
S_SRC := $(SRC_DIR)/boot.S
OBJ := $(patsubst $(SRC_DIR)/%.c,$(BUILD_DIR)/%.o,$(C_SRC)) \
	$(patsubst $(SRC_DIR)/%.S,$(BUILD_DIR)/%.o,$(S_SRC))
KERNEL_ELF := $(BUILD_DIR)/kernel8.elf
KERNEL_IMG := $(BOOT_DIR)/kernel8.img

.PHONY: all clean qemu

all: $(KERNEL_IMG)

$(BUILD_DIR):
	mkdir -p $(BUILD_DIR)

$(BOOT_DIR):
	mkdir -p $(BOOT_DIR)

$(BUILD_DIR)/%.o: $(SRC_DIR)/%.S | $(BUILD_DIR)
	mkdir -p $(dir $@)
	$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@

$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c | $(BUILD_DIR)
	mkdir -p $(dir $@)
	$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@

$(KERNEL_ELF): $(OBJ) $(SRC_DIR)/link.ld | $(BUILD_DIR)
	$(LD) $(LDFLAGS) $(OBJ) -o $@

$(KERNEL_IMG): $(KERNEL_ELF) | $(BOOT_DIR)
	$(OBJCOPY) -O binary $< $@

clean:
	rm -rf $(BUILD_DIR)
	rm -f $(KERNEL_IMG)

qemu: clean
	$(MAKE) BUILD_DIR=build/qemu BOOT_DIR=build/qemu/boot CPPFLAGS=-DQEMU_RASPI4 build/qemu/kernel8.elf
	qemu-system-aarch64 -M raspi4b -cpu cortex-a72 -m 2G -nographic -monitor none -serial stdio -kernel build/qemu/kernel8.elf
