1LOCAL_DIR := $(GET_LOCAL_DIR) 2 3MODULE := $(LOCAL_DIR) 4 5MODULE_SRCS += $(LOCAL_DIR)/start.S 6 7MODULE_SRCS += $(LOCAL_DIR)/arch.c 8MODULE_SRCS += $(LOCAL_DIR)/asm.S 9MODULE_SRCS += $(LOCAL_DIR)/exceptions.c 10MODULE_SRCS += $(LOCAL_DIR)/feature.c 11MODULE_SRCS += $(LOCAL_DIR)/fpu_asm.S 12MODULE_SRCS += $(LOCAL_DIR)/mmu.cpp 13MODULE_SRCS += $(LOCAL_DIR)/mp.c 14MODULE_SRCS += $(LOCAL_DIR)/sbi.c 15MODULE_SRCS += $(LOCAL_DIR)/spinlock.c 16MODULE_SRCS += $(LOCAL_DIR)/thread.c 17MODULE_SRCS += $(LOCAL_DIR)/time.c 18 19MODULE_DEPS += lib/libcpp 20 21# one file uses slightly complicated designated initializer 22MODULE_CFLAGS += -Wno-override-init 23 24SMP_MAX_CPUS ?= 1 25RISCV_MMU ?= none 26RISCV_FPU ?= false 27SUBARCH ?= 32 28RISCV_MODE ?= machine 29RISCV_EXTENSION_LIST ?= 30ARCH_RISCV_EMBEDDED ?= false 31ARCH_RISCV_TWOSEGMENT ?= false 32 33GLOBAL_DEFINES += SMP_MAX_CPUS=$(SMP_MAX_CPUS) 34GLOBAL_DEFINES += PLATFORM_HAS_DYNAMIC_TIMER=1 35 36ifeq (true,$(call TOBOOL,$(WITH_SMP))) 37GLOBAL_DEFINES += WITH_SMP=1 38endif 39 40ifeq ($(strip $(RISCV_MODE)),machine) 41$(info RISCV: Machine Mode) 42GLOBAL_DEFINES += RISCV_M_MODE=1 43ifneq ($(RISCV_MMU),none) 44$(error RISCV mmu not supported in machine mode) 45endif 46else ifeq ($(strip $(RISCV_MODE)),supervisor) 47$(info RISCV: Supervisor Mode) 48GLOBAL_DEFINES += RISCV_S_MODE=1 49else 50$(error Unknown RISC-V mode: "$(strip $(RISCV_MODE))" (valid values are "machine", "supervisor")) 51endif 52 53ifeq ($(RISCV_MMU),sv48) 54ifeq ($(SUBARCH),32) 55$(error RISCV: sv48 mmu not supported for 32 bit riscv) 56endif 57$(info RISCV: MMU sv48) 58GLOBAL_DEFINES += RISCV_MMU=48 59WITH_KERNEL_VM ?= 1 60 61# 48 bits split between two 47 bit halves 62KERNEL_ASPACE_BASE := 0xffff800000000000 63KERNEL_ASPACE_SIZE := 0x0000800000000000 64USER_ASPACE_BASE := 0x0000000001000000 65USER_ASPACE_SIZE := 0x00007ffffe000000 66 67else ifeq ($(RISCV_MMU),sv39) 68ifeq ($(SUBARCH),32) 69$(error RISCV: sv39 mmu not supported for 32 bit riscv) 70endif 71$(info RISCV: MMU sv39) 72GLOBAL_DEFINES += RISCV_MMU=39 73WITH_KERNEL_VM ?= 1 74 75# 39 bits split between two 38 bit halves 76KERNEL_ASPACE_BASE := 0xffffffc000000000 77KERNEL_ASPACE_SIZE := 0x0000004000000000 78USER_ASPACE_BASE := 0x0000000001000000 79USER_ASPACE_SIZE := 0x0000003ffe000000 80 81else ifeq ($(RISCV_MMU),sv32) 82$(info RISCV: MMU sv32) 83GLOBAL_DEFINES += RISCV_MMU=32 84WITH_KERNEL_VM ?= 1 85 86# 32 bits split between two 31 bit halves 87KERNEL_ASPACE_BASE := 0x80000000 88KERNEL_ASPACE_SIZE := 0x80000000 89USER_ASPACE_BASE := 0x01000000 90USER_ASPACE_SIZE := 0x7e000000 91 92else ifeq ($(RISCV_MMU),none) 93else 94$(error Unknown RISCV_MMU: "$(strip $(RISCV_MMU))" (valid values are "none", "sv32", "sv39", "sv48")) 95endif 96 97ifeq (true,$(call TOBOOL,$(WITH_KERNEL_VM))) 98 99GLOBAL_DEFINES += \ 100 ARCH_HAS_MMU=1 \ 101 KERNEL_ASPACE_BASE=$(KERNEL_ASPACE_BASE) \ 102 KERNEL_ASPACE_SIZE=$(KERNEL_ASPACE_SIZE) \ 103 USER_ASPACE_BASE=$(USER_ASPACE_BASE) \ 104 USER_ASPACE_SIZE=$(USER_ASPACE_SIZE) 105 106KERNEL_BASE ?= $(KERNEL_ASPACE_BASE)+$(MEMBASE) 107KERNEL_LOAD_OFFSET ?= 0 108 109GLOBAL_DEFINES += KERNEL_BASE=$(KERNEL_BASE) 110GLOBAL_DEFINES += KERNEL_LOAD_OFFSET=$(KERNEL_LOAD_OFFSET) 111 112else # no kernel vm 113 114KERNEL_BASE ?= $(MEMBASE) 115KERNEL_LOAD_OFFSET ?= 0 116 117endif 118 119ROMBASE ?= 0 120 121GLOBAL_DEFINES += ROMBASE=$(ROMBASE) 122GLOBAL_DEFINES += MEMBASE=$(MEMBASE) 123GLOBAL_DEFINES += MEMSIZE=$(MEMSIZE) 124 125# if ARCH_riscv{32|64}_TOOLCHAIN_PREFIX is set use it as an override 126# for toolchain prefix. 127ifdef ARCH_$(ARCH)$(SUBARCH)_TOOLCHAIN_PREFIX 128 TOOLCHAIN_PREFIX := $(ARCH_$(ARCH)$(SUBARCH)_TOOLCHAIN_PREFIX) 129endif 130 131# default toolchain is riscv{32|64}-elf-. assume its in the path. 132ifndef TOOLCHAIN_PREFIX 133 TOOLCHAIN_PREFIX := riscv$(SUBARCH)-elf- 134endif 135 136ifeq (true,$(call TOBOOL,$(RISCV_FPU))) 137 GLOBAL_DEFINES += RISCV_FPU=1 138endif 139 140# based on a list of optional extensions passed in, collapse the extensions into 141# a string appended to the end of the -march line below 142$(info RISCV_EXTENSION_LIST = $(RISCV_EXTENSION_LIST)) 143ifneq ($(RISCV_EXTENSION_LIST),) 144 RISCV_MARCH_EXTENSIONS := _$(subst $(SPACE),_,$(RISCV_EXTENSION_LIST)) 145else 146 RISCV_MARCH_EXTENSIONS := 147endif 148#$(info RISCV_MARCH_EXTENSIONS = $(RISCV_MARCH_EXTENSIONS)) 149 150# for the moment simply build all sources the same way, with or without float based on 151# the configuration of the platform 152ARCH_COMPILEFLAGS_FLOAT := 153ARCH_COMPILEFLAGS_NOFLOAT := 154 155# based on 32 or 64 bitness, select the right toolchain and some 156# compiler codegen flags 157ifeq ($(SUBARCH),32) 158 ifeq (true,$(call TOBOOL,$(RISCV_FPU))) 159 ARCH_COMPILEFLAGS := -march=rv32gc$(RISCV_MARCH_EXTENSIONS) -mabi=ilp32d 160 else 161 ARCH_COMPILEFLAGS := -march=rv32imac$(RISCV_MARCH_EXTENSIONS) -mabi=ilp32 162 endif 163 164 # override machine for ld -r 165 GLOBAL_MODULE_LDFLAGS += -m elf32lriscv 166else ifeq ($(SUBARCH),64) 167 GLOBAL_DEFINES += IS_64BIT=1 168 169 ifeq (true,$(call TOBOOL,$(RISCV_FPU))) 170 # HACK: use rv64imafdc instead of the equivalent rv64gc due to 171 # older toolchains not supporting the mapping of one to the other 172 # when selecting libgcc. 173 ARCH_COMPILEFLAGS := -march=rv64imafdc$(RISCV_MARCH_EXTENSIONS) -mabi=lp64d -mcmodel=medany 174 else 175 ARCH_COMPILEFLAGS := -march=rv64imac$(RISCV_MARCH_EXTENSIONS) -mabi=lp64 -mcmodel=medany 176 endif 177 178 # override machine for ld -r 179 GLOBAL_MODULE_LDFLAGS += -m elf64lriscv 180else 181 $(error SUBARCH not set or set to something unknown) 182endif 183 184# test to see if -misa-spec=2.2 is a valid switch. 185# misa-spec is added to make sure the compiler picks up the zicsr extension by default. 186MISA_SPEC := $(shell $(TOOLCHAIN_PREFIX)gcc $(ARCH_COMPILEFLAGS) -misa-spec=2.2 -E - < /dev/null > /dev/null 2>1 && echo supported) 187$(info MISA_SPEC = $(MISA_SPEC)) 188ifeq ($(MISA_SPEC),supported) 189ARCH_COMPILEFLAGS += -misa-spec=2.2 190endif 191 192# embedded switch sets the default compile optimization and passes 193# a flag to the code to switch other things on 194ifeq (true,$(call TOBOOL,$(ARCH_RISCV_EMBEDDED))) 195ARCH_OPTFLAGS ?= -Os 196GLOBAL_DEFINES += ARCH_RISCV_EMBEDDED=1 197WITH_LINKER_GC ?= 1 198else 199ARCH_OPTFLAGS ?= -O2 200WITH_LINKER_GC ?= 0 201endif 202 203LIBGCC := $(shell $(TOOLCHAIN_PREFIX)gcc $(GLOBAL_COMPILEFLAGS) $(ARCH_COMPILEFLAGS) $(GLOBAL_CFLAGS) -print-libgcc-file-name) 204$(info LIBGCC = $(LIBGCC)) 205 206# potentially generated files that should be cleaned out with clean make rule 207GENERATED += \ 208 $(BUILDDIR)/linker-onesegment.ld \ 209 $(BUILDDIR)/linker-twosegment.ld 210 211# rules for generating the linker script 212$(BUILDDIR)/linker-%.ld: $(LOCAL_DIR)/linker-%.ld $(wildcard arch/*.ld) linkerscript.phony 213 @echo generating $@ 214 @$(MKDIR) 215 $(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)/" < $< > $@.tmp 216 @$(call TESTANDREPLACEFILE,$@.tmp,$@) 217 218linkerscript.phony: 219.PHONY: linkerscript.phony 220 221# select the appropriate linker script based on if we're a one or two segment system 222ifeq (true,$(call TOBOOL,$(ARCH_RISCV_TWOSEGMENT))) 223GLOBAL_DEFINES += ARCH_RISCV_TWOSEGMENT=1 224LINKER_SCRIPT += $(BUILDDIR)/linker-twosegment.ld 225# set MAXPAGESIZE to 8 to cause the linker script to pack things in much tighter than 226# a paged sytem would. 227# NOTE: 8 seems to be about as far as you can go. experienced some extra stuffed words 228# when using 4. 229ARCH_LDFLAGS += -z max-page-size=8 230else 231GLOBAL_DEFINES += ARCH_RISCV_TWOSEGMENT=0 232LINKER_SCRIPT += $(BUILDDIR)/linker-onesegment.ld 233endif 234 235$(info ARCH_COMPILEFLAGS = $(ARCH_COMPILEFLAGS)) 236 237include make/module.mk 238 239# vim: set ts=4 sw=4 expandtab: 240