1LOCAL_DIR := $(GET_LOCAL_DIR)
2
3MODULE := $(LOCAL_DIR)
4
5MODULE_SRCS += $(LOCAL_DIR)/start.S
6MODULE_SRCS += $(LOCAL_DIR)/arch.c
7MODULE_SRCS += $(LOCAL_DIR)/asm.S
8MODULE_SRCS += $(LOCAL_DIR)/exceptions.c
9MODULE_SRCS += $(LOCAL_DIR)/thread.c
10MODULE_SRCS += $(LOCAL_DIR)/mmu.cpp
11MODULE_SRCS += $(LOCAL_DIR)/mp.c
12MODULE_SRCS += $(LOCAL_DIR)/sbi.c
13MODULE_SRCS += $(LOCAL_DIR)/spinlock.c
14MODULE_SRCS += $(LOCAL_DIR)/time.c
15
16MODULE_DEPS += lib/libcpp
17
18# one file uses slightly complicated designated initializer
19MODULE_CFLAGS += -Wno-override-init
20
21SMP_MAX_CPUS ?= 1
22RISCV_MMU ?= none
23RISCV_FPU ?= false
24SUBARCH ?= 32
25RISCV_MODE ?= machine
26
27GLOBAL_DEFINES += SMP_MAX_CPUS=$(SMP_MAX_CPUS)
28GLOBAL_DEFINES += PLATFORM_HAS_DYNAMIC_TIMER=1
29
30ifeq (true,$(call TOBOOL,$(WITH_SMP)))
31GLOBAL_DEFINES += WITH_SMP=1
32endif
33
34ifeq (true,$(call TOBOOL,$(RISCV_FPU)))
35GLOBAL_DEFINES += RISCV_FPU=1
36endif
37
38ifeq ($(strip $(RISCV_MODE)),machine)
39$(info RISCV: Machine Mode)
40GLOBAL_DEFINES += RISCV_M_MODE=1
41ifneq ($(RISCV_MMU),none)
42$(error RISCV mmu not supported in machine mode)
43endif
44else ifeq ($(strip $(RISCV_MODE)),supervisor)
45$(info RISCV: Supervisor Mode)
46GLOBAL_DEFINES += RISCV_S_MODE=1
47else
48$(error Unknown RISC-V mode: "$(strip $(RISCV_MODE))" (valid values are "machine", "supervisor"))
49endif
50
51ifeq ($(RISCV_MMU),sv48)
52ifeq ($(SUBARCH),32)
53$(error RISCV: sv48 mmu not supported for 32 bit riscv)
54endif
55$(info RISCV: MMU sv48)
56GLOBAL_DEFINES += RISCV_MMU=48
57WITH_KERNEL_VM ?= 1
58
59# 48 bits split between two 47 bit halves
60KERNEL_ASPACE_BASE := 0xffff800000000000
61KERNEL_ASPACE_SIZE := 0x0000800000000000
62USER_ASPACE_BASE   := 0x0000000001000000
63USER_ASPACE_SIZE   := 0x00007ffffe000000
64
65else ifeq ($(RISCV_MMU),sv39)
66ifeq ($(SUBARCH),32)
67$(error RISCV: sv39 mmu not supported for 32 bit riscv)
68endif
69$(info RISCV: MMU sv39)
70GLOBAL_DEFINES += RISCV_MMU=39
71WITH_KERNEL_VM ?= 1
72
73# 39 bits split between two 38 bit halves
74KERNEL_ASPACE_BASE := 0xffffffc000000000
75KERNEL_ASPACE_SIZE := 0x0000004000000000
76USER_ASPACE_BASE   := 0x0000000001000000
77USER_ASPACE_SIZE   := 0x0000003ffe000000
78
79else ifeq ($(RISCV_MMU),sv32)
80$(info RISCV: MMU sv32)
81GLOBAL_DEFINES += RISCV_MMU=32
82WITH_KERNEL_VM ?= 1
83
84# 32 bits split between two 31 bit halves
85KERNEL_ASPACE_BASE := 0x80000000
86KERNEL_ASPACE_SIZE := 0x80000000
87USER_ASPACE_BASE   := 0x01000000
88USER_ASPACE_SIZE   := 0x7e000000
89
90else ifeq ($(RISCV_MMU),none)
91else
92$(error Unknown RISCV_MMU: "$(strip $(RISCV_MMU))" (valid values are "none", "sv32", "sv39", "sv48"))
93endif
94
95ifeq (true,$(call TOBOOL,$(WITH_KERNEL_VM)))
96
97GLOBAL_DEFINES += \
98    ARCH_HAS_MMU=1 \
99    KERNEL_ASPACE_BASE=$(KERNEL_ASPACE_BASE) \
100    KERNEL_ASPACE_SIZE=$(KERNEL_ASPACE_SIZE) \
101    USER_ASPACE_BASE=$(USER_ASPACE_BASE) \
102    USER_ASPACE_SIZE=$(USER_ASPACE_SIZE)
103
104KERNEL_BASE ?= $(KERNEL_ASPACE_BASE)+$(MEMBASE)
105KERNEL_LOAD_OFFSET ?= 0
106
107GLOBAL_DEFINES += KERNEL_BASE=$(KERNEL_BASE)
108GLOBAL_DEFINES += KERNEL_LOAD_OFFSET=$(KERNEL_LOAD_OFFSET)
109
110else # no kernel vm
111
112KERNEL_BASE ?= $(MEMBASE)
113KERNEL_LOAD_OFFSET ?= 0
114
115endif
116
117ROMBASE ?= 0
118
119GLOBAL_DEFINES += ROMBASE=$(ROMBASE)
120GLOBAL_DEFINES += MEMBASE=$(MEMBASE)
121GLOBAL_DEFINES += MEMSIZE=$(MEMSIZE)
122
123# if ARCH_riscv{32|64}_TOOLCHAIN_PREFIX is set use it as an override
124# for toolchain prefix.
125ifdef ARCH_$(ARCH)$(SUBARCH)_TOOLCHAIN_PREFIX
126TOOLCHAIN_PREFIX := $(ARCH_$(ARCH)$(SUBARCH)_TOOLCHAIN_PREFIX)
127endif
128
129# default toolchain is riscv{32|64}-elf-. assume its in the path.
130ifndef TOOLCHAIN_PREFIX
131TOOLCHAIN_PREFIX := riscv$(SUBARCH)-elf-
132endif
133
134# based on 32 or 64 bitness, select the right toolchain and some
135# compiler codegen flags
136ifeq ($(SUBARCH),32)
137ARCH_COMPILEFLAGS := -march=rv32imac -mabi=ilp32
138# override machine for ld -r
139GLOBAL_MODULE_LDFLAGS += -m elf32lriscv
140else ifeq ($(SUBARCH),64)
141GLOBAL_DEFINES += IS_64BIT=1
142ARCH_COMPILEFLAGS := -march=rv64imac -mabi=lp64 -mcmodel=medany
143# override machine for ld -r
144GLOBAL_MODULE_LDFLAGS += -m elf64lriscv
145else
146$(error SUBARCH not set or set to something unknown)
147endif
148
149# embedded switch sets the default compile optimization and passes
150# a flag to the code to switch other things on
151ifeq (true,$(call TOBOOL,$(ARCH_RISCV_EMBEDDED)))
152ARCH_OPTFLAGS ?= -Os
153GLOBAL_DEFINES += ARCH_RISCV_EMBEDDED=1
154WITH_LINKER_GC ?= 1
155else
156ARCH_OPTFLAGS ?= -O2
157WITH_LINKER_GC ?= 0
158endif
159
160LIBGCC := $(shell $(TOOLCHAIN_PREFIX)gcc $(GLOBAL_COMPILEFLAGS) $(ARCH_COMPILEFLAGS) $(GLOBAL_CFLAGS) -print-libgcc-file-name)
161$(info LIBGCC = $(LIBGCC))
162
163# potentially generated files that should be cleaned out with clean make rule
164GENERATED += \
165	$(BUILDDIR)/linker-onesegment.ld \
166	$(BUILDDIR)/linker-twosegment.ld
167
168# rules for generating the linker script
169$(BUILDDIR)/linker-%.ld: $(LOCAL_DIR)/linker-%.ld $(wildcard arch/*.ld) linkerscript.phony
170	@echo generating $@
171	@$(MKDIR)
172	$(NOECHO)sed "s/%BITS%/$(SUBARCH)/g;s/%ROMBASE%/$(ROMBASE)/;s/%MEMBASE%/$(MEMBASE)/;s/%MEMSIZE%/$(MEMSIZE)/;s/%KERNEL_BASE%/$(KERNEL_BASE)/;s/%KERNEL_LOAD_OFFSET%/$(KERNEL_LOAD_OFFSET)/;s/%VECTOR_BASE_PHYS%/$(VECTOR_BASE_PHYS)/" < $< > $@.tmp
173	@$(call TESTANDREPLACEFILE,$@.tmp,$@)
174
175linkerscript.phony:
176.PHONY: linkerscript.phony
177
178# select the appropriate linker script based on if we're a one or two segment system
179ifeq (true,$(call TOBOOL,$(ARCH_RISCV_TWOSEGMENT)))
180GLOBAL_DEFINES += ARCH_RISCV_TWOSEGMENT=1
181LINKER_SCRIPT += $(BUILDDIR)/linker-twosegment.ld
182# set MAXPAGESIZE to 8 to cause the linker script to pack things in much tighter than
183# a paged sytem would.
184# NOTE: 8 seems to be about as far as you can go. experienced some extra stuffed words
185# when using 4.
186ARCH_LDFLAGS += -z max-page-size=8
187else
188GLOBAL_DEFINES += ARCH_RISCV_TWOSEGMENT=0
189LINKER_SCRIPT += $(BUILDDIR)/linker-onesegment.ld
190endif
191
192include make/module.mk
193