mirror of
https://github.com/t-crest/rtems.git
synced 2025-11-16 04:24:46 +00:00
Add NoC management functions to Patmos CPU
This commit is contained in:
143
c/src/lib/libbsp/patmos/shared/noc/noc.c
Executable file
143
c/src/lib/libbsp/patmos/shared/noc/noc.c
Executable file
@@ -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 <stdio.h>
|
||||
#include <bsp.h>
|
||||
#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)));
|
||||
}
|
||||
162
c/src/lib/libbsp/patmos/shared/noc/noc.h
Executable file
162
c/src/lib/libbsp/patmos/shared/noc/noc.h
Executable file
@@ -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 <wpuffitsch@gmail.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file has been modified by GMVIS Skysoft S.A.
|
||||
*/
|
||||
|
||||
#ifndef _NOC_H_
|
||||
#define _NOC_H_
|
||||
|
||||
#include <bsp.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// 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_ */
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user