diff --git a/Makefile b/Makefile index 15feb748..5a8ea56b 100644 --- a/Makefile +++ b/Makefile @@ -7,4 +7,3 @@ CAR_ROOT ?= $(shell pwd) include carfield.mk - diff --git a/carfield.mk b/carfield.mk index 36de8fce..22269187 100644 --- a/carfield.mk +++ b/carfield.mk @@ -5,6 +5,8 @@ # Luca Valente # Alessandro Ottaviano # Yvan Tortorella +# Robert Balas +# Manuel Eggimann CAR_ROOT ?= $(shell $(BENDER) path carfield) CHS_ROOT ?= $(CAR_ROOT)/cheshire @@ -67,7 +69,7 @@ endif ###################### CAR_NONFREE_REMOTE ?= git@iis-git.ee.ethz.ch:carfield/carfield-nonfree.git -CAR_NONFREE_COMMIT ?= 3c2bf51894b699a49eb8e69e21ade567e1b28b49 +CAR_NONFREE_COMMIT ?= f09457c9aabc3b150ae36c854961e89b679360aa ## Clone the non-free verification IP for the Carfield TB car-nonfree-init: diff --git a/hw/carfield.sv b/hw/carfield.sv index 9f418833..82c6a02e 100644 --- a/hw/carfield.sv +++ b/hw/carfield.sv @@ -660,12 +660,12 @@ carfield_rstgen #( ) i_carfield_rstgen ( .clks_i(domain_clk), .pwr_on_rst_ni, - .sw_rsts_ni(~{car_regs_reg2hw.periph_rst.q, - car_regs_reg2hw.safety_island_rst.q, - car_regs_reg2hw.security_island_rst.q, - car_regs_reg2hw.pulp_cluster_rst.q, + .sw_rsts_ni(~{car_regs_reg2hw.l2_rst.q, car_regs_reg2hw.spatz_cluster_rst.q, - car_regs_reg2hw.l2_rst.q}), + car_regs_reg2hw.pulp_cluster_rst.q, + car_regs_reg2hw.security_island_rst.q, + car_regs_reg2hw.safety_island_rst.q, + car_regs_reg2hw.periph_rst.q}), .test_mode_i, .rsts_no(rsts_n), .pwr_on_rsts_no(pwr_on_rsts_n), diff --git a/sw/include/car_memory_map.h b/sw/include/car_memory_map.h index b1a73f36..3c3cbb75 100644 --- a/sw/include/car_memory_map.h +++ b/sw/include/car_memory_map.h @@ -36,6 +36,9 @@ extern void *__base_l2; #define CAR_SAFETY_ISLAND_SPM_BASE_ADDR 0x60000000 #define CAR_SAFETY_ISLAND_SPM_END_ADDR 0x60020000 +#define CAR_SAFETY_ISLAND_PERIPHS_BASE_ADDR 0x60200000 +#define CAR_SAFETY_ISLAND_PERIPHS_END_ADDR 0x60300000 + // Integer Cluster #define CAR_INT_CLUSTER_SPM_BASE_ADDR 0x50000000 #define CAR_INT_CLUSTER_SPM_END_ADDR 0x50040000 @@ -44,6 +47,9 @@ extern void *__base_l2; #define CAR_FP_CLUSTER_SPM_BASE_ADDR 0x51000000 #define CAR_FP_CLUSTER_SPM_END_ADDR 0x51020000 +#define CAR_FP_CLUSTER_PERIPHS_BASE_ADDR 0x51020000 +// #define CAR_FP_CLUSTER_PERIPHS_END_ADDR unknown + // HyperRAM #define CAR_HYPERRAM_BASE_ADDR 0x80400000 #define CAR_HYPERRAM_END_ADDR 0x80800000 diff --git a/sw/include/car_util.h b/sw/include/car_util.h new file mode 100644 index 00000000..485dbe79 --- /dev/null +++ b/sw/include/car_util.h @@ -0,0 +1,163 @@ +// Copyright 2023 ETH Zurich and University of Bologna. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Robert Balas +// Alessandro Ottaviano + +#ifndef __CAR_UTIL_H +#define __CAR_UTIL_H + +#include "util.h" +#include "car_memory_map.h" +#include "regs/soc_ctrl.h" +#include "io.h" + +// for the calculation check safety island top +#define SAFETY_ISLAND_BOOT_ADDR_RSVAL (CAR_SAFETY_ISLAND_PERIPHS_BASE_ADDR + 0x1080) + +enum car_isolation_status { CAR_ISOLATE_DISABLE = 0, CAR_ISOLATE_ENABLE = 1 }; + +enum car_rst_status { CAR_RST_ASSERT = 1, CAR_RST_RELEASE = 0 }; + +enum car_clk { + CAR_HOST_CLK = 0, + CAR_PERIPH_CLK = 1, + CAR_SAFETY_CLK = 2, + CAR_SECURITY_CLK = 3, + CAR_PULP_CLK = 4, + CAR_SPATZ_CLK = 5, + CAR_L2_CLK = 6, +}; + +enum car_rst { + CAR_PERIPH_RST = 0, + CAR_SAFETY_RST = 1, + CAR_SECURITY_RST = 2, + CAR_PULP_RST = 3, + CAR_SPATZ_RST = 4, + CAR_L2_RST = 5, +}; + +// these do not exist so we set a dummy value +#define CARFIELD_L2_ISOLATE_REG_OFFSET -1 +#define CARFIELD_L2_ISOLATE_STATUS_REG_OFFSET -1 + +#define CARFIELD_HOST_CLK_EN_REG_OFFSET -1 +#define CARFIELD_HOST_CLK_SEL_REG_OFFSET -1 +#define CARFIELD_HOST_CLK_DIV_VALUE_REG_OFFSET -1 + +// generate register offset for reset domains from autogenerated soc_ctrl.h +#define X(NAME) \ + static inline uint32_t car_get_##NAME##_offset(enum car_rst rst) \ + { \ + switch (rst) { \ + case CAR_PERIPH_RST: \ + return CARFIELD_PERIPH_##NAME##_REG_OFFSET; \ + case CAR_SAFETY_RST: \ + return CARFIELD_SAFETY_ISLAND_##NAME##_REG_OFFSET; \ + case CAR_SECURITY_RST: \ + return CARFIELD_SECURITY_ISLAND_##NAME##_REG_OFFSET; \ + case CAR_PULP_RST: \ + return CARFIELD_PULP_CLUSTER_##NAME##_REG_OFFSET; \ + case CAR_SPATZ_RST: \ + return CARFIELD_SPATZ_CLUSTER_##NAME##_REG_OFFSET; \ + case CAR_L2_RST: \ + return CARFIELD_L2_##NAME##_REG_OFFSET; \ + default: \ + return -1; \ + } \ + } + +X(RST); +X(ISOLATE); +X(ISOLATE_STATUS); +#undef X + +// generate register offset for clock domains from autogenerated soc_ctrl.h +#define X(NAME) \ + static inline uint32_t car_get_##NAME##_offset(enum car_clk clk) \ + { \ + switch (clk) { \ + case CAR_HOST_CLK: \ + return CARFIELD_HOST_##NAME##_REG_OFFSET; \ + case CAR_PERIPH_CLK: \ + return CARFIELD_PERIPH_##NAME##_REG_OFFSET; \ + case CAR_SAFETY_CLK: \ + return CARFIELD_SAFETY_ISLAND_##NAME##_REG_OFFSET; \ + case CAR_SECURITY_CLK: \ + return CARFIELD_SECURITY_ISLAND_##NAME##_REG_OFFSET; \ + case CAR_SPATZ_CLK: \ + return CARFIELD_SPATZ_CLUSTER_##NAME##_REG_OFFSET; \ + case CAR_L2_CLK: \ + return CARFIELD_L2_##NAME##_REG_OFFSET; \ + default: \ + return -1; \ + } \ + } + +X(CLK_EN); +X(CLK_SEL); +X(CLK_DIV_VALUE); +#undef X + +static inline enum car_clk car_clkd_from_rstd(enum car_rst rst) +{ + switch (rst) { + case CAR_PERIPH_RST: + return CAR_PERIPH_CLK; + case CAR_SAFETY_RST: + return CAR_SAFETY_CLK; + case CAR_SECURITY_RST: + return CAR_SECURITY_CLK; + case CAR_PULP_RST: + return CAR_PULP_CLK; + case CAR_SPATZ_RST: + return CAR_SPATZ_CLK; + case CAR_L2_RST: + return CAR_L2_CLK; + } +} + +void car_set_isolate(enum car_rst rst, enum car_isolation_status status) +{ + writew(status, CAR_SOC_CTRL_BASE_ADDR + car_get_ISOLATE_offset(rst)); + fence(); + while (readw(CAR_SOC_CTRL_BASE_ADDR + car_get_ISOLATE_STATUS_offset(rst)) != + status) + ; +} + +void car_enable_clk(enum car_clk clk) +{ + writew(1, CAR_SOC_CTRL_BASE_ADDR + car_get_CLK_EN_offset(clk)); + fence(); +} + +void car_disable_clk(enum car_clk clk) +{ + writew(0, CAR_SOC_CTRL_BASE_ADDR + car_get_CLK_EN_offset(clk)); + fence(); +} + +void car_set_rst(enum car_rst rst, enum car_rst_status status) +{ + writew(status, CAR_SOC_CTRL_BASE_ADDR + car_get_RST_offset(rst)); + fence(); +} + +void car_reset_domain(enum car_rst rst) +{ + car_set_isolate(rst, CAR_ISOLATE_ENABLE); + car_disable_clk(car_clkd_from_rstd(rst)); + + car_set_rst(rst, CAR_RST_ASSERT); + for (volatile int i = 0; i < 16; i++) + ; + car_set_rst(rst, CAR_RST_RELEASE); + + car_enable_clk(car_clkd_from_rstd(rst)); + car_set_isolate(rst, CAR_ISOLATE_DISABLE); +} + +#endif diff --git a/sw/include/regs/safety_soc_ctrl.h b/sw/include/regs/safety_soc_ctrl.h new file mode 100644 index 00000000..a6986467 --- /dev/null +++ b/sw/include/regs/safety_soc_ctrl.h @@ -0,0 +1,40 @@ +// Generated register defines for safety_soc_ctrl + +// Copyright information found in source file: +// Copyright 2023 ETH Zurich and University of Bologna + +// Licensing information found in source file: +// +// SPDX-License-Identifier: SHL-0.51 + +#ifndef _SAFETY_SOC_CTRL_REG_DEFS_ +#define _SAFETY_SOC_CTRL_REG_DEFS_ + +#ifdef __cplusplus +extern "C" { +#endif +// Register width +#define SAFETY_SOC_CTRL_PARAM_REG_WIDTH 32 + +// Core Boot Address +#define SAFETY_SOC_CTRL_BOOTADDR_REG_OFFSET 0x0 + +// Core Fetch Enable +#define SAFETY_SOC_CTRL_FETCHEN_REG_OFFSET 0x4 +#define SAFETY_SOC_CTRL_FETCHEN_FETCHEN_BIT 0 + +// Core Return Status (return value, EOC) +#define SAFETY_SOC_CTRL_CORESTATUS_REG_OFFSET 0x8 + +// Core Boot Mode +#define SAFETY_SOC_CTRL_BOOTMODE_REG_OFFSET 0xc +#define SAFETY_SOC_CTRL_BOOTMODE_BOOTMODE_MASK 0x3 +#define SAFETY_SOC_CTRL_BOOTMODE_BOOTMODE_OFFSET 0 +#define SAFETY_SOC_CTRL_BOOTMODE_BOOTMODE_FIELD \ + ((bitfield_field32_t) { .mask = SAFETY_SOC_CTRL_BOOTMODE_BOOTMODE_MASK, .index = SAFETY_SOC_CTRL_BOOTMODE_BOOTMODE_OFFSET }) + +#ifdef __cplusplus +} // extern "C" +#endif +#endif // _SAFETY_SOC_CTRL_REG_DEFS_ +// End generated register defines for safety_soc_ctrl \ No newline at end of file diff --git a/sw/include/regs/spatz_cluster_peripheral.h b/sw/include/regs/spatz_cluster_peripheral.h new file mode 100644 index 00000000..aef4ceaf --- /dev/null +++ b/sw/include/regs/spatz_cluster_peripheral.h @@ -0,0 +1,199 @@ +// Generated register defines for spatz_cluster_peripheral + +// Copyright information found in source file: +// Copyright 2020 ETH Zurich and University of Bologna. + +// Licensing information found in source file: +// Licensed under Solderpad Hardware License, Version 0.51, see LICENSE for +// details. SPDX-License-Identifier: SHL-0.51 + +#ifndef _SPATZ_CLUSTER_PERIPHERAL_REG_DEFS_ +#define _SPATZ_CLUSTER_PERIPHERAL_REG_DEFS_ + +#ifdef __cplusplus +extern "C" { +#endif +// Number of performance counters +#define SPATZ_CLUSTER_PERIPHERAL_PARAM_NUM_PERF_COUNTERS 2 + +// Register width +#define SPATZ_CLUSTER_PERIPHERAL_PARAM_REG_WIDTH 64 + +// Enable particular performance counter and start tracking. (common +// parameters) +// Enable particular performance counter and start tracking. +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0_REG_OFFSET 0x0 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0_CYCLE_0_BIT 0 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0_TCDM_ACCESSED_0_BIT 1 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0_TCDM_CONGESTED_0_BIT 2 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0_ISSUE_FPU_0_BIT 3 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0_ISSUE_FPU_SEQ_0_BIT 4 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0_ISSUE_CORE_TO_FPU_0_BIT 5 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0_RETIRED_INSTR_0_BIT 6 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0_RETIRED_LOAD_0_BIT 7 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0_RETIRED_I_0_BIT 8 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0_RETIRED_ACC_0_BIT 9 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0_DMA_AW_STALL_0_BIT 10 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0_DMA_AR_STALL_0_BIT 11 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0_DMA_R_STALL_0_BIT 12 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0_DMA_W_STALL_0_BIT 13 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0_DMA_BUF_W_STALL_0_BIT 14 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0_DMA_BUF_R_STALL_0_BIT 15 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0_DMA_AW_DONE_0_BIT 16 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0_DMA_AW_BW_0_BIT 17 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0_DMA_AR_DONE_0_BIT 18 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0_DMA_AR_BW_0_BIT 19 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0_DMA_R_DONE_0_BIT 20 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0_DMA_R_BW_0_BIT 21 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0_DMA_W_DONE_0_BIT 22 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0_DMA_W_BW_0_BIT 23 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0_DMA_B_DONE_0_BIT 24 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0_DMA_BUSY_0_BIT 25 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0_ICACHE_MISS_0_BIT 26 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0_ICACHE_HIT_0_BIT 27 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0_ICACHE_PREFETCH_0_BIT 28 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0_ICACHE_DOUBLE_HIT_0_BIT \ + 29 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0_ICACHE_STALL_0_BIT 30 + +// Enable particular performance counter and start tracking. +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_1_REG_OFFSET 0x8 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_1_CYCLE_1_BIT 0 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_1_TCDM_ACCESSED_1_BIT 1 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_1_TCDM_CONGESTED_1_BIT 2 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_1_ISSUE_FPU_1_BIT 3 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_1_ISSUE_FPU_SEQ_1_BIT 4 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_1_ISSUE_CORE_TO_FPU_1_BIT 5 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_1_RETIRED_INSTR_1_BIT 6 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_1_RETIRED_LOAD_1_BIT 7 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_1_RETIRED_I_1_BIT 8 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_1_RETIRED_ACC_1_BIT 9 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_1_DMA_AW_STALL_1_BIT 10 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_1_DMA_AR_STALL_1_BIT 11 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_1_DMA_R_STALL_1_BIT 12 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_1_DMA_W_STALL_1_BIT 13 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_1_DMA_BUF_W_STALL_1_BIT 14 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_1_DMA_BUF_R_STALL_1_BIT 15 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_1_DMA_AW_DONE_1_BIT 16 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_1_DMA_AW_BW_1_BIT 17 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_1_DMA_AR_DONE_1_BIT 18 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_1_DMA_AR_BW_1_BIT 19 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_1_DMA_R_DONE_1_BIT 20 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_1_DMA_R_BW_1_BIT 21 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_1_DMA_W_DONE_1_BIT 22 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_1_DMA_W_BW_1_BIT 23 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_1_DMA_B_DONE_1_BIT 24 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_1_DMA_BUSY_1_BIT 25 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_1_ICACHE_MISS_1_BIT 26 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_1_ICACHE_HIT_1_BIT 27 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_1_ICACHE_PREFETCH_1_BIT 28 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_1_ICACHE_DOUBLE_HIT_1_BIT \ + 29 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_1_ICACHE_STALL_1_BIT 30 + +// Select from which hart in the cluster, starting from `0`, +#define SPATZ_CLUSTER_PERIPHERAL_HART_SELECT_HART_SELECT_FIELD_WIDTH 10 +#define SPATZ_CLUSTER_PERIPHERAL_HART_SELECT_HART_SELECT_FIELDS_PER_REG 6 +#define SPATZ_CLUSTER_PERIPHERAL_HART_SELECT_MULTIREG_COUNT 2 + +// Select from which hart in the cluster, starting from `0`, +#define SPATZ_CLUSTER_PERIPHERAL_HART_SELECT_0_REG_OFFSET 0x10 +#define SPATZ_CLUSTER_PERIPHERAL_HART_SELECT_0_HART_SELECT_0_MASK 0x3ff +#define SPATZ_CLUSTER_PERIPHERAL_HART_SELECT_0_HART_SELECT_0_OFFSET 0 +#define SPATZ_CLUSTER_PERIPHERAL_HART_SELECT_0_HART_SELECT_0_FIELD \ + ((bitfield_field32_t){ \ + .mask = SPATZ_CLUSTER_PERIPHERAL_HART_SELECT_0_HART_SELECT_0_MASK, \ + .index = SPATZ_CLUSTER_PERIPHERAL_HART_SELECT_0_HART_SELECT_0_OFFSET}) + +// Select from which hart in the cluster, starting from `0`, +#define SPATZ_CLUSTER_PERIPHERAL_HART_SELECT_1_REG_OFFSET 0x18 +#define SPATZ_CLUSTER_PERIPHERAL_HART_SELECT_1_HART_SELECT_1_MASK 0x3ff +#define SPATZ_CLUSTER_PERIPHERAL_HART_SELECT_1_HART_SELECT_1_OFFSET 0 +#define SPATZ_CLUSTER_PERIPHERAL_HART_SELECT_1_HART_SELECT_1_FIELD \ + ((bitfield_field32_t){ \ + .mask = SPATZ_CLUSTER_PERIPHERAL_HART_SELECT_1_HART_SELECT_1_MASK, \ + .index = SPATZ_CLUSTER_PERIPHERAL_HART_SELECT_1_HART_SELECT_1_OFFSET}) + +// Performance counter. Set corresponding PERF_COUNTER_ENABLE bits depending +// on what +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_PERF_COUNTER_FIELD_WIDTH 48 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_PERF_COUNTER_FIELDS_PER_REG 1 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_MULTIREG_COUNT 2 + +// Performance counter. Set corresponding PERF_COUNTER_ENABLE bits depending +// on what +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_0_REG_OFFSET 0x20 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_0_PERF_COUNTER_0_MASK \ + 0xffffffffffff +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_0_PERF_COUNTER_0_OFFSET 0 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_0_PERF_COUNTER_0_FIELD \ + ((bitfield_field32_t){ \ + .mask = SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_0_PERF_COUNTER_0_MASK, \ + .index = SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_0_PERF_COUNTER_0_OFFSET}) + +// Performance counter. Set corresponding PERF_COUNTER_ENABLE bits depending +// on what +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_1_REG_OFFSET 0x28 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_1_PERF_COUNTER_1_MASK \ + 0xffffffffffff +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_1_PERF_COUNTER_1_OFFSET 0 +#define SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_1_PERF_COUNTER_1_FIELD \ + ((bitfield_field32_t){ \ + .mask = SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_1_PERF_COUNTER_1_MASK, \ + .index = SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_1_PERF_COUNTER_1_OFFSET}) + +// Set bits in the cluster-local CLINT. Writing a 1 at location i sets the +// cluster-local interrupt +#define SPATZ_CLUSTER_PERIPHERAL_CL_CLINT_SET_REG_OFFSET 0x30 +#define SPATZ_CLUSTER_PERIPHERAL_CL_CLINT_SET_CL_CLINT_SET_MASK 0xffffffff +#define SPATZ_CLUSTER_PERIPHERAL_CL_CLINT_SET_CL_CLINT_SET_OFFSET 0 +#define SPATZ_CLUSTER_PERIPHERAL_CL_CLINT_SET_CL_CLINT_SET_FIELD \ + ((bitfield_field32_t){ \ + .mask = SPATZ_CLUSTER_PERIPHERAL_CL_CLINT_SET_CL_CLINT_SET_MASK, \ + .index = SPATZ_CLUSTER_PERIPHERAL_CL_CLINT_SET_CL_CLINT_SET_OFFSET}) + +// Clear bits in the cluster-local CLINT. Writing a 1 at location i clears +// the cluster-local interrupt +#define SPATZ_CLUSTER_PERIPHERAL_CL_CLINT_CLEAR_REG_OFFSET 0x38 +#define SPATZ_CLUSTER_PERIPHERAL_CL_CLINT_CLEAR_CL_CLINT_CLEAR_MASK 0xffffffff +#define SPATZ_CLUSTER_PERIPHERAL_CL_CLINT_CLEAR_CL_CLINT_CLEAR_OFFSET 0 +#define SPATZ_CLUSTER_PERIPHERAL_CL_CLINT_CLEAR_CL_CLINT_CLEAR_FIELD \ + ((bitfield_field32_t){ \ + .mask = SPATZ_CLUSTER_PERIPHERAL_CL_CLINT_CLEAR_CL_CLINT_CLEAR_MASK, \ + .index = SPATZ_CLUSTER_PERIPHERAL_CL_CLINT_CLEAR_CL_CLINT_CLEAR_OFFSET}) + +// Hardware barrier register. Loads to this register will block until all +// cores have +#define SPATZ_CLUSTER_PERIPHERAL_HW_BARRIER_REG_OFFSET 0x40 +#define SPATZ_CLUSTER_PERIPHERAL_HW_BARRIER_HW_BARRIER_MASK 0xffffffff +#define SPATZ_CLUSTER_PERIPHERAL_HW_BARRIER_HW_BARRIER_OFFSET 0 +#define SPATZ_CLUSTER_PERIPHERAL_HW_BARRIER_HW_BARRIER_FIELD \ + ((bitfield_field32_t){ \ + .mask = SPATZ_CLUSTER_PERIPHERAL_HW_BARRIER_HW_BARRIER_MASK, \ + .index = SPATZ_CLUSTER_PERIPHERAL_HW_BARRIER_HW_BARRIER_OFFSET}) + +// Controls prefetching of the instruction cache. +#define SPATZ_CLUSTER_PERIPHERAL_ICACHE_PREFETCH_ENABLE_REG_OFFSET 0x48 +#define SPATZ_CLUSTER_PERIPHERAL_ICACHE_PREFETCH_ENABLE_ICACHE_PREFETCH_ENABLE_BIT \ + 0 + +// Sets the status of the Spatz cluster. +#define SPATZ_CLUSTER_PERIPHERAL_SPATZ_STATUS_REG_OFFSET 0x50 +#define SPATZ_CLUSTER_PERIPHERAL_SPATZ_STATUS_SPATZ_CLUSTER_PROBE_BIT 0 + +// Controls the cluster boot process. +#define SPATZ_CLUSTER_PERIPHERAL_CLUSTER_BOOT_CONTROL_REG_OFFSET 0x58 +#define SPATZ_CLUSTER_PERIPHERAL_CLUSTER_BOOT_CONTROL_ENTRY_POINT_MASK \ + 0xffffffff +#define SPATZ_CLUSTER_PERIPHERAL_CLUSTER_BOOT_CONTROL_ENTRY_POINT_OFFSET 0 +#define SPATZ_CLUSTER_PERIPHERAL_CLUSTER_BOOT_CONTROL_ENTRY_POINT_FIELD \ + ((bitfield_field32_t){ \ + .mask = SPATZ_CLUSTER_PERIPHERAL_CLUSTER_BOOT_CONTROL_ENTRY_POINT_MASK, \ + .index = \ + SPATZ_CLUSTER_PERIPHERAL_CLUSTER_BOOT_CONTROL_ENTRY_POINT_OFFSET}) + +#ifdef __cplusplus +} // extern "C" +#endif +#endif // _SPATZ_CLUSTER_PERIPHERAL_REG_DEFS_ + // End generated register defines for spatz_cluster_peripheral \ No newline at end of file diff --git a/sw/tests/hostd/addressability_test.c b/sw/tests/hostd/addressability_test.c index d42c6421..8f140d6b 100644 --- a/sw/tests/hostd/addressability_test.c +++ b/sw/tests/hostd/addressability_test.c @@ -9,6 +9,7 @@ #include "dif/clint.h" #include "dif/uart.h" #include "io.h" +#include "car_util.h" #include "params.h" #include "regs/cheshire.h" #include "util.h" @@ -91,7 +92,7 @@ int probe_range_lfsr_wrwr(volatile uintptr_t from, volatile uintptr_t to, int sa // write lfsr = lfsr_64bits(lfsr, lfsr_byte_feedback); writed(lfsr, addr); - asm volatile("fence" : : : "memory"); + fence(); // read if (lfsr != readd(addr)) return 1; @@ -119,7 +120,7 @@ int probe_range_lfsr_wwrr(volatile uintptr_t from, volatile uintptr_t to, int sa addr += incr; } - asm volatile("fence" : : : "memory"); + fence(); // read addr = from; diff --git a/sw/tests/hostd/sw_rst_seq.c b/sw/tests/hostd/sw_rst_seq.c new file mode 100644 index 00000000..4045a1f9 --- /dev/null +++ b/sw/tests/hostd/sw_rst_seq.c @@ -0,0 +1,77 @@ +// Copyright 2023 ETH Zurich and University of Bologna. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Robert Balas +// Alessandro Ottaviano + +// basic testing of warm resets + +// Safety Island OK +// Spatz OK +// PULP cluster Hangs +// Security Island Hangs +// Peripherals Hangs + +#include +#include "params.h" +#include "regs/cheshire.h" +#include "regs/soc_ctrl.h" +#include "regs/safety_soc_ctrl.h" +#include "regs/spatz_cluster_peripheral.h" +#include "util.h" +#include "car_util.h" +#include "car_memory_map.h" + +int main(void) +{ + // Safety Island + + // We write a bunch of bytes to the safety island's boot register and check + // that it reads the reset value after a warm reset. Note that we can't use + // the safety island's scratchpad for that since it is not resetable + uint64_t magic = 0xcafebeef; + + // Write a pattern to safety island boot addr + writew(magic, CAR_SAFETY_ISLAND_PERIPHS_BASE_ADDR + + SAFETY_SOC_CTRL_BOOTADDR_REG_OFFSET); + + // Double check + if (readw(CAR_SAFETY_ISLAND_PERIPHS_BASE_ADDR + + SAFETY_SOC_CTRL_BOOTADDR_REG_OFFSET) != magic) + return 2; + + // engage reset sequence for safety island + car_reset_domain(CAR_SAFETY_RST); + + // After the reset we should only see zeros + if (readw(CAR_SAFETY_ISLAND_PERIPHS_BASE_ADDR + + SAFETY_SOC_CTRL_BOOTADDR_REG_OFFSET) != + SAFETY_ISLAND_BOOT_ADDR_RSVAL) + return 3; + + // Spatz + writew(magic, CAR_FP_CLUSTER_PERIPHS_BASE_ADDR + + SPATZ_CLUSTER_PERIPHERAL_CLUSTER_BOOT_CONTROL_REG_OFFSET); + if (readw(CAR_FP_CLUSTER_PERIPHS_BASE_ADDR + + SPATZ_CLUSTER_PERIPHERAL_CLUSTER_BOOT_CONTROL_REG_OFFSET) != + magic) + return 4; + + car_reset_domain(CAR_SPATZ_RST); + if (readw(CAR_FP_CLUSTER_PERIPHS_BASE_ADDR + + SPATZ_CLUSTER_PERIPHERAL_CLUSTER_BOOT_CONTROL_REG_OFFSET) != 0) + return 5; + + // PULP Reset + // car_reset_domain(CAR_PULP_RST); + + // Periph Reset + // car_reset_domain(CAR_PERIPH_RST); + + // Security Island + // We can't access anything no way to check if the reset worked + // car_reset_domain(CAR_SECURITY_RST); + + return 0; +}