diff --git a/.ci/check-format.sh b/.ci/check-format.sh index 74503163..78ca95e3 100755 --- a/.ci/check-format.sh +++ b/.ci/check-format.sh @@ -4,8 +4,6 @@ set -u -o pipefail -REPO_ROOT="$(git rev-parse --show-toplevel)" - # Use git ls-files to exclude submodules and untracked files C_SOURCES=() while IFS= read -r file; do @@ -58,4 +56,20 @@ else PY_FORMAT_EXIT=0 fi -exit $((C_FORMAT_EXIT + SH_FORMAT_EXIT + PY_FORMAT_EXIT)) +DTS_SOURCES=() +while IFS= read -r file; do + [ -n "$file" ] && DTS_SOURCES+=("$file") +done < <(git ls-files -- '*.dts' '*.dtsi') + +if [ ${#DTS_SOURCES[@]} -gt 0 ]; then + echo "Checking DTS/DTSI files..." + DTS_FORMAT_EXIT=0 + for dts_src in "${DTS_SOURCES[@]}"; do + dtsfmt --check "${dts_src}" + DTS_FORMAT_EXIT=$((DTS_FORMAT_EXIT + $?)) + done +else + DTS_FORMAT_EXIT=0 +fi + +exit $((C_FORMAT_EXIT + SH_FORMAT_EXIT + PY_FORMAT_EXIT + DTS_FORMAT_EXIT)) diff --git a/.dtsfmtrc.toml b/.dtsfmtrc.toml new file mode 100644 index 00000000..450da15a --- /dev/null +++ b/.dtsfmtrc.toml @@ -0,0 +1,2 @@ +indent_str = " " +warn_on_unhandled_tokens = true diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 12dba5c1..c235557a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -594,6 +594,7 @@ jobs: run: | sudo apt-get install -q=2 clang-format-18 shfmt python3-pip pip3 install black==25.1.0 + curl -LSfs https://go.mskelton.dev/dtsfmt/install | sh -s -- -y .ci/check-newline.sh .ci/check-format.sh shell: bash diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c4c462fa..a97c7fde 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -50,12 +50,24 @@ Software requirement: * [clang-format](https://clang.llvm.org/docs/ClangFormat.html) version 18. * [shfmt](https://github.com/mvdan/sh). * [black](https://github.com/psf/black) version 25.1.0. +* [dtsfmt](https://github.com/mskelton/dtsfmt). To maintain a uniform style across languages, run: * `clang-format -i *.{c,h}` to apply the project’s C/C++ formatting rules from the up-to-date .clang-format file. * `shfmt -w $(find . -type f -name "*.sh")` to clean and standardize all shell scripts. * `black .` to enforce a consistent, idiomatic layout for Python code. -* `make format` to automatically run all three formatters. +* `dtsfmt ./src/devices/` to enforce a consistent layout for device tree source (and include). +* `make format` to automatically run all four formatters. + +## Coding Style for Device Tree Source and Device Tree Source Include + +Device Tree Source (and Include) must be clean, consistent, and portable. The following `dtsfmt` rules(check `.dtsfmtrc.toml` file) are enforced project-wide: +* Use spaces for indentation. +* Indent with 4 spaces. +* Use multi-line comments. +* Use Unix-style line endings (LF). +* Remove trailing whitespace at the end of lines. +* Ensure the file ends with a newline. ## Coding Style for Shell Script diff --git a/Makefile b/Makefile index 88fa36cc..5ed91564 100644 --- a/Makefile +++ b/Makefile @@ -492,6 +492,8 @@ CLANG_FORMAT := $(shell which clang-format-18 2>/dev/null) SHFMT := $(shell which shfmt 2>/dev/null) +DTSFMT := $(shell which dtsfmt 2>/dev/null) + BLACK := $(shell which black 2>/dev/null) BLACK_VERSION := $(if $(strip $(BLACK)),$(shell $(BLACK) --version | head -n 1 | awk '{print $$2}'),) BLACK_MAJOR := $(shell echo $(BLACK_VERSION) | cut -f1 -d.) @@ -520,6 +522,15 @@ else $(Q)$(SHFMT) -w $(shell find . \( $(SUBMODULES_PRUNE_PATHS) -o -path \"./$(OUT)\" \) \ -prune -o -name "*.sh" -print) endif +ifeq ($(DTSFMT),) + $(error dtsfmt not found. Install dtsfmt and try again) +else + $(Q)for dts_src in $$(find . \( $(SUBMODULES_PRUNE_PATHS) -o -path "./$(OUT)" \) \ + -prune -o \( -name "*.dts" -o -name "*.dtsi" \) -print); \ + do \ + $(DTSFMT) $$dts_src; \ + done +endif ifeq ($(BLACK),) $(error black not found. Install black version 25.1.0 or above and try again) else diff --git a/src/devices/minimal.dts b/src/devices/minimal.dts index 1b0b0957..66a25630 100644 --- a/src/devices/minimal.dts +++ b/src/devices/minimal.dts @@ -8,24 +8,24 @@ aliases { serial0 = "/soc@F0000000/serial@4000000"; }; - chosen { bootargs = "earlycon console=ttyS0"; stdout-path = "serial0"; linux,initrd-start = ; linux,initrd-end = ; }; - cpus { #address-cells = <1>; #size-cells = <0>; timebase-frequency = <65000000>; + cpu0: cpu@0 { device_type = "cpu"; compatible = "riscv"; reg = <0>; riscv,isa = "rv32ima"; mmu-type = "riscv,sv32"; + cpu0_intc: interrupt-controller { #interrupt-cells = <1>; #address-cells = <0>; @@ -34,13 +34,11 @@ }; }; }; - sram: memory@0 { device_type = "memory"; reg = ; reg-names = "sram0"; }; - soc: soc@F0000000 { #address-cells = <1>; #size-cells = <1>; @@ -57,13 +55,14 @@ interrupts-extended = <&cpu0_intc 9>; riscv,ndev = <31>; }; - serial@4000000 { compatible = "ns16550"; reg = <0x4000000 0x100000>; interrupts = <1>; no-loopback-test; - clock-frequency = <5000000>; /* the baudrate divisor is ignored */ + clock-frequency = <5000000>; + + /* the baudrate divisor is ignored */ }; /*