Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Metal depend script #251

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions freedom-metal.make
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Copyright © 2020 Keith Packard #
# SPDX-License-Identifier: Apache-2.0 #

.DEFAULT_GOAL = $(PROGRAM)

ifeq ($(RISCV_LIBC),picolibc)
include $(FREEDOM_METAL)/metal_pico.make
endif

ifeq ($(RISCV_LIBC),nano)
include $(FREEDOM_METAL)/metal_nano.make
endif

include $(FREEDOM_METAL)/metal-depend.make

include metal.mk

SOURCE ?= .

SOURCE_VPATH ?= $(SOURCE)

vpath %.c $(SOURCE_VPATH):$(METAL_HELPER_VPATH):$(TARGET_C_VPATH)
vpath %.S $(SOURCE_VPATH):$(METAL_HELPER_VPATH):$(TARGET_S_VPATH)

CC = riscv64-unknown-elf-gcc

LDFLAGS = -nostartfiles -Wl,--gc-sections -T$(LDSCRIPT)

ABIFLAGS = $(METAL_CFLAGS) -msave-restore

INCFLAGS = -I. -I$(FREEDOM_METAL)

OPT ?= -Os -g

CFLAGS = --specs=$(RISCV_LIBC).specs -ffunction-sections -fdata-sections $(OPT) $(ABIFLAGS) $(INCFLAGS) $(LDFLAGS) $(SOURCE_CFLAGS)
LIBS = $(SOURCE_LIBS)

SRC_C += $(METAL_HELPER_C) $(TARGET_C)
SRC_S += $(METAL_HELPER_S) $(TARGET_S)
OBJ = $(notdir $(SRC_C:.c=.o)) $(notdir $(SRC_S:.S=.o))
GEN_HDR = metal/machine.h metal/machine/platform.h metal/machine/inline.h metal/machine-inline.h
HDR = $(wildcard *.h) $(GEN_HDR)

ifndef quiet

V?=0
# The user has explicitly enabled quiet compilation.
ifeq ($(V),0)
quiet = @printf " $1 $2 $@\n"; $($1)
endif

# Otherwise, print the full command line.
quiet ?= $($1)

.c.o:
$(call quiet,CC) -c $(CFLAGS) -o $@ $<

.S.o:
$(call quiet,CC) -c $(CFLAGS) -o $@ $<
endif

$(PROGRAM): $(OBJ) $(LDSCRIPT)
$(CC) $(CFLAGS) -o $@ $(OBJ) -Wl,-Map=$(PROGRAM).map $(LIBS)

$(OBJ): $(HDR)

clean::
rm -f $(PROGRAM) $(PROGRAM).map *.o

echo::
echo $(OBJ)
49 changes: 49 additions & 0 deletions metal-depend.make
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Copyright © 2020 Keith Packard #
# SPDX-License-Identifier: Apache-2.0 #

METAL_DEPEND ?= $(FREEDOM_METAL)/scripts/metal_depend/metal_depend.py
LDSCRIPT_GENERATOR ?= $(FREEDOM_METAL)/../scripts/ldscript-generator/generate_ldscript.py

LDSCRIPT ?= metal.default.lds

METAL_HDR = metal/machine.h metal/machine/platform.h metal/machine/inline.h metal/machine-inline.h

METAL_FILES = metal.mk $(METAL_HDR) design.dtb $(LDSCRIPT)

ifneq ($(METAL_FEATURES),)
METAL_FEATURES_FLAG=-f $(METAL_FEATURES)
endif

include $(BSP)/settings.mk

METAL_CFLAGS=-march=$(RISCV_ARCH) -mabi=$(RISCV_ABI) -mcmodel=$(RISCV_CMODEL)

metal.mk: $(BSP)/design.dts
python3 $(METAL_DEPEND) -o $@ -d $(BSP)/design.dts $(METAL_FEATURES_FLAG) -m $(FREEDOM_METAL)

metal/machine.h: metal design.dtb
freedom-metal_header-generator -d design.dtb -o $@

