SpiNNFrontEndCommon 7.1.1
Common support code for user-facing front end systems.
Loading...
Searching...
No Matches
extra_monitor_support.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2017 The University of Manchester
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
28
29// SARK-based program
30#include <sark.h>
31#include <stdbool.h>
32#include <common-typedefs.h>
33#include <spinn_extra.h>
34#include "common.h"
35#include "data_specification.h"
36#include <wfi.h>
37
38// Debugging control
39//#define DEBUG_DATA_IN
40#undef DEBUG_DATA_IN
41
42// ------------------------------------------------------------------------
43// constants
44// ------------------------------------------------------------------------
45
46//-----------------------------------------------------------------------------
47// stuff to do with SARK DMA
48//-----------------------------------------------------------------------------
49
55#define DMA_BURST_SIZE 4
56
58#define N_DMA_BUFFERS 2
59
60//-----------------------------------------------------------------------------
61// magic numbers for data speed up extractor
62//-----------------------------------------------------------------------------
63
65#define END_FLAG_SIZE 4
67#define END_FLAG 0xFFFFFFFF
68
70enum {
80};
81
82//-----------------------------------------------------------------------------
84//-----------------------------------------------------------------------------
85
97
99#define SDP_TIMEOUT 1000
100
102#define LENGTH_OF_SDP_HEADER 8
103
104//-----------------------------------------------------------------------------
105// speed up Data in stuff
106//-----------------------------------------------------------------------------
107
109#define N_ROUTER_ENTRIES 1024
110
112#define INVALID_ROUTER_ENTRY_KEY 0xFFFFFFFF
113
115#define INVALID_ROUTER_ENTRY_MASK 0x00000000
116
118#define INVALID_ROUTER_ENTRY_ROUTE 0xFF000000
119
121#define APP_ID_MASK_FROM_FREE 0x000000FF
122
124#define APP_ID_OFFSET_FROM_FREE 24
125
127#define N_BASIC_SYSTEM_ROUTER_ENTRIES 1
128
130#define N_USABLE_ROUTER_ENTRIES (N_ROUTER_ENTRIES - N_BASIC_SYSTEM_ROUTER_ENTRIES)
131
132//-----------------------------------------------------------------------------
133// reinjection functionality magic numbers
134//-----------------------------------------------------------------------------
135
137#define TDMA_WAIT_PERIOD 0
138
140#define ROUTER_INITIAL_TIMEOUT 0x4f
141
143#define TICK_PERIOD 10
144
146#define PKT_QUEUE_SIZE 4096
147
149#define ROUTER_TIMEOUT_MAX 0xFF
150
151//-----------------------------------------------------------------------------
152// VIC slots assigned
153//-----------------------------------------------------------------------------
154
156enum {
172
173// ------------------------------------------------------------------------
174// structs used in system
175// ------------------------------------------------------------------------
176
183
185typedef struct pkt_queue_t {
186 uint head;
187 uint tail;
191
204
218
225
239
242 POSITION_OF_NO_MISSING_SEQ_PACKETS = 2,
243 START_OF_MISSING_MORE = 2,
244 START_OF_MISSING_SEQ_NUMS = 3,
245};
246
278
295
299 DATA_SPEED_UP_OUT_PORT = 5,
301};
302
314
324
338
350
353 SDP = 0,
354 DMA = 0
355};
356
357// ------------------------------------------------------------------------
358// global variables for reinjector functionality
359// ------------------------------------------------------------------------
360
365
368
369// statistics
372
375
378
381
385
389
392
393// Determine what to reinject
394
396static bool reinject_mc;
397
399static bool reinject_pp;
400
402static bool reinject_nn;
403
405static bool reinject_fr;
406
408static bool reinject_run = true;
409
410// ------------------------------------------------------------------------
411// global variables for data speed up in functionality
412// ------------------------------------------------------------------------
413
414// data in variables
418
421
424
427
430
433
436
439
440// ------------------------------------------------------------------------
441// global variables for data speed up out functionality
442// ------------------------------------------------------------------------
443
444// transmission stuff
445
448
452
455
458
464
467
469static bool data_out_has_finished = false;
470
473
474// retransmission stuff
475
478
481
484
487
490
491// retransmission DMA stuff
492
497
500
503
507
510
513
516
519
522
525
528
531
533static bool data_out_stop = false;
534
535// ------------------------------------------------------------------------
536// support functions and variables
537// ------------------------------------------------------------------------
538
541
546
548static vcpu_t *const _sark_virtual_processor_info = (vcpu_t *) SV_VCPU;
549
552
555
562static inline void *dse_block(uint index) {
564}
565
573 _sark_virtual_processor_info[sark.virt_cpu].user1 = transaction_id;
574}
575
579static inline void *sdram_alloc(uint size) {
580 return sark_xalloc(sv->sdram_heap, size, 0,
581 ALLOC_LOCK | ALLOC_ID | (sark_vec->app_id << 8));
582}
583
586static inline void sdram_free(void *data) {
587 sark_xfree(sv->sdram_heap, data,
588 ALLOC_LOCK | ALLOC_ID | (sark_vec->app_id << 8));
589}
590
593static inline uint sdram_max_block_size(void) {
594 return sark_heap_max(sv->sdram_heap, ALLOC_LOCK);
595}
596
602 sdp_msg_t *msg = sark_msg_get();
603 if (msg != NULL) {
604 sark_msg_cpy(msg, shm_msg);
605 }
608 return msg;
609}
610
612static inline void vic_interrupt_done(void) {
614}
615
620static inline void set_vic_callback(
621 uint8_t slot, uint type, vic_interrupt_handler_t callback) {
624 .source = type,
625 .enable = true
626 };
627}
628
629// ------------------------------------------------------------------------
630// reinjector main functions
631// ------------------------------------------------------------------------
632
635static inline void reinjection_enable_comms_interrupt(void) {
637 .cc_tx_not_full = true
638 };
639}
640
643static inline void reinjection_disable_comms_interrupt(void) {
645 .cc_tx_not_full = true
646 };
647}
648
654
657 // clear interrupt in timer,
659
660 // check if router not blocked
662 // access packet queue with FIQ disabled,
664
665 // if queue not empty turn on packet bouncing,
666 if (reinject_pkt_queue.tail != reinject_pkt_queue.head) {
667 // restore FIQ after queue access,
669
670 // enable communications controller. interrupt to bounce packets
672 } else {
673 // restore FIQ after queue access
675 }
676 }
677
678 // and tell VIC we're done
680}
681
684static inline void reinjection_reinject_packet(const dumped_packet_t *pkt) {
685 // write header and route
687 .control_byte = pkt->hdr.control
688 };
691 .route = pkt->hdr.route
692 };
693
694 // maybe write payload,
697 if (control.payload) {
698 comms_control->tx_data = pkt->pld;
699 }
700
701 // write key to fire packet,
702 comms_control->tx_key = pkt->key;
703
704 // Add to statistics
706}
707
711 // TODO: may need to deal with packet timestamp.
712
713 // check if router not blocked
715 // access packet queue with FIQ disabled,
717
718 // if queue not empty bounce packet,
719 if (reinject_pkt_queue.tail != reinject_pkt_queue.head) {
720 // dequeue packet and update queue pointer
721 dumped_packet_t pkt =
723 reinject_pkt_queue.head =
725
726 // restore FIQ queue access,
728
729 // reinject the packet
731 } else {
732 // restore FIQ after queue access,
734
735 // and disable communications controller interrupts; queue empty!
737 }
738 } else {
739 // disable communications controller interrupts
741 }
742
743 // and tell VIC we're done
745}
746
749 // get packet from router,
751 uint pld = router_control->dump.payload;
752 uint key = router_control->dump.key;
753
754 // clear dump status and interrupt in router,
757
758 // only reinject if configured
759
760 uint packet_type = ((spinnaker_packet_control_byte_t) hdr.control).type;
761 if (((packet_type == SPINNAKER_PACKET_TYPE_MC) && reinject_mc) ||
762 ((packet_type == SPINNAKER_PACKET_TYPE_P2P) && reinject_pp) ||
763 ((packet_type == SPINNAKER_PACKET_TYPE_NN) && reinject_nn) ||
764 ((packet_type == SPINNAKER_PACKET_TYPE_FR) && reinject_fr)) {
765
766 // check for overflow from router
767 if (rtr_dstat.overflow) {
769 } else {
770 // Note that the processor_dump and link_dump flags are sticky
771 // so you can only really count these if you *haven't* missed a
772 // dropped packet - hence this being split out
773
774 if (rtr_dump_outputs.processor > 0) {
775 // add to the count the number of active bits from this dumped
776 // packet, as this indicates how many processors this packet
777 // was meant to go to.
781 }
782
783 if (rtr_dump_outputs.link > 0) {
784 // add to the count the number of active bits from this dumped
785 // packet, as this indicates how many links this packet was
786 // meant to go to.
790 }
791 }
792
793 // Only update this counter if this is a packet to reinject
795
796 // Disable FIQ for queue access
798
799 // try to insert dumped packet in the queue,
801
802 // check for space in the queue
803 if (new_tail != reinject_pkt_queue.head) {
804 // queue packet,
805 reinject_pkt_queue.queue[reinject_pkt_queue.tail].hdr = hdr;
806 reinject_pkt_queue.queue[reinject_pkt_queue.tail].key = key;
807 reinject_pkt_queue.queue[reinject_pkt_queue.tail].pld = pld;
808
809 // update queue pointer,
811 } else {
812 // The queue of packets has overflowed
814 }
815
816 // restore FIQ after queue access,
818 }
819}
820
824 // process multicast reinject flag
825 if (config->multicast_flag == 1) {
826 reinject_mc = false;
827 } else {
828 reinject_mc = true;
829 }
830
831 // process point to point flag
832 if (config->point_to_point_flag == 1) {
833 reinject_pp = false;
834 } else {
835 reinject_pp = true;
836 }
837
838 // process fixed route flag
839 if (config->fixed_route_flag == 1) {
840 reinject_fr = false;
841 } else {
842 reinject_fr = true;
843 }
844
845 // process fixed route flag
846 if (config->nearest_neighbour_flag == 1) {
847 reinject_nn = false;
848 } else {
849 reinject_nn = true;
850 }
851
853 "[INFO] Setting reinject mc to %d\n[INFO] Setting reinject pp to %d\n"
854 "[INFO] Setting reinject fr to %d\n[INFO] Setting reinject nn to %d\n",
856
857 // set the reinjection mc api
858 initialise_reinjection_mc_api(config->reinjection_base_mc_key);
859
860}
861
868
871static inline void reinjection_set_wait2_timeout(uint payload) {
874}
875
883static inline int reinjection_set_timeout_sdp(sdp_msg_t *msg) {
884#ifdef DEBUG_REINJECTOR
885 io_printf(IO_BUF, "[DEBUG] setting router timeouts via sdp\n");
886#endif
887 if (msg->arg1 > ROUTER_TIMEOUT_MAX) {
888 msg->cmd_rc = RC_ARG;
889 return 0;
890 }
891
894
895 // set SCP command to OK, as successfully completed
896 msg->cmd_rc = RC_OK;
897 return 0;
898}
899
908#ifdef DEBUG_REINJECTOR
909 io_printf(IO_BUF, "[DEBUG] setting router emergency timeouts via sdp\n");
910#endif
911 if (msg->arg1 > ROUTER_TIMEOUT_MAX) {
912 msg->cmd_rc = RC_ARG;
913 return 0;
914 }
915
918
919 // set SCP command to OK, as successfully completed
920 msg->cmd_rc = RC_OK;
921 return 0;
922}
923
929 reinject_mc = msg->arg1;
930 reinject_pp = msg->arg2;
931 reinject_fr = msg->arg3;
932 reinject_nn = msg->data[0];
934
936 "[INFO] Setting reinject mc to %d\n[INFO] Setting reinject pp to %d\n"
937 "[INFO] Setting reinject fr to %d\n[INFO] Setting reinject nn to %d\n",
939
940 // set SCP command to OK, as successfully completed
941 msg->cmd_rc = RC_OK;
942 return 0;
943}
944
949static inline int reinjection_get_status(sdp_msg_t *msg) {
952
953 // Put the router timeouts in the packet
955 data->router_timeout = control.begin_emergency_wait_time;
956 data->router_emergency_timeout = control.drop_wait_time;
957
958 // Put the statistics in the packet
959 data->n_dropped_packets = reinject_n_dropped_packets;
960 data->n_missed_dropped_packets = reinject_n_missed_dropped_packets;
961 data->n_dropped_packets_overflows = reinject_n_dropped_packet_overflows;
962 data->n_reinjected_packets = reinject_n_reinjected_packets;
963 data->n_link_dumped_packets = reinject_n_link_dumped_packets;
964 data->n_processor_dumped_packets = reinject_n_processor_dumped_packets;
965 data->link_proc_bits = reinject_link_proc_bits;
966
967 // Put the current services enabled in the packet
968 data->packet_types_reinjected = 0;
971 for (int i = 0; i < 4; i++) {
972 data->packet_types_reinjected |= (values_to_check[i] << i);
973 }
974
975 // set SCP command to OK, as successfully completed
976 msg->cmd_rc = RC_OK;
977 // Return the number of bytes in the packet
979}
980
985static inline int reinjection_reset_counters(sdp_msg_t *msg) {
993
994 // set SCP command to OK, as successfully completed
995 msg->cmd_rc = RC_OK;
996 return 0;
997}
998
1003static inline int reinjection_exit(sdp_msg_t *msg) {
1005 .timer1 = true,
1006 .router_dump = true
1007 };
1010 // Also all the rest are not FIQ
1011 .router_dump = false
1012 };
1013 reinject_run = false;
1014
1015 // set SCP command to OK, as successfully completed
1016 msg->cmd_rc = RC_OK;
1017 return 0;
1018}
1019
1021static void reinjection_clear(void) {
1022 // Disable FIQ for queue access
1024 // Clear any stored dropped packets
1025 reinject_pkt_queue.head = 0;
1026 reinject_pkt_queue.tail = 0;
1027 // restore FIQ after queue access,
1029 // and disable communications controller interrupts
1031}
1032
1037static inline int reinjection_clear_message(sdp_msg_t *msg) {
1040 // set SCP command to OK, as successfully completed
1041 msg->cmd_rc = RC_OK;
1042 return 0;
1043}
1044
1050 switch (msg->cmd_rc) {
1051#ifdef DEBUG_REINJECTOR
1052 io_printf(IO_BUF, "[DEBUG] seq %d\n", msg->seq);
1053#endif
1055#ifdef DEBUG_REINJECTOR
1056 io_printf(IO_BUF, "[DEBUG] router timeout\n");
1057#endif
1058 return reinjection_set_timeout_sdp(msg);
1060#ifdef DEBUG_REINJECTOR
1061 io_printf(IO_BUF, "[DEBUG] router emergency timeout\n");
1062#endif
1065#ifdef DEBUG_REINJECTOR
1066 io_printf(IO_BUF, "[DEBUG] router set packet type\n");
1067#endif
1068 return reinjection_set_packet_types(msg);
1070#ifdef DEBUG_REINJECTOR
1071 io_printf(IO_BUF, "[DEBUG] router get status\n");
1072#endif
1073 return reinjection_get_status(msg);
1075#ifdef DEBUG_REINJECTOR
1076 io_printf(IO_BUF, "[DEBUG] router reset\n");
1077#endif
1078 return reinjection_reset_counters(msg);
1079 case CMD_DPRI_EXIT:
1080#ifdef DEBUG_REINJECTOR
1081 io_printf(IO_BUF, "[DEBUG] router exit\n");
1082#endif
1083 return reinjection_exit(msg);
1084 case CMD_DPRI_CLEAR:
1085#ifdef DEBUG_REINJECTOR
1086 io_printf(IO_BUF, "[DEBUG] router clear\n");
1087#endif
1088 return reinjection_clear_message(msg);
1089 default:
1090 // If we are here, the command was not recognised, so fail (ARG as the
1091 // command is an argument)
1092 msg->cmd_rc = RC_ARG;
1093 return 0;
1094 }
1095}
1096
1099 // Clear the interrupt
1101 .enable = false,
1102 .interrupt_enable = false
1103 };
1105
1106 // Set the timer times
1107 timer1_control->load_value = sv->cpu_clk * TICK_PERIOD;
1109}
1110
1113 // remember SAR register contents (p2p source ID)
1115}
1116
1119 // re-configure wait values in router
1122 control.drop_wait_time = 0;
1123 router_control->control = control;
1124
1125 // clear router interrupts,
1127
1128 // clear router dump status,
1129 (void) router_control->dump.status;
1130
1131 // clear router error status,
1132 (void) router_control->error.status;
1133
1134 // and enable router interrupts when dumping packets, and count errors
1135 control.dump_interrupt_enable = true;
1136 control.count_framing_errors = true;
1137 control.count_parity_errors = true;
1138 control.count_timestamp_errors = true;
1139 router_control->control = control;
1140}
1141
1142//-----------------------------------------------------------------------------
1143// data in speed up main functions
1144//-----------------------------------------------------------------------------
1145
1147static void data_in_clear_router(void) {
1149
1150 // clear the currently loaded routing table entries
1156 rtr_free(entry_id, 1);
1157 }
1158 }
1159#ifdef DEBUG_DATA_IN
1160 io_printf(IO_BUF, "[DEBUG] max free block is %d\n", rtr_alloc_max());
1161#endif
1162}
1163
1165static inline void data_in_process_boundary(void) {
1167#ifdef DEBUG_DATA_IN
1168 io_printf(IO_BUF, "[DEBUG] Wrote %u words\n",
1170#endif
1172 }
1174}
1175
1178static inline void data_in_process_address(uint data) {
1181 }
1182#ifdef DEBUG_DATA_IN
1183 io_printf(IO_BUF, "[DEBUG] Setting write address to 0x%08x\n", data);
1184#endif
1186}
1187
1190static inline void data_in_process_data(uint data) {
1191 // data keys require writing to next point in sdram
1192
1193 if (data_in_write_address == NULL) {
1194 io_printf(IO_BUF, "[ERROR] Write address not set when write data received!\n");
1196 }
1199}
1200
1212 // get data from comm controller
1214 uint key = comms_control->rx_key;
1215
1216 if (key == reinject_timeout_mc_key) {
1218 } else if (key == reinject_emergency_timeout_mc_key) {
1220 } else if (key == reinject_clear_mc_key) {
1222 } else if (key == data_in_address_key) {
1224 } else if (key == data_in_data_key) {
1226 } else if (key == data_in_boundary_key) {
1227 prov->n_in_streams++;
1229 } else {
1231 "[WARNING] failed to recognise multicast packet key 0x%08x\n",
1232 key);
1233 }
1234
1235 // and tell VIC we're done
1237}
1238
1243 router_entry_t *sdram_address, uint n_entries) {
1244#ifdef DEBUG_DATA_IN
1245 io_printf(IO_BUF, "[DEBUG] Writing %u router entries\n", n_entries);
1246#endif
1247 if (n_entries == 0) {
1248 return;
1249 }
1251 if (start_entry_id == 0) {
1253 "[ERROR] Received error with requesting %u router entries.\n",
1254 n_entries);
1256 }
1257
1258 for (uint idx = 0; idx < n_entries; idx++) {
1259 // check for invalid entries (possible during alloc and free or
1260 // just not filled in.
1261 if (sdram_address[idx].key != INVALID_ROUTER_ENTRY_KEY &&
1262 sdram_address[idx].mask != INVALID_ROUTER_ENTRY_MASK &&
1263 sdram_address[idx].route != INVALID_ROUTER_ENTRY_ROUTE) {
1264#ifdef DEBUG_DATA_IN
1265 // Produces quite a lot of debugging output when enabled
1267 "[DEBUG] Setting key %08x, mask %08x, route %08x for entry %u\n",
1268 sdram_address[idx].key, sdram_address[idx].mask,
1269 sdram_address[idx].route, idx + start_entry_id);
1270#endif
1271 // try setting the valid router entry
1272 if (rtr_mc_set(idx + start_entry_id, sdram_address[idx].key,
1273 sdram_address[idx].mask, sdram_address[idx].route) != 1) {
1274 io_printf(IO_BUF, "[WARNING] failed to write router entry %d, "
1275 "with key %08x, mask %08x, route %08x\n",
1276 idx + start_entry_id, sdram_address[idx].key,
1277 sdram_address[idx].mask, sdram_address[idx].route);
1278 }
1279 }
1280 }
1282}
1283
1306
1313 // read in router table into app store in sdram (in case its changed
1314 // since last time)
1316
1317 // clear the currently loaded routing table entries to avoid conflicts
1319
1320 // read in and load routing table entries
1321#ifdef DEBUG_DATA_IN
1322 io_printf(IO_BUF, "[INFO] Loading system routes\n");
1323#endif
1325 items->system_router_entries, items->n_system_router_entries);
1326}
1327
1332 // clear the currently loaded routing table entries
1334
1335 // load app router entries from sdram
1336#ifdef DEBUG_DATA_IN
1337 io_printf(IO_BUF, "[INFO] Loading application routes\n");
1338#endif
1342}
1343
1350 switch (msg->cmd_rc) {
1352#ifdef DEBUG_DATA_IN
1353 io_printf(IO_BUF, "[INFO] Saving application router entries from router\n");
1354#endif
1356 msg->cmd_rc = RC_OK;
1357 break;
1360 msg->cmd_rc = RC_OK;
1362 break;
1365#ifdef DEBUG_DATA_IN
1367 "[WARNING] Already loaded system router; ignoring but replying\n");
1368#endif
1369 msg->cmd_rc = RC_OK;
1370 break;
1371 }
1374 msg->cmd_rc = RC_OK;
1376 break;
1377 default:
1379 "[WARNING] Received unknown SDP packet in data in speed up port"
1380 " with command id %d\n", msg->cmd_rc);
1381 msg->cmd_rc = RC_ARG;
1382 }
1383 return 0;
1384}
1385
1386//-----------------------------------------------------------------------------
1387// data speed up out main functions
1388//-----------------------------------------------------------------------------
1389
1394 enum {
1396 TX_NOT_FULL_MASK = 0x10000000
1397 };
1398
1399 // If stop, don't send anything
1400 if (data_out_stop) {
1401 return;
1402 }
1403
1404 // Wait for a router slot
1406 // Empty body; CC array is volatile
1407 }
1409 .payload = true,
1411 };
1414 };
1416 comms_control->tx_key = key;
1417}
1418
1443
1454static inline void data_out_start_dma_read(
1455 uint32_t dma_tag, void *source, void *destination, uint n_words) {
1457 dma_control->sdram_address = source;
1461 .burst = DMA_BURST_SIZE,
1462 .direction = DMA_DIRECTION_READ,
1463 .length_words = n_words
1464 };
1465}
1466
1491
1496
1504 // set up state
1509
1510 // put size in bytes if first send
1512 //io_printf(IO_BUF, "in first\n");
1519 }
1520
1521 // stopping procedure
1522 // if a full packet, read another and try again
1527
1528 // if less data needed request less data
1533 }
1534
1535 // set off another read and transmit DMA'ed one
1539 } else {
1542
1543 // send end flag.
1545
1546 data_out_has_finished = true;
1548 }
1549
1550 if (TDMA_WAIT_PERIOD != 0) {
1552 }
1553}
1554
1560 uint32_t data[], uint length, uint32_t start_offset) {
1562 i < length; i++, j++) {
1564#ifdef DEBUG_DATA_OUT
1565 if (data[i] > data_out_max_seq_num) {
1566 io_printf(IO_BUF, "[WARNING] Storing bad seq num. %d %d\n",
1568 }
1569#endif
1570 }
1572}
1573
1584 uint32_t data[], uint length, bool first) {
1585 uint32_t start_reading_offset = START_OF_MISSING_MORE;
1586 if (first) {
1588 data[POSITION_OF_NO_MISSING_SEQ_PACKETS];
1589
1592 + END_FLAG_SIZE;
1593
1597 }
1599
1600 // if not got enough sdram to alllocate all missing seq nums
1602 // biggest sdram block
1604 // if can't hold more than this packets worth of data, blow up
1607 "[ERROR] Can't allocate SDRAM for missing seq nums\n");
1609 }
1610#ifdef DEBUG_DATA_OUT
1611 io_printf(IO_BUF, "[DEBUG] Activate bacon protocol!\n");
1612#endif
1613 // allocate biggest block
1615 // determine max full seq num packets to store
1618 + max_bytes / (ITEMS_PER_DATA_PACKET * sizeof(uint));
1619 }
1620 start_reading_offset = START_OF_MISSING_SEQ_NUMS;
1621 }
1623 // write data to SDRAM and update packet counter
1625 data, length, start_reading_offset);
1627#ifdef DEBUG_DATA_OUT
1628 } else {
1629 io_printf(IO_BUF, "[WARNING] Unable to save missing sequence number\n");
1630#endif
1631 }
1632}
1633
1645
1651 // check if at end of read missing sequence numbers
1658 }
1659 return;
1660 }
1661
1662 // get next sequence number to regenerate
1666 // regenerate data
1672
1676 } else {
1680 }
1681 } else { // finished data send, tell host its done
1687 }
1691 }
1692}
1693
1718
1721#ifdef DEBUG_DATA_OUT
1722 io_printf(IO_BUF, "[INFO] Need to figure what to do here\n");
1723#endif
1724}
1725
1731
1732 switch (message->command) {
1734 // updater transaction id if it hits the cap
1735 if (((data_out_transaction_id + 1) & TRANSACTION_CAP) == 0) {
1738 }
1739
1740 // if transaction id is not as expected. ignore it as its from the past.
1741 // and worthless
1742 if (message->transaction_id != data_out_transaction_id + 1) {
1744 "[WARNING] received start message with unexpected "
1745 "transaction id %d; mine is %d\n",
1746 message->transaction_id, data_out_transaction_id + 1);
1747 return;
1748 }
1749
1750 //extract transaction id and update
1751 data_out_transaction_id = message->transaction_id;
1753
1754 data_out_stop = false;
1755
1756 // set SDRAM position and length
1757 data_out_store_address = message->sdram_location;
1758 // state for how many bytes it needs to send, gives approximate
1759 // bandwidth if round number.
1761
1764 data_out_max_seq_num += mod > 0;
1765
1766 // reset states
1771 bytes_to_read_write / sizeof(uint);
1772
1776 } else {
1778 }
1780 return;
1781 }
1783 if (message->transaction_id != data_out_transaction_id) {
1785 "[WARNING] received data from a different transaction for "
1786 "start of missing. expected %d got %d\n",
1787 data_out_transaction_id, message->transaction_id);
1788 return;
1789 }
1790
1791 // if already in a retransmission phase, don't process as normal
1793#ifdef DEBUG_DATA_OUT
1794 io_printf(IO_BUF, "[INFO] forcing start of retransmission packet\n");
1795#endif
1798 END_FLAG;
1803 return;
1804 }
1805 // fall through
1807 if (message->transaction_id != data_out_transaction_id) {
1809 "[WARNING] received data from different transaction for "
1810 "more missing; expected %d, got %d\n",
1811 data_out_transaction_id, message->transaction_id);
1812 return;
1813 }
1814
1815 // reset state, as could be here from multiple attempts
1817 // put missing sequence numbers into SDRAM
1819 msg->data,
1820 (msg->length - LENGTH_OF_SDP_HEADER) / sizeof(uint),
1822
1823 // if got all missing packets, start retransmitting them to host
1825 // packets all received, add finish flag for DMA stoppage
1826
1832
1833 // start DMA off
1836 }
1837 }
1838 }
1839 return;
1840 case SDP_CMD_CLEAR:
1841 if (message->transaction_id != data_out_transaction_id) {
1843 "[WARNING] received data from different transaction for "
1844 "clear; expected %d, got %d\n",
1845 data_out_transaction_id, message->transaction_id);
1846 return;
1847 }
1848#ifdef DEBUG_DATA_OUT
1849 io_printf(IO_BUF, "[INFO] data out clear\n");
1850#endif
1851 data_out_stop = true;
1852 break;
1853 default:
1854 io_printf(IO_BUF, "[WARNING] Received unknown SDP packet: %d\n",
1855 message->command);
1856 }
1857}
1858
1867 // reset the interrupt.
1869 .clear_done_int = true
1870 };
1871 if (!data_out_stop) {
1872 // Only do something if we have not been told to stop
1876 break;
1879 break;
1882 break;
1885 break;
1886 default:
1887 io_printf(IO_BUF, "[ERROR] Invalid DMA callback port: %d\n",
1890 }
1891 }
1892 // and tell VIC we're done
1894}
1895
1898 io_printf(IO_BUF, "[WARNING] DMA failed: 0x%08x\n", dma_control->status);
1900 // Clear the error
1901 .restart = true
1902 };
1905}
1906
1909 io_printf(IO_BUF, "[WARNING] DMA timeout: 0x%08x\n", dma_control->status);
1911 .clear_timeout_int = true
1912 };
1914}
1915
1916//-----------------------------------------------------------------------------
1917// common code
1918//-----------------------------------------------------------------------------
1919
1920void __real_sark_int(void *pc);
1922// This function is why this code *can't* use Spin1API.
1923void __wrap_sark_int(void *pc) {
1924 // Get the message from SCAMP and see if t belongs to SARK
1925 if (sark.vcpu->mbox_ap_cmd != SHM_MSG) {
1926 // Run the default callback
1927 __real_sark_int(pc);
1928 return;
1929 }
1930
1931 // Make a copy so we can release the mailbox, and flag as ready for
1932 // interrupt again
1934 //io_printf(IO_BUF, "seq is %d\n", msg->seq);
1937 .select = 1 << sark.phys_cpu,
1938 };
1939 if (msg == NULL) {
1940 return;
1941 }
1942
1943 switch ((msg->dest_port & PORT_MASK) >> PORT_SHIFT) {
1944 case REINJECTION_PORT:
1946 while (!sark_msg_send(msg, 10)) {
1947#ifdef DEBUG_REINJECTOR
1948 io_printf(IO_BUF, "[DEBUG] timeout when sending reinjection reply\n");
1949#endif
1950 }
1952 break;
1953 case DATA_SPEED_UP_OUT_PORT:
1954 // These are all one-way messages; replies are out of band
1957 break;
1960 while (!sark_msg_send(msg, 10)) {
1961#ifdef DEBUG_DATA_IN
1962 io_printf(IO_BUF, "[DEBUG] timeout when sending speedup ctl reply\n");
1963#endif
1964 }
1966 break;
1967 default:
1968 io_printf(IO_BUF, "[WARNING] unexpected port %d\n",
1969 (msg->dest_port & PORT_MASK) >> PORT_SHIFT);
1970 io_printf(IO_BUF,
1971 "[INFO] from:%04x:%02x to:%04x:%02x cmd:%04x len:%d iam:%04x\n",
1972 msg->srce_addr, msg->srce_port,
1973 msg->dest_addr, msg->dest_port,
1974 msg->cmd_rc, msg->length, my_addr);
1975 // Do nothing
1976 }
1977 sark_msg_free(msg);
1978}
1979
1980//-----------------------------------------------------------------------------
1981// initializers
1982//-----------------------------------------------------------------------------
1983
1985static void reinjection_initialise(void) {
1986 // set up config region
1987 // Get the address this core's DTCM data starts at from SRAM
1989
1990 // Setup the CPU interrupt for WDOG
1991 vic_interrupt_control[sark_vec->sark_slot] = (vic_vector_control_t) {
1992 .enable = false
1993 };
1995
1996 // Setup the communications controller interrupt
1998
1999 // Setup the timer interrupt
2001
2002 // Setup the router interrupt as a fast interrupt
2003 sark_vec->fiq_vec = reinjection_dropped_packet_callback;
2005 .router_dump = true
2006 };
2007}
2008
2010static void data_out_initialise(void) {
2013 data_out_new_sequence_key = config->new_seq_key;
2014 data_out_first_data_key = config->first_data_key;
2015 data_out_transaction_id_key = config->transaction_id_key;
2016 data_out_end_flag_key = config->end_flag_key;
2017
2018#ifdef DEBUG_DATA_OUT
2020 "[INFO] new seq key = %d, first data key = %d, transaction id key = %d, "
2021 "end flag key = %d, basic_data_key = %d\n",
2024#endif
2025
2026 // Various DMA callbacks
2030
2031 // configuration for the DMA's by the speed data loader
2033 // Abort pending and active transfers
2034 .uncommit = true,
2035 .abort = true,
2036 .restart = true,
2037 .clear_done_int = true,
2038 .clear_timeout_int = true,
2039 .clear_write_buffer_int = true
2040 };
2042 // clear possible transfer done and restart
2043 .uncommit = true,
2044 .restart = true,
2045 .clear_done_int = true
2046 };
2048 // enable DMA done and error interrupt
2050 .transfer2_done_interrupt = true,
2051 .timeout_interrupt = true,
2052 .crc_error_interrupt = true,
2053 .tcm_error_interrupt = true,
2054 .axi_error_interrupt = true, // SDRAM error
2055 .user_abort_interrupt = true,
2056 .soft_reset_interrupt = true,
2057 .write_buffer_error_interrupt = true
2058 };
2059}
2060
2062static void data_in_initialise(void) {
2067 "[ERROR] failed to allocate SDRAM for application mc router entries\n");
2069 }
2070
2072
2073 data_in_address_key = items->address_mc_key;
2074 data_in_data_key = items->data_mc_key;
2075 data_in_boundary_key = items->boundary_mc_key;
2076 // Save the current (application?) state
2078
2079 // load user 1 in case this is a consecutive load
2081
2082 // set up mc interrupts to deal with data writing
2084}
2085
2087static void provenance_initialise(void) {
2089 prov->n_sdp_packets = 0;
2090 prov->n_in_streams = 0;
2091 prov->n_out_streams = 0;
2093}
2094
2095//-----------------------------------------------------------------------------
2097//-----------------------------------------------------------------------------
2098void c_main(void) {
2100
2104 }
2105
2106 // Configure
2107 my_addr = sv->p2p_addr;
2111
2112 // Initialise the statistics
2117
2118 // set up VIC callbacks and interrupts accordingly
2119 // Disable the interrupts that we are configuring (except CPU for WDOG)
2120 const vic_mask_t int_select = {
2121 .timer1 = true,
2122 .router_dump = true,
2123 .dma_done = true,
2124 .dma_error = true,
2125 .dma_timeout = true,
2126 .cc_rx_mc = true,
2127 };
2128 vic_control->int_disable = int_select;
2130
2131 // set up provenance area
2133
2134 // set up reinjection functionality
2136
2137 // set up data speed up functionality
2140
2141 // Enable interrupts and timer
2142 vic_control->int_enable = int_select;
2144 .size = 1,
2145 .interrupt_enable = true,
2146 .periodic_mode = true,
2147 .enable = true
2148 };
2149
2150 io_printf(IO_BUF, "[INFO] extra monitor initialisation complete\n");
2151
2152 // Run until told to exit
2153 while (reinject_run) {
2155 }
2156}
2157// ------------------------------------------------------------------------
@ DMA
DMA processing is lowest priority.
@ SDP
Responding to communications from host is next highest.
callback_priorities
values for the priority for each callback
Data type definitions for SpiNNaker Neuron-modelling.
uint32_t * address_t
A generic pointer to a word.
Common definitions for the non-SCAMP system binaries.
static void initialise_reinjection_mc_api(uint32_t base_mc_key)
sets up the multicast keys for the reinjection multicast API
Definition common.h:73
static uint reinject_clear_mc_key
the multicast key used for clear reinjector queue to all extra monitors
Definition common.h:69
@ CMD_DPRI_SET_ROUTER_EMERGENCY_TIMEOUT
Set the router's wait2 timeout.
Definition common.h:32
@ CMD_DPRI_RESET_COUNTERS
Reset the reinjection counters.
Definition common.h:38
@ CMD_DPRI_SET_ROUTER_TIMEOUT
Set the router's wait1 timeout.
Definition common.h:30
@ CMD_DPRI_GET_STATUS
Get the status of the reinjector.
Definition common.h:36
@ CMD_DPRI_EXIT
Stop doing reinjection.
Definition common.h:40
@ CMD_DPRI_CLEAR
Clear the reinjection queue.
Definition common.h:42
@ CMD_DPRI_SET_PACKET_TYPES
Set what packet types are reinjected.
Definition common.h:34
static uint reinject_emergency_timeout_mc_key
the multicast key used for emergency timeouts to all extra monitors
Definition common.h:66
static uint reinject_timeout_mc_key
the multicast key used for basic timeouts to all extra monitors
Definition common.h:63
#define TRANSACTION_CAP
Flag for cap on transaction id.
Definition common.h:85
static void reflect_sdp_message(sdp_msg_t *msg, uint body_length)
Updates an SDP message so its content (a response to the message) goes back to where the message came...
Definition common.h:91
Data Specification region access API.
data_specification_metadata_t * data_specification_get_data_address(void)
Gets the location of the data for this core using the user0 entry of the SARK VCPU structure.
bool data_specification_read_header(data_specification_metadata_t *ds_regions)
Reads the header from the address given and checks if the parameters are of the correct values.
static void * data_specification_get_region(uint32_t region, data_specification_metadata_t *ds_regions)
Gets the address of a region.
The central structure that the DSE writes.
static uint32_t data[ITEMS_PER_DATA_PACKET]
functionality_to_port_num_map
values for port numbers this core will respond to
@ REINJECTION_PORT
Reinjection control messages.
@ DATA_SPEED_UP_IN_PORT
Data Speed Up Inbound messages.
static uint32_t transaction_id
The Data In transaction ID. Used to distinguish streams of packets.
static void data_in_load_router(router_entry_t *sdram_address, uint n_entries)
Writes router entries to the router.
uint pld
Payload word of packet (might be undefined)
static uint32_t data_out_n_missing_seq_packets
The number of missing packets that the host wants us to resend.
static uint32_t data_out_missing_seq_num_being_processed
The current sequence number for the chunk being being DMA'd in.
static bool reinjection_can_send_now(void)
Whether the comms hardware can accept packet now.
#define N_BASIC_SYSTEM_ROUTER_ENTRIES
number of entries in the multicast router for SARK and SCAMP
static void reinjection_timer_callback(void)
the plugin callback for the timer
#define N_DMA_BUFFERS
the number of DMA buffers to build
uint32_t route
The SpiNNaker router route (to use when masked key matches)
static uint data_in_speed_up_command(sdp_msg_t *msg)
The handler for all control messages coming in for data in speed up functionality.
static void provenance_initialise(void)
Set up where we collect provenance.
static bool reinject_nn
Flag: whether to reinject nearest neighbour packets.
static void data_out_start_dma_read(uint32_t dma_tag, void *source, void *destination, uint n_words)
Initiate a DMA read, copying from SDRAM into DTCM.
uint n_router_changes
The number of times we've modified the router.
#define DMA_BURST_SIZE
Use DMA bursts of 16 (24) transfer units (double words)
static void reinjection_read_packet_types(const reinject_config_t *config)
reads a DSG memory region to set packet types for reinjection
static void data_out_dma_complete_reading_retransmission_data(void)
DMA complete callback for have read missing sequence number data.
uint nearest_neighbour_flag
Whether we are reinjecting nearest neighbour packets.
static uint32_t data_out_retransmitted_seq_num_items_read
The size of payload DMA'd into the send buffer.
static uint32_t data_out_data_to_transmit[N_DMA_BUFFERS][ITEMS_PER_DATA_PACKET]
The DTCM buffers holding data to transmit. DMA targets.
static void data_out_dma_complete_writing_missing_seq_to_sdram(void)
DMA complete callback for have read missing sequence number data.
static uint32_t data_out_retransmit_seq_nums[ITEMS_PER_DATA_PACKET]
DTCM buffer of sequence numbers to be retransmitted.
static uint reinject_n_missed_dropped_packets
Count of packets dumped because the router was itself overloaded.
missing_seq_num_data_positions
position in message for missing sequence numbers
uint n_out_streams
The number of times we've streamed data out.
static void reinjection_clear(void)
Clear the queue of messages to reinject.
static int reinjection_set_emergency_timeout_sdp(sdp_msg_t *msg)
Set the router wait2 timeout.
static uint reinject_n_link_dumped_packets
Estimated count of packets dropped by router because a destination link is busy.
static void vic_interrupt_done(void)
Marks the end of an interrupt handler from the VIC's perspective.
static uint reinject_n_reinjected_packets
Count of all packets reinjected.
static uint32_t data_out_dma_port_last_used
The tag of the current DMA.
uint n_dropped_packets_overflows
The number of packets that were dropped due to overflow.
static void * sdram_alloc(uint size)
allocate a block of SDRAM (to be freed with sdram_free())
static uint reinjection_sdp_command(sdp_msg_t *msg)
handles the commands for the reinjector code.
static void data_out_dma_complete_read_missing_seqeuence_nums(void)
reads in missing sequence numbers and sets off the reading of SDRAM for the equivalent data
static void data_out_send_end_flag(void)
Sends the end flag to the packet gatherer.
static void data_out_write_missing_seq_nums_into_sdram(uint32_t data[], uint length, uint32_t start_offset)
Basic write sequence numbers to SDRAM that need retransmitting.
#define TICK_PERIOD
Amount to call the timer callback.
static uint32_t data_out_num_items_read
Size of the current DMA transfer.
uint n_reinjected_packets
The number of packets that were reinjected.
static ushort my_addr
Where are we (as a P2P address)?
uint32_t address_mc_key
What key to use to receive an address to write to.
static data_specification_metadata_t * dse_regions
The DSE regions structure.
static void data_in_speed_up_load_in_system_tables(data_in_data_items_t *items)
Sets up system routes on router.
static bool reinject_fr
Flag: whether to reinject fixed route packets.
uint n_dropped_packets
The number of packets that were dropped.
static void data_out_dma_timeout(void)
the handler for DMA timeouts (hopefully unlikely...)
uint n_missed_dropped_packets
The number of packets that were dumped by the router.
#define TDMA_WAIT_PERIOD
Throttle power on the MC transmissions if needed (assume not needed)
uint length
How much data are we moving.
#define END_FLAG
flag for saying stuff has ended
uint new_seq_key
The key to say that we are starting a new sequence.
static void data_out_retransmission_dma_read(void)
sets off a DMA for retransmission stuff
static void reinjection_configure_router(void)
sets up SARK and router to have a interrupt when a packet is dropped
uint router_timeout
The current router timeout.
static void reinjection_configure_comms_controller(void)
Store this chip's p2p address for future use.
static router_entry_t * data_in_saved_application_router_table
Where we save a copy of the application code's router table while the system router table entries are...
uint n_in_streams
The number of times we've streamed data in.
static void reinjection_enable_comms_interrupt(void)
Enable the interrupt when the Communications Controller can accept another packet.
static bool data_out_first_transmission
Whether we are about the first transmission in a stream.
static int reinjection_exit(sdp_msg_t *msg)
Stop the reinjector.
static void send_fixed_route_packet(uint32_t key, uint32_t data)
Sends a fixed route packet with payload.
static address_t data_in_first_write_address
Where we wrote the first word in the stream. NULL if not in a stream.
static uint32_t data_out_basic_data_key
The SpiNNaker packet key for a piece of data.
static uint reinject_n_processor_dumped_packets
Estimated count of packets dropped by router because a destination core (local) is busy.
data_out_sdp_commands command
What operation are we dealing with.
static void data_in_initialise(void)
Sets up data and callback required by the data in speed up system.
static uint data_in_boundary_key
This packet is the end of a stream.
static address_t data_out_missing_seq_num_sdram_address
Buffer in SDRAM where the sequence numbers of missing packets are stored.
static void publish_transaction_id(int transaction_id)
publishes the current transaction ID to the user1 register.
static uint32_t data_out_position_in_store
Index (by words) into the block of SDRAM being read.
static uint32_t data_out_max_seq_num
The maximum sequence number that can be in a transmission stream.
#define INVALID_ROUTER_ENTRY_KEY
hardcoded invalud router entry state for key
static void data_out_dma_complete_reading_for_original_transmission(void)
DMA complete callback for reading for original transmission.
uint key
Key word of packet.
static uint32_t data_out_new_sequence_key
The SpiNNaker packet key for the start of a sequence.
void sark_int_han(void)
The standard SARK CPU interrupt handler.
static uint data_in_data_key
This packet contains a word of data in the stream.
uint n_processor_dumped_packets
The number of packets dropped because a processor was busy.
static bool reinject_mc
Flag: whether to reinject multicast packets.
uint router_emergency_timeout
The current router emergency timeout.
uint32_t data_mc_key
What key to use to receive a word to write.
static void data_in_process_boundary(void)
Resets the state due to reaching the end of a data stream.
uint32_t n_system_router_entries
The number of system (non-app, non-SCAMP) router entries to use for Data In.
uint packet_types_reinjected
What packet types are we reinjecting.
static uint32_t data_out_end_flag_key
The SpiNNaker packet key for the end of a stream.
static int reinjection_set_packet_types(sdp_msg_t *msg)
Set the re-injection options.
static void data_in_speed_up_load_in_application_routes(void)
Sets up application routes on router.
@ CC_SLOT
Communications controller VIC slot.
@ DMA_TIMEOUT_SLOT
DMA timeout VIC slot.
@ CPU_SLOT
CPU VIC slot (WDOG and SDP; message from SCAMP for SARK)
@ MC_PAYLOAD_SLOT
Multicast-with-payload message arrived VIC slot.
@ TIMER_SLOT
Timer VIC slot.
@ DMA_ERROR_SLOT
DMA error VIC slot.
@ DMA_SLOT
DMA completed VIC slot.
static void reinjection_initialise(void)
Sets up data and callbacks required by the reinjection system.
static void data_out_initialise(void)
Sets up data and callbacks required by the data speed up system.
static void process_mc_payload_packet(void)
Process a multicast packet with payload.
static void reinjection_disable_comms_interrupt(void)
Disable the interrupt when the Communications Controller can accept another packet.
static pkt_queue_t reinject_pkt_queue
dumped packet queue
static void reinjection_configure_timer(void)
SARK level timer interrupt setup.
uint transaction_id
What is the transaction ID.
static uint reinject_n_dropped_packet_overflows
Count of packets lost because we ran out of queue space.
#define INVALID_ROUTER_ENTRY_ROUTE
hardcoded invalid router entry state for route
uint end_flag_key
The key to say that we've finished transmitting data.
static int data_in_application_table_n_valid_entries
The size of the data_in_saved_application_router_table.
static void set_vic_callback(uint8_t slot, uint type, vic_interrupt_handler_t callback)
Install an interrupt handler.
static uint32_t data_out_transaction_id_key
The SpiNNaker packet key for the transaction ID.
uint32_t boundary_mc_key
What key to use to receive an instruction that writing is done.
static void data_out_dma_error(void)
the handler for DMA errors
static extra_monitor_provenance_t * prov
Where we collect provenance in SDRAM.
static void reinjection_set_wait1_timeout(uint payload)
Set the wait1 router timeout.
static int reinjection_reset_counters(sdp_msg_t *msg)
Reset the counters.
static void data_out_speed_up_command(sdp_msg_pure_data *msg)
the handler for all messages coming in for data speed up functionality.
data_spec_regions
DSG region identifiers.
@ PROVENANCE_REGION
Provenance collection region (format: extra_monitor_provenance_t)
@ CONFIG_REINJECTION
Reinjector configuration.
@ CONFIG_DATA_SPEED_UP_IN
Data Speed Up (Inbound) configuration.
@ CONFIG_DATA_SPEED_UP_OUT
Data Speed Up (Outbound) configuration.
static uint data_in_address_key
This packet contains the address of the start of a stream.
speed_up_in_command
Commands for supporting Data In routing.
@ SDP_COMMAND_FOR_LOADING_SYSTEM_MC_ROUTES
load system multicast routes
@ SDP_COMMAND_FOR_SAVING_APPLICATION_MC_ROUTING
read in application multicast routes
@ SDP_COMMAND_FOR_LOADING_APPLICATION_MC_ROUTES
load application multicast routes
static int reinjection_clear_message(sdp_msg_t *msg)
Clear the queue of messages to reinject.
uint n_sdp_packets
The total number of relevant SDP packets processed.
uint link_proc_bits
The link / processor bit fields of dropped packets.
static sdp_msg_t * get_message_from_mailbox(void)
How to get an SDP message out of the mailbox correctly.
static void reinjection_reinject_packet(const dumped_packet_t *pkt)
Does the actual reinjection of a packet.
static uint32_t data_out_read_data_position
Index into data_out_retransmit_seq_nums used to track where we are in a chunk of sequence numbers to ...
static void data_in_save_router(void)
reads in routers entries and places in application sdram location
#define ROUTER_TIMEOUT_MAX
Maximum router timeout value.
void c_main(void)
main entry point
static void data_out_dma_complete(void)
The handler for all DMAs complete.
static address_t data_out_store_address
The location in SDRAM where data is being read out from.
data_out_sdp_commands
SDP flags.
@ SDP_CMD_CLEAR
stop sending now!
@ SDP_CMD_START_OF_MISSING_SDP_PACKETS
@ SDP_CMD_START_SENDING_DATA
send data command ID in SDP
@ SDP_CMD_MORE_MISSING_SDP_PACKETS
other missing SDP sequence numbers in SDP
static void data_out_read(uint32_t dma_tag, uint32_t offset, uint32_t items_to_read)
sets off a DMA reading a block of SDRAM in preparation for sending to the packet gatherer
static uint32_t data_out_n_missing_seq_nums_in_sdram
The number of sequence numbers of missing packets that we've accumulated.
address_t sdram_location
What location are we talking about.
#define N_ROUTER_ENTRIES
max router entries
static void reinjection_ready_to_send_callback(void)
Called when the router can accept a packet and the reinjection queue is non-empty.
static bool data_in_last_table_load_was_system
Do we have the system router table loaded?
@ TRANSACTION_ID_SIZE
Size of the transaction ID, in words.
@ SDP_PAYLOAD_WORDS
Effective size of the SDP packet payload, in words of actual content.
@ SDP_PAYLOAD_BYTES
Effective size of the SDP packet payload, in bytes of actual content.
@ SEQUENCE_NUMBER_SIZE
Size of the sequence number, in words.
static void sdram_free(void *data)
free a block of SDRAM allocated with sdram_alloc()
static bool data_out_has_finished
Whether we have reached the end of a stream.
static uint32_t data_out_transaction_id
The current transaction identifier, identifying the stream of items being moved.
#define PKT_QUEUE_SIZE
dumped packet queue length
static bool reinject_pp
Flag: whether to reinject point-to-point packets.
uint my_key
The key to say here is a piece of data.
static bool reinject_run
Whether we are running the reinjector.
static uint32_t data_out_position_for_retransmission
Used to track where we are in the retransmissions.
uint multicast_flag
Whether we are reinjecting multicast packets.
#define LENGTH_OF_SDP_HEADER
extra length adjustment for the SDP header, in bytes
static void data_out_send_data_block(uint32_t current_dma_pointer, uint32_t n_elements_to_send, uint32_t first_packet_key, uint32_t second_packet_key)
takes a DMA'ed block and transmits its contents as fixed route packets to the packet gatherer.
static int reinjection_get_status(sdp_msg_t *msg)
Get the status and put it in the packet.
#define END_FLAG_SIZE
flag size for saying ended, in bytes
dma_tags_for_data_speed_up
SDP tags used by the SDRAM reader component.
@ DMA_TAG_FOR_WRITING_MISSING_SEQ_NUMS
DMA complete tag for writing the missing SEQ numbers to SDRAM.
@ DMA_TAG_READ_FOR_RETRANSMISSION
DMA complete tag for retransmission of data sequence numbers.
@ DMA_TAG_RETRANSMISSION_READING
DMA complete tag for the reading from SDRAM of data to be retransmitted.
@ DMA_TAG_READ_FOR_TRANSMISSION
uint32_t key
The SpiNNaker router key.
static void reinjection_set_wait2_timeout(uint payload)
Set the wait2 router timeout.
static bool data_out_in_retransmission_mode
Whether we're transmitting or retransmitting.
uint point_to_point_flag
Whether we are reinjecting point-to-point packets.
uint fixed_route_flag
Whether we are reinjecting fixed route packets.
static address_t data_in_write_address
Where we will write the next received word. NULL if not in a stream.
uint transaction_id_key
The key to say that this data is a transaction identifier.
static uint sdram_max_block_size(void)
the maximum SDRAM block size
static uint32_t data_out_first_data_key
The SpiNNaker packet key for the first piece of data of some data.
static bool data_out_stop
Whether the data out streaming has been asked to stop.
static void * dse_block(uint index)
Get the DSG region with the given index.
#define N_USABLE_ROUTER_ENTRIES
number of entries in the multicast router that we can manage
static void data_out_store_missing_seq_nums(uint32_t data[], uint length, bool first)
Store sequence numbers into SDRAM.
static uint32_t data_out_n_elements_to_read_from_sdram
The number of words that remain to be read from SDRAM.
router_packet_header_t hdr
Header word of packet.
static void data_in_process_data(uint data)
Writes a word in a stream and advances the write pointer.
static void data_in_process_address(uint data)
Sets the next location to write data at.
uint n_link_dumped_packets
The number of packets dropped because a link was busy.
static void data_in_clear_router(void)
Clears all (non-SARK/SCAMP) entries from the router.
static uint32_t data_out_transmit_dma_pointer
Which data_out_data_to_transmit buffer is the target of the current DMA transfer.
static uint reinject_p2p_source_id
The content of the communications controller SAR register.
uint first_data_key
The key to say that this data is the first.
#define INVALID_ROUTER_ENTRY_MASK
hardcoded invalid router entry state for mask
static uint reinject_n_dropped_packets
Count of all packets dropped by router.
static int reinjection_set_timeout_sdp(sdp_msg_t *msg)
Set the router wait1 timeout.
uint32_t mask
The SpiNNaker router mask.
static uint reinject_link_proc_bits
Which links and processors packets were dumped from (cumulative bit field)
#define ROUTER_INITIAL_TIMEOUT
The initial timeout of the router.
static void reinjection_dropped_packet_callback(void)
the callback plugin for handling dropped packets
data positions in sdram for data in config
human readable definitions of each element in the transmission region
dumped packet type
The information in the provenance region.
how the reinjection configuration is laid out in memory.
defintion of response packet for reinjector status
router entry positions in sdram
message payload for the data speed up out SDP messages
static uint32_t packets_sent
The number of packets sent so far this timestamp.
static uint32_t mask
Mask for keys to determine if the key matches the key_space.
The configuration parameters for the application.
uchar data[SDP_BUF_SIZE]
ushort seq
void sark_delay_us(uint delay)
#define ALLOC_LOCK
uchar dest_port
ushort cmd_rc
void * sark_xalloc(heap_t *heap, uint size, uint tag, uint flag)
void io_printf(char *stream, char *format,...)
uint rtr_alloc_id(uint size, uint app_id)
uchar srce_port
CPU_STATE_RUN
#define PORT_SHIFT
RTE_SWERR
RTE_DABT
uint user1
void cpu_int_restore(uint cpsr)
uint sark_msg_send(sdp_msg_t *msg, uint timeout)
void * mbox_ap_msg
volatile uchar mbox_ap_cmd
uint sark_app_id(void)
void rtr_free(uint entry, uint clear)
RC_ARG
RC_OK
void sark_shmsg_free(sdp_msg_t *msg)
#define ALLOC_ID
uint cpu_fiq_disable(void)
uint rtr_mc_set(uint entry, uint key, uint mask, uint route)
sark_data_t sark
void sark_msg_free(sdp_msg_t *msg)
void sark_cpu_state(cpu_state state)
uint sark_heap_max(heap_t *heap, uint flag)
vcpu_t * vcpu
#define IO_BUF
ushort length
sdp_msg_t * sark_msg_get(void)
SHM_IDLE
void rt_error(uint code,...)
void sark_msg_cpy(sdp_msg_t *to, sdp_msg_t *from)
ushort dest_addr
uint rtr_mc_get(uint entry, rtr_entry_t *r)
ushort srce_addr
void sark_xfree(heap_t *heap, void *ptr, uint flag)
uint rtr_alloc_max(void)
#define TX_NOT_FULL_MASK
uint16_t length
Length (measured from flags field start)
Definition sdp_no_scp.h:33
uint32_t data[ITEMS_PER_DATA_PACKET]
User data (272 bytes when no SCP header)
Definition sdp_no_scp.h:45
@ ITEMS_PER_DATA_PACKET
How many multicast packets are to be received per SDP packet.
Definition sdp_no_scp.h:25
An SDP message with purely data, no SCP header.
Definition sdp_no_scp.h:31
#define NULL
cback_t callback[NUM_EVENTS]
Extra definitions of things on SpiNNaker chips that aren't already mentioned in spinnaker....
router_control_t control
Router control register.
static volatile system_controller_t *const system_control
System controller registers.
const router_dump_status_t status
dumped packet status
uint dump_interrupt_enable
enable dump packet interrupt
uint output_stage
Router output stage status (see router_output_stage)
uint enable
enable counter/timer (1 = enabled)
static volatile router_t *const router_control
Router controller registers.
comms_tx_control_t tx_control
Controls packet transmission.
uint p2p_source_id
16-bit chip source ID for P2P packets
uint clear_timeout_int
clear Timeout interrupt request
uint width
transfer width, see dma_transfer_unit_t
vic_mask_t int_enable
interrupt enable set register
static volatile vic_interrupt_handler_t *const vic_interrupt_vector
VIC interrupt handlers. Array of 32 elements.
uint size
0 = 16 bit, 1 = 32 bit
dma_global_control_t global_control
Control of the DMA device.
const dma_status_t status
Status of DMA and other transfers.
const router_status_t status
Router status.
static volatile comms_ctl_t *const comms_control
Communications controller registers.
uint control_byte
control byte of next sent packet
static volatile vic_control_t *const vic_control
VIC registers.
vic_mask_t int_select
interrupt select register
void * sdram_address
DMA address on the system interface.
@ DMA_TRANSFER_DOUBLE_WORD
Transfer in double-words.
@ SYSTEM_CONTROLLER_MAGIC_NUMBER
Magic number for enabling writing to critical fields.
timer_control_t control
Timer control register.
const router_error_status_t status
error packet status
dma_description_t description
DMA transfer descriptor; note that setting this commits a DMA.
void * tcm_address
DMA address on the TCM interface.
const router_dump_outputs_t outputs
dumped packet intended destinations
const uint key
dumped packet routing word
uint drop_wait_time
wait2; wait time before dropping packet after entering emergency routing
@ SPINNAKER_PACKET_TYPE_NN
Nearest-neighbour packet.
@ SPINNAKER_PACKET_TYPE_FR
Fixed-route packet.
@ SPINNAKER_PACKET_TYPE_P2P
Peer-to-peer packet.
@ SPINNAKER_PACKET_TYPE_MC
Multicast packet.
uint count_parity_errors
enable count of packet parity errors
uint uncommit
setting this bit uncommits a queued transfer
sc_magic_proc_map_t clear_cpu_irq
Writing a 1 clears a processor’s interrupt line.
uint enable
interrupt enable
uint background_load_value
Background load value for Timer.
uint load_value
Load value for Timer.
uint tx_key
Send MC key/P2P dest ID & seq code; writing this commits a send.
uint transfer_done_interrupt
interrupt if dma_status_t::transfer_done set
const router_packet_header_t header
dumped packet control byte and flags
vic_interrupt_handler_t vector_address
current vector address register
static volatile vic_vector_control_t *const vic_interrupt_control
VIC individual interrupt control. Array of 32 elements.
uint count_framing_errors
enable count of packet framing errors
uint count_timestamp_errors
enable count of packet time stamp errors
dma_control_t control
Control DMA transfer.
comms_source_addr_t source_addr
P2P source address.
@ ROUTER_OUTPUT_STAGE_EMPTY
output stage is empty
vic_mask_t int_disable
interrupt enable clear register
uint clear_done_int
clear Done interrupt request
uint restart
resume transfer (clears DMA errors)
uint security_code
SYSTEM_CONTROLLER_MAGIC_NUMBER to enable write
static volatile timer_controller_t *const timer1_control
Timer 1 control registers.
static volatile dma_t *const dma_control
DMA control registers.
const uint rx_data
32-bit received data
const uint rx_key
Received MC key/P2P source ID & seq code; reading this clears the received packet.
const uint payload
dumped packet data payload
uint not_full
Tx buffer not full, so it is safe to send a packet.
uint tx_data
32-bit data for transmission
@ DMA_DIRECTION_READ
read from system bus (SDRAM)
uint source
interrupt source
void(* vic_interrupt_handler_t)(void)
The type of an interrupt handler.
uint begin_emergency_wait_time
wait1; wait time before emergency routing
uint interrupt_clear
Interrupt clear (any value may be written)
P2P source address.
Controls packet transmission.
DMA control register.
DMA descriptor.
DMA global control register.
Router control register.
Router dump outputs.
Router dump status.
System controller processor select.
Timer control register.
VIC individual vector control.
Router error/dump header.
The control byte of a SpiNNaker packet.
Mask describing interrupts that can be selected.
DMA_TO_INT
CC_TNF_INT
DMA_DONE_INT
CC_MC_INT
DMA_ERR_INT
CPU_INT
TIMER1_INT
unsigned int uint
unsigned short ushort
Wait for interrupt.
static void wait_for_interrupt(void)
Wait for any interrupt to occur.
Definition wfi.h:32