diff --git a/bin/openocd-genesys2.cfg b/bin/openocd-genesys2.cfg index b0de858..1c8711f 100644 --- a/bin/openocd-genesys2.cfg +++ b/bin/openocd-genesys2.cfg @@ -22,8 +22,8 @@ ftdi_layout_signal nTRST -ndata 0x0010 set _CHIPNAME riscv -jtag newtap $_CHIPNAME unknown0 -irlen 5 -expected-id 0x10102001 -jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x249511C3 +jtag newtap $_CHIPNAME unknown0 -irlen 5 -expected-id 0x53501db3 +jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x5cafedb3 set _TARGETNAME $_CHIPNAME.cpu target create $_TARGETNAME riscv -chain-position $_TARGETNAME -coreid 0x3e0 diff --git a/configs/control-pulp.sh b/configs/control-pulp.sh index d2071c0..0783da5 100644 --- a/configs/control-pulp.sh +++ b/configs/control-pulp.sh @@ -13,3 +13,7 @@ else fi source $scriptDir/common.sh + +export PULPRT_CONFIG_CFLAGS='-DARCHI_ASIC_PER_FREQUENCY=100000000 \ + -DARCHI_ASIC_FC_FREQUENCY=100000000 \ + -DARCHI_ASIC_CL_FREQUENCY=100000000' diff --git a/configs/fpgas/control-pulp/zcu102.sh b/configs/fpgas/control-pulp/zcu102.sh new file mode 100644 index 0000000..c058a27 --- /dev/null +++ b/configs/fpgas/control-pulp/zcu102.sh @@ -0,0 +1,21 @@ +#!/bin/bash -e + +export PULPRT_TARGET=control-pulp +export PULPRUN_TARGET=control-pulp + +if [ -n "${ZSH_VERSION:-}" ]; then + DIR="$(readlink -f -- "${(%):-%x}")" + scriptDir="$(dirname $DIR)" +else + scriptDir="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" +fi + +source $scriptDir/../../common.sh + +export PULPRUN_PLATFORM=fpga + +export PULPRT_CONFIG_CFLAGS='-DARCHI_FPGA_PER_FREQUENCY=10000000 \ + -DARCHI_FPGA_FC_FREQUENCY=20000000 \ + -DARCHI_FPGA_CL_FREQUENCY=20000000' + +export io=uart diff --git a/configs/kairos.sh b/configs/kairos.sh new file mode 100644 index 0000000..5019729 --- /dev/null +++ b/configs/kairos.sh @@ -0,0 +1,19 @@ +#!/bin/bash -e + +export PULPRT_TARGET=kairos +export PULPRUN_TARGET=kairos + +if [ -n "${ZSH_VERSION:-}" ]; then + DIR="$(readlink -f -- "${(%):-%x}")" + scriptDir="$(dirname $DIR)" +else + + scriptDir="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" + +fi + +source $scriptDir/common.sh + +export PULPRT_CONFIG_CFLAGS='-DARCHI_ASIC_PER_FREQUENCY=100000000 \ + -DARCHI_ASIC_FC_FREQUENCY=100000000 \ + -DARCHI_ASIC_CL_FREQUENCY=100000000' diff --git a/include/archi/chips/control-pulp/memory_map.h b/include/archi/chips/control-pulp/memory_map.h index df13047..93402be 100644 --- a/include/archi/chips/control-pulp/memory_map.h +++ b/include/archi/chips/control-pulp/memory_map.h @@ -98,6 +98,7 @@ #define ARCHI_HWCE_OFFSET 0x00001000 #define ARCHI_ICACHE_CTRL_OFFSET 0x00001400 #define ARCHI_MCHAN_EXT_OFFSET 0x00001800 +#define ARCHI_IDMA_EXT_OFFSET 0x00001800 #define ARCHI_CLUSTER_PERIPHERALS_ADDR ( ARCHI_CLUSTER_ADDR + ARCHI_CLUSTER_PERIPHERALS_OFFSET ) #define ARCHI_CLUSTER_PERIPHERALS_GLOBAL_ADDR(cid) ( ARCHI_CLUSTER_GLOBAL_ADDR(cid) + ARCHI_CLUSTER_PERIPHERALS_OFFSET ) @@ -107,6 +108,7 @@ #define ARCHI_EU_ADDR ( ARCHI_CLUSTER_PERIPHERALS_ADDR + ARCHI_EU_OFFSET ) #define ARCHI_HWCE_ADDR ( ARCHI_CLUSTER_PERIPHERALS_ADDR + ARCHI_HWCE_OFFSET ) #define ARCHI_MCHAN_EXT_ADDR ( ARCHI_CLUSTER_PERIPHERALS_ADDR + ARCHI_MCHAN_EXT_OFFSET ) +#define ARCHI_IDMA_EXT_ADDR ( ARCHI_CLUSTER_PERIPHERALS_ADDR + ARCHI_IDMA_EXT_OFFSET ) @@ -118,11 +120,13 @@ #define ARCHI_EU_DEMUX_OFFSET ( 0x00000 ) #define ARCHI_MCHAN_DEMUX_OFFSET ( 0x00400 ) +#define ARCHI_IDMA_DEMUX_OFFSET ( 0x00400 ) #define ARCHI_DEMUX_PERIPHERALS_ADDR ( ARCHI_CLUSTER_ADDR + ARCHI_DEMUX_PERIPHERALS_OFFSET ) #define ARCHI_EU_DEMUX_ADDR ( ARCHI_DEMUX_PERIPHERALS_ADDR + ARCHI_EU_DEMUX_OFFSET ) #define ARCHI_MCHAN_DEMUX_ADDR ( ARCHI_DEMUX_PERIPHERALS_ADDR + ARCHI_MCHAN_DEMUX_OFFSET ) +#define ARCHI_IDMA_DEMUX_ADDR ( ARCHI_DEMUX_PERIPHERALS_ADDR + ARCHI_IDMA_DEMUX_OFFSET ) #endif diff --git a/include/archi/chips/control-pulp/properties.h b/include/archi/chips/control-pulp/properties.h index 1f45793..ea9c30c 100644 --- a/include/archi/chips/control-pulp/properties.h +++ b/include/archi/chips/control-pulp/properties.h @@ -22,7 +22,6 @@ * FPGA */ -#define ARCHI_FPGA_FREQUENCY 5000000 /* * MEMORIES @@ -67,9 +66,14 @@ #define ITC_VERSION 1 #define FLL_VERSION 1 #define RISCV_VERSION 4 -#define MCHAN_VERSION 7 +// TODO: if we have to switch between idma and mchan, make this configurable with #ifdef +//#define MCHAN_VERSION 7 +#define IDMA_VERSION 1 #define PADS_VERSION 2 +#if defined(MCHAN_VERSION) && defined(IDMA_VERSION) +#error "MCHAN and IDMA not compatible" +#endif /* * CLUSTER @@ -80,6 +84,7 @@ #define ARCHI_CLUSTER_NB_PE 8 #define ARCHI_NB_CLUSTER 1 +#define ARCHI_HAS_DMA_DEMUX 1 /* * HWS @@ -96,7 +101,7 @@ #define ARCHI_FC_CID 31 #define ARCHI_HAS_FC_ITC 1 #define ARCHI_HAS_FC 1 - +#define ARCHI_CORE_HAS_1_10 1 /* * CLOCKS @@ -113,33 +118,31 @@ #define ARCHI_UDMA_HAS_SPIM 1 #define ARCHI_UDMA_HAS_UART 1 -#define ARCHI_UDMA_HAS_SDIO 1 +#define ARCHI_UDMA_HAS_SDIO 0 #define ARCHI_UDMA_HAS_I2C 1 -#define ARCHI_UDMA_HAS_I2S 1 -#define ARCHI_UDMA_HAS_CAM 1 -#define ARCHI_UDMA_HAS_TRACER 1 -#define ARCHI_UDMA_HAS_FILTER 1 +#define ARCHI_UDMA_HAS_I2S 0 +#define ARCHI_UDMA_HAS_CAM 0 +#define ARCHI_UDMA_HAS_TRACER 0 +#define ARCHI_UDMA_HAS_FILTER 0 -#define ARCHI_UDMA_NB_SPIM 1 +#define ARCHI_UDMA_NB_SPIM 8 #define ARCHI_UDMA_NB_UART 1 -#define ARCHI_UDMA_NB_SDIO 1 -#define ARCHI_UDMA_NB_I2C 1 -#define ARCHI_UDMA_NB_I2S 1 -#define ARCHI_UDMA_NB_CAM 1 -#define ARCHI_UDMA_NB_TRACER 1 -#define ARCHI_UDMA_NB_FILTER 1 +#define ARCHI_UDMA_NB_SDIO 0 +#define ARCHI_UDMA_NB_I2C 12 +#define ARCHI_UDMA_NB_I2S 0 +#define ARCHI_UDMA_NB_CAM 0 +#define ARCHI_UDMA_NB_TRACER 0 +#define ARCHI_UDMA_NB_FILTER 1 #define ARCHI_UDMA_UART_ID(id) 0 #define ARCHI_UDMA_SPIM_ID(id) (1 + (id)) #define ARCHI_UDMA_I2C_ID(id) (9 + (id)) -#define ARCHI_UDMA_SDIO_ID(id) (21 + (id)) -#define ARCHI_UDMA_FILTER_ID(id) (22 + (id)) -#define ARCHI_UDMA_TRACER_ID(id) 23 -#define ARCHI_UDMA_TGEN_ID(id) 24 - -#define ARCHI_NB_PERIPH 25 +#define ARCHI_UDMA_FILTER_ID(id) (21 + (id)) +#define ARCHI_NB_PERIPH 22 +#define ARCHI_UDMA_NB_I2C_MAX 12 +#define ARCHI_UDMA_NB_SPIM_MAX 8 /* * FLLS @@ -162,9 +165,12 @@ #define ARCHI_SOC_EVENT_UDMA_NB_CHANNEL_EVT_LOG2 2 #define ARCHI_SOC_EVENT_UDMA_NB_CHANNEL_EVT (1<>2) + #define ARCHI_SOC_EVENT_PERIPH_FIRST_EVT(x) ((x)*ARCHI_SOC_EVENT_UDMA_NB_CHANNEL_EVT) #define ARCHI_SOC_EVENT_UART0_RX 0 @@ -176,6 +182,7 @@ #define ARCHI_SOC_EVENT_SPIM_TX (id) (5 + (id) * 4) #define ARCHI_SOC_EVENT_SPIM_CMD(id) (6 + (id) * 4) #define ARCHI_SOC_EVENT_SPIM_EOT(id) (7 + (id) * 4) +#define ARCHI_SOC_EVENT_SPIM_REQ(id) (ARCHI_SOC_EVENT_UDMA_NB_EVT + (id)) #define ARCHI_SOC_EVENT_I2C0_RX 8 #define ARCHI_SOC_EVENT_I2C0_TX 9 @@ -252,11 +259,12 @@ #define ARCHI_FC_EVT_FIRST_SW 0 #define ARCHI_FC_EVT_NB_SW 8 -#define ARCHI_FC_EVT_TIMER0_LO 10 -#define ARCHI_FC_EVT_TIMER0_HI 11 +#define ARCHI_FC_EVT_TIMER0_LO 10 +#define ARCHI_FC_EVT_TIMER0_HI 11 +#define ARCHI_FC_EVT_I2C_SLV_BMC 13 #define ARCHI_FC_EVT_CLK_REF 14 #define ARCHI_FC_EVT_GPIO 15 -#define ARCHI_FC_EVT_RTC 16 +#define ARCHI_FC_EVT_I2C_SLV 16 #define ARCHI_FC_EVT_ADV_TIMER0 17 #define ARCHI_FC_EVT_ADV_TIMER1 18 #define ARCHI_FC_EVT_ADV_TIMER2 19 diff --git a/include/archi/chips/control-pulp/pulp.h b/include/archi/chips/control-pulp/pulp.h index 486a082..d6f1169 100644 --- a/include/archi/chips/control-pulp/pulp.h +++ b/include/archi/chips/control-pulp/pulp.h @@ -25,12 +25,19 @@ // cv32e40p-specific #include "archi/cv32e40p/cv32e40p.h" -#include "archi/riscv/priv_1_11.h" +#include "archi/riscv/priv_1_12.h" #include "archi/chips/control-pulp/memory_map.h" #include "archi/chips/control-pulp/apb_soc.h" #include "archi/stdout/stdout_v3.h" +// TODO: do we need to have this switch bounded to exact versions? +// Maybe better to bound them to dma type (mchan or idma) +#if MCHAN_VERSION == 7 #include "archi/dma/mchan_v7.h" +#endif +#if IDMA_VERSION == 1 +#include "archi/dma/idma_v1.h" +#endif #include "archi/udma/spim/udma_spim_v3.h" #include "archi/udma/i2c/udma_i2c_v2.h" diff --git a/include/archi/chips/kairos/apb_soc.h b/include/archi/chips/kairos/apb_soc.h new file mode 100644 index 0000000..822f81e --- /dev/null +++ b/include/archi/chips/kairos/apb_soc.h @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2018 ETH Zurich and University of Bologna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __ARCHI_KAIROS_APB_SOC_H__ +#define __ARCHI_KAIROS_APB_SOC_H__ + +#define APB_SOC_BOOT_OTHER 0 +#define APB_SOC_BOOT_JTAG 1 +#define APB_SOC_BOOT_SPI 2 +#define APB_SOC_BOOT_ROM 3 +#define APB_SOC_BOOT_PRELOAD 4 +#define APB_SOC_BOOT_HYPER 5 +#define APB_SOC_BOOT_SPIM 6 +#define APB_SOC_BOOT_SPIM_QPI 7 + +#define APB_SOC_PLT_OTHER 0 +#define APB_SOC_PLT_FPGA 1 +#define APB_SOC_PLT_RTL 2 +#define APB_SOC_PLT_VP 3 +#define APB_SOC_PLT_CHIP 4 + +//PADs configuration is made of 8bits out of which only the first 6 are used +//bit0 enable pull UP +//bit1 enable pull DOWN +//bit2 enable ST +//bit3 enable SlewRate Limit +//bit4..5 Driving Strength +//bit6..7 not used + +#define APB_SOC_BOOTADDR_OFFSET 0x04 +#define APB_SOC_INFO_OFFSET 0x00 //contains number of cores [31:16] and clusters [15:0] +#define APB_SOC_INFOEXTD_OFFSET 0x04 //not used at the moment +#define APB_SOC_NOTUSED0_OFFSET 0x08 //not used at the moment +#define APB_SOC_CLUSTER_ISOLATE_OFFSET 0x0C //not used at the moment + +#define APB_SOC_PADFUN0_OFFSET 0x10 +#define APB_SOC_PADCFG0_OFFSET 0x20 + +#define APB_SOC_PADFUN_OFFSET(g) (APB_SOC_PADFUN0_OFFSET+(g)*4) //sets the mux for pins g*16+0 (bits [1:0]) to g*16+15 (bits [31:30]) +#define APB_SOC_PADFUN_NO(pad) ((pad) >> 4) +#define APB_SOC_PADFUN_PAD(padfun) ((padfun)*16) +#define APB_SOC_PADFUN_SIZE 2 +#define ARCHI_APB_SOC_PADFUN_NB 4 +#define APB_SOC_PADFUN_BIT(pad) (((pad) & 0xF) << 1) + +#define APB_SOC_PADCFG_OFFSET(g) (APB_SOC_PADCFG0_OFFSET+(g)*4) //sets config for pin g*4+0(bits [7:0]) to pin g*4+3(bits [31:24]) +#define APB_SOC_PADCFG_NO(pad) ((pad) >> 2) +#define APB_SOC_PADCFG_PAD(padfun) ((padfun)*4) +#define APB_SOC_PADCFG_SIZE 8 +#define APB_SOC_PADCFG_BIT(pad) (((pad) & 0x3) << 3) + +#define APB_SOC_PWRCMD_OFFSET 0x60 //change power mode(not funtional yet) +#define APB_SOC_PWRCFG_OFFSET 0x64 //configures power modes(not funtional yet) +#define APB_SOC_PWRREG_OFFSET 0x68 //32 bit GP register used by power pngmt routines to see if is hard or cold reboot +#define APB_SOC_BUSY_OFFSET 0x6C //not used at the moment +#define APB_SOC_MMARGIN_OFFSET 0x70 //memory margin pins(not used at the moment) +#define APB_SOC_JTAG_REG 0x74 // R/W register for interaction with the the chip environment +#define APB_SOC_L2_SLEEP_OFFSET 0x78 //memory margin pins(not used at the moment) +#define APB_SOC_NOTUSED3_OFFSET 0x7C //not used at the moment +#define APB_SOC_CLKDIV0_OFFSET 0x80 //soc clock divider(to be removed) +#define APB_SOC_CLKDIV1_OFFSET 0x84 //cluster clock divider(to be removed) +#define APB_SOC_CLKDIV2_OFFSET 0x88 //not used at the moment +#define APB_SOC_CLKDIV3_OFFSET 0x8C //not used at the moment +#define APB_SOC_CLKDIV4_OFFSET 0x90 //not used at the moment +#define APB_SOC_NOTUSED4_OFFSET 0x94 //not used at the moment +#define APB_SOC_NOTUSED5_OFFSET 0x98 //not used at the moment +#define APB_SOC_NOTUSED6_OFFSET 0x9C //not used at the moment +#define APB_SOC_CORESTATUS_OFFSET 0xA0 //32bit GP register to be used during testing to return EOC(bit[31]) and status(bit[30:0]) +#define APB_SOC_CORESTATUS_RO_OFFSET 0xC0 //32bit GP register to be used during testing to return EOC(bit[31]) and status(bit[30:0]) +#define APB_SOC_PADS_CONFIG 0xC4 + +#define APB_SOC_PADS_CONFIG_BOOTSEL_BIT 0 + +#define APB_SOC_JTAG_REG_EXT_BIT 8 +#define APB_SOC_JTAG_REG_EXT_WIDTH 4 + +#define APB_SOC_JTAG_REG_LOC_BIT 0 +#define APB_SOC_JTAG_REG_LOC_WIDTH 4 + +#define APB_SOC_INFO_CORES_OFFSET (APB_SOC_INFO_OFFSET + 2) +#define APB_SOC_INFO_CLUSTERS_OFFSET (APB_SOC_INFO_OFFSET) + +#define APB_SOC_STATUS_EOC_BIT 31 +#define APB_SOC_NB_CORE_BIT 16 + + +#define APB_SOC_BYPASS_OFFSET 0x70 + +#define APB_SOC_BYPASS_CLOCK_GATE_BIT 10 +#define APB_SOC_BYPASS_CLUSTER_STATE_BIT 3 +#define APB_SOC_BYPASS_USER0_BIT 14 +#define APB_SOC_BYPASS_USER1_BIT 15 + + +#define APB_SOC_FLL_CTRL_OFFSET 0xD0 +#define APB_SOC_CLKDIV_SOC_OFFSET 0xD4 +#define APB_SOC_CLKDIV_CLUSTER_OFFSET 0xD8 +#define APB_SOC_CLKDIV_PERIPH_OFFSET 0xDC + + +#define APB_SOC_FLL_CTRL_SOC_BIT 0 +#define APB_SOC_FLL_CTRL_CLUSTER_BIT 1 +#define APB_SOC_FLL_CTRL_PERIPH_BIT 2 + + +#define APB_SOC_RTC_OFFSET 0x1D0 + +#endif diff --git a/include/archi/chips/kairos/apb_soc_ctrl.h b/include/archi/chips/kairos/apb_soc_ctrl.h new file mode 100644 index 0000000..d1a7b3a --- /dev/null +++ b/include/archi/chips/kairos/apb_soc_ctrl.h @@ -0,0 +1,116 @@ + +/* THIS FILE HAS BEEN GENERATED, DO NOT MODIFY IT. + */ + +/* + * Copyright (C) 2018 ETH Zurich, University of Bologna + * and GreenWaves Technologies + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __INCLUDE_ARCHI_CHIPS_KAIROS_APB_SOC_CTRL_H__ +#define __INCLUDE_ARCHI_CHIPS_KAIROS_APB_SOC_CTRL_H__ + +#ifndef LANGUAGE_ASSEMBLY + +#include +#include "archi/utils.h" + +#endif + + + + +// +// REGISTERS +// + +// Value of pad bootsel +#define APB_SOC_BOOTSEL_OFFSET 0xc4 + + + +// +// REGISTERS FIELDS +// + + + +// +// REGISTERS STRUCTS +// + +#ifndef LANGUAGE_ASSEMBLY + +typedef union { + struct { + }; + unsigned int raw; +} __attribute__((packed)) apb_soc_bootsel_t; + +#endif + + + +// +// REGISTERS STRUCTS +// + +#ifdef __GVSOC__ + +class vp_apb_soc_bootsel : public vp::reg_32 +{ +public: +}; + +#endif + + + +// +// REGISTERS GLOBAL STRUCT +// + +#ifndef LANGUAGE_ASSEMBLY + +typedef struct { + unsigned int bootsel ; // Value of pad bootsel +} __attribute__((packed)) apb_soc_apb_soc_t; + +#endif + + + +// +// REGISTERS ACCESS FUNCTIONS +// + +#ifndef LANGUAGE_ASSEMBLY + +static inline uint32_t apb_soc_bootsel_get(uint32_t base) { return ARCHI_READ(base, APB_SOC_BOOTSEL_OFFSET); } +static inline void apb_soc_bootsel_set(uint32_t base, uint32_t value) { ARCHI_WRITE(base, APB_SOC_BOOTSEL_OFFSET, value); } + +#endif + + + +// +// REGISTERS FIELDS MACROS +// + +#ifndef LANGUAGE_ASSEMBLY + +#endif + +#endif diff --git a/include/archi/chips/kairos/memory_map.h b/include/archi/chips/kairos/memory_map.h new file mode 100644 index 0000000..f6aa177 --- /dev/null +++ b/include/archi/chips/kairos/memory_map.h @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2018 ETH Zurich, University of Bologna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __ARCHI_CHIPS_KAIROS_MEMORY_MAP_H__ +#define __ARCHI_CHIPS_KAIROS_MEMORY_MAP_H__ + + +/* + * MEMORIES + */ + +#define ARCHI_L2_PRIV0_ADDR 0x1c000000 +#define ARCHI_L2_PRIV0_SIZE 0x00008000 + +#define ARCHI_L2_PRIV1_ADDR 0x1c008000 +#define ARCHI_L2_PRIV1_SIZE 0x00008000 + +#define ARCHI_L2_SHARED_ADDR 0x1c010000 +#define ARCHI_L2_SHARED_SIZE 0x00070000 + + +/* + * SOC PERIPHERALS + */ + +#define ARCHI_SOC_PERIPHERALS_ADDR 0x1A100000 + +#define ARCHI_FC_TIMER_SIZE 0x00000800 + + +#define ARCHI_FLL_OFFSET 0x00000000 +#define ARCHI_GPIO_OFFSET 0x00001000 +#define ARCHI_UDMA_OFFSET 0x00002000 +#define ARCHI_APB_SOC_CTRL_OFFSET 0x00004000 +#define ARCHI_SOC_EU_OFFSET 0x00006000 +#define ARCHI_FC_ITC_OFFSET 0x00009800 +#define ARCHI_FC_TIMER_OFFSET 0x0000B000 +#define ARCHI_STDOUT_OFFSET 0x0000F000 + + + +#define ARCHI_GPIO_ADDR ( ARCHI_SOC_PERIPHERALS_ADDR + ARCHI_GPIO_OFFSET ) +#define ARCHI_UDMA_ADDR ( ARCHI_SOC_PERIPHERALS_ADDR + ARCHI_UDMA_OFFSET ) +#define ARCHI_APB_SOC_CTRL_ADDR ( ARCHI_SOC_PERIPHERALS_ADDR + ARCHI_APB_SOC_CTRL_OFFSET ) +#define ARCHI_SOC_EU_ADDR ( ARCHI_SOC_PERIPHERALS_ADDR + ARCHI_SOC_EU_OFFSET ) +#define ARCHI_FC_ITC_ADDR ( ARCHI_SOC_PERIPHERALS_ADDR + ARCHI_FC_ITC_OFFSET ) +#define ARCHI_FC_TIMER_ADDR ( ARCHI_SOC_PERIPHERALS_ADDR + ARCHI_FC_TIMER_OFFSET ) +#define ARCHI_STDOUT_ADDR ( ARCHI_SOC_PERIPHERALS_ADDR + ARCHI_STDOUT_OFFSET ) + +#define ARCHI_FLL_AREA_SIZE 0x00000010 + + + + +/* + * FC + */ + +#define ARCHI_FC_ADDR 0x00000000 +#define ARCHI_FC_GLOBAL_ADDR 0x1B000000 + + +/* + * CLUSTER + */ + +#define ARCHI_CLUSTER_ADDR 0x00000000 +#define ARCHI_CLUSTER_SIZE 0x00400000 +#define ARCHI_CLUSTER_GLOBAL_ADDR(cid) (0x10000000 + (cid)*ARCHI_CLUSTER_SIZE) + + + +/* + * CLUSTER PERIPHERALS + */ + +#define ARCHI_CLUSTER_PERIPHERALS_OFFSET 0x00200000 + +#define ARCHI_TIMER_SIZE 0x00000800 + +#define ARCHI_CLUSTER_CTRL_OFFSET 0x00000000 +#define ARCHI_TIMER_OFFSET 0x00000400 +#define ARCHI_EU_OFFSET 0x00000800 +#define ARCHI_HWCE_OFFSET 0x00001000 +#define ARCHI_ICACHE_CTRL_OFFSET 0x00001400 +#define ARCHI_MCHAN_EXT_OFFSET 0x00001800 + +#define ARCHI_CLUSTER_PERIPHERALS_ADDR ( ARCHI_CLUSTER_ADDR + ARCHI_CLUSTER_PERIPHERALS_OFFSET ) +#define ARCHI_CLUSTER_PERIPHERALS_GLOBAL_ADDR(cid) ( ARCHI_CLUSTER_GLOBAL_ADDR(cid) + ARCHI_CLUSTER_PERIPHERALS_OFFSET ) + +#define ARCHI_CLUSTER_CTRL_ADDR ( ARCHI_CLUSTER_PERIPHERALS_ADDR + ARCHI_CLUSTER_CTRL_OFFSET ) +#define ARCHI_ICACHE_CTRL_ADDR ( ARCHI_CLUSTER_PERIPHERALS_ADDR + ARCHI_ICACHE_CTRL_OFFSET ) +#define ARCHI_EU_ADDR ( ARCHI_CLUSTER_PERIPHERALS_ADDR + ARCHI_EU_OFFSET ) +#define ARCHI_HWCE_ADDR ( ARCHI_CLUSTER_PERIPHERALS_ADDR + ARCHI_HWCE_OFFSET ) +#define ARCHI_MCHAN_EXT_ADDR ( ARCHI_CLUSTER_PERIPHERALS_ADDR + ARCHI_MCHAN_EXT_OFFSET ) + + + +/* + * CLUSTER DEMUX PERIPHERALS + */ + +#define ARCHI_DEMUX_PERIPHERALS_OFFSET 0x204000 + +#define ARCHI_EU_DEMUX_OFFSET ( 0x00000 ) +#define ARCHI_MCHAN_DEMUX_OFFSET ( 0x00400 ) + + +#define ARCHI_DEMUX_PERIPHERALS_ADDR ( ARCHI_CLUSTER_ADDR + ARCHI_DEMUX_PERIPHERALS_OFFSET ) + +#define ARCHI_EU_DEMUX_ADDR ( ARCHI_DEMUX_PERIPHERALS_ADDR + ARCHI_EU_DEMUX_OFFSET ) +#define ARCHI_MCHAN_DEMUX_ADDR ( ARCHI_DEMUX_PERIPHERALS_ADDR + ARCHI_MCHAN_DEMUX_OFFSET ) + +#endif diff --git a/include/archi/chips/kairos/properties.h b/include/archi/chips/kairos/properties.h new file mode 100644 index 0000000..9d34a81 --- /dev/null +++ b/include/archi/chips/kairos/properties.h @@ -0,0 +1,262 @@ +/* + * Copyright (C) 2018 ETH Zurich, University of Bologna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __ARCHI_CHIPS_KAIROS_PROPERTIES_H__ +#define __ARCHI_CHIPS_KAIROS_PROPERTIES_H__ + +/* + * FPGA + */ + + +/* + * MEMORIES + */ + +#define ARCHI_HAS_L2 1 +#define ARCHI_HAS_L2_MULTI 1 + +#define ARCHI_L2_PRIV0_ADDR 0x1c000000 +#define ARCHI_L2_PRIV0_SIZE 0x00008000 + +#define ARCHI_L2_PRIV1_ADDR 0x1c008000 +#define ARCHI_L2_PRIV1_SIZE 0x00008000 + +#define ARCHI_L2_SHARED_ADDR 0x1c010000 +#define ARCHI_L2_SHARED_SIZE 0x00070000 + + + +/* + * MEMORY ALIAS + */ + +#define ARCHI_HAS_L2_ALIAS 1 + + + +/* + * IP VERSIONS + */ + +#define UDMA_VERSION 3 +#define PERIPH_VERSION 2 +#define TIMER_VERSION 2 +#define SOC_EU_VERSION 2 +#define APB_SOC_VERSION 3 +#define STDOUT_VERSION 2 +#define GPIO_VERSION 2 +#define EU_VERSION 3 +#define ITC_VERSION 1 +#define FLL_VERSION 1 +#define RISCV_VERSION 4 +#define PADS_VERSION 2 + + +/* + * HWS + */ + +#define ARCHI_EU_NB_HW_MUTEX 1 + + + +/* + * FC + */ + +#define ARCHI_FC_CID 31 +#define ARCHI_HAS_FC_ITC 1 +#define ARCHI_HAS_FC 1 +#define ARCHI_CORE_HAS_1_10 1 + +/* + * CLOCKS + */ + +#define ARCHI_REF_CLOCK_LOG2 15 +#define ARCHI_REF_CLOCK (1<>2) + +#define ARCHI_SOC_EVENT_PERIPH_FIRST_EVT(x) ((x)*ARCHI_SOC_EVENT_UDMA_NB_CHANNEL_EVT) + +#define ARCHI_SOC_EVENT_UART0_RX 0 +#define ARCHI_SOC_EVENT_UART0_TX 1 +#define ARCHI_SOC_EVENT_UART0_EOT 2 +#define ARCHI_SOC_EVENT_UART0_RX_DATA 3 + +#define ARCHI_SOC_EVENT_SPIM_RX (id) (4 + (id) * 4) +#define ARCHI_SOC_EVENT_SPIM_TX (id) (5 + (id) * 4) +#define ARCHI_SOC_EVENT_SPIM_CMD(id) (6 + (id) * 4) +#define ARCHI_SOC_EVENT_SPIM_EOT(id) (7 + (id) * 4) +#define ARCHI_SOC_EVENT_SPIM_REQ(id) (ARCHI_SOC_EVENT_UDMA_NB_EVT + (id)) + +#define ARCHI_SOC_EVENT_I2C0_RX 8 +#define ARCHI_SOC_EVENT_I2C0_TX 9 + +#define ARCHI_SOC_EVENT_I2C1_RX 12 +#define ARCHI_SOC_EVENT_I2C1_TX 13 + +#define ARCHI_SOC_EVENT_SDIO0_RX 16 +#define ARCHI_SOC_EVENT_SDIO0_TX 17 + +#define ARCHI_SOC_EVENT_I2S0_RX 20 +#define ARCHI_SOC_EVENT_I2S0_TX 21 + +#define ARCHI_SOC_EVENT_CPI0_RX 24 + +#define ARCHI_SOC_EVENT_FILTER0_RX 28 +#define ARCHI_SOC_EVENT_FILTER0_TX 29 + +#define ARCHI_SOC_EVENT_CLUSTER_ON_OFF 31 +#define ARCHI_SOC_EVENT_MSP 37 +#define ARCHI_SOC_EVENT_ICU_MODE_CHANGED 37 +#define ARCHI_SOC_EVENT_ICU_OK 37 +#define ARCHI_SOC_EVENT_ICU_DELAYED 37 +#define ARCHI_SOC_EVENT_CLUSTER_CG_OK 35 +#define ARCHI_SOC_EVENT_PICL_OK 36 +#define ARCHI_SOC_EVENT_SCU_OK 37 +#define ARCHI_SOC_EVENT_PMU_FIRST_EVENT ARCHI_SOC_EVENT_CLUSTER_ON_OFF +#define ARCHI_SOC_EVENT_PMU_NB_EVENTS 7 + +#define ARCHI_SOC_EVENT_GPIO 42 + + +#define ARCHI_SOC_EVENT_NB_I2S_CHANNELS 4 +#define ARCHI_SOC_EVENT_NB_UDMA_CHANNELS 19 + +#define ARCHI_SOC_EVENT_SW_EVENT0 48 +#define ARCHI_SOC_EVENT_SW_EVENT1 49 +#define ARCHI_SOC_EVENT_SW_EVENT2 50 +#define ARCHI_SOC_EVENT_SW_EVENT3 51 +#define ARCHI_SOC_EVENT_SW_EVENT4 52 +#define ARCHI_SOC_EVENT_SW_EVENT5 53 +#define ARCHI_SOC_EVENT_SW_EVENT6 54 +#define ARCHI_SOC_EVENT_SW_EVENT7 55 + +#define ARCHI_SOC_EVENT_NB 8 + +#define ARCHI_SOC_EVENT_REF_CLK_RISE 56 + + +/* + * CLUSTER EVENTS + */ + +#define ARCHI_CL_EVT_DMA0 8 +#define ARCHI_CL_EVT_DMA1 9 +#define ARCHI_EVT_TIMER0 10 +#define ARCHI_EVT_TIMER1 11 +#define ARCHI_CL_EVT_ACC0 12 +#define ARCHI_CL_EVT_ACC1 13 +#define ARCHI_CL_EVT_ACC2 14 +#define ARCHI_CL_EVT_ACC3 15 +#define ARCHI_CL_EVT_BAR 16 +#define ARCHI_CL_EVT_MUTEX 17 +#define ARCHI_CL_EVT_DISPATCH 18 +#define ARCHI_EVT_MPU_ERROR 28 +#define ARCHI_CL_EVT_SOC_EVT 30 +#define ARCHI_EVT_SOC_FIFO 31 + + + +/* + * FC EVENTS + */ + +#define ARCHI_FC_EVT_FIRST_SW 0 +#define ARCHI_FC_EVT_NB_SW 8 +#define ARCHI_FC_EVT_TIMER0_LO 10 +#define ARCHI_FC_EVT_TIMER0_HI 11 +#define ARCHI_FC_EVT_I2C_SLV_BMC 13 +#define ARCHI_FC_EVT_CLK_REF 14 +#define ARCHI_FC_EVT_GPIO 15 +#define ARCHI_FC_EVT_I2C_SLV 16 +#define ARCHI_FC_EVT_ADV_TIMER0 17 +#define ARCHI_FC_EVT_ADV_TIMER1 18 +#define ARCHI_FC_EVT_ADV_TIMER2 19 +#define ARCHI_FC_EVT_ADV_TIMER3 20 +#define ARCHI_FC_EVT_CLUSTER_NOT_BUSY 21 +#define ARCHI_FC_EVT_CLUSTER_POK 22 +#define ARCHI_FC_EVT_CLUSTER_CG_OK 23 +#define ARCHI_FC_EVT_PICL_OK 24 +#define ARCHI_FC_EVT_SCU_OK 25 +#define ARCHI_FC_EVT_SOC_EVT 26 +#define ARCHI_FC_EVT_QUEUE_ERROR 29 + + +#endif diff --git a/include/archi/chips/kairos/pulp.h b/include/archi/chips/kairos/pulp.h new file mode 100644 index 0000000..3af40b5 --- /dev/null +++ b/include/archi/chips/kairos/pulp.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2018 ETH Zurich, University of Bologna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __ARCHI_CHIPS_KAIROS_H__ +#define __ARCHI_CHIPS_KAIROS_H__ + +#include "archi/chips/kairos/properties.h" +#include "archi/chips/kairos/apb_soc_ctrl.h" + +#include "archi/itc/itc_v1.h" + +// cv32e40p-specific +#include "archi/cv32e40p/cv32e40p.h" +#include "archi/riscv/priv_1_11.h" + +#include "archi/chips/kairos/memory_map.h" +#include "archi/chips/kairos/apb_soc.h" +#include "archi/stdout/stdout_v3.h" +#include "archi/dma/mchan_v7.h" + +#include "archi/udma/spim/udma_spim_v3.h" +#include "archi/udma/i2c/udma_i2c_v2.h" +#include "archi/udma/uart/udma_uart_v1.h" +#include "archi/udma/udma_v3.h" + +#endif diff --git a/include/archi/cv32e40p/cv32e40p.h b/include/archi/cv32e40p/cv32e40p.h index 817b97c..1a1b52c 100644 --- a/include/archi/cv32e40p/cv32e40p.h +++ b/include/archi/cv32e40p/cv32e40p.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 ETH Zurich and University of Bologna + * Copyright (C) 2022 ETH Zurich and University of Bologna * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,9 @@ */ +#ifndef __CV32E40P_H__ +#define __CV32E40P_H__ + /* * Bit definitions for Performance counters mode registers * @@ -62,3 +65,12 @@ id == 14 ? "APU_DEP" : \ id == 15 ? "APU_WB" : \ "NA") + +#define CSR_HWLOOP0_START 0x800 +#define CSR_HWLOOP0_END 0x801 +#define CSR_HWLOOP0_COUNTER 0x802 +#define CSR_HWLOOP1_START 0x804 +#define CSR_HWLOOP1_END 0x805 +#define CSR_HWLOOP1_COUNTER 0x806 + +#endif diff --git a/include/archi/dma/idma_v1.h b/include/archi/dma/idma_v1.h new file mode 100644 index 0000000..1256e84 --- /dev/null +++ b/include/archi/dma/idma_v1.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2021 ETH Zurich and University of Bologna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __ARCHI_IDMA_V1_H__ +#define __ARCHI_IDMA_V1_H__ + +// Generated register defines for idma_reg32_2d_frontend + +#ifndef _IDMA_REG32_2D_FRONTEND_REG_DEFS_ +#define _IDMA_REG32_2D_FRONTEND_REG_DEFS_ + +#ifdef __cplusplus +extern "C" { +#endif +// Register width +#define IDMA_REG32_2D_FRONTEND_PARAM_REG_WIDTH 32 + +// Source Address +#define IDMA_REG32_2D_FRONTEND_SRC_ADDR_REG_OFFSET 0x0 + +// Destination Address +#define IDMA_REG32_2D_FRONTEND_DST_ADDR_REG_OFFSET 0x4 + +// Number of bytes +#define IDMA_REG32_2D_FRONTEND_NUM_BYTES_REG_OFFSET 0x8 + +// Configuration Register for DMA settings +#define IDMA_REG32_2D_FRONTEND_CONF_REG_OFFSET 0xc +#define IDMA_REG32_2D_FRONTEND_CONF_DECOUPLE_BIT 0 +#define IDMA_REG32_2D_FRONTEND_CONF_DEBURST_BIT 1 +#define IDMA_REG32_2D_FRONTEND_CONF_SERIALIZE_BIT 2 +#define IDMA_REG32_2D_FRONTEND_CONF_TWOD_BIT 3 + +// Source Stride +#define IDMA_REG32_2D_FRONTEND_STRIDE_SRC_REG_OFFSET 0x10 + +// Destination Stride +#define IDMA_REG32_2D_FRONTEND_STRIDE_DST_REG_OFFSET 0x14 + +// Number of 2D repetitions +#define IDMA_REG32_2D_FRONTEND_NUM_REPETITIONS_REG_OFFSET 0x18 + +// DMA Status +#define IDMA_REG32_2D_FRONTEND_STATUS_REG_OFFSET 0x1c +#define IDMA_REG32_2D_FRONTEND_STATUS_BUSY_MASK 0xffff +#define IDMA_REG32_2D_FRONTEND_STATUS_BUSY_OFFSET 0 +#define IDMA_REG32_2D_FRONTEND_STATUS_BUSY_FIELD \ + ((bitfield_field32_t) { .mask = IDMA_REG32_2D_FRONTEND_STATUS_BUSY_MASK, .index = IDMA_REG32_2D_FRONTEND_STATUS_BUSY_OFFSET }) + +// Next ID, launches transfer, returns 0 if transfer not set up properly. +#define IDMA_REG32_2D_FRONTEND_NEXT_ID_REG_OFFSET 0x20 + +// Get ID of finished transactions. +#define IDMA_REG32_2D_FRONTEND_DONE_REG_OFFSET 0x24 + +#ifdef __cplusplus +} // extern "C" +#endif +#endif // _IDMA_REG32_2D_FRONTEND_REG_DEFS_ +// End generated register defines for idma_reg32_2d_frontend + +#endif // __ARCHI_IDMA_V1_H__ diff --git a/include/archi/riscv/priv_1_11.h b/include/archi/riscv/priv_1_11.h index 11a836f..6482bd5 100644 --- a/include/archi/riscv/priv_1_11.h +++ b/include/archi/riscv/priv_1_11.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 ETH Zurich and University of Bologna + * Copyright (C) 2022 ETH Zurich and University of Bologna * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,42 +14,97 @@ * limitations under the License. */ -#ifndef _ARCHI_RISCV_PRIV_1_9_H -#define _ARCHI_RISCV_PRIV_1_9_H - -#define RV_CSR_MSTATUS 0x300 -#define RV_CSR_MEPC 0x341 -#define RV_CSR_MCAUSE 0x342 -#define RV_CSR_MTVAL 0x343 -#define RV_CSR_MESTATUS 0x7C0 -#ifdef RISCV_1_7 -#define RV_CSR_MCPUID 0xF00 -#define RV_CSR_MIMPID 0xF01 -#define RV_CSR_MHARTID 0xF10 -#else -#define RV_CSR_MISA 0xF10 -#define RV_CSR_MIMPID 0xF13 -#define RV_CSR_MHARTID 0xF14 -#endif +#ifndef _ARCHI_RISCV_PRIV_1_11_H +#define _ARCHI_RISCV_PRIV_1_11_H + +#define CSR_USTATUS 0x000 /* URW ustatus User status register. */ +#define CSR_UIE 0x004 /* URW uie User interrupt-enable register. */ +#define CSR_UTVEC 0x005 /* URW utvec User trap handler base address. */ + +#define CSR_USCRATCH 0x040 /* URW uscratch Scratch register for user trap handlers. */ +#define CSR_UEPC 0x041 /* URW uepc User exception program counter. */ +#define CSR_UCAUSE 0x042 /* URW ucause User trap cause. */ +#define CSR_UTVAL 0x043 /* URW utval User bad address or instruction. */ +#define CSR_UIP 0x044 /* URW uip User interrupt pending. */ + +#define CSR_FFLAGS 0x001 /* URW fflags Floating-Point Accrued Exceptions. */ +#define CSR_FRM 0x002 /* URW frm Floating-Point Dynamic Rounding Mode. */ +#define CSR_FCSR 0x003 /* URW fcsr Floating-Point Control and Status Register (frm + fflags). */ + +#define CSR_CYCLE 0xC00 /* URO cycle Cycle counter for RDCYCLE instruction. */ +#define CSR_TIME 0xC01 /* URO time Timer for RDTIME instruction. */ +#define CSR_INSTRET 0xC02 /* URO instret Instructions-retired counter for RDINSTRET instruction. */ +#define CSR_HPMCOUNTER(id) (0xC00 + id) /* URO hpmcounter Performance-monitoring counter. */ + +#define CSR_CYCLEH 0xC80 /* URO cycleh Upper 32 bits of cycle, RV32 only. */ +#define CSR_TIMEH 0xC81 /* URO timeh Upper 32 bits of time, RV32 only. */ +#define CSR_INSTRETH 0xC82 /* URO instreth Upper 32 bits of instret, RV32 only. */ +#define CSR_HPMCOUNTERH(id) (0xC80 + id) /* URO hpmcounterh Upper 32 bits of hpmcounter, RV32 only. */ + +#define CSR_SSTATUS 0x100 /* SRW sstatus Supervisor status register. */ +#define CSR_SEDELEG 0x102 /* SRW sedeleg Supervisor exception delegation register. */ +#define CSR_SIDELEG 0x103 /* SRW sideleg Supervisor interrupt delegation register. */ +#define CSR_SIE 0x104 /* SRW sie Supervisor interrupt-enable register. */ +#define CSR_STVEC 0x105 /* SRW stvec Supervisor trap handler base address. */ +#define CSR_SCOUNTEREN 0x106 /* SRW scounteren Supervisor counter enable. */ + +#define CSR_SSCRATCH 0x140 /* SRW sscratch Scratch register for supervisor trap handlers. */ +#define CSR_SEPC 0x141 /* SRW sepc Supervisor exception program counter. */ +#define CSR_SCAUSE 0x142 /* SRW scause Supervisor trap cause. */ +#define CSR_STVAL 0x143 /* SRW stval Supervisor bad address or instruction. */ +#define CSR_SIP 0x144 /* SRW sip Supervisor interrupt pending. */ + +#define CSR_SATP 0x180 /* SRW satp Supervisor address translation and protection. */ + +#define CSR_MVENDORID 0xF11 /* MRO mvendorid Vendor ID. */ +#define CSR_MARCHID 0xF12 /* MRO marchid Architecture ID. */ +#define CSR_MIMPID 0xF13 /* MRO mimpid Implementation ID. */ +#define CSR_MHARTID 0xF14 /* MRO mhartid Hardware thread ID. */ + +#define CSR_MSTATUS 0x300 /* MRW mstatus Machine status register. */ +#define CSR_MISA 0x301 /* MRW misa ISA and extensions */ +#define CSR_MEDELEG 0x302 /* MRW medeleg Machine exception delegation register. */ +#define CSR_MIDELEG 0x303 /* MRW mideleg Machine interrupt delegation register. */ +#define CSR_MIE 0x304 /* MRW mie Machine interrupt-enable register. */ +#define CSR_MTVEC 0x305 /* MRW mtvec Machine trap-handler base address. */ +#define CSR_MCOUNTEREN 0x306 /* MRW mcounteren Machine counter enable. */ + +#define CSR_MSCRATCH 0x340 /* MRW mscratch Scratch register for machine trap handlers. */ +#define CSR_MEPC 0x341 /* MRW mepc Machine exception program counter. */ +#define CSR_MCAUSE 0x342 /* MRW mcause Machine trap cause. */ +#define CSR_MTVAL 0x343 /* MRW mtval Machine bad address or instruction. */ +#define CSR_MIP 0x344 /* MRW mip Machine interrupt pending. */ + +#define CSR_PMPCFG(id) (0x3A0 + id) /* MRW pmpcfg Physical memory protection configuration. */ +#define CSR_PMPADDR(id) (0x3B0 + id) /* MRW pmpaddr Physical memory protection address register. */ -#define CSR_PCCR(N) (0x780 + (N)) -#define CSR_PCER 0xCC0 -#define CSR_PCMR 0xCC1 +#define CSR_MCYCLE 0xB00 /* MRW mcycle Machine cycle counter. */ +#define CSR_MINSTRET 0xB02 /* MRW minstret Machine instructions-retired counter. */ +#define CSR_MHPMCOUNTER(id) (0xB00 + id) /* MRW mhpmcounter Machine performance-monitoring counter. */ +#define CSR_MCYCLEH 0xB80 /* MRW mcycleh Upper 32 bits of mcycle, RV32 only. */ +#define CSR_MINSTRETH 0xB82 /* MRW minstreth Upper 32 bits of minstret, RV32 only. */ +#define CSR_MHPMCOUNTERH(id) (0xB80 + id) /* MRW mhpmcounterh Upper 32 bits of mhpmcounter3, RV32 only. */ -#define CSR_STACK_CONF 0x7D0 -#define CSR_STACK_START 0x7D1 -#define CSR_STACK_END 0x7D2 +#define CSR_MCOUNTINHIBIT 0x320 /* MRW mcountinhibit Machine counter-inhibit register. */ +#define CSR_MHPMEVENT(id) (0x320 + id) /* MRW mhpmevent Machine performance-monitoring event selector. */ -#define CSR_MESTATUS_INTEN_BIT 0 -#define CSR_MESTATUS_PRV_BIT 1 +#define CSR_TSELECT 0x7A0 /* MRW tselect Debug/Trace trigger register select. */ +#define CSR_TDATA1 0x7A1 /* MRW tdata1 First Debug/Trace trigger data register. */ +#define CSR_TDATA2 0x7A2 /* MRW tdata2 Second Debug/Trace trigger data register. */ +#define CSR_TDATA3 0x7A3 /* MRW tdata3 Third Debug/Trace trigger data register. */ -#define CSR_MESTATUS_PRV_MACH 3 +#define CSR_DCSR 0x7B0 /* DRW dcsr Debug control and status register. */ +#define CSR_DPC 0x7B1 /* DRW dpc Debug PC. */ +#define CSR_DSCRATCH0 0x7B2 /* DRW dscratch0 Debug scratch register 0. */ +#define CSR_DSCRATCH1 0x7B3 /* DRW dscratch1 Debug scratch register 1. */ -#define CSR_HWLOOP0_START 0x800 -#define CSR_HWLOOP0_END 0x801 -#define CSR_HWLOOP0_COUNTER 0x802 -#define CSR_HWLOOP1_START 0x804 -#define CSR_HWLOOP1_END 0x805 -#define CSR_HWLOOP1_COUNTER 0x806 +/* backwards compatibility */ +#define RV_CSR_MSTATUS CSR_MSTATUS +#define RV_CSR_MEPC CSR_MEPC +#define RV_CSR_MCAUSE CSR_MCAUSE +#define RV_CSR_MTVAL CSR_MTVAL +#define RV_CSR_MISA CSR_MISA +#define RV_CSR_MIMPID CSR_MIMPID +#define RV_CSR_MHARTID CSR_MHARTID #endif diff --git a/include/archi/riscv/priv_1_12.h b/include/archi/riscv/priv_1_12.h new file mode 100644 index 0000000..b578d7c --- /dev/null +++ b/include/archi/riscv/priv_1_12.h @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2022 ETH Zurich and University of Bologna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ARCHI_RISCV_PRIV_1_12_H +#define _ARCHI_RISCV_PRIV_1_12_H + +#define CSR_FFLAGS 0x001 /* URW fflags Floating-Point Accrued Exceptions. */ +#define CSR_FRM 0x002 /* URW frm Floating-Point Dynamic Rounding Mode. */ +#define CSR_FCSR 0x003 /* URW fcsr Floating-Point Control and Status Register (frm + fflags). */ + +#define CSR_CYCLE 0xC00 /* URO cycle Cycle counter for RDCYCLE instruction. */ +#define CSR_TIME 0xC01 /* URO time Timer for RDTIME instruction. */ +#define CSR_INSTRET 0xC02 /* URO instret Instructions-retired counter for RDINSTRET instruction. */ +#define CSR_HPMCOUNTER(id) (0xC00 + id) /* URO hpmcounter Performance-monitoring counter. */ + +#define CSR_CYCLEH 0xC80 /* URO cycleh Upper 32 bits of cycle, RV32 only. */ +#define CSR_TIMEH 0xC81 /* URO timeh Upper 32 bits of time, RV32 only. */ +#define CSR_INSTRETH 0xC82 /* URO instreth Upper 32 bits of instret, RV32 only. */ +#define CSR_HPMCOUNTERH(id) (0xC80 + id) /* URO hpmcounterh Upper 32 bits of hpmcounter, RV32 only. */ + +#define CSR_SSTATUS 0x100 /* SRW sstatus Supervisor status register. */ +#define CSR_SIE 0x104 /* SRW sie Supervisor interrupt-enable register. */ +#define CSR_STVEC 0x105 /* SRW stvec Supervisor trap handler base address. */ +#define CSR_SCOUNTEREN 0x106 /* SRW scounteren Supervisor counter enable. */ + +#define CSR_SENVCFG 0x10A /* SRW senvcfg Supervisor environment configuration register. */ + +#define CSR_SSCRATCH 0x140 /* SRW sscratch Scratch register for supervisor trap handlers. */ +#define CSR_SEPC 0x141 /* SRW sepc Supervisor exception program counter. */ +#define CSR_SCAUSE 0x142 /* SRW scause Supervisor trap cause. */ +#define CSR_STVAL 0x143 /* SRW stval Supervisor bad address or instruction. */ +#define CSR_SIP 0x144 /* SRW sip Supervisor interrupt pending. */ + +#define CSR_SATP 0x180 /* SRW satp Supervisor address translation and protection. */ + +#define CSR_SCONTEXT 0x5A8 /* SRW scontext Supervisor-mode context register. */ + +#define CSR_HSTATUS 0x600 /* HRW hstatus Hypervisor status register. */ +#define CSR_HEDELEG 0x602 /* HRW hedeleg Hypervisor exception delegation register. */ +#define CSR_HIDELEG 0x603 /* HRW hideleg Hypervisor interrupt delegation register. */ +#define CSR_HIE 0x604 /* HRW hie Hypervisor interrupt-enable register. */ +#define CSR_HCOUNTEREN 0x606 /* HRW hcounteren Hypervisor counter enable. */ +#define CSR_HGEIE 0x607 /* HRW hgeie Hypervisor guest external interrupt-enable register. */ + +#define CSR_HTVAL 0x643 /* HRW htval Hypervisor bad guest physical address. */ +#define CSR_HIP 0x644 /* HRW hip Hypervisor interrupt pending. */ +#define CSR_HVIP 0x645 /* HRW hvip Hypervisor virtual interrupt pending. */ +#define CSR_HTINST 0x64A /* HRW htinst Hypervisor trap instruction (transformed). */ +#define CSR_HGEIP 0xE12 /* HRO hgeip Hypervisor guest external interrupt pending. */ + +#define CSR_HENVCFG 0x60A /* HRW henvcfg Hypervisor environment configuration register. */ +#define CSR_HENVCFGH 0x61A /* HRW henvcfgh Additional hypervisor env. conf. register, RV32 only. */ + +#define CSR_HGATP 0x680 /* HRW hgatp Hypervisor guest address translation and protection. */ + +#define CSR_HCONTEXT 0x6A8 /* HRW hcontext Hypervisor-mode context register. */ + +#define CSR_HTIMEDELTA 0x605 /* HRW htimedelta Delta for VS/VU-mode timer. */ +#define CSR_HTIMEDELTAH 0x615 /* HRW htimedeltah Upper 32 bits of htimedelta, HSXLEN=32 only. */ + +#define CSR_VSSTATUS 0x200 /* HRW vsstatus Virtual supervisor status register. */ +#define CSR_VSIE 0x204 /* HRW vsie Virtual supervisor interrupt-enable register. */ +#define CSR_VSTVEC 0x205 /* HRW vstvec Virtual supervisor trap handler base address. */ +#define CSR_VSSCRATCH 0x240 /* HRW vsscratch Virtual supervisor scratch register. */ +#define CSR_VSEPC 0x241 /* HRW vsepc Virtual supervisor exception program counter. */ +#define CSR_VSCAUSE 0x242 /* HRW vscause Virtual supervisor trap cause. */ +#define CSR_VSTVAL 0x243 /* HRW vstval Virtual supervisor bad address or instruction. */ +#define CSR_VSIP 0x244 /* HRW vsip Virtual supervisor interrupt pending. */ +#define CSR_VSATP 0x280 /* HRW vsatp Virtual supervisor address translation and protection. */ + +#define CSR_MVENDORID 0xF11 /* MRO mvendorid Vendor ID. */ +#define CSR_MARCHID 0xF12 /* MRO marchid Architecture ID. */ +#define CSR_MIMPID 0xF13 /* MRO mimpid Implementation ID. */ +#define CSR_MHARTID 0xF14 /* MRO mhartid Hardware thread ID. */ +#define CSR_MCONFIGPTR 0xF15 /* MRO mconfigptr Pointer to configuration data structure. */ + +#define CSR_MSTATUS 0x300 /* MRW mstatus Machine status register. */ +#define CSR_MISA 0x301 /* MRW misa ISA and extensions */ +#define CSR_MEDELEG 0x302 /* MRW medeleg Machine exception delegation register. */ +#define CSR_MIDELEG 0x303 /* MRW mideleg Machine interrupt delegation register. */ +#define CSR_MIE 0x304 /* MRW mie Machine interrupt-enable register. */ +#define CSR_MTVEC 0x305 /* MRW mtvec Machine trap-handler base address. */ +#define CSR_MCOUNTEREN 0x306 /* MRW mcounteren Machine counter enable. */ +#define CSR_MSTATUSH 0x310 /* MRW mstatush Additional machine status register, RV32 only */ + +#define CSR_MSCRATCH 0x340 /* MRW mscratch Scratch register for machine trap handlers. */ +#define CSR_MEPC 0x341 /* MRW mepc Machine exception program counter. */ +#define CSR_MCAUSE 0x342 /* MRW mcause Machine trap cause. */ +#define CSR_MTVAL 0x343 /* MRW mtval Machine bad address or instruction. */ +#define CSR_MIP 0x344 /* MRW mip Machine interrupt pending. */ +#define CSR_MTINST 0x34A /* MRW mtinst Machine trap instruction (transformed). */ +#define CSR_MTVAL2 0x34B /* MRW mtval2 Machine bad guest physical address. */ + +#define CSR_MENVCFG 0x30A /* MRW menvcfg Machine environment configuration register. */ +#define CSR_MENVCFGH 0x31A /* MRW menvcfgh Additional machine env. conf. register, RV32 only. */ +#define CSR_MSECCFG 0x747 /* MRW mseccfg Machine security configuration register. */ +#define CSR_MSECCFGH 0x757 /* MRW mseccfgh Additional machine security conf. register, RV32 only. */ + +#define CSR_PMPCFG(id) (0x3A0+id) /* MRW pmpcfg Physical memory protection configuration. */ +#define CSR_PMPADDR(id) (0x3B0+id) /* MRW pmpaddr Physical memory protection address register. */ + +#define CSR_MCYCLE 0xB00 /* MRW mcycle Machine cycle counter. */ +#define CSR_MINSTRET 0xB02 /* MRW minstret Machine instructions-retired counter. */ +#define CSR_MHPMCOUNTER(id) (0xB00 + id) /* MRW mhpmcounter Machine performance-monitoring counter. */ +#define CSR_MCYCLEH 0xB80 /* MRW mcycleh Upper 32 bits of mcycle, RV32 only. */ +#define CSR_MINSTRETH 0xB82 /* MRW minstreth Upper 32 bits of minstret, RV32 only. */ +#define CSR_MHPMCOUNTERH(id) (0xB80 + id) /* MRW mhpmcounterh Upper 32 bits of mhpmcounter3, RV32 only. */ + +#define CSR_MCOUNTINHIBIT 0x320 /* MRW mcountinhibit Machine counter-inhibit register. */ +#define CSR_MHPMEVENT(id) (0x320 + id) /* MRW mhpmevent Machine performance-monitoring event selector. */ + +#define CSR_TSELECT 0x7A0 /* MRW tselect Debug/Trace trigger register select. */ +#define CSR_TDATA1 0x7A1 /* MRW tdata1 First Debug/Trace trigger data register. */ +#define CSR_TDATA2 0x7A2 /* MRW tdata2 Second Debug/Trace trigger data register. */ +#define CSR_TDATA3 0x7A3 /* MRW tdata3 Third Debug/Trace trigger data register. */ +#define CSR_MCONTEXT 0x7A8 /* MRW mcontext Machine-mode context register. */ + +#define CSR_DCSR 0x7B0 /* DRW dcsr Debug control and status register. */ +#define CSR_DPC 0x7B1 /* DRW dpc Debug PC. */ +#define CSR_DSCRATCH0 0x7B2 /* DRW dscratch0 Debug scratch register 0. */ +#define CSR_DSCRATCH1 0x7B3 /* DRW dscratch1 Debug scratch register 1. */ + +#endif diff --git a/include/chips/kairos/config.h b/include/chips/kairos/config.h new file mode 100644 index 0000000..6f0fb2d --- /dev/null +++ b/include/chips/kairos/config.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2019 ETH Zurich, University of Bologna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __KAIROS_CONFIG_H__ +#define __KAIROS_CONFIG_H__ + +#include "archi/pulp_defs.h" + +#define PULP_CHIP CHIP_KAIROS +#define PULP_CHIP_FAMILY CHIP_KAIROS +#define CONFIG_PULP 1 +#define PULP_CHIP_STR kairos +#define PULP_CHIP_FAMILY_STR kairos + +#endif diff --git a/include/chips/kairos/soc.h b/include/chips/kairos/soc.h new file mode 100644 index 0000000..9d62295 --- /dev/null +++ b/include/chips/kairos/soc.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2019 ETH Zurich, University of Bologna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CONTROL_PULP_SOC_H__ +#define __CONTROL_PULP_SOC_H__ + + +/* TODO we should remove the fll code for control-pulp */ +#define POS_FLL_CL 2 +#define POS_FLL_PERIPH 1 +#define POS_FLL_FC 0 + +extern int pos_freq_domains[PI_FREQ_NB_DOMAINS]; + + +void pos_soc_init(); + +static inline int pos_freq_get_fll(int domain) +{ + switch (domain) + { + case PI_FREQ_DOMAIN_FC: + return POS_FLL_FC; + + case PI_FREQ_DOMAIN_PERIPH: + return POS_FLL_PERIPH; + + case PI_FREQ_DOMAIN_CL: + default: + return POS_FLL_CL; + } +} + +#endif diff --git a/include/hal/chips/control-pulp/pulp.h b/include/hal/chips/control-pulp/pulp.h index dda1d45..bcb57f4 100644 --- a/include/hal/chips/control-pulp/pulp.h +++ b/include/hal/chips/control-pulp/pulp.h @@ -22,7 +22,12 @@ #include "hal/eu/eu_v3.h" #include "hal/itc/itc_v1.h" +#if MCHAN_VERSION == 7 #include "hal/dma/mchan_v7.h" +#endif +#if IDMA_VERSION == 1 +#include "hal/dma/idma_v1.h" +#endif #include "hal/timer/timer_v2.h" #include "hal/soc_eu/soc_eu_v2.h" #include "hal/cluster_ctrl/cluster_ctrl_v2.h" diff --git a/include/hal/chips/kairos/pulp.h b/include/hal/chips/kairos/pulp.h new file mode 100644 index 0000000..c472719 --- /dev/null +++ b/include/hal/chips/kairos/pulp.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2018 ETH Zurich and University of Bologna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __HAL_CHIPS_KAIROS_H__ +#define __HAL_CHIPS_KAIROS_H__ + +// cv32e40p-specific +#include "hal/cv32e40p/cv32e40p.h" + +#include "hal/eu/eu_v3.h" +#include "hal/itc/itc_v1.h" +#include "hal/timer/timer_v2.h" +#include "hal/soc_eu/soc_eu_v2.h" +#include "hal/apb_soc/apb_soc_v3.h" +#include "hal/fll/fll_v1.h" +#include "hal/gpio/gpio_v3.h" +#include "hal/rom/rom_v2.h" + +#include "hal/udma/udma_v3.h" +#include "hal/udma/i2c/udma_i2c_v2.h" +#include "hal/udma/spim/udma_spim_v3.h" +#include "hal/udma/uart/udma_uart_v1.h" + + +#endif diff --git a/include/hal/dma/idma_v1.h b/include/hal/dma/idma_v1.h new file mode 100644 index 0000000..91f0c9b --- /dev/null +++ b/include/hal/dma/idma_v1.h @@ -0,0 +1,355 @@ +/* + * Copyright (C) 2021 ETH Zurich and University of Bologna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __HAL_IDMA_V1_H__ +#define __HAL_IDMA_V1_H__ + +#include +#include "hal/pulp.h" + +#define PLP_DMA_LOC2EXT 0 +#define PLP_DMA_EXT2LOC 1 + +#define PLP_DMA_1D 0 +#define PLP_DMA_2D 1 + +#define IDMA_EVENT 8 // all iDMA tx_cplt events are broadcast +#define IDMA_ID_COUNTER_WIDTH 28 +#define IDMA_ID_MASK 0x0fffffff + +#define IDMA_DEFAULT_CONFIG 0x0 +#define IDMA_DEFAULT_CONFIG_2D 0x8 + +typedef unsigned int dma_ext_t; +typedef unsigned int dma_loc_t; + +/** @name High-level DMA memory copy functions + * The following functions can be used to trigger DMA transfers to copy data between the cluster memory (L1) and another memory outside the cluster (another cluster L1 or L2). + * The DMA supports the following features: + * - Transfers are event-based. With event-based transfers the core can call a wait function to block execution until the transfer is done. + * - The DMA supports 2D transfers which allows transfering a 2D tile in one command. Additional information must then be given to specify the width of the tile and the number of bytes between 2 lines of the tile. + * - The event sent at the end of the transfer is broadcasted to all cluster cores. + * - To identify specific transfers, the DMA provides a transfer identifier. + * - Multiple transfers can be launched simultaneously, with them being executed 2-4 in parallel, with more waiting in a queue. + */ +/**@{*/ + +/** Memory transfer with event-based completion. + * + \param ext Address in the external memory where to access the data. There is no restriction on memory alignment. + \param loc Address in the cluster memory where to access the data. There is no restriction on memory alignment. + \param size Number of bytes to be transfered. The only restriction is that this size must fit 16 bits, i.e. must be inferior to 65536. + \param ext2loc If 1, the transfer is loading data from external memory and storing to cluster memory. If 0, it is the contrary + \return The identifier of the transfer. This can be used with plp_dma_wait to wait for the completion of this transfer. + */ +static inline int plp_dma_memcpy(dma_ext_t ext, unsigned int loc, unsigned int size, int ext2loc); + +/** Cluster memory to external memory transfer with event-based completion. + * + \param ext Address in the external memory where to store the data. There is no restriction on memory alignment. + \param loc Address in the cluster memory where to load the data. There is no restriction on memory alignment. + \param size Number of bytes to be transfered. The only restriction is that this size must fit 16 bits, i.e. must be inferior to 65536. + \return The identifier of the transfer. This can be used with plp_dma_wait to wait for the completion of this transfer. + */ +static inline int plp_dma_l1ToExt(dma_ext_t ext, unsigned int loc, unsigned short size); + +/** External memory to cluster memory transfer with event-based completion. + * + \param loc Address in the cluster memory where to store the data. There is no restriction on memory alignment. + \param ext Address in the external memory where to load the data. There is no restriction on memory alignment. + \param size Number of bytes to be transfered. The only restriction is that this size must fit 16 bits, i.e. must be inferior to 65536. + \return The identifier of the transfer. This can be used with plp_dma_wait to wait for the completion of this transfer. + */ +static inline int plp_dma_extToL1(unsigned int loc, dma_ext_t ext, unsigned short size); + +/** 2-dimensional memory transfer with event-based completion. + * + \param ext Address in the external memory where to access the data. There is no restriction on memory alignment. + \param loc Address in the cluster memory where to access the data. There is no restriction on memory alignment. + \param size Number of bytes to be transfered. The only restriction is that this size must fit 16 bits, i.e. must be inferior to 65536. + \param stride 2D stride, which is the number of bytes which are added to the beginning of the current line to switch to the next one. Must fit 16 bits, i.e. must be inferior to 65536. + \param length 2D length, which is the number of transfered bytes after which the DMA will switch to the next line. Must fit 16 bits, i.e. must be inferior to 65536. + \param ext2loc If 1, the transfer is loading data from external memory and storing to cluster memory. If 0, it is the contrary + \return The identifier of the transfer. This can be used with plp_dma_wait to wait for the completion of this transfer. + */ +static inline int plp_dma_memcpy_2d(dma_ext_t ext, unsigned int loc, unsigned int size, unsigned int stride, unsigned int length, int ext2loc); + +/** Cluster memory to external memory 2-dimensional transfer with event-based completion. + * + \param ext Address in the external memory where to store the data. There is no restriction on memory alignment. + \param loc Address in the cluster memory where to load the data. There is no restriction on memory alignment. + \param size Number of bytes to be transfered. The only restriction is that this size must fit 16 bits, i.e. must be inferior to 65536. + \param stride 2D stride, which is the number of bytes which are added to the beginning of the current line to switch to the next one. Must fit 16 bits, i.e. must be inferior to 65536. This applies only to the external memory. + \param length 2D length, which is the number of transfered bytes after which the DMA will switch to the next line. Must fit 16 bits, i.e. must be inferior to 65536. This applies only to the external memory. + \return The identifier of the transfer. This can be used with plp_dma_wait to wait for the completion of this transfer. + */ +static inline int plp_dma_l1ToExt_2d(dma_ext_t ext, unsigned int loc, unsigned short size, unsigned short stride, unsigned short length); + +/** External memory to cluster memory 2-dimensional transfer with event-based completion. + * + \param loc Address in the cluster memory where to store the data. There is no restriction on memory alignment. + \param ext Address in the external memory where to load the data. There is no restriction on memory alignment. + \param size Number of bytes to be transfered. The only restriction is that this size must fit 16 bits, i.e. must be inferior to 65536. + \param stride 2D stride, which is the number of bytes which are added to the beginning of the current line to switch to the next one. Must fit 16 bits, i.e. must be inferior to 65536. This applies only to the external memory. + \param length 2D length, which is the number of transfered bytes after which the DMA will switch to the next line. Must fit 16 bits, i.e. must be inferior to 65536. This applies only to the external memory. + \return The identifier of the transfer. This can be used with plp_dma_wait to wait for the completion of this transfer + */ +static inline int plp_dma_extToL1_2d(unsigned int loc, dma_ext_t ext, unsigned short size, unsigned short stride, unsigned short length); + +//!@} + +/** @name DMA wait functions + */ + +/** DMA barrier. + * This blocks the core until no transfer is on-going in the DMA. + */ +static inline void plp_dma_barrier(); + +/** DMA wait. + * This blocks the core until the specified transfer is finished. + * + \param counter The counter ID identifying the transfer. This has been returned from an enqueued transfer (e.g. plp_dma_extToL1_2d) + */ +static inline void plp_dma_wait(unsigned int dma_tx_id); + +//!@} + + +/** @name iDMA low-level functions. + * This can be used instead of the high-level ones in order to have more control over the DMA features. + */ + +/** + * iDMA configuration generation + * A standard memcpy will set all of these values to 0. + * + \param decouple if set to true, there is no longer exactly one AXI write_request issued for + every read request. This mode can improve performance of unaligned transfers when crossing + the AXI page boundaries. + \param deburst if set, the DMA will split all bursts in single transfers + \param serialize if set, the DMA will only send AX belonging to a given Arbitrary 1D burst request + at a time. This is default behavior to prevent deadlocks. Setting `serialize` to + zero violates the AXI4+ATOP specification. + \param twod if set, the DMA will execute a 2D transfer. + \return The generated configuration + */ +static inline unsigned int pulp_idma_get_conf(unsigned int decouple, unsigned int deburst, unsigned int serialize, unsigned int twod); + +/** + * iDMA transfer status + * + \param dma_tx_id The dma transfer identifier + \return transfer status. 1 if complete, 0 if still ongoing or waiting. + */ +static inline unsigned int pulp_idma_tx_cplt(unsigned int dma_tx_id); + +/** + * iDMA memory transfer + * Launches a standard 1D memory transfer + * + \param dst_addr The destination address + \param src_addr The source address + \param num_bytes The number bytes + \return The dma transfer identifier + */ +static inline unsigned int pulp_idma_memcpy(unsigned int const dst_addr, unsigned int const src_addr, unsigned int num_bytes); + +/** + * iDMA 2D memory transfer + * Launches a standard 2D memory transfer + * + \param dst_addr The destination address + \param src_addr The source address + \param num_bytes The number bytes (per stride) + \param dst_stride The stride at the destination + \param src_stride The stride at the source + \param num_reps The number of repetitions + \return The dma transfer identifier + */ +static inline unsigned int pulp_idma_memcpy_2d(unsigned int const dst_addr, unsigned int const src_addr, unsigned int num_bytes, unsigned int dst_stride, unsigned int src_stride, unsigned int num_reps); + + +/** + * iDMA advanced memory transfer + * Launches a 1D memory transfer with special configuration options + * + \param dst_addr The destination address + \param src_addr The source address + \param num_bytes The number bytes + \param decouple if set to true, there is no longer exactly one AXI write_request issued for + every read request. This mode can improve performance of unaligned transfers when crossing + the AXI page boundaries. + \param deburst if set, the DMA will split all bursts in single transfers + \param serialize if set, the DMA will only send AX belonging to a given Arbitrary 1D burst request + at a time. This is default behavior to prevent deadlocks. Setting `serialize` to + zero violates the AXI4+ATOP specification. + \param twod if set, the DMA will execute a 2D transfer + \param dst_stride if 2D, the stride at the destination + \param src_stride if 2D, the stride at the source + \param num_reps if 2D, the number of repetitions + \return The dma trasfer identifier + */ +static inline unsigned int pulp_idma_memcpy_advanced(unsigned int const dst_addr, unsigned int const src_addr, unsigned int num_bytes, unsigned int decouple, unsigned int deburst, unsigned int serialize, unsigned int twod, unsigned int dst_stride, unsigned int src_stride, unsigned int num_reps); + +/** Return the DMA status. + * + \return DMA status. 1 means there are still on-going transfers, 0 means nothing is on-going. + */ +static inline unsigned int plp_dma_status(); + + +//!@} + + +/// @cond IMPLEM + +#if ARCHI_HAS_DMA_DEMUX +#define DMA_ADDR ARCHI_IDMA_DEMUX_ADDR +#else +#define DMA_ADDR ARCHI_IDMA_EXT_ADDR +#endif +#if defined(__riscv__) && !defined(RV_ISA_RV32) && !defined(__LLVM__) +#define DMA_WRITE(value, offset) __builtin_pulp_OffsetedWrite((value), (int *)DMA_ADDR, (offset)) +#define DMA_READ(offset) __builtin_pulp_OffsetedRead((int *)DMA_ADDR, (offset)) +#else +#define DMA_WRITE(value, offset) pulp_write32(DMA_ADDR + (offset), (value)) +#define DMA_READ(offset) pulp_read32(DMA_ADDR + (offset)) +#endif + +static inline unsigned int pulp_idma_get_conf(unsigned int decouple, unsigned int deburst, unsigned int serialize, unsigned int twod) { + unsigned int conf; +#if defined(__riscv__) + conf = __builtin_bitinsert(0, decouple, 1, IDMA_REG32_2D_FRONTEND_CONF_DECOUPLE_BIT); + conf = __builtin_bitinsert(conf, deburst, 1, IDMA_REG32_2D_FRONTEND_CONF_DEBURST_BIT); + conf = __builtin_bitinsert(conf, serialize, 1, IDMA_REG32_2D_FRONTEND_CONF_SERIALIZE_BIT); + conf = __builtin_bitinsert(conf, twod, 1, IDMA_REG32_2D_FRONTEND_CONF_TWOD_BIT); +#else + conf = (((decouple & 0x1)<> (IDMA_ID_COUNTER_WIDTH-1) == my_id >> (IDMA_ID_COUNTER_WIDTH-1)) { + return my_id <= done_id; + } else { + return ((done_id & (IDMA_ID_MASK - (1<<(IDMA_ID_COUNTER_WIDTH-1))) < (1<<(IDMA_ID_COUNTER_WIDTH-2)))); + } +} + + +static inline unsigned int pulp_idma_memcpy(unsigned int const dst_addr, unsigned int const src_addr, unsigned int num_bytes) { + DMA_WRITE(src_addr, IDMA_REG32_2D_FRONTEND_SRC_ADDR_REG_OFFSET); + DMA_WRITE(dst_addr, IDMA_REG32_2D_FRONTEND_DST_ADDR_REG_OFFSET); + DMA_WRITE(num_bytes, IDMA_REG32_2D_FRONTEND_NUM_BYTES_REG_OFFSET); + DMA_WRITE(IDMA_DEFAULT_CONFIG, IDMA_REG32_2D_FRONTEND_CONF_REG_OFFSET); + asm volatile("" : : : "memory"); + + // Launch TX + unsigned int dma_tx_id = DMA_READ(IDMA_REG32_2D_FRONTEND_NEXT_ID_REG_OFFSET); + + return dma_tx_id; +} + +static inline unsigned int pulp_idma_memcpy_2d(unsigned int const dst_addr, unsigned int const src_addr, unsigned int num_bytes, unsigned int dst_stride, unsigned int src_stride, unsigned int num_reps) { + DMA_WRITE(src_addr, IDMA_REG32_2D_FRONTEND_SRC_ADDR_REG_OFFSET); + DMA_WRITE(dst_addr, IDMA_REG32_2D_FRONTEND_DST_ADDR_REG_OFFSET); + DMA_WRITE(num_bytes, IDMA_REG32_2D_FRONTEND_NUM_BYTES_REG_OFFSET); + DMA_WRITE(IDMA_DEFAULT_CONFIG_2D, IDMA_REG32_2D_FRONTEND_CONF_REG_OFFSET); + DMA_WRITE(src_stride, IDMA_REG32_2D_FRONTEND_STRIDE_SRC_REG_OFFSET); + DMA_WRITE(dst_stride, IDMA_REG32_2D_FRONTEND_STRIDE_DST_REG_OFFSET); + DMA_WRITE(num_reps, IDMA_REG32_2D_FRONTEND_NUM_REPETITIONS_REG_OFFSET); + asm volatile("" : : : "memory"); + + // Launch TX + unsigned int dma_tx_id = DMA_READ(IDMA_REG32_2D_FRONTEND_NEXT_ID_REG_OFFSET); + + return dma_tx_id; +} + + +static inline unsigned int pulp_idma_memcpy_advanced(unsigned int const dst_addr, unsigned int const src_addr, unsigned int num_bytes, unsigned int decouple, unsigned int deburst, unsigned int serialize, unsigned int twod, unsigned int dst_stride, unsigned int src_stride, unsigned int num_reps) { + DMA_WRITE(src_addr, IDMA_REG32_2D_FRONTEND_SRC_ADDR_REG_OFFSET); + DMA_WRITE(dst_addr, IDMA_REG32_2D_FRONTEND_DST_ADDR_REG_OFFSET); + DMA_WRITE(num_bytes, IDMA_REG32_2D_FRONTEND_NUM_BYTES_REG_OFFSET); + unsigned int conf = pulp_idma_get_conf(decouple, deburst, serialize, twod); + DMA_WRITE(conf, IDMA_REG32_2D_FRONTEND_CONF_REG_OFFSET); + if (twod) { + DMA_WRITE(src_stride, IDMA_REG32_2D_FRONTEND_STRIDE_SRC_REG_OFFSET); + DMA_WRITE(dst_stride, IDMA_REG32_2D_FRONTEND_STRIDE_DST_REG_OFFSET); + DMA_WRITE(num_reps, IDMA_REG32_2D_FRONTEND_NUM_REPETITIONS_REG_OFFSET); + } + asm volatile("" : : : "memory"); + + // Launch TX + unsigned int dma_tx_id = DMA_READ(IDMA_REG32_2D_FRONTEND_NEXT_ID_REG_OFFSET); + + return dma_tx_id; +} + +static inline unsigned int plp_dma_status() { + return DMA_READ(IDMA_REG32_2D_FRONTEND_STATUS_REG_OFFSET); +} + +static inline void plp_dma_wait(unsigned int dma_tx_id) { + while(!pulp_idma_tx_cplt(dma_tx_id)) { + eu_evt_maskWaitAndClr(1 << IDMA_EVENT); + } + return; +} + +static inline int plp_dma_memcpy(dma_ext_t ext, unsigned int loc, unsigned int size, int ext2loc) { + if (ext2loc) { + return pulp_idma_memcpy(loc, ext, size); + } else { + return pulp_idma_memcpy(ext, loc, size); + } +} + +static inline int plp_dma_l1ToExt(dma_ext_t ext, unsigned int loc, unsigned short size) { + return pulp_idma_memcpy(ext, loc, size); +} + +static inline int plp_dma_extToL1(unsigned int loc, dma_ext_t ext, unsigned short size) { + return pulp_idma_memcpy(loc, ext, size); +} + +static inline int plp_dma_memcpy_2d(dma_ext_t ext, unsigned int loc, unsigned int size, unsigned int stride, unsigned int length, int ext2loc) { + if (ext2loc) { + return pulp_idma_memcpy_2d(loc, ext, length, length, stride, size/length); + } else { + return pulp_idma_memcpy_2d(ext, loc, length, stride, length, size/length); + } +} + +static inline int plp_dma_l1ToExt_2d(dma_ext_t ext, unsigned int loc, unsigned short size, unsigned short stride, unsigned short length) { + return pulp_idma_memcpy_2d(ext, loc, length, stride, length, size/length); +} + +static inline int plp_dma_extToL1_2d(unsigned int loc, dma_ext_t ext, unsigned short size, unsigned short stride, unsigned short length) { + return pulp_idma_memcpy_2d(loc, ext, length, length, stride, size/length); +} + +static inline void plp_dma_barrier() { + while(plp_dma_status()) { + eu_evt_maskWaitAndClr(1 << IDMA_EVENT); + } +} + +#endif // __HAL_IDMA_V1_H__ diff --git a/include/hal/dma/mchan_v7.h b/include/hal/dma/mchan_v7.h index 7f07f81..d95dee5 100644 --- a/include/hal/dma/mchan_v7.h +++ b/include/hal/dma/mchan_v7.h @@ -267,9 +267,17 @@ static inline unsigned int plp_dma_status(); /// @cond IMPLEM #if defined(__riscv__) && !defined(RV_ISA_RV32) && !defined(__LLVM__) +#ifdef ARCHI_HAS_DMA_DEMUX +#define DMA_WRITE_DEMUX(value, offset) __builtin_pulp_OffsetedWrite((value), (int *)ARCHI_MCHAN_DEMUX_ADDR, (offset)) +#define DMA_READ_DEMUX(offset) __builtin_pulp_OffsetedRead((int *)ARCHI_MCHAN_DEMUX_ADDR, (offset)) +#endif // ARCHI_HAS_DMA_DEMUX #define DMA_WRITE(value, offset) __builtin_pulp_OffsetedWrite((value), (int *)ARCHI_MCHAN_EXT_ADDR, (offset)) #define DMA_READ(offset) __builtin_pulp_OffsetedRead((int *)ARCHI_MCHAN_EXT_ADDR, (offset)) #else +#ifdef ARCHI_HAS_DMA_DEMUX +#define DMA_WRITE_DEMUX(value, offset) pulp_write32(ARCHI_MCHAN_DEMUX_ADDR + (offset), (value)) +#define DMA_READ_DEMUX(value, offset) pulp_read32(ARCHI_MCHAN_DEMUX_ADDR + (offset)) +#endif // ARCHI_HAS_DMA_DEMUX #define DMA_WRITE(value, offset) pulp_write32(ARCHI_MCHAN_EXT_ADDR + (offset), (value)) #define DMA_READ(offset) pulp_read32(ARCHI_MCHAN_EXT_ADDR + (offset)) #endif @@ -278,10 +286,26 @@ static inline int plp_dma_counter_alloc() { return DMA_READ(MCHAN_CMD_OFFSET); } +static inline int plp_cl_dma_counter_alloc() { +#ifdef ARCHI_HAS_DMA_DEMUX + return DMA_READ_DEMUX(MCHAN_CMD_OFFSET); +#else // ARCHI_HAS_DMA_DEMUX + return plp_dma_counter_alloc(); +#endif // ARCHI_HAS_DMA_DEMUX +} + static inline void plp_dma_counter_free(int counter) { DMA_WRITE(1<>32), MCHAN_CMD_OFFSET); +#else + DMA_WRITE_DEMUX(extAddr, MCHAN_CMD_OFFSET); +#endif +#else // ARCHI_HAS_DMA_DEMUX + plp_dma_cmd_push(cmd, locAddr, extAddr); +#endif // ARCHI_HAS_DMA_DEMUX +} + static inline void plp_dma_cmd_push_2d(unsigned int cmd, unsigned int locAddr, mchan_ext_t extAddr, unsigned int stride, unsigned int length) { plp_dma_cmd_push(cmd, locAddr, extAddr); DMA_WRITE(length, MCHAN_CMD_OFFSET); DMA_WRITE(stride, MCHAN_CMD_OFFSET); } +static inline void plp_cl_dma_cmd_push_2d(unsigned int cmd, unsigned int locAddr, mchan_ext_t extAddr, unsigned int stride, unsigned int length) { +#ifdef ARCHI_HAS_DMA_DEMUX + plp_cl_dma_cmd_push(cmd, locAddr, extAddr); + DMA_WRITE_DEMUX(length, MCHAN_CMD_OFFSET); + DMA_WRITE_DEMUX(stride, MCHAN_CMD_OFFSET); +#else // ARCHI_HAS_DMA_DEMUX + plp_dma_cmd_push_2d(cmd, locAddr, extAddr, stride, length); +#endif // ARCHI_HAS_DMA_DEMUX +} + static inline int plp_dma_memcpy(mchan_ext_t ext, unsigned int loc, unsigned short size, int ext2loc) { unsigned int counter = plp_dma_counter_alloc(); unsigned int cmd = plp_dma_getCmd(ext2loc, size, PLP_DMA_1D, PLP_DMA_TRIG_EVT, PLP_DMA_NO_TRIG_IRQ, PLP_DMA_SHARED); @@ -323,6 +375,17 @@ static inline int plp_dma_memcpy(mchan_ext_t ext, unsigned int loc, unsigned sho return counter; } +static inline int plp_cl_dma_memcpy(mchan_ext_t ext, unsigned int loc, unsigned short size, int ext2loc) { +#ifdef ARCHI_HAS_DMA_DEMUX + unsigned int counter = plp_cl_dma_counter_alloc(); + unsigned int cmd = plp_cl_dma_getCmd(ext2loc, size, PLP_DMA_1D, PLP_DMA_TRIG_EVT, PLP_DMA_NO_TRIG_IRQ, PLP_DMA_SHARED); + plp_cl_dma_cmd_push(cmd, loc, ext); + return counter; +#else // ARCHI_HAS_DMA_DEMUX + return plp_dma_memcpy(ext, loc, size, ext2loc); +#endif // ARCHI_HAS_DMA_DEMUX +} + static inline int plp_dma_l1ToExt(mchan_ext_t ext, unsigned int loc, unsigned short size) { unsigned int counter = plp_dma_counter_alloc(); unsigned int cmd = plp_dma_getCmd(PLP_DMA_LOC2EXT, size, PLP_DMA_1D, PLP_DMA_TRIG_EVT, PLP_DMA_NO_TRIG_IRQ, PLP_DMA_SHARED); @@ -330,6 +393,17 @@ static inline int plp_dma_l1ToExt(mchan_ext_t ext, unsigned int loc, unsigned sh return counter; } +static inline int plp_cl_dma_l1ToExt(mchan_ext_t ext, unsigned int loc, unsigned short size) { +#ifdef ARCHI_HAS_DMA_DEMUX + unsigned int counter = plp_cl_dma_counter_alloc(); + unsigned int cmd = plp_cl_dma_getCmd(PLP_DMA_LOC2EXT, size, PLP_DMA_1D, PLP_DMA_TRIG_EVT, PLP_DMA_NO_TRIG_IRQ, PLP_DMA_SHARED); + plp_cl_dma_cmd_push(cmd, loc, ext); + return counter; +#else // ARCHI_HAS_DMA_DEMUX + return plp_dma_l1ToExt(ext, loc, size); +#endif // ARCHI_HAS_DMA_DEMUX +} + static inline int plp_dma_extToL1(unsigned int loc, mchan_ext_t ext, unsigned short size) { unsigned int counter = plp_dma_counter_alloc(); unsigned int cmd = plp_dma_getCmd(PLP_DMA_EXT2LOC, size, PLP_DMA_1D, PLP_DMA_TRIG_EVT, PLP_DMA_NO_TRIG_IRQ, PLP_DMA_SHARED); @@ -337,6 +411,17 @@ static inline int plp_dma_extToL1(unsigned int loc, mchan_ext_t ext, unsigned sh return counter; } +static inline int plp_cl_dma_extToL1(unsigned int loc, mchan_ext_t ext, unsigned short size) { +#ifdef ARCHI_HAS_DMA_DEMUX + unsigned int counter = plp_cl_dma_counter_alloc(); + unsigned int cmd = plp_cl_dma_getCmd(PLP_DMA_EXT2LOC, size, PLP_DMA_1D, PLP_DMA_TRIG_EVT, PLP_DMA_NO_TRIG_IRQ, PLP_DMA_SHARED); + plp_cl_dma_cmd_push(cmd, loc, ext); + return counter; +#else // ARCHI_HAS_DMA_DEMUX + return plp_dma_extToL1(loc, ext, size); +#endif // ARCHI_HAS_DMA_DEMUX +} + static inline int plp_dma_memcpy_irq(mchan_ext_t ext, unsigned int loc, unsigned short size, int ext2loc) { unsigned int counter = plp_dma_counter_alloc(); unsigned int cmd = plp_dma_getCmd(ext2loc, size, PLP_DMA_1D, PLP_DMA_NO_TRIG_EVT, PLP_DMA_TRIG_IRQ, PLP_DMA_SHARED); @@ -344,6 +429,17 @@ static inline int plp_dma_memcpy_irq(mchan_ext_t ext, unsigned int loc, unsigned return counter; } +static inline int plp_cl_dma_memcpy_irq(mchan_ext_t ext, unsigned int loc, unsigned short size, int ext2loc) { +#ifdef ARCHI_HAS_DMA_DEMUX + unsigned int counter = plp_cl_dma_counter_alloc(); + unsigned int cmd = plp_cl_dma_getCmd(ext2loc, size, PLP_DMA_1D, PLP_DMA_NO_TRIG_EVT, PLP_DMA_TRIG_IRQ, PLP_DMA_SHARED); + plp_cl_dma_cmd_push(cmd, loc, ext); + return counter; +#else // ARCHI_HAS_DMA_DEMUX + return plp_dma_memcpy_irq(ext, loc, size, ext2loc); +#endif // ARCHI_HAS_DMA_DEMUX +} + static inline int plp_dma_l1ToExt_irq(mchan_ext_t ext, unsigned int loc, unsigned short size) { unsigned int counter = plp_dma_counter_alloc(); unsigned int cmd = plp_dma_getCmd(PLP_DMA_LOC2EXT, size, PLP_DMA_1D, PLP_DMA_NO_TRIG_EVT, PLP_DMA_TRIG_IRQ, PLP_DMA_SHARED); @@ -351,6 +447,17 @@ static inline int plp_dma_l1ToExt_irq(mchan_ext_t ext, unsigned int loc, unsigne return counter; } +static inline int plp_cl_dma_l1ToExt_irq(mchan_ext_t ext, unsigned int loc, unsigned short size) { +#ifdef ARCHI_HAS_DMA_DEMUX + unsigned int counter = plp_cl_dma_counter_alloc(); + unsigned int cmd = plp_cl_dma_getCmd(PLP_DMA_LOC2EXT, size, PLP_DMA_1D, PLP_DMA_NO_TRIG_EVT, PLP_DMA_TRIG_IRQ, PLP_DMA_SHARED); + plp_cl_dma_cmd_push(cmd, loc, ext); + return counter; +#else // ARCHI_HAS_DMA_DEMUX + return plp_dma_l1ToExt_irq(ext, loc, size); +#endif // ARCHI_HAS_DMA_DEMUX +} + static inline int plp_dma_extToL1_irq(unsigned int loc, mchan_ext_t ext, unsigned short size) { unsigned int counter = plp_dma_counter_alloc(); unsigned int cmd = plp_dma_getCmd(PLP_DMA_EXT2LOC, size, PLP_DMA_1D, PLP_DMA_NO_TRIG_EVT, PLP_DMA_TRIG_IRQ, PLP_DMA_SHARED); @@ -358,17 +465,47 @@ static inline int plp_dma_extToL1_irq(unsigned int loc, mchan_ext_t ext, unsigne return counter; } +static inline int plp_cl_dma_extToL1_irq(unsigned int loc, mchan_ext_t ext, unsigned short size) { +#ifdef ARCHI_HAS_DMA_DEMUX + unsigned int counter = plp_cl_dma_counter_alloc(); + unsigned int cmd = plp_cl_dma_getCmd(PLP_DMA_EXT2LOC, size, PLP_DMA_1D, PLP_DMA_NO_TRIG_EVT, PLP_DMA_TRIG_IRQ, PLP_DMA_SHARED); + plp_cl_dma_cmd_push(cmd, loc, ext); + return counter; +#else // ARCHI_HAS_DMA_DEMUX + return plp_dma_extToL1_irq(loc, ext, size); +#endif // ARCHI_HAS_DMA_DEMUX +} + static inline void plp_dma_memcpy_2d_keepCounter(mchan_ext_t ext, unsigned int loc, unsigned short size, unsigned short stride, unsigned short length, int ext2loc) { unsigned int cmd = plp_dma_getCmd(ext2loc, size, PLP_DMA_2D, PLP_DMA_TRIG_EVT, PLP_DMA_NO_TRIG_IRQ, PLP_DMA_SHARED); plp_dma_cmd_push_2d(cmd, loc, ext, stride, length); } +static inline void plp_cl_dma_memcpy_2d_keepCounter(mchan_ext_t ext, unsigned int loc, unsigned short size, unsigned short stride, unsigned short length, int ext2loc) { +#ifdef ARCHI_HAS_DMA_DEMUX + unsigned int cmd = plp_cl_dma_getCmd(ext2loc, size, PLP_DMA_2D, PLP_DMA_TRIG_EVT, PLP_DMA_NO_TRIG_IRQ, PLP_DMA_SHARED); + plp_cl_dma_cmd_push_2d(cmd, loc, ext, stride, length); +#else // ARCHI_HAS_DMA_DEMUX + plp_dma_memcpy_2d_keepCounter(ext, loc, size, stride, length, ext2loc); +#endif // ARCHI_HAS_DMA_DEMUX +} + static inline int plp_dma_memcpy_2d(mchan_ext_t ext, unsigned int loc, unsigned short size, unsigned short stride, unsigned short length, int ext2loc) { unsigned int counter = plp_dma_counter_alloc(); plp_dma_memcpy_2d_keepCounter(ext, loc, size, stride, length, ext2loc); return counter; } +static inline int plp_cl_dma_memcpy_2d(mchan_ext_t ext, unsigned int loc, unsigned short size, unsigned short stride, unsigned short length, int ext2loc) { +#ifdef ARCHI_HAS_DMA_DEMUX + unsigned int counter = plp_cl_dma_counter_alloc(); + plp_cl_dma_memcpy_2d_keepCounter(ext, loc, size, stride, length, ext2loc); + return counter; +#else // ARCHI_HAS_DMA_DEMUX + return plp_dma_memcpy_2d(ext, loc, size, stride, length, ext2loc); +#endif // ARCHI_HAS_DMA_DEMUX +} + static inline int plp_dma_l1ToExt_2d(mchan_ext_t ext, unsigned int loc, unsigned short size, unsigned short stride, unsigned short length) { unsigned int counter = plp_dma_counter_alloc(); unsigned int cmd = plp_dma_getCmd(PLP_DMA_LOC2EXT, size, PLP_DMA_2D, PLP_DMA_TRIG_EVT, PLP_DMA_NO_TRIG_IRQ, PLP_DMA_SHARED); @@ -376,6 +513,17 @@ static inline int plp_dma_l1ToExt_2d(mchan_ext_t ext, unsigned int loc, unsigned return counter; } +static inline int plp_cl_dma_l1ToExt_2d(mchan_ext_t ext, unsigned int loc, unsigned short size, unsigned short stride, unsigned short length) { +#ifdef ARCHI_HAS_DMA_DEMUX + unsigned int counter = plp_cl_dma_counter_alloc(); + unsigned int cmd = plp_cl_dma_getCmd(PLP_DMA_LOC2EXT, size, PLP_DMA_2D, PLP_DMA_TRIG_EVT, PLP_DMA_NO_TRIG_IRQ, PLP_DMA_SHARED); + plp_cl_dma_cmd_push_2d(cmd, loc, ext, stride, length); + return counter; +#else // ARCHI_HAS_DMA_DEMUX + return plp_dma_l1ToExt_2d(ext, loc, size, stride, length); +#endif // ARCHI_HAS_DMA_DEMUX +} + static inline int plp_dma_extToL1_2d(unsigned int loc, mchan_ext_t ext, unsigned short size, unsigned short stride, unsigned short length) { unsigned int counter = plp_dma_counter_alloc(); unsigned int cmd = plp_dma_getCmd(PLP_DMA_EXT2LOC, size, PLP_DMA_2D, PLP_DMA_TRIG_EVT, PLP_DMA_NO_TRIG_IRQ, PLP_DMA_SHARED); @@ -383,6 +531,17 @@ static inline int plp_dma_extToL1_2d(unsigned int loc, mchan_ext_t ext, unsigned return counter; } +static inline int plp_cl_dma_extToL1_2d(unsigned int loc, mchan_ext_t ext, unsigned short size, unsigned short stride, unsigned short length) { +#ifdef ARCHI_HAS_DMA_DEMUX + unsigned int counter = plp_cl_dma_counter_alloc(); + unsigned int cmd = plp_cl_dma_getCmd(PLP_DMA_EXT2LOC, size, PLP_DMA_2D, PLP_DMA_TRIG_EVT, PLP_DMA_NO_TRIG_IRQ, PLP_DMA_SHARED); + plp_cl_dma_cmd_push_2d(cmd, loc, ext, stride, length); + return counter; +#else // ARCHI_HAS_DMA_DEMUX + return plp_dma_extToL1_2d(loc, ext, size, stride, length); +#endif // ARCHI_HAS_DMA_DEMUX +} + static inline int plp_dma_memcpy_2d_irq(mchan_ext_t ext, unsigned int loc, unsigned short size, unsigned short stride, unsigned short length, int ext2loc) { unsigned int counter = plp_dma_counter_alloc(); unsigned int cmd = plp_dma_getCmd(ext2loc, size, PLP_DMA_2D, PLP_DMA_NO_TRIG_EVT, PLP_DMA_TRIG_IRQ, PLP_DMA_SHARED); @@ -390,6 +549,17 @@ static inline int plp_dma_memcpy_2d_irq(mchan_ext_t ext, unsigned int loc, unsig return counter; } +static inline int plp_cl_dma_memcpy_2d_irq(mchan_ext_t ext, unsigned int loc, unsigned short size, unsigned short stride, unsigned short length, int ext2loc) { +#ifdef ARCHI_HAS_DMA_DEMUX + unsigned int counter = plp_cl_dma_counter_alloc(); + unsigned int cmd = plp_cl_dma_getCmd(ext2loc, size, PLP_DMA_2D, PLP_DMA_NO_TRIG_EVT, PLP_DMA_TRIG_IRQ, PLP_DMA_SHARED); + plp_cl_dma_cmd_push_2d(cmd, loc, ext, stride, length); + return counter; +#else // ARCHI_HAS_DMA_DEMUX + return plp_dma_memcpy_2d_irq(ext, loc, size, stride, length, ext2loc); +#endif // ARCHI_HAS_DMA_DEMUX +} + static inline int plp_dma_l1ToExt_2d_irq(mchan_ext_t ext, unsigned int loc, unsigned short size, unsigned short stride, unsigned short length) { unsigned int counter = plp_dma_counter_alloc(); unsigned int cmd = plp_dma_getCmd(PLP_DMA_LOC2EXT, size, PLP_DMA_2D, PLP_DMA_NO_TRIG_EVT, PLP_DMA_TRIG_IRQ, PLP_DMA_SHARED); @@ -397,6 +567,17 @@ static inline int plp_dma_l1ToExt_2d_irq(mchan_ext_t ext, unsigned int loc, unsi return counter; } +static inline int plp_cl_dma_l1ToExt_2d_irq(mchan_ext_t ext, unsigned int loc, unsigned short size, unsigned short stride, unsigned short length) { +#ifdef ARCHI_HAS_DMA_DEMUX + unsigned int counter = plp_cl_dma_counter_alloc(); + unsigned int cmd = plp_cl_dma_getCmd(PLP_DMA_LOC2EXT, size, PLP_DMA_2D, PLP_DMA_NO_TRIG_EVT, PLP_DMA_TRIG_IRQ, PLP_DMA_SHARED); + plp_cl_dma_cmd_push_2d(cmd, loc, ext, stride, length); + return counter; +#else // ARCHI_HAS_DMA_DEMUX + return plp_dma_l1ToExt_2d_irq(ext, loc, size, stride, length); +#endif // ARCHI_HAS_DMA_DEMUX +} + static inline int plp_dma_extToL1_2d_irq(unsigned int loc, mchan_ext_t ext, unsigned short size, unsigned short stride, unsigned short length) { unsigned int counter = plp_dma_counter_alloc(); unsigned int cmd = plp_dma_getCmd(PLP_DMA_EXT2LOC, size, PLP_DMA_2D, PLP_DMA_NO_TRIG_EVT, PLP_DMA_TRIG_IRQ, PLP_DMA_SHARED); @@ -404,6 +585,17 @@ static inline int plp_dma_extToL1_2d_irq(unsigned int loc, mchan_ext_t ext, unsi return counter; } +static inline int plp_cl_dma_extToL1_2d_irq(unsigned int loc, mchan_ext_t ext, unsigned short size, unsigned short stride, unsigned short length) { +#ifdef ARCHI_HAS_DMA_DEMUX + unsigned int counter = plp_cl_dma_counter_alloc(); + unsigned int cmd = plp_cl_dma_getCmd(PLP_DMA_EXT2LOC, size, PLP_DMA_2D, PLP_DMA_NO_TRIG_EVT, PLP_DMA_TRIG_IRQ, PLP_DMA_SHARED); + plp_cl_dma_cmd_push_2d(cmd, loc, ext, stride, length); + return counter; +#else // ARCHI_HAS_DMA_DEMUX + return plp_dma_extToL1_2d_irq(loc, ext, size, stride, length); +#endif // ARCHI_HAS_DMA_DEMUX +} + static inline void plp_dma_barrier() { while(DMA_READ(MCHAN_STATUS_OFFSET) & 0xFFFF) { eu_evt_maskWaitAndClr(1< L2 + + + .fini : + { + . = ALIGN(4); + KEEP( *(.fini) ) + } > L2 + + + .preinit_array : { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } > L2 + + + .init_array : { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + __CTOR_LIST__ = .; + LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) + KEEP(*(.ctors.start)) + KEEP(*(.ctors)) + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array )) + LONG(0) + __CTOR_END__ = .; + PROVIDE_HIDDEN (__init_array_end = .); + } > L2 + + + .fini_array : { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + __DTOR_LIST__ = .; + LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) + KEEP(*(.dtors.start)) + KEEP(*(.dtors)) + LONG(0) + __DTOR_END__ = .; + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array )) + PROVIDE_HIDDEN (__fini_array_end = .); + } > L2 + + + .boot : { + . = ALIGN(4); + *(.boot) + *(.boot.data) + } > L2 + + + .rodata : { + . = ALIGN(4); + *(.rodata); + *(.rodata.*) + *(.srodata); + *(.srodata.*) + *(.eh_frame*) + } > L2 + + + .got : { + . = ALIGN(4); + *(.got.plt) * (.igot.plt) *(.got) *(.igot) + } > L2 + + + .shbss : { + . = ALIGN(4); + *(.shbss) + } > L2 + + + .talias : { + } > L2 + + + .gnu.offload_funcs : { + . = ALIGN(4); + KEEP(*(.gnu.offload_funcs)) + } > L2 + + + .gnu.offload_vars : { + . = ALIGN(4); + KEEP(*(.gnu.offload_vars)) + } > L2 + + + .stack : { + . = ALIGN(4); + . = ALIGN(16); + stack_start = .; + . = . + 0x800; + stack = .; + } > L2 + + + .data : { + . = ALIGN(4); + sdata = .; + _sdata = .; + *(.data_fc) + *(.data_fc.*) + *(.data); + *(.data.*) + *(.sdata); + *(.sdata.*) + *(.heapl2ram) + *(.fcTcdm) + *(.fcTcdm.*) + *(.fcTcdm_g) + *(.fcTcdm_g.*) + . = ALIGN(4); + edata = .; + _edata = .; + } > L2 + + + .bss : { + . = ALIGN(8); + _bss_start = .; + *(.bss) + *(.bss.*) + *(.sbss) + *(.sbss.*) + *(COMMON) + . = ALIGN(4); + _bss_end = .; + } > L2 + + + __l2_priv0_end = ALIGN(4); + + + + + /* + * L2 PRIVATE BANK1 + * + * Contains FC code + */ + + .vectors MAX(0x1c008000,ALIGN(256)) : + { + __irq_vector_base = .; + KEEP(*(.vectors)) + } > L2 + + .text : + { + . = ALIGN(4); + _stext = .; + *(.text) + *(.text.*) + _etext = .; + *(.lit) + *(.shdata) + _endtext = .; + . = ALIGN(4); + } > L2 + + __l2_priv1_end = ALIGN(4); + + + /* + * L2 SHARED BANKS + * + * Contains other data such as peripheral data and cluster code and data + */ + + .l2_data MAX(0x1c010000,ALIGN(4)) : + { + . = ALIGN(4); + __cluster_text_start = .; + *(.cluster.text) + *(.cluster.text.*) + . = ALIGN(4); + __cluster_text_end = .; + *(.l2_data) + *(.l2_data.*) + *(.data_fc_shared) + *(.data_fc_shared.*) + . = ALIGN(4); + } > L2 + + __l2_shared_end = .; +} diff --git a/kernel/chips/kairos/soc.c b/kernel/chips/kairos/soc.c new file mode 100644 index 0000000..a185830 --- /dev/null +++ b/kernel/chips/kairos/soc.c @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2019 ETH Zurich, University of Bologna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "pulp.h" + +void pos_soc_init() +{ +#if __PLATFORM__ != ARCHI_PLATFORM_FPGA + pos_freq_domains[PI_FREQ_DOMAIN_FC] = ARCHI_ASIC_FC_FREQUENCY; + pos_freq_domains[PI_FREQ_DOMAIN_PERIPH] = ARCHI_ASIC_PER_FREQUENCY; +#else + pos_freq_domains[PI_FREQ_DOMAIN_FC] = ARCHI_FPGA_FC_FREQUENCY; + pos_freq_domains[PI_FREQ_DOMAIN_PERIPH] = ARCHI_FPGA_PER_FREQUENCY; +#endif +} + diff --git a/rules/pulpos/src.mk b/rules/pulpos/src.mk index e7b065e..22152d0 100644 --- a/rules/pulpos/src.mk +++ b/rules/pulpos/src.mk @@ -13,4 +13,4 @@ PULP_ASM_SRCS += kernel/irq_asm.S ifneq '$(cluster/version)' '' PULP_SRCS += kernel/cluster.c -endif \ No newline at end of file +endif diff --git a/rules/pulpos/targets/kairos.mk b/rules/pulpos/targets/kairos.mk new file mode 100644 index 0000000..7e8a75e --- /dev/null +++ b/rules/pulpos/targets/kairos.mk @@ -0,0 +1,57 @@ +ifdef USE_IBEX +$(error IBEX is not supported in control-pulp) +endif + +# we need at least pulp-gcc v2.4.0 +PULP_LDFLAGS += +PULP_CFLAGS += -D__cv32e40p__ -D__riscv__ +PULP_ARCH_CFLAGS ?= -march=rv32imc_zfinx_xcorev -mabi=ilp32 -mno-pulp-hwloop +PULP_ARCH_LDFLAGS ?= -march=rv32imc_zfinx_xcorev -mabi=ilp32 -mno-pulp-hwloop +# uses elf attributes to disassemble so no need to set it manually +PULP_ARCH_OBJDFLAGS ?= + +PULP_CFLAGS += -fdata-sections -ffunction-sections \ + -include chips/kairos/config.h -I$(PULPRT_HOME)/include/chips/kairos +PULP_OMP_CFLAGS += -fopenmp -mnativeomp +PULP_LDFLAGS += -nostartfiles -nostdlib -Wl,--gc-sections \ + -L$(PULPRT_HOME)/kernel -Tchips/kairos/link.ld -lgcc + +PULP_CC = riscv32-unknown-elf-gcc +PULP_AR ?= riscv32-unknown-elf-ar +PULP_LD ?= riscv32-unknown-elf-gcc +PULP_OBJDUMP ?= riscv32-unknown-elf-objdump + +fc/archi=riscv +pe/archi=riscv +pulp_chip=kairos +pulp_chip_family=kairos +fc_itc/version=1 +udma/cpi/version=1 +udma/i2c/version=2 +soc/fll/version=1 +udma/i2s/version=2 +udma/uart/version=1 +event_unit/version=3 +perf_counters=True +fll/version=1 +padframe/version=1 +udma/spim/version=3 +gpio/version=3 +udma/archi=3 +udma/version=3 +soc_eu/version=2 + + +# FLL +PULP_SRCS += kernel/fll-v$(fll/version).c +PULP_SRCS += kernel/freq-domains.c +PULP_SRCS += kernel/chips/kairos/soc.c + + +include $(PULPRT_HOME)/rules/pulpos/configs/default.mk + +ifeq '$(platform)' 'fpga' +CONFIG_IO_UART=1 +endif + +include $(PULPRT_HOME)/rules/pulpos/default_rules.mk