diff --git a/c/src/lib/libbsp/patmos/shared/noc/noc.c b/c/src/lib/libbsp/patmos/shared/noc/noc.c new file mode 100755 index 0000000000..e1df9dda6f --- /dev/null +++ b/c/src/lib/libbsp/patmos/shared/noc/noc.c @@ -0,0 +1,143 @@ +/* + Copyright 2014 Technical University of Denmark, DTU Compute. + All rights reserved. + + This file is part of the time-predictable VLIW processor Patmos. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + The views and conclusions contained in the software and documentation are + those of the authors and should not be interpreted as representing official + policies, either expressed or implied, of the copyright holder. + */ + +/* + * Functions to initialize and use the NoC. + * + * Author: Wolfgang Puffitsch (wpuffitsch@gmail.com) + * + */ + +/* + * This file has been modified by GMVIS Skysoft S.A. + */ + +#include +#include +#include "noc.h" + +// Structure to model the network interface +static struct network_interface +{ + volatile int _IODEV *dma; + volatile int _IODEV *dma_p; + volatile int _IODEV *st; +} noc_interface = { + NOC_DMA_BASE, NOC_DMA_P_BASE, NOC_ST_BASE +}; + +// Configure network interface according to initialization information +void noc_configure(void) { + int row_size = NOC_TIMESLOTS > NOC_DMAS ? NOC_TIMESLOTS : NOC_DMAS; + int core_idx = CORE_ID * NOC_TABLES * row_size; + for (unsigned i = 0; i < NOC_TIMESLOTS; ++i) { + *(noc_interface.st+i) = noc_init_array[core_idx + i]; + } + for (unsigned i = 0; i < NOC_DMAS; ++i) { + *(noc_interface.dma_p+i) = noc_init_array[core_idx + row_size + i]; + } +} + +// Synchronize start-up +static void noc_sync(void) { + + if (CORE_ID == NOC_MASTER) { + // Wait until all slaves have configured their network interface + int done = 0; + do { + done = 1; + for (unsigned i = 0; i < MAX_CORES; i++) { + if (boot_info->slave[i].status != STATUS_NULL && + boot_info->slave[i].status != STATUS_INITDONE) { + done = 0; + } + } + } while (!done); + + // TODO: start up network + + // Notify slaves that the network is started + boot_info->master.status = STATUS_INITDONE; + + } else { + // Notify master that network interface is configured + boot_info->slave[CORE_ID].status = STATUS_INITDONE; + // Wait until master has started the network + while (boot_info->master.status != STATUS_INITDONE) { + /* spin */ + } + } +} + +// Initialize the NoC +void noc_init(void) { + /* if (CORE_ID == NOC_MASTER) puts("noc_configure"); */ + noc_configure(); + /* if (CORE_ID == NOC_MASTER) puts("noc_sync"); */ + noc_sync(); + /* if (CORE_ID == NOC_MASTER) puts("noc_done"); */ +} + +// Start a NoC transfer +// The addresses and the size are in double-words and relative to the +// communication SPM +int noc_dma(unsigned rcv_id, + unsigned short write_ptr, + unsigned short read_ptr, + unsigned short size) { + + // Ony send if previous transfer is done + unsigned status = *(noc_interface.dma+(rcv_id<<1)); + if ((status & NOC_VALID_BIT) != 0 && (status & NOC_DONE_BIT) == 0) { + return 0; + } + + // Read pointer and write pointer in the dma table + *(noc_interface.dma+(rcv_id<<1)+1) = (read_ptr << 16) | write_ptr; + // DWord count and valid bit, done bit cleared + *(noc_interface.dma+(rcv_id<<1)) = (size | NOC_VALID_BIT) & ~NOC_DONE_BIT; + + return 1; +} + +// Convert from byte address or size to double-word address or size +#define DW(X) (((X)+7)/8) + +// Transfer data via the NoC +// The addresses and the size are in bytes +void noc_send(int dst_id, volatile void _SPM *dst, + volatile void _SPM *src, size_t len) { + + unsigned wp = (char *)dst - (char *)NOC_SPM_BASE; + unsigned rp = (char *)src - (char *)NOC_SPM_BASE; + while(!noc_dma(dst_id, DW(wp), DW(rp), DW(len))); +} diff --git a/c/src/lib/libbsp/patmos/shared/noc/noc.h b/c/src/lib/libbsp/patmos/shared/noc/noc.h new file mode 100755 index 0000000000..9cba2c44d5 --- /dev/null +++ b/c/src/lib/libbsp/patmos/shared/noc/noc.h @@ -0,0 +1,162 @@ +/* + Copyright 2014 Technical University of Denmark, DTU Compute. + All rights reserved. + + This file is part of the time-predictable VLIW processor Patmos. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + The views and conclusions contained in the software and documentation are + those of the authors and should not be interpreted as representing official + policies, either expressed or implied, of the copyright holder. + */ + +/** + * \file noc.h Definitions for libnoc. + * + * \author Wolfgang Puffitsch + * + */ + +/* + * This file has been modified by GMVIS Skysoft S.A. + */ + +#ifndef _NOC_H_ +#define _NOC_H_ + +#include + +//////////////////////////////////////////////////////////////////////////// +// Definitions used for initialization of network interface +//////////////////////////////////////////////////////////////////////////// + +/// The CPU ID +#define CORE_ID *((_iodev_ptr_t) __PATMOS_CPU_ID_ADDR) + +/// \brief The number of cores on the platform. +/// +/// Defined by the application +extern const int NOC_CORES; + +/// \brief The number of tables for Noc configuration. +/// +/// Defined by the application +extern const int NOC_TABLES; + +/// \brief The number of timeslots in the schedule. +/// +/// Defined by the application +extern const int NOC_TIMESLOTS; + +/// \brief The number of DMAs in the configuration. +/// +/// Defined by the application +extern const int NOC_DMAS; + +/// \brief The array for initialization data. +/// +/// Defined by the application +extern const int noc_init_array []; + +/// \brief The master core, which governs booting and startup synchronization. +/// +/// Defined by the application +extern const int NOC_MASTER; + +/// \brief Configure network interface according to initialization +/// information in #noc_init_array. +void noc_configure(void); + +/// \brief Configure network-on-chip and synchronize all cores. +/// +/// #noc_init is a static constructor and not intended to be called directly. +void noc_init(void) __attribute__((constructor,used)); + +//////////////////////////////////////////////////////////////////////////// +// Functions for transmitting data +//////////////////////////////////////////////////////////////////////////// + +/// \brief Start a NoC transfer. +/// +/// The addresses and the size are in double-words and relative to the +/// communication SPM base #NOC_SPM_BASE. +/// \param rcv_id The core id of the receiver. +/// \param write_ptr The address in the receiver's communication SPM, +/// in double-words, relative to #NOC_SPM_BASE. +/// \param read_ptr The address in the sender's communication SPM, in +/// double-words, relative to #NOC_SPM_BASE. +/// \param size The size of data to be transferred, in double-words. +/// \returns 1 if sending was successful, 0 otherwise. +int noc_dma(unsigned rcv_id, unsigned short write_ptr, + unsigned short read_ptr, unsigned short size); + +/// \brief Transfer data via the NoC. +/// +/// The addresses and the size are absolute and in bytes. +/// \param rcv_id The core id of the receiver. +/// \param dst A pointer to the destination of the transfer. +/// \param src A pointer to the source of the transfer. +/// \param size The size of data to be transferred, in bytes. +void noc_send(int rcv_id, volatile void _SPM *dst, + volatile void _SPM *src, size_t size); + + +//////////////////////////////////////////////////////////////////////////// +// Definitions for setting up a transfer +//////////////////////////////////////////////////////////////////////////// + +/// The flag to mark a DMA entry as valid +#define NOC_VALID_BIT 0x08000 +/// The flag to mark a DMA entry as done +#define NOC_DONE_BIT 0x04000 + +//////////////////////////////////////////////////////////////////////////// +// Boot data definitions +//////////////////////////////////////////////////////////////////////////// + +#define MAX_CORES 64 + +#define STATUS_NULL 0 +#define STATUS_BOOT 1 +#define STATUS_INIT 2 +#define STATUS_INITDONE 3 + +struct master_info_t { + volatile entrypoint_t entrypoint; + volatile int status; +}; + +struct slave_info_t { + volatile int status; +}; + +struct boot_info_t { + struct master_info_t master; + struct slave_info_t slave[MAX_CORES]; +}; + +/* Place boot info at the beginning of the memory. Nothing else may be + placed there. */ +#define boot_info ((_UNCACHED struct boot_info_t *)0x00000010) + +#endif /* _NOC_H_ */ diff --git a/c/src/lib/libbsp/patmos/tcrest/Makefile.am b/c/src/lib/libbsp/patmos/tcrest/Makefile.am index 6487892de6..30c868108b 100755 --- a/c/src/lib/libbsp/patmos/tcrest/Makefile.am +++ b/c/src/lib/libbsp/patmos/tcrest/Makefile.am @@ -21,6 +21,7 @@ noinst_PROGRAMS = include_HEADERS += include/tcrest.h include_HEADERS += ../../shared/include/coverhd.h +include_HEADERS += ../shared/noc/noc.h noinst_LIBRARIES = libbspstart.a libbspstart_a_SOURCES = ../../patmos/shared/startup/start.S @@ -43,6 +44,8 @@ libbsp_a_SOURCES += ../shared/console/console.c libbsp_a_SOURCES += ../shared/console/debugputs.c # clock libbsp_a_SOURCES += ../shared/clock/ckinit.c ../../../shared/clockdrv_shell.h +# noc +libbsp_a_SOURCES += ../shared/noc/noc.c # timer libbsp_a_SOURCES += ../shared/timer/timer.c diff --git a/c/src/lib/libbsp/patmos/tcrest/include/tcrest.h b/c/src/lib/libbsp/patmos/tcrest/include/tcrest.h index 7028eb7ebd..ddc1b14d96 100755 --- a/c/src/lib/libbsp/patmos/tcrest/include/tcrest.h +++ b/c/src/lib/libbsp/patmos/tcrest/include/tcrest.h @@ -35,6 +35,22 @@ extern "C" { typedef _IODEV unsigned int volatile * const _iodev_ptr_t; +/* + * Attribute for pointers into the scratchpad memory. Use as + * + * _SPM int *p = (_SPM int *) 0x1234; + * + */ +#define _SPM __attribute__((address_space(1))) + +/* + * Attribute for pointers into main memory using cache bypass. Use as + * + * _UNCACHED int *p = (_UNCACHED int *) &mydata; + */ +#define _UNCACHED __attribute__((address_space(3))) + +typedef volatile int (*entrypoint_t)(void); /* * CPU Info Management @@ -179,6 +195,25 @@ extern char _excunit_base; /* linker symbol giving the base address of the excep * End of Exception Management */ +/* + * NOC Management + * + * TODO: replace these by linker symbols + */ + +/* The base address for DMA entries */ +#define NOC_DMA_BASE ((volatile int _IODEV *)0xE0000000) +/* The base address for DMA routing information */ +#define NOC_DMA_P_BASE ((volatile int _IODEV *)0xE1000000) +/* The base address for the slot table */ +#define NOC_ST_BASE ((volatile int _IODEV *)0xE2000000) +/* The base address of the communication SPM */ +#define NOC_SPM_BASE ((volatile int _SPM *)0xE8000000) + +/* + * End of NOC Management + */ + #endif /* !ASM */ #ifdef __cplusplus diff --git a/c/src/lib/libbsp/patmos/tcrest/preinstall.am b/c/src/lib/libbsp/patmos/tcrest/preinstall.am index b17551b76e..b3baa92787 100755 --- a/c/src/lib/libbsp/patmos/tcrest/preinstall.am +++ b/c/src/lib/libbsp/patmos/tcrest/preinstall.am @@ -61,6 +61,10 @@ $(PROJECT_INCLUDE)/coverhd.h: ../../shared/include/coverhd.h $(PROJECT_INCLUDE)/ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/coverhd.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/coverhd.h +$(PROJECT_INCLUDE)/noc.h: ../shared/noc/noc.h $(PROJECT_INCLUDE)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/noc.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/noc.h + $(PROJECT_LIB)/start.$(OBJEXT): start.$(OBJEXT) $(PROJECT_LIB)/$(dirstamp) $(INSTALL_DATA) $< $(PROJECT_LIB)/start.$(OBJEXT) TMPINSTALL_FILES += $(PROJECT_LIB)/start.$(OBJEXT)