Skip to content
Merged
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
19 changes: 14 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,17 @@ GCPT_SOURCE_DIR := $(if $(filter 1,$(MULTIHART)),bootloader/LibCheckpoint,bootlo
GCPT_BUILD_DIR := $(if $(filter 1,$(MULTIHART)),build/LibCheckpoint,build/LibCheckpointAlpha)
GCPT_BIN := $(GCPT_BUILD_DIR)/build/gcpt.bin
GCPT_DEFAULT_DTB ?= $(if $(DEFAULT_DTB),$(DEFAULT_DTB),xiangshan)
GCPT_DEFAULT_DTS := dts/$(GCPT_DEFAULT_DTB).dts.in
GCPT_CONFIGURE_MODE := $(if $(filter 1,$(MULTIHART)),dual_core,normal)
GCPT_CONFIG_STAMP := $(if $(filter 1,$(MULTIHART)),build/LibCheckpoint-config/mode.$(GCPT_CONFIGURE_MODE),build/LibCheckpointAlpha-config/dtb.$(shell printf '%s\n' "$(GCPT_DEFAULT_DTB)" | sha256sum | cut -d ' ' -f 1))
GCPT_DTB_CONFIG_HASH := $(shell printf '%s\n' "$(GCPT_DEFAULT_DTB)" | sha256sum | cut -d ' ' -f 1)
GCPT_CONFIG_STAMP := $(if $(filter 1,$(MULTIHART)),build/LibCheckpoint-config/mode.$(GCPT_CONFIGURE_MODE),build/LibCheckpointAlpha-config/dtb.$(GCPT_DTB_CONFIG_HASH))
GCPT_SOURCES := $(if $(filter 1,$(MULTIHART)),$(shell find $(GCPT_SOURCE_DIR) -path '*/.git' -prune -o -path '*/tests' -prune -o -type f -print 2>/dev/null),$(shell find $(GCPT_SOURCE_DIR) -path '*/.git' -prune -o -type f -print 2>/dev/null))
GCPT_DTS_SOURCES := $(if $(filter 1,$(MULTIHART)),,$(shell find dts -type f 2>/dev/null))
GCPT_DTS_SOURCES := $(if $(filter 1,$(MULTIHART)),,$(GCPT_DEFAULT_DTS))
$(GCPT_CONFIG_STAMP):
mkdir -p "$(@D)"
rm -f $(if $(filter 1,$(MULTIHART)),build/LibCheckpoint-config/mode.*,build/LibCheckpointAlpha-config/dtb.*)
touch "$@"
$(GCPT_BIN): scripts/build-gcpt.sh $(TOOLCHAIN_WRAPPER) $(GCPT_SOURCES) $(GCPT_DTS_SOURCES) $(GCPT_CONFIG_STAMP) $(if $(filter 1,$(MULTIHART)),$(SBI_BIN),)
$(GCPT_BIN): scripts/build-gcpt.sh scripts/dts-config.sh $(TOOLCHAIN_WRAPPER) $(GCPT_SOURCES) $(GCPT_DTS_SOURCES) $(GCPT_CONFIG_STAMP) $(if $(filter 1,$(MULTIHART)),$(SBI_BIN),)
CROSS_COMPILE="$(abspath $(BUILDROOT_DIR)/output/host/bin)/riscv64-linux-" \
GCPT_IMPLEMENTATION="$(GCPT_IMPLEMENTATION)" \
GCPT_CONFIGURE_MODE="$(GCPT_CONFIGURE_MODE)" \
Expand All @@ -70,9 +72,16 @@ $(GCPT_BIN): scripts/build-gcpt.sh $(TOOLCHAIN_WRAPPER) $(GCPT_SOURCES) $(GCPT_D
bash scripts/build-gcpt.sh $(GCPT_SOURCE_DIR) $(GCPT_BUILD_DIR)

# Build OpenSBI
$(SBI_BIN): scripts/build-sbi.sh bootloader/opensbi.config $(TOOLCHAIN_WRAPPER)
SBI_CONFIG_STAMP := $(SBI_BUILD_DIR)-config/$(if $(filter 1,$(MULTIHART)),multihart-fixed,dtb.$(GCPT_DTB_CONFIG_HASH))
$(SBI_CONFIG_STAMP):
mkdir -p "$(@D)"
rm -f "$(@D)"/dtb.* "$(@D)"/multihart-fixed
touch "$@"
$(SBI_BIN): scripts/build-sbi.sh scripts/dts-config.sh bootloader/opensbi.config $(TOOLCHAIN_WRAPPER) $(if $(filter 1,$(MULTIHART)),,$(GCPT_DEFAULT_DTS)) $(SBI_CONFIG_STAMP)
CROSS_COMPILE="$(abspath $(BUILDROOT_DIR)/output/host/bin)/riscv64-linux-" \
MULTIHART="$(MULTIHART)" \
DEFAULT_DTB="$(GCPT_DEFAULT_DTB)" \
DTS_TEMPLATE_DIR="$(abspath dts)" \
bash scripts/build-sbi.sh bootloader/opensbi $(SBI_BUILD_DIR)

define add_workload_linux
Expand Down Expand Up @@ -101,7 +110,7 @@ build/linux-workloads/$(1)/firmware-vars.$(LINUX_FIRMWARE_BUILD_VARS_HASH).stamp
rm -f "$$(@D)"/firmware-vars.*.stamp
touch "$$@"

build/linux-workloads/$(1)/fw_payload.bin: $$(shell find $$(abspath dts)) $(GCPT_BIN) dts/xiangshan.dts.in scripts/build-sbi.sh scripts/build-firmware-linux.sh build/linux-workloads/$(1)/rootfs.cpio $(LINUX_IMAGE) $(SBI_BIN) build/linux-workloads/$(1)/firmware-vars.$(LINUX_FIRMWARE_BUILD_VARS_HASH).stamp
build/linux-workloads/$(1)/fw_payload.bin: $$(shell find $$(abspath dts)) $(GCPT_BIN) dts/xiangshan.dts.in scripts/build-sbi.sh scripts/dts-config.sh scripts/build-firmware-linux.sh build/linux-workloads/$(1)/rootfs.cpio $(LINUX_IMAGE) $(SBI_BIN) build/linux-workloads/$(1)/firmware-vars.$(LINUX_FIRMWARE_BUILD_VARS_HASH).stamp
CROSS_COMPILE="$$(abspath $(BUILDROOT_DIR)/output/host/bin)/riscv64-linux-" \
DTC="$$(abspath $(BUILDROOT_DIR)/output/host/bin)/dtc" \
DEFAULT_DTB="$(LINUX_DEFAULT_DTB)" \
Expand Down
26 changes: 14 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ For Linux workloads:

- `build/linux-workloads/workload_name/fw_payload.bin`: The all-in-one image that can be directly loaded by NEMU.
- `build/linux-workloads/workload_name/rootfs.cpio`: The initramfs overlay of the workload.
- `build/linux-workloads/workload_name/dt/`: A directory containing device tree files.
- `build/linux-workloads/workload_name/dt/`: The selected device tree source and binary.

For AM workloads:

Expand Down Expand Up @@ -64,21 +64,23 @@ To create a compressed tarball containing all built workloads, run `make tarball

- [x] Add workload `kvmtool`.
- [ ] Add workload `Xvisor`.
- [x] Support for building multiple device trees for each Linux workload.
- [x] Support for selectable device tree templates.
- [ ] Test Linux workloads with checkpoint functionalities of NEMU.

## Format of the Image

### Linux Workloads

For Linux workloads, the image assumes that execution begins at `0x80000000`, and the image is loaded into a continuous memory starting from that address. A single-core image contains:
For single-core Linux workloads, execution begins at the DRAM base from the
selected DTS, and the image is loaded into continuous memory starting there.
A single-core image contains:

| Offset | Content |
|---------|-------------------------------|
| 0.0 MiB | LibCheckpointAlpha |
| 1.0 MiB | OpenSBI |
| 1.5 MiB | device tree |
| 2.0 MiB | Linux kernel |
| >=2.0 MiB | Linux kernel at the next 2 MiB-aligned address |
| -- | initramfs containing workload |

A multi-hart image uses the fixed QEMU checkpoint layout:
Expand All @@ -96,15 +98,14 @@ For OpenSBI, the multi-hart image uses `FW_TEXT_START=0x80100000`,
The canonical single-core and multi-hart DTS memory maps, including DRAM
profiles and DTS selection examples, are in [dts/README.md](dts/README.md#single-core-physical-memory-map).

Multiple device trees are built for each workload, each corresponds to a specific NEMU configuration. The device tree files are placed under the `dt` directory in the build output directory of that workload. The "default" device tree built into the image is `dt/xiangshan.dtb`. To replace the device tree, the following command can be used:
For single-core images, the selected DTS is the source of truth for the DRAM
base used by GCPT, OpenSBI, the firmware packer, and the exported manifest, as
well as the CLINT address used by GCPT. Its generated DTS and DTB are placed in
the workload's `dt` directory and the DTB is embedded in the firmware image.

For DTS files used with gcpt, the beginning of RAM must be reserved with a `reserved-memory` node so Linux does not allocate or map the gcpt checkpoint buffer. The XiangShan FPGA DTS templates reserve 1 MiB at `0x80000000` for this purpose.
For DTS files used with gcpt, the beginning of RAM must be reserved with a `reserved-memory` node so Linux does not allocate or map the gcpt checkpoint buffer. The XiangShan FPGA DTS templates reserve the first 1 MiB of their declared DRAM for this purpose.

```shell
dd conv=notrunc bs=1024 seek=1536 if=dt/some_device.dtb of=fw_payload.bin
```

OpenSBI is patched (see `bootloader/opensbi.patch`) to load the device tree from a fixed location. The initramfs is placed after the Linux kernel and aligned to 1 MiB.
OpenSBI is patched (see `bootloader/opensbi.patch`) to load the device tree from a fixed offset relative to the DRAM base. The initramfs is placed after the Linux kernel and aligned to 1 MiB.

### AM Workloads

Expand Down Expand Up @@ -205,7 +206,8 @@ Then run `make` to build your new workload.

## Adding a Device Tree

To add a device tree, simply create a template file `device_name.dts.in` in the `dts` directory. It will be automatically found by the build system.
To add a device tree, create a template file `device_name.dts.in` in the `dts`
directory and select it with `DEFAULT_DTB=device_name`.

Currently, the memory location of the initramfs containing the workload is passed to the kernel by device tree. So for each workload, device tree files are generated from the template on the fly, because the size of the initramfs cannot be known in advance. You should use the parameters `INITRAMFS_BEGIN` and `INITRAMFS_END` in the device tree template.

Expand Down
2 changes: 1 addition & 1 deletion bootloader/LibCheckpointAlpha
24 changes: 16 additions & 8 deletions dts/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Device Tree Templates

This directory contains device tree templates for each device configuration. For each workload, device tree files are generated from the template on the fly, because some parameters cannot be known in advance.
This directory contains device tree templates for each device configuration.
For each workload, the selected device tree is generated from its template on
the fly because some parameters cannot be known in advance.

## Parameters

Expand Down Expand Up @@ -29,25 +31,31 @@ the build fails if it does not.

Single-core images use `MULTIHART=0` and LibCheckpointAlpha. They keep the
original compact placement below; the multi-hart checkpoint-state reservation
and the `0x88600000` kernel address do not apply:
and the `0x88600000` kernel address do not apply. This table shows the default
`0x80000000` DRAM base:

| Physical address / range | Size or offset | Assignment |
|-------------------------|----------------|------------|
| `0x80000000–0x800fffff` | 1 MiB | LibCheckpointAlpha checkpoint-recovery program; reserved as `no-map` in the DTS |
| `0x80100000` | +1 MiB | OpenSBI firmware starts here |
| `0x80180000` | +1.5 MiB | Device tree placed here by firmware assembly |
| `0x80200000` and above | +2 MiB | Linux kernel image, then the MiB-aligned initramfs |
| `0x80200000` and above | >=+2 MiB | Linux kernel at the first 2 MiB-aligned address, then the MiB-aligned initramfs |

The single-core firmware packer uses `DTB_OFFSET_KB=1536`,
`SBI_OFFSET_KB=1024`, and `KERNEL_OFFSET_MB=2`. The initramfs address is
`SBI_OFFSET_KB=1024`, and a minimum kernel offset of 2 MiB. The kernel's
physical address is rounded up to a 2 MiB boundary. The initramfs address is
computed from the actual kernel size and starts at the next MiB boundary. The
selected single-core DTS supplies the DRAM capacity; no fixed 8 GiB or 64 GiB
profile is imposed by this layout.
selected single-core DTS supplies the DRAM base and capacity; no fixed 8 GiB or
64 GiB profile is imposed by this layout.

The `memory` node's first address cell pair is the image's DRAM base. The build
uses it for GCPT, OpenSBI, kernel, initramfs, and manifest placement, and uses
the single `riscv,clint0` node to configure GCPT.

## Multi-Hart Physical Memory Map

All `MULTIHART=1` images use the same physical placement, regardless of the
selected DRAM capacity or hart count. The image is loaded at `0x80000000`:
All `MULTIHART=1` images use the same physical placement, regardless of
the selected DRAM capacity or hart count. The image is loaded at `0x80000000`:

| Physical range | Size | Assignment |
|----------------|------|------------|
Expand Down
123 changes: 52 additions & 71 deletions scripts/build-firmware-linux.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@ DTS_TEMPLATE_DIR="$(realpath "$3")"
KERNEL_IMAGE="$(realpath "$4")"
WORKLOAD_BUILD_DIR="$(realpath "$5")"
CPIO_ARCHIVE="$WORKLOAD_BUILD_DIR/rootfs.cpio"
source "$(dirname "${BASH_SOURCE[0]}")/dts-config.sh"
DEFAULT_DTB="${DEFAULT_DTB:-}"
DTB_MEMORY_PROFILE="${DTB_MEMORY_PROFILE:-}"
DTB_MIN_MEMORY_BYTES="${DTB_MIN_MEMORY_BYTES:-}"
HARTS="${HARTS:-2}"
readonly MULTIHART_MAX_HARTS=128
readonly MULTIHART_KERNEL_OFFSET_MB=134

MEM_BEGIN=$(( 0x80000000 ))
DTB_OFFSET_KB=1536
DTB_MAX_SIZE_KB=512
SBI_OFFSET_KB=1024
KERNEL_OFFSET_MB=2
KERNEL_MIN_OFFSET_MB=2

if [ "${MULTIHART:-0}" = 1 ]; then
if [ -z "$DEFAULT_DTB" ]; then
Expand All @@ -34,18 +34,52 @@ if [ "${MULTIHART:-0}" = 1 ]; then
fi
DTB_OFFSET_KB=2048
DTB_MAX_SIZE_KB=1024
KERNEL_OFFSET_MB="$MULTIHART_KERNEL_OFFSET_MB"
KERNEL_MIN_OFFSET_MB="$MULTIHART_KERNEL_OFFSET_MB"
elif [ -z "$DEFAULT_DTB" ]; then
DEFAULT_DTB=xiangshan
fi

resolve_default_dtb_base() {
local default_dtb="$1"
local memory_profile="$2"

if [ -z "$memory_profile" ]; then
printf '%s\n' "$default_dtb"
return
fi
if [[ "$default_dtb" == *-novec ]]; then
printf '%s\n' "${default_dtb%-novec}-mem${memory_profile}-novec"
return
fi
printf '%s\n' "${default_dtb}-mem${memory_profile}"
}

DEFAULT_DTB_BASE="$(resolve_default_dtb_base "$DEFAULT_DTB" "$DTB_MEMORY_PROFILE")"
DEFAULT_DTB_TEMPLATE="$DTS_TEMPLATE_DIR/$DEFAULT_DTB_BASE.dts.in"
if ! [ -f "$DEFAULT_DTB_TEMPLATE" ]; then
echo "Default device tree template not found in dts directory: $DEFAULT_DTB_TEMPLATE" >&2
exit 1
fi
DTS_CONFIG="$(dts_extract_config "$DEFAULT_DTB_TEMPLATE")"
read -r MEM_BEGIN MEM_SIZE CLINT_MMIO <<< "$DTS_CONFIG"
if [ "${MULTIHART:-0}" = 1 ] && {
(( MEM_BEGIN != 0x80000000 )) ||
(( CLINT_MMIO != 0x38000000 ));
}; then
printf 'Multi-hart DTS addresses are fixed: expected DRAM=0x80000000 and CLINT=0x38000000 in %s\n' \
"$DEFAULT_DTB_TEMPLATE" >&2
exit 1
fi

KILOBYTE=1024
MEGABYTE=$(( 1024*1024 ))
KERNEL_SIZE=$(stat -c%s "$KERNEL_IMAGE")
KERNEL_SIZE_MB=$(( (KERNEL_SIZE + MEGABYTE - 1) / MEGABYTE ))
INITRAMFS_OFFSET_MB=$(( KERNEL_OFFSET_MB + KERNEL_SIZE_MB ))
KERNEL_BEGIN_ADDR="$(dts_linux_kernel_address "$MEM_BEGIN" "$((KERNEL_MIN_OFFSET_MB * MEGABYTE))")"
KERNEL_END_ADDR=$(( KERNEL_BEGIN_ADDR + KERNEL_SIZE ))
KERNEL_OFFSET_KB=$(( (KERNEL_BEGIN_ADDR - MEM_BEGIN) / KILOBYTE ))
INITRAMFS_BEGIN_ADDR=$(( (KERNEL_END_ADDR + MEGABYTE - 1) / MEGABYTE * MEGABYTE ))
INITRAMFS_OFFSET_KB=$(( (INITRAMFS_BEGIN_ADDR - MEM_BEGIN) / KILOBYTE ))
INITRAMFS_SIZE=$(stat -c%s "$CPIO_ARCHIVE")
INITRAMFS_BEGIN_ADDR=$(( MEM_BEGIN + INITRAMFS_OFFSET_MB*MEGABYTE ))
INITRAMFS_END_ADDR=$(( INITRAMFS_BEGIN_ADDR + INITRAMFS_SIZE ))
INITRAMFS_BEGIN_HEX=$(printf "0x%x" "$INITRAMFS_BEGIN_ADDR")
INITRAMFS_END_HEX=$(printf "0x%x" "$INITRAMFS_END_ADDR")
Expand All @@ -58,41 +92,11 @@ INITRAMFS_END_LO=$(printf "0x%x" $(( INITRAMFS_END_ADDR & 0xffffffff )))
DTC="${DTC:-dtc}"
dtb_memory_range_bytes() {
local dts_file="$1"
local cells
cells="$(
awk '
/device_type[[:space:]]*=[[:space:]]*"memory"/ { in_memory = 1 }
in_memory && /reg[[:space:]]*=/ {
line = $0
while (line !~ /;/ && (getline more) > 0) {
line = line " " more
}
gsub(/[<>;]/, " ", line)
n = split(line, fields, /[[:space:]]+/)
count = 0
for (i = 1; i <= n; i++) {
if (fields[i] ~ /^(0x[0-9a-fA-F]+|[0-9]+)$/) {
values[++count] = fields[i]
}
}
if (count >= 4) {
print values[1], values[2], values[3], values[4]
exit
}
}
' "$dts_file"
)"
if [ -z "$cells" ]; then
return 1
fi
set -- $cells
local begin_high="$1"
local begin_low="$2"
local size_high="$3"
local size_low="$4"
printf '%s %s\n' \
$(( begin_high * 4294967296 + begin_low )) \
$(( size_high * 4294967296 + size_low ))
local memory_begin memory_bytes unused_clint
local dts_config
dts_config="$(dts_extract_config "$dts_file")" || return
read -r memory_begin memory_bytes unused_clint <<< "$dts_config"
printf '%s %s\n' "$((memory_begin))" "$((memory_bytes))"
}

check_dtb_memory_layout() {
Expand All @@ -107,9 +111,9 @@ check_dtb_memory_layout() {
exit 1
fi
read -r memory_begin memory_bytes <<< "$memory_range"
if [ "$memory_begin" -ne "$MEM_BEGIN" ]; then
printf 'DTS memory must begin at 0x80000000: found 0x%x in %s\n' \
"$memory_begin" "$dts_file" >&2
if (( memory_begin != MEM_BEGIN )); then
printf 'DTS memory base differs from selected DTS: found 0x%x, expected 0x%x in %s\n' \
"$memory_begin" "$MEM_BEGIN" "$dts_file" >&2
exit 1
fi
if [ -n "$min_bytes" ] && [ "$memory_bytes" -lt "$min_bytes" ]; then
Expand Down Expand Up @@ -242,32 +246,9 @@ build-dtb() {
"$DTC" -I dts -O dtb -o "$dtb_file" "$dts_file"
}

resolve_default_dtb_base() {
local default_dtb="$1"
local memory_profile="$2"

if [ -z "$memory_profile" ]; then
printf '%s\n' "$default_dtb"
return
fi
if [[ "$default_dtb" == *-novec ]]; then
printf '%s\n' "${default_dtb%-novec}-mem${memory_profile}-novec"
return
fi
printf '%s\n' "${default_dtb}-mem${memory_profile}"
}

# Assemble the image using the selected DTB basename and optional memory profile.
DEFAULT_DTB_BASE="$(resolve_default_dtb_base "$DEFAULT_DTB" "$DTB_MEMORY_PROFILE")"
DEFAULT_DTB_TEMPLATE="$DTS_TEMPLATE_DIR/$DEFAULT_DTB_BASE.dts.in"
if ! [ -f "$DEFAULT_DTB_TEMPLATE" ]; then
echo "Default device tree template not found in dts directory: $DEFAULT_DTB_TEMPLATE" >&2
exit 1
fi

for dts_template in "$DTS_TEMPLATE_DIR"/*.dts.in ; do
build-dtb "$dts_template"
done
rm -rf "$WORKLOAD_BUILD_DIR/dt"
build-dtb "$DEFAULT_DTB_TEMPLATE"

DEFAULT_DTB_FILE="$WORKLOAD_BUILD_DIR/dt/$DEFAULT_DTB_BASE.dtb"
DEFAULT_DTS_FILE="$WORKLOAD_BUILD_DIR/dt/$DEFAULT_DTB_BASE.dts"
Expand Down Expand Up @@ -297,5 +278,5 @@ check_image_component_size DTB "$DEFAULT_DTB_FILE" $(( DTB_MAX_SIZE_KB * KILOBYT
dd if="$STARTUP_FILE" of="$WORKLOAD_BUILD_DIR/fw_payload.bin" bs="$KILOBYTE" count="$SBI_OFFSET_KB" status=none
dd if="$DEFAULT_DTB_FILE" of="$WORKLOAD_BUILD_DIR/fw_payload.bin" bs="$KILOBYTE" seek="$DTB_OFFSET_KB" conv=notrunc status=none
dd if="$SBI_IMAGE" of="$WORKLOAD_BUILD_DIR/fw_payload.bin" bs="$KILOBYTE" seek="$SBI_OFFSET_KB" conv=notrunc status=none
dd if="$KERNEL_IMAGE" of="$WORKLOAD_BUILD_DIR/fw_payload.bin" bs="$MEGABYTE" seek="$KERNEL_OFFSET_MB" conv=notrunc status=none
dd if="$CPIO_ARCHIVE" of="$WORKLOAD_BUILD_DIR/fw_payload.bin" bs="$MEGABYTE" seek="$INITRAMFS_OFFSET_MB" conv=notrunc status=none
dd if="$KERNEL_IMAGE" of="$WORKLOAD_BUILD_DIR/fw_payload.bin" bs="$KILOBYTE" seek="$KERNEL_OFFSET_KB" conv=notrunc status=none
dd if="$CPIO_ARCHIVE" of="$WORKLOAD_BUILD_DIR/fw_payload.bin" bs="$KILOBYTE" seek="$INITRAMFS_OFFSET_KB" conv=notrunc status=none
35 changes: 5 additions & 30 deletions scripts/build-gcpt.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,7 @@ GCPT_IMPLEMENTATION="${GCPT_IMPLEMENTATION:-alpha}"
GCPT_CONFIGURE_MODE="${GCPT_CONFIGURE_MODE:-normal}"
GCPT_PAYLOAD_PATH="${GCPT_PAYLOAD_PATH:-${3:-}}"

extract_clint_mmio() {
local dts_template_dir="$1"
local default_dtb="$2"
local dts_template="$dts_template_dir/$default_dtb.dts.in"

if ! [ -f "$dts_template" ]; then
echo "Default DTS template not found: $dts_template" >&2
return 1
fi

perl -0777 -ne '
while (/(?:[A-Za-z_][A-Za-z0-9_]*:\s*)?[A-Za-z0-9,_-]*clint@[^{]*\{(.*?)\};/sg) {
my $node = $1;
next unless $node =~ /compatible\s*=\s*[^;]*"riscv,clint0"/s;
next unless $node =~ /reg\s*=\s*<([^>]+)>/s;
my @cells = $1 =~ /(0x[0-9a-fA-F]+|\d+)/g;
next unless @cells >= 2;
my $addr = (hex_or_dec($cells[0]) << 32) + hex_or_dec($cells[1]);
printf "0x%x\n", $addr;
exit 0;
}
exit 1;
sub hex_or_dec {
my ($v) = @_;
return $v =~ /^0x/i ? hex($v) : int($v);
}
' "$dts_template"
}
source "$(dirname "${BASH_SOURCE[0]}")/dts-config.sh"

mkdir -p "$BUILD_DIR"
rm -rf "$GCPT_BUILD_DIR"
Expand All @@ -48,8 +21,10 @@ case "$GCPT_IMPLEMENTATION" in
alpha)
DTS_TEMPLATE_DIR="$(realpath "${DTS_TEMPLATE_DIR:?DTS_TEMPLATE_DIR is required for LibCheckpointAlpha}")"
DEFAULT_DTB="${DEFAULT_DTB:-xiangshan}"
CLINT_MMIO="${CLINT_MMIO:-$(extract_clint_mmio "$DTS_TEMPLATE_DIR" "$DEFAULT_DTB")}"
export CFLAGS="${CFLAGS:-} -DCONFIG_CLINT_MMIO=$CLINT_MMIO"
DTS_TEMPLATE="$DTS_TEMPLATE_DIR/$DEFAULT_DTB.dts.in"
DTS_CONFIG="$(dts_extract_config "$DTS_TEMPLATE")"
read -r MEM_BEGIN MEM_SIZE CLINT_MMIO <<< "$DTS_CONFIG"
export CFLAGS="${CFLAGS:-} -DCONFIG_CLINT_MMIO=$CLINT_MMIO -DCONFIG_DRAM_BASE=$MEM_BEGIN"
make -C "$GCPT_BUILD_DIR"
;;
libcheckpoint)
Expand Down
Loading
Loading