Newer
Older
/* ****************************************************************************
* This work is part of the White Rabbit project
*
* Copyright (C) 2017 CERN (www.cern.ch)
* Author: Grzegorz Daniluk <grzegorz.daniluk@cern.ch>
* Author: Maciej Lipinski <maciej.lipinski@cern.ch>
* Author: Adam Wujek <adam.wujek@cern.ch>
*
* Released according to the GNU GPL, version 2 or any later version.
*
* ****************************************************************************
* Description:
* This file provides the main() function that replaces the main function of
* wrc_main.c file when WRPC is compiled for testbench. This is done by
* configuring WRPC using make menuconfig:
* a) by using the default wrpc_sim_defconfig, i.e. "make wrpc_sim_defconfig",or
* b) by chosing in make menuconfig the following opton:
* "Build simple software for test of WR PTP Core in simulatin"
*
* When compiled for testbench simulation, the main() function of this file is
* used. This file includes all the tests needed for different testbenches
* (so far only one...)
* ****************************************************************************
#include <stdio.h>
#include <inttypes.h>
#include "system_checks.h"
#include "endpoint.h"
#include "minic.h"
#include "pps_gen.h"
#include "softpll_ng.h"
#include <wrpc.h> /*needed for htons()*/
#define TESTBENCH_MAGIC 0x4d433ebc
#define TESTBENCH_VERSION 1
#define TESTBENCH_RET_NO_TEST 0
#define TESTBENCH_RET_OK 1
#define TESTBENCH_RET_ERROR 2
* This is a structure to pass information from the testbench to lm32's
* software. hdl_testbench structure is meant to be set by testbench through
* memory-manipulation.
* At the address HDL_TESTBENCH_PADDR is a pointer to hdl_testbench structure.
* hdl_testbench_t structure can be expanded to carry information with any
* size.
* The idea behind is that different tests for different testbenches are
* compiled in this file, and the proper test is loaded based on variable
* hdl_testbench.test_num.
* Each HDL testbench sets the proper testbench number at the startup.
struct hdl_testbench_t {
uint32_t magic;
uint32_t version;
uint32_t test_num;
uint32_t return_val;
};
struct hdl_testbench_t hdl_testbench = {
.magic = TESTBENCH_MAGIC,
.version = TESTBENCH_VERSION,
.test_num = 0,
};
int wrpc_test_1(void);
/*
* Basic initialization required for simulation
*/
static void wrc_sim_initialize(void)
{
uint8_t mac_addr[6];
sdb_find_devices();
timer_init(1);
/* Source MAC used by WRPC's Endpoint */
mac_addr[0] = 0xDE;
mac_addr[1] = 0xAD;
mac_addr[2] = 0xBE;
mac_addr[3] = 0xEF;
mac_addr[4] = 0xBA;
mac_addr[5] = 0xBE;
ep_init(mac_addr);
ep_enable(1, 1);
minic_init();
shw_pps_gen_init();
spll_very_init();
Maciej Lipinski
committed
shw_pps_gen_enable_output(1);
}
/*
* This is a test used by:
* - WRPC testbench located in "testbench/wrc_core" folder of the wr-cores
* repository (git://ohwr.org/hdl-core-lib/wr-cores.git)
*
* This test:
* - sends min-size frames of PTP EtherType (0x88f7) and Dst MAC
* (01:1B:19:00:00:00) with embedded sequence number and flags providing
* information about the previously received frame
* - checkes whether the transmitted frames are successfully received back in a
* proper sequence (it is supposed that the testbench loops back the frames)
* - embeds in the next frame flag and return value regarding the previously
* received frames, i.e.:
* # the flags say:
* 0xAA: this is the first frame (no previous frames)
* 0xBB: previous frame was successfully received
* 0xE*: something was wrong with the previously received frame
* # return value - it is the value returned by the reception funcation
*
*/
int wrpc_test_1(void)
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
struct hw_timestamp hwts;
struct wr_ethhdr_vlan tx_hdr;
struct wr_ethhdr rx_hdr;
int j;
uint8_t tx_payload[NET_MAX_SKBUF_SIZE - 32];
uint8_t rx_payload[NET_MAX_SKBUF_SIZE - 32];
int ret = 0;
int tx_cnt = 0, rx_cnt = 0, pl_cnt;
/* error code:
* 0xAA - first
* 0xBB - normal
* 0xE* - error code:
* 0 - Error: returned zero value
* 1 - Error: wrong seqID
* 2 - Error: error of rx */
int code = 0xAA;
/** prepare dummy frame */
/* payload */
for (j = 0; j < 80; ++j)
tx_payload[j] = 0xC7;/* j; */
/* MAC address and EtherType of PTP */
memcpy(tx_hdr.dstmac, "\x01\x1B\x19\x00\x00\x00", 6);
tx_hdr.ethtype = htons(0x88f7);
hdl_testbench.return_val = TESTBENCH_RET_OK;
/** main loop, send test frames */
for (;;) {
/* seqID */
tx_payload[0] = 0xFF & (tx_cnt >> 8);
tx_payload[1] = 0xFF & tx_cnt;
tx_payload[2] = 0xFF & (code >> 8);
tx_payload[3] = 0xFF & code;
/* rx return value */
tx_payload[4] = 0xFF & (ret >> 8);
tx_payload[5] = 0xFF & ret;
/* A frame is sent out with sequenceID (firt octet) and awaited
* reception. */
minic_tx_frame(&tx_hdr, tx_payload, 62, &hwts);
tx_cnt++;
ret = minic_rx_frame(&rx_hdr, rx_payload, NET_MAX_SKBUF_SIZE,
&hwts);
/** check whether the received value is OK */
if (ret == 0) {
code = 0xE0; /* Error: returned zero value */
hdl_testbench.return_val = TESTBENCH_RET_ERROR;
}
else if (ret > 0) {
pl_cnt = 0xFFFF & ((tx_payload[0] << 8) | tx_payload[1]);
if (pl_cnt == rx_cnt) {
rx_cnt++;
code = 0xBB; /* OK */
hdl_testbench.return_val = TESTBENCH_RET_OK;
} else {
rx_cnt = pl_cnt+1;
code = 0xE1; /* Error: wrong seqID */
hdl_testbench.return_val = TESTBENCH_RET_ERROR;
} else {
code = 0xE2; /* Error: error of rx */
hdl_testbench.return_val = TESTBENCH_RET_ERROR;
}
}
void main(void)
{
wrc_sim_initialize();
if (hdl_testbench.magic != TESTBENCH_MAGIC
|| hdl_testbench.magic != TESTBENCH_VERSION) {
/* Wrong testbench structure */
hdl_testbench.return_val = TESTBENCH_RET_ERROR;
while (1)
;
}
switch (hdl_testbench.test_num) {
case 0:
/* for simulations that just need link-up */
hdl_testbench.return_val = TESTBENCH_RET_NO_TEST;
while (1)
;
wrpc_test_1();
break;
default:
/* Wrong test number */
hdl_testbench.return_val = TESTBENCH_RET_ERROR;
while (1)
;
}