blob: 54197419ed25e65ec2c02a17912edb28397748c9 [file] [log] [blame]
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +01001ROOT_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
2ifeq ($(ROOT_DIR),./)
3 ROOT_DIR :=
4endif
5
Andrew Scull5e96ef72018-07-18 10:46:26 +01006#
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +01007# Defaults.
Andrew Scull5e96ef72018-07-18 10:46:26 +01008#
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +01009ARCH ?= aarch64
10PLAT ?= qemu
11DEBUG ?= 1
12NAME := hafnium
13
Andrew Scull5e96ef72018-07-18 10:46:26 +010014# Toolchain
15CROSS_COMPILE ?= aarch64-linux-gnu-
16
17ifeq ($(CLANG),1)
18 CLANG := clang
19endif
20GCC ?= gcc
21
22ifdef CLANG
23 CC := $(CLANG) -target $(patsubst %-,%,$(CROSS_COMPILE))
24else
25 CC := $(CROSS_COMPILE)$(GCC)
26endif
27
28# Output
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010029OUT := $(ROOT_DIR)out/$(ARCH)/$(PLAT)
30
31all: $(OUT)/$(NAME).bin
32
33# Include platform-specific constants.
34include $(ROOT_DIR)src/arch/$(ARCH)/$(PLAT).mk
35
36define include_module
37 SRCS :=
38 OFFSET_SRCS :=
39 include $(ROOT_DIR)$(1)/rules.mk
40 GLOBAL_SRCS += $$(addprefix $(1)/,$$(SRCS))
41 GLOBAL_OFFSET_SRCS += $$(addprefix $(1)/,$$(OFFSET_SRCS))
42endef
43
44#
45# Include each module.
46#
47MODULES := src
48MODULES += src/arch/$(ARCH)
49GLOBAL_SRCS :=
50GLOBAL_OFFSET_SRCS :=
51$(foreach mod,$(MODULES),$(eval $(call include_module,$(mod))))
52
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010053#
54# Rules to build C files.
55#
56COPTS = -mcpu=cortex-a57+nofp
57COPTS += -fno-stack-protector
58COPTS += -fno-builtin -ffreestanding
59COPTS += -g
60COPTS += -O2
61COPTS += -fpic
62COPTS += -std=c11
63COPTS += -Wall -Wpedantic -Werror
Andrew Scull87425072018-07-19 11:44:35 +010064COPTS += -Wno-extended-offsetof
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010065COPTS += -DDEBUG=$(DEBUG)
66COPTS += -MMD -MP -MF $$(patsubst %,%.d,$$@)
67COPTS += -DMAX_CPUS=8
Wedson Almeida Filho87009642018-07-02 10:20:07 +010068COPTS += -DMAX_VMS=16
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010069COPTS += -DSTACK_SIZE=4096
70COPTS += -I$(ROOT_DIR)inc
71COPTS += -I$(ROOT_DIR)src/arch/$(ARCH)/inc
72COPTS += -I$(OUT)/arch/$(ARCH)/inc
73COPTS += -DGICD_BASE=$(GICD_BASE)
74COPTS += -DGICC_BASE=$(GICC_BASE)
75COPTS += -DGICR_BASE=$(GICR_BASE)
76COPTS += -DTIMER_IRQ=$(TIMER_IRQ)
77
78ifeq ($(PL011),1)
79 COPTS += -DPL011_BASE=$(PL011_BASE)
80endif
81
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010082define build_c
83 TGT := $(patsubst %.c,%.o,$(OUT)/$(patsubst src/%,%,$(1)))
84 GLOBAL_OBJS += $$(TGT)
85 REMAIN_SRCS := $$(filter-out $(1),$$(REMAIN_SRCS))
86$$(TGT): $(ROOT_DIR)$(1) | $$(dir $$(TGT))
87 $$(info CC $(ROOT_DIR)$1)
Andrew Scull7ae61652018-07-12 16:14:14 +010088 @$(CC) $(COPTS) -c $(ROOT_DIR)$(1) -o $$@
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010089endef
90
91#
92# Rules to generate offsets.
93#
94define gen_offsets
95 TMP := $(patsubst src/%,%,$(1))
96 TMP := $$(dir $$(TMP))inc/$$(notdir $$(TMP))
97 TGT := $$(patsubst %.c,%.h,$(OUT)/$$(TMP))
98 GLOBAL_OFFSETS += $$(TGT)
99$$(TGT): $(ROOT_DIR)$(1) | $$(dir $$(TGT))
100 $$(info GENOFFSET $(ROOT_DIR)$1)
Andrew Scull87425072018-07-19 11:44:35 +0100101 @$(CC) $(COPTS) -MT $$@ -S -c $(ROOT_DIR)$(1) -o - | \
102 grep ^DEFINE_OFFSET -A1 | \
103 grep -v ^--$ | \
104 sed 's/^DEFINE_OFFSET__\([^:]*\):/#define \1 \\/g' | sed 's/\.xword//g' > $$@
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +0100105endef
106
107#
108# Rules to build S files.
109#
110define build_S
111 TGT := $(patsubst %.S,%.o,$(OUT)/$(patsubst src/%,%,$(1)))
112 GLOBAL_OBJS += $$(TGT)
113 REMAIN_SRCS := $$(filter-out $(1),$$(REMAIN_SRCS))
114$$(TGT): $(ROOT_DIR)$(1) $(GLOBAL_OFFSETS) | $$(dir $$(TGT))
115 $$(info AS $(ROOT_DIR)$1)
Andrew Scull7ae61652018-07-12 16:14:14 +0100116 @$(CC) $(COPTS) -c $(ROOT_DIR)$(1) -o $$@
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +0100117endef
118
119#
120# Generate the build rules for all .c and .S files.
121#
122GLOBAL_OBJS :=
123GLOBAL_OFFSETS :=
124REMAIN_SRCS := $(GLOBAL_SRCS)
125$(foreach file,$(filter %.c,$(GLOBAL_OFFSET_SRCS)),$(eval $(call gen_offsets,$(file))))
126$(foreach file,$(filter %.c,$(GLOBAL_SRCS)),$(eval $(call build_c,$(file))))
127$(foreach file,$(filter %.S,$(GLOBAL_SRCS)),$(eval $(call build_S,$(file))))
128
129#
130# Check if there are any source files which we don't know to handle.
131#
132ifneq ($(REMAIN_SRCS),)
133 $(error Don't know how to handle $(REMAIN_SRCS))
134endif
135
136#
137# Rule to create all output directories.
138#
139define create_dir
140$1:
141 @mkdir -p $1
142endef
143$(foreach name,$(sort $(dir $(GLOBAL_OBJS))),$(eval $(call create_dir,$(name))))
144$(foreach name,$(sort $(dir $(GLOBAL_OFFSETS))),$(eval $(call create_dir,$(name))))
145
146#
147# Rules to build the hypervisor.
148#
149$(OUT)/$(NAME): $(GLOBAL_OBJS) $(ROOT_DIR)src/$(NAME).ld
150 $(info LD $(ROOT_DIR)src/$(NAME).ld)
Wedson Almeida Filho049f1412018-07-17 23:54:51 +0100151 @$(CROSS_COMPILE)ld -g -pie $(GLOBAL_OBJS) -T$(ROOT_DIR)src/$(NAME).ld --defsym PREFERRED_LOAD_ADDRESS=$(LOAD_ADDRESS) -o $@
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +0100152
153$(OUT)/$(NAME).bin: $(OUT)/$(NAME)
154 $(info OBJCOPY $@)
Wedson Almeida Filho049f1412018-07-17 23:54:51 +0100155 @$(CROSS_COMPILE)objcopy -O binary $< $@
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +0100156
157clean:
158 rm -rf $(ROOT_DIR)out
159
Andrew Scull4f170f52018-07-19 12:58:20 +0100160format:
161 find $(ROOT_DIR)src/ -name *.c -o -name *.h | xargs clang-format -style file -i
162 find $(ROOT_DIR)inc/ -name *.c -o -name *.h | xargs clang-format -style file -i
163
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +0100164-include $(patsubst %,%.d,$(GLOBAL_OBJS),$(GLOBAL_OFFSETS))