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