# Makefile  —  RISC-V bare-metal starter project
#
# Target:  QEMU "virt" machine, RV32IMA, machine mode
# Toolchain requirement:
#   riscv32-unknown-elf-gcc  (or riscv64-unknown-elf-gcc with -march=rv32ima -mabi=ilp32)
#
# Quick reference:
#   make          — build app.elf
#   make run      — build and launch in QEMU (Ctrl-A X to quit)
#   make dump     — disassemble the ELF (useful for debugging)
#   make clean    — remove generated files
#
# Computer Architecture: Design and Analysis (2026 edition)
# Krerk Piromsopa, Ph.D. · Chulalongkorn University

# ── Toolchain ────────────────────────────────────────────────────────
# Prefer the 32-bit bare-metal toolchain; fall back to the 64-bit one.
CROSS   ?= riscv32-unknown-elf
CC       = $(CROSS)-gcc
OBJDUMP  = $(CROSS)-objdump
OBJCOPY  = $(CROSS)-objcopy
SIZE     = $(CROSS)-size

# ── Build flags ──────────────────────────────────────────────────────
ARCH     = rv32ima
ABI      = ilp32
CFLAGS   = -march=$(ARCH) -mabi=$(ABI) -mcmodel=medany \
           -O2 -Wall -Wextra \
           -ffreestanding -fno-builtin -nostdlib \
           -g
ASFLAGS  = -march=$(ARCH) -mabi=$(ABI)
LDFLAGS  = -T link.ld -nostdlib -static

# ── Sources ───────────────────────────────────────────────────────────
SRCS_C  = main.c uart.c
SRCS_S  = startup.S
OBJS    = $(SRCS_S:.S=.o) $(SRCS_C:.c=.o)
TARGET  = app

# ── QEMU ─────────────────────────────────────────────────────────────
QEMU    ?= qemu-system-riscv32
QFLAGS   = -machine virt -bios none -kernel $(TARGET).elf -nographic

# ── Default target ───────────────────────────────────────────────────
.PHONY: all run dump clean

all: $(TARGET).elf

$(TARGET).elf: $(OBJS) link.ld
	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS)
	$(SIZE) $@

startup.o: startup.S platform.h
	$(CC) $(CFLAGS) -c -o $@ $<

%.o: %.c
	$(CC) $(CFLAGS) -c -o $@ $<

# Explicit header dependencies
main.o: main.c uart.h platform.h
uart.o: uart.c uart.h platform.h

# ── Run in QEMU ──────────────────────────────────────────────────────
run: $(TARGET).elf
	@echo "Launching QEMU  (press Ctrl-A then X to exit)"
	$(QEMU) $(QFLAGS)

# ── Disassembly ──────────────────────────────────────────────────────
dump: $(TARGET).elf
	$(OBJDUMP) -d -S $<

# ── Clean ────────────────────────────────────────────────────────────
clean:
	rm -f $(OBJS) $(TARGET).elf $(TARGET).bin