metal/machine/platform.h: metal/machine design.dtb
freedom-bare_header-generator -d design.dtb -o $@

metal/machine-inline.h: metal/machine.h

metal/machine/inline.h: metal/machine
echo "#include <metal/machine-inline.h>" > $@

metal:
mkdir $@

metal/machine:
mkdir -p $@

design.dtb: $(BSP)/design.dts
dtc -I dts -O dtb -o $@ $^

$(LDSCRIPT): $(BSP)/design.dts
$(LDSCRIPT_GENERATOR) -d $(BSP)/design.dts -o $@

clean::
$(RM) $(METAL_FILES)
$(RM) -r metal
39 changes: 39 additions & 0 deletions metal_nano.make
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
METAL_HELPER_C = \
nanosleep.c \
sys_access.c \
sys_chdir.c \
sys_chmod.c \
sys_chown.c \
sys_clock_gettime.c \
sys_close.c \
sys_execve.c \
sys_exit.c \
sys_faccessat.c \
sys_fork.c \
sys_fstat.c \
sys_fstatat.c \
sys_ftime.c \
sys_getcwd.c \
sys_getpid.c \
sys_gettimeofday.c \
sys_isatty.c \
sys_kill.c \
sys_link.c \
sys_lseek.c \
sys_lstat.c \
sys_open.c \
sys_openat.c \
sys_read.c \
sys_sbrk.c \
sys_stat.c \
sys_sysconf.c \
sys_times.c \
sys_unlink.c \
sys_utime.c \
sys_wait.c \
sys_write.c

METAL_HELPER_S = \
crt0.S

METAL_HELPER_VPATH=$(FREEDOM_METAL)/gloss
14 changes: 14 additions & 0 deletions metal_pico.make
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
METAL_HELPER_C = \
iob.c \
sys_sbrk.c \
sys_exit.c \
sys_times.c \
sys_sysconf.c \
sys_gettimeofday.c \
sys_clock_gettime.c \
sys_write.c

METAL_HELPER_S = \
crt0.S

METAL_HELPER_VPATH=$(FREEDOM_METAL)/pico:$(FREEDOM_METAL)/gloss
3 changes: 2 additions & 1 deletion pico/iob.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,5 @@ static int metal_flush(FILE *file) { return 0; }
static FILE __stdio =
FDEV_SETUP_STREAM(metal_putc, metal_getc, metal_flush, _FDEV_SETUP_RW);

FILE *const __iob[3] = {&__stdio, &__stdio, &__stdio};
/* Let applications replace this if they want */
FILE *const __iob[3] __attribute__((weak)) = {&__stdio, &__stdio, &__stdio};
2 changes: 2 additions & 0 deletions scripts/metal_depend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
__pycache__
venv
26 changes: 26 additions & 0 deletions scripts/metal_depend/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright (c) 2020 SiFive Inc.
# SPDX-License-Identifier: Apache-2.0

all: virtualenv

.PHONY: virtualenv
virtualenv: venv/.stamp

venv/.stamp: venv/bin/activate requirements.txt
. venv/bin/activate && pip install --upgrade pip
. venv/bin/activate && pip install -r requirements.txt
@echo "Remember to source venv/bin/activate!"
touch $@

venv/bin/activate:
python3 -m venv venv

.PHONY: test-lint
test-lint: virtualenv
. venv/bin/activate && pylint *.py

.PHONY: test
test: test-lint

clean:
-rm -rf venv __pycache__
51 changes: 51 additions & 0 deletions scripts/metal_depend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# metal_depend

This is a python tool based on pydevicetree
([GitHub](https://github.com/sifive/pydevicetree)/[PyPI](https://pypi.org/project/pydevicetree/))
which computes the set of FreedomMetal sources needed on a particular platform.

## Usage

```
usage: metal_depend.py [-h] -d DTS -o OUTPUT

Compute freedom-metal depedencies from Devicetrees

optional arguments:
-h, --help show this help message and exit
-d DTS, --dts DTS The path to the Devicetree for the target
-o OUTPUT, --output OUTPUT
The path of the linker script file to output
```

## Required Devicetree Properties

This source dependency generator expects that the Devicetree has annotated
each block with the compatible hardware definition. That property is:

- `compatible`, which describes which interface this block supports

Each of these properties is a `string` that describes the interface supported.

For example, the chosen node may include the following property:
```
compatible = "sifive,fe310-g000,hfxosc";
```
This maps to a driver named sifive_fe310-g000_hfxosc.c, which is found
in freedom-metal/src/drivers

## Example Invocation

```
$ ./metal_depend.py -d e31.dts -o metal.mk
Discovering source dependencies for e31.dts

$ head -n 20 metal.mk
```

## Copyright and License

Copyright (c) 2020 SiFive Inc.

The contents of this repository are distributed according to the terms described in the LICENSE
file.
77 changes: 77 additions & 0 deletions scripts/metal_depend/build.wake
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
tuple MetalDependOptions =
global TopDTSFile: Path
global OtherDTSFiles: List Path
global OutputFile: String
global Layout: MetalDependLayout

global data MetalDependLayout =
# The default mode tries to strike a good balance for all use-cases.
# If you don't need scratchpad or ramrodata modes, use the default one.
METALDEPEND_DEFAULT
# Scratchpad mode places the entire binary contents into the memory
# selected by metal,ram in the chosen node.
METALDEPEND_SCRATCHPAD
# Ramrodata mode places all read-only data into writable memory under
# the assumption that this decreases read latency for benchmarks.
# Also, if the memory selected by metal,itim is large enough, this places
# all non-init text into the ITIM.
METALDEPEND_RAMRODATA
# This layout is used for freertos use when pmp is need, it introduce symbole
# and sections for memory isolation (based on defauult lds)
METALDEPEND_FREERTOS

# Instead of copying the script sources into build/{here}, we'll just
# execute directly out of the package directory, since nothing gets
# modified during execution.
#
# The virtualenv does get placed in build/{here} by
# addPythonRequirementsEnv, along with a copy of requirements.txt
def generatorDir = here

#######################################################################
# makeMetalDependOptions takes the following parameters:
# - topDTSFile: The top-level Devicetree source file
# - otherDTSFiles: any other Devicetree source files included in the
# hierarchy of Devicetree source files
# - layout: one of {METALDEPEND_DEFAULT, METALDEPEND_SCRATCHPAD,
# METALDEPEND_RAMRODATA}
# - outputFile: A string representing the path of the output file to
# produce
#######################################################################
global def makeMetalDependOptions topDTSFile otherDTSFiles layout outputFile =
MetalDependOptions topDTSFile otherDTSFiles outputFile layout

global def runMetalDepend options =
def topDTSFile = options.getMetalDependOptionsTopDTSFile
def otherDTSFiles = options.getMetalDependOptionsOtherDTSFiles

def inputs =
# During execution, the generator needs access to both
# Python sources and the linker script template files
def generatorSources = sources here `.*\.(py|lds)`
def dtsSources = topDTSFile, otherDTSFiles
generatorSources ++ dtsSources

def outputs = options.getMetalDependOptionsOutputFile, Nil

def args =
def base =
"-d", topDTSFile.getPathName,
"-o", options.getMetalDependOptionsOutputFile,
Nil

match options.getMetalDependOptionsLayout
METALDEPEND_DEFAULT = base
METALDEPEND_SCRATCHPAD = "--scratchpad", base
METALDEPEND_RAMRODATA = "--ramrodata", base
METALDEPEND_FREERTOS = "--freertos", base

makePlan (pythonCommand "{generatorDir}/metal-depend.py" args) inputs
| addPlanRelativePath "PYTHONPATH" generatorDir
| addPythonRequirementsEnv generatorDir
| setPlanFnOutputs (\_ outputs)
| runJob

# This allows the python virtualenv to be created prior to running a build
# with `wake preinstall Unit`.
publish preinstall = (pythonRequirementsInstaller generatorDir), Nil
Loading