SpiNNFrontEndCommon development
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 {
158 CPU_SLOT = SLOT_0,
160 CC_SLOT = SLOT_1,
162 TIMER_SLOT = SLOT_2,
164 DMA_SLOT = SLOT_3,
170 MC_PAYLOAD_SLOT = SLOT_6
172
173// ------------------------------------------------------------------------
174// structs used in system
175// ------------------------------------------------------------------------
176
183
185typedef struct pkt_queue_t {
186 uint head;
187 uint tail;
191
204
218
220typedef struct router_entry_t {
221 uint32_t key;
222 uint32_t mask;
223 uint32_t route;
225
227typedef struct data_in_data_items {
231 uint32_t data_mc_key;
237 router_entry_t system_router_entries[];
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
454static uint32_t data_out_position_in_store = 0;
455
457static uint32_t data_out_num_items_read = 0;
458
463static uint32_t data_out_transaction_id = 0;
464
467
469static bool data_out_has_finished = false;
470
473
474// retransmission stuff
475
478
481
484
487
489static uint32_t data_out_max_seq_num = 0;
490
491// retransmission DMA stuff
492
497
500
503
506static uint32_t data_out_read_data_position = 0;
507
509static uint32_t data_out_dma_port_last_used = 0;
510
513
516
518static uint32_t data_out_basic_data_key = 0;
519
521static uint32_t data_out_new_sequence_key = 0;
522
524static uint32_t data_out_first_data_key = 0;
525
527static uint32_t data_out_transaction_id_key = 0;
528
530static uint32_t data_out_end_flag_key = 0;
531
533static bool data_out_stop = false;
534
535// ------------------------------------------------------------------------
536// support functions and variables
537// ------------------------------------------------------------------------
538
540extern INT_HANDLER sark_int_han(void);
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
601 sdp_msg_t *shm_msg = (sdp_msg_t *) sark.vcpu->mbox_ap_msg;
602 sdp_msg_t *msg = sark_msg_get();
603 if (msg != NULL) {
604 sark_msg_cpy(msg, shm_msg);
605 }
606 sark_shmsg_free(shm_msg);
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
656static INT_HANDLER reinjection_timer_callback(void) {
657 // clear interrupt in timer,
659
660 // check if router not blocked
662 // access packet queue with FIQ disabled,
663 uint cpsr = cpu_fiq_disable();
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,
668 cpu_int_restore(cpsr);
669
670 // enable communications controller. interrupt to bounce packets
672 } else {
673 // restore FIQ after queue access
674 cpu_int_restore(cpsr);
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 };
690 .p2p_source_id = reinject_p2p_source_id,
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
710static INT_HANDLER reinjection_ready_to_send_callback(void) {
711 // TODO: may need to deal with packet timestamp.
712
713 // check if router not blocked
715 // access packet queue with FIQ disabled,
716 uint cpsr = cpu_fiq_disable();
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,
727 cpu_int_restore(cpsr);
728
729 // reinject the packet
731 } else {
732 // restore FIQ after queue access,
733 cpu_int_restore(cpsr);
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
747static inline void extract_dropped_packet_details(
748 router_dump_outputs_t rtr_dump_outputs) {
749 if (rtr_dump_outputs.processor > 0) {
750 // add to the count the number of active bits from this dumped
751 // packet, as this indicates how many processors this packet
752 // was meant to go to.
754 __builtin_popcount(rtr_dump_outputs.processor);
755 reinject_link_proc_bits |= rtr_dump_outputs.processor << 6;
756 }
757
758 if (rtr_dump_outputs.link > 0) {
759 // add to the count the number of active bits from this dumped
760 // packet, as this indicates how many links this packet was
761 // meant to go to.
763 __builtin_popcount(rtr_dump_outputs.link);
764 reinject_link_proc_bits |= rtr_dump_outputs.link & 0x3F;
765 }
766}
767
769static INT_HANDLER reinjection_dropped_packet_callback(void) {
770 // get packet from router,
772 uint pld = router_control->dump.payload;
773 uint key = router_control->dump.key;
774
775 // clear dump status and interrupt in router,
776 router_dump_outputs_t rtr_dump_outputs = router_control->dump.outputs;
778
779 // only reinject if configured
780 uint packet_type = ((spinnaker_packet_control_byte_t) hdr.control).type;
781 if (((packet_type == SPINNAKER_PACKET_TYPE_MC) && reinject_mc) ||
782 ((packet_type == SPINNAKER_PACKET_TYPE_P2P) && reinject_pp) ||
783 ((packet_type == SPINNAKER_PACKET_TYPE_NN) && reinject_nn) ||
784 ((packet_type == SPINNAKER_PACKET_TYPE_FR) && reinject_fr)) {
785
786 // check for overflow from router
787 if (rtr_dstat.overflow) {
789 } else {
790 // Note that the processor_dump and link_dump flags are sticky
791 // so you can only really count these if you *haven't* missed a
792 // dropped packet - hence this being split out
793 extract_dropped_packet_details(rtr_dump_outputs);
794 }
795
796 // Only update this counter if this is a packet to reinject
798
799 // Disable FIQ for queue access
800 uint cpsr = cpu_fiq_disable();
801
802 // try to insert dumped packet in the queue,
803 uint new_tail = (reinject_pkt_queue.tail + 1) % PKT_QUEUE_SIZE;
804
805 // check for space in the queue
806 if (new_tail != reinject_pkt_queue.head) {
807 // queue packet,
808 reinject_pkt_queue.queue[reinject_pkt_queue.tail].hdr = hdr;
809 reinject_pkt_queue.queue[reinject_pkt_queue.tail].key = key;
810 reinject_pkt_queue.queue[reinject_pkt_queue.tail].pld = pld;
811
812 // update queue pointer,
813 reinject_pkt_queue.tail = new_tail;
814 } else {
815 // The queue of packets has overflowed
817 }
818
819 // restore FIQ after queue access,
820 cpu_int_restore(cpsr);
821 } else {
822 // Even if not re-injecting, we can still get this level of detail
823 extract_dropped_packet_details(rtr_dump_outputs);
824 }
825}
826
830 // process multicast reinject flag
831 if (config->multicast_flag == 1) {
832 reinject_mc = false;
833 } else {
834 reinject_mc = true;
835 }
836
837 // process point to point flag
838 if (config->point_to_point_flag == 1) {
839 reinject_pp = false;
840 } else {
841 reinject_pp = true;
842 }
843
844 // process fixed route flag
845 if (config->fixed_route_flag == 1) {
846 reinject_fr = false;
847 } else {
848 reinject_fr = true;
849 }
850
851 // process fixed route flag
852 if (config->nearest_neighbour_flag == 1) {
853 reinject_nn = false;
854 } else {
855 reinject_nn = true;
856 }
857
859 "[INFO] Setting reinject mc to %d\n[INFO] Setting reinject pp to %d\n"
860 "[INFO] Setting reinject fr to %d\n[INFO] Setting reinject nn to %d\n",
862
863 // set the reinjection mc api
864 initialise_reinjection_mc_api(config->reinjection_base_mc_key);
865
866}
867
874
877static inline void reinjection_set_wait2_timeout(uint payload) {
880}
881
889static inline int reinjection_set_timeout_sdp(sdp_msg_t *msg) {
890#ifdef DEBUG_REINJECTOR
891 io_printf(IO_BUF, "[DEBUG] setting router timeouts via sdp\n");
892#endif
893 if (msg->arg1 > ROUTER_TIMEOUT_MAX) {
894 msg->cmd_rc = RC_ARG;
895 return 0;
896 }
897
900
901 // set SCP command to OK, as successfully completed
902 msg->cmd_rc = RC_OK;
903 return 0;
904}
905
914#ifdef DEBUG_REINJECTOR
915 io_printf(IO_BUF, "[DEBUG] setting router emergency timeouts via sdp\n");
916#endif
917 if (msg->arg1 > ROUTER_TIMEOUT_MAX) {
918 msg->cmd_rc = RC_ARG;
919 return 0;
920 }
921
924
925 // set SCP command to OK, as successfully completed
926 msg->cmd_rc = RC_OK;
927 return 0;
928}
929
935 reinject_mc = msg->arg1;
936 reinject_pp = msg->arg2;
937 reinject_fr = msg->arg3;
938 reinject_nn = msg->data[0];
940
942 "[INFO] Setting reinject mc to %d\n[INFO] Setting reinject pp to %d\n"
943 "[INFO] Setting reinject fr to %d\n[INFO] Setting reinject nn to %d\n",
945
946 // set SCP command to OK, as successfully completed
947 msg->cmd_rc = RC_OK;
948 return 0;
949}
950
955static inline int reinjection_get_status(sdp_msg_t *msg) {
958
959 // Put the router timeouts in the packet
961 data->router_timeout = control.begin_emergency_wait_time;
962 data->router_emergency_timeout = control.drop_wait_time;
963
964 // Put the statistics in the packet
965 data->n_dropped_packets = reinject_n_dropped_packets;
966 data->n_missed_dropped_packets = reinject_n_missed_dropped_packets;
967 data->n_dropped_packets_overflows = reinject_n_dropped_packet_overflows;
968 data->n_reinjected_packets = reinject_n_reinjected_packets;
969 data->n_link_dumped_packets = reinject_n_link_dumped_packets;
970 data->n_processor_dumped_packets = reinject_n_processor_dumped_packets;
971 data->link_proc_bits = reinject_link_proc_bits;
972
973 // Put the current services enabled in the packet
974 data->packet_types_reinjected = 0;
975 bool values_to_check[] = {reinject_mc, reinject_pp,
977 for (int i = 0; i < 4; i++) {
978 data->packet_types_reinjected |= (values_to_check[i] << i);
979 }
980
981 // set SCP command to OK, as successfully completed
982 msg->cmd_rc = RC_OK;
983 // Return the number of bytes in the packet
985}
986
991static inline int reinjection_reset_counters(sdp_msg_t *msg) {
999
1000 // set SCP command to OK, as successfully completed
1001 msg->cmd_rc = RC_OK;
1002 return 0;
1003}
1004
1009static inline int reinjection_exit(sdp_msg_t *msg) {
1011 .timer1 = true,
1012 .router_dump = true
1013 };
1016 // Also all the rest are not FIQ
1017 .router_dump = false
1018 };
1019 reinject_run = false;
1020
1021 // set SCP command to OK, as successfully completed
1022 msg->cmd_rc = RC_OK;
1023 return 0;
1024}
1025
1027static void reinjection_clear(void) {
1028 // Disable FIQ for queue access
1029 uint cpsr = cpu_fiq_disable();
1030 // Clear any stored dropped packets
1031 reinject_pkt_queue.head = 0;
1032 reinject_pkt_queue.tail = 0;
1033 // restore FIQ after queue access,
1034 cpu_int_restore(cpsr);
1035 // and disable communications controller interrupts
1037}
1038
1043static inline int reinjection_clear_message(sdp_msg_t *msg) {
1046 // set SCP command to OK, as successfully completed
1047 msg->cmd_rc = RC_OK;
1048 return 0;
1049}
1050
1056 switch (msg->cmd_rc) {
1057#ifdef DEBUG_REINJECTOR
1058 io_printf(IO_BUF, "[DEBUG] seq %d\n", msg->seq);
1059#endif
1061#ifdef DEBUG_REINJECTOR
1062 io_printf(IO_BUF, "[DEBUG] router timeout\n");
1063#endif
1064 return reinjection_set_timeout_sdp(msg);
1066#ifdef DEBUG_REINJECTOR
1067 io_printf(IO_BUF, "[DEBUG] router emergency timeout\n");
1068#endif
1071#ifdef DEBUG_REINJECTOR
1072 io_printf(IO_BUF, "[DEBUG] router set packet type\n");
1073#endif
1074 return reinjection_set_packet_types(msg);
1076#ifdef DEBUG_REINJECTOR
1077 io_printf(IO_BUF, "[DEBUG] router get status\n");
1078#endif
1079 return reinjection_get_status(msg);
1081#ifdef DEBUG_REINJECTOR
1082 io_printf(IO_BUF, "[DEBUG] router reset\n");
1083#endif
1084 return reinjection_reset_counters(msg);
1085 case CMD_DPRI_EXIT:
1086#ifdef DEBUG_REINJECTOR
1087 io_printf(IO_BUF, "[DEBUG] router exit\n");
1088#endif
1089 return reinjection_exit(msg);
1090 case CMD_DPRI_CLEAR:
1091#ifdef DEBUG_REINJECTOR
1092 io_printf(IO_BUF, "[DEBUG] router clear\n");
1093#endif
1094 return reinjection_clear_message(msg);
1095 default:
1096 // If we are here, the command was not recognised, so fail (ARG as the
1097 // command is an argument)
1098 msg->cmd_rc = RC_ARG;
1099 return 0;
1100 }
1101}
1102
1105 // Clear the interrupt
1107 .enable = false,
1108 .interrupt_enable = false
1109 };
1111
1112 // Set the timer times
1113 timer1_control->load_value = sv->cpu_clk * TICK_PERIOD;
1115}
1116
1119 // remember SAR register contents (p2p source ID)
1121}
1122
1125 // re-configure wait values in router
1128 control.drop_wait_time = 0;
1129 router_control->control = control;
1130
1131 // clear router interrupts,
1132 (void) router_control->status;
1133
1134 // clear router dump status,
1135 (void) router_control->dump.status;
1136
1137 // clear router error status,
1138 (void) router_control->error.status;
1139
1140 // and enable router interrupts when dumping packets, and count errors
1141 control.dump_interrupt_enable = true;
1142 control.count_framing_errors = true;
1143 control.count_parity_errors = true;
1144 control.count_timestamp_errors = true;
1145 router_control->control = control;
1146}
1147
1148//-----------------------------------------------------------------------------
1149// data in speed up main functions
1150//-----------------------------------------------------------------------------
1151
1153static void data_in_clear_router(void) {
1154 rtr_entry_t router_entry;
1155
1156 // clear the currently loaded routing table entries
1157 for (uint entry_id = N_BASIC_SYSTEM_ROUTER_ENTRIES;
1158 entry_id < N_ROUTER_ENTRIES; entry_id++) {
1159 if (rtr_mc_get(entry_id, &router_entry) &&
1160 router_entry.key != INVALID_ROUTER_ENTRY_KEY &&
1161 router_entry.mask != INVALID_ROUTER_ENTRY_MASK) {
1162 rtr_free(entry_id, 1);
1163 }
1164 }
1165#ifdef DEBUG_DATA_IN
1166 io_printf(IO_BUF, "[DEBUG] max free block is %d\n", rtr_alloc_max());
1167#endif
1168}
1169
1171static inline void data_in_process_boundary(void) {
1173#ifdef DEBUG_DATA_IN
1174 io_printf(IO_BUF, "[DEBUG] Wrote %u words\n",
1176#endif
1178 }
1180}
1181
1184static inline void data_in_process_address(uint data) {
1187 }
1188#ifdef DEBUG_DATA_IN
1189 io_printf(IO_BUF, "[DEBUG] Setting write address to 0x%08x\n", data);
1190#endif
1192}
1193
1196static inline void data_in_process_data(uint data) {
1197 // data keys require writing to next point in sdram
1198
1199 if (data_in_write_address == NULL) {
1200 io_printf(IO_BUF, "[ERROR] Write address not set when write data received!\n");
1202 }
1205}
1206
1217static INT_HANDLER process_mc_payload_packet(void) {
1218 // get data from comm controller
1220 uint key = comms_control->rx_key;
1221
1222 if (key == reinject_timeout_mc_key) {
1224 } else if (key == reinject_emergency_timeout_mc_key) {
1226 } else if (key == reinject_clear_mc_key) {
1228 } else if (key == data_in_address_key) {
1230 } else if (key == data_in_data_key) {
1232 } else if (key == data_in_boundary_key) {
1233 prov->n_in_streams++;
1235 } else {
1237 "[WARNING] failed to recognise multicast packet key 0x%08x\n",
1238 key);
1239 }
1240
1241 // and tell VIC we're done
1243}
1244
1249 router_entry_t *sdram_address, uint n_entries) {
1250#ifdef DEBUG_DATA_IN
1251 io_printf(IO_BUF, "[DEBUG] Writing %u router entries\n", n_entries);
1252#endif
1253 if (n_entries == 0) {
1254 return;
1255 }
1256 uint start_entry_id = rtr_alloc_id(n_entries, sark_app_id());
1257 if (start_entry_id == 0) {
1259 "[ERROR] Received error with requesting %u router entries.\n",
1260 n_entries);
1262 }
1263
1264 for (uint idx = 0; idx < n_entries; idx++) {
1265 // check for invalid entries (possible during alloc and free or
1266 // just not filled in.
1267 if (sdram_address[idx].key != INVALID_ROUTER_ENTRY_KEY &&
1268 sdram_address[idx].mask != INVALID_ROUTER_ENTRY_MASK &&
1269 sdram_address[idx].route != INVALID_ROUTER_ENTRY_ROUTE) {
1270#ifdef DEBUG_DATA_IN
1271 // Produces quite a lot of debugging output when enabled
1273 "[DEBUG] Setting key %08x, mask %08x, route %08x for entry %u\n",
1274 sdram_address[idx].key, sdram_address[idx].mask,
1275 sdram_address[idx].route, idx + start_entry_id);
1276#endif
1277 // try setting the valid router entry
1278 if (rtr_mc_set(idx + start_entry_id, sdram_address[idx].key,
1279 sdram_address[idx].mask, sdram_address[idx].route) != 1) {
1280 io_printf(IO_BUF, "[WARNING] failed to write router entry %d, "
1281 "with key %08x, mask %08x, route %08x\n",
1282 idx + start_entry_id, sdram_address[idx].key,
1283 sdram_address[idx].mask, sdram_address[idx].route);
1284 }
1285 }
1286 }
1288}
1289
1291static void data_in_save_router(void) {
1292 rtr_entry_t router_entry;
1294 for (uint entry_id = N_BASIC_SYSTEM_ROUTER_ENTRIES, i = 0;
1295 entry_id < N_ROUTER_ENTRIES; entry_id++, i++) {
1296 (void) rtr_mc_get(entry_id, &router_entry);
1297
1298 if (router_entry.key != INVALID_ROUTER_ENTRY_KEY &&
1299 router_entry.mask != INVALID_ROUTER_ENTRY_MASK &&
1300 router_entry.route != INVALID_ROUTER_ENTRY_ROUTE) {
1301 // move to sdram
1309 }
1310 }
1311}
1312
1318 data_in_data_items_t *items) {
1319 // read in router table into app store in sdram (in case its changed
1320 // since last time)
1322
1323 // clear the currently loaded routing table entries to avoid conflicts
1325
1326 // read in and load routing table entries
1327#ifdef DEBUG_DATA_IN
1328 io_printf(IO_BUF, "[INFO] Loading system routes\n");
1329#endif
1332}
1333
1338 // clear the currently loaded routing table entries
1340
1341 // load app router entries from sdram
1342#ifdef DEBUG_DATA_IN
1343 io_printf(IO_BUF, "[INFO] Loading application routes\n");
1344#endif
1348}
1349
1356 switch (msg->cmd_rc) {
1358#ifdef DEBUG_DATA_IN
1359 io_printf(IO_BUF, "[INFO] Saving application router entries from router\n");
1360#endif
1362 msg->cmd_rc = RC_OK;
1363 break;
1366 msg->cmd_rc = RC_OK;
1368 break;
1371#ifdef DEBUG_DATA_IN
1373 "[WARNING] Already loaded system router; ignoring but replying\n");
1374#endif
1375 msg->cmd_rc = RC_OK;
1376 break;
1377 }
1380 msg->cmd_rc = RC_OK;
1382 break;
1383 default:
1385 "[WARNING] Received unknown SDP packet in data in speed up port"
1386 " with command id %d\n", msg->cmd_rc);
1387 msg->cmd_rc = RC_ARG;
1388 }
1389 return 0;
1390}
1391
1392//-----------------------------------------------------------------------------
1393// data speed up out main functions
1394//-----------------------------------------------------------------------------
1395
1399static inline void send_fixed_route_packet(uint32_t key, uint32_t data) {
1400 enum {
1402 TX_NOT_FULL_MASK = 0x10000000
1403 };
1404
1405 // If stop, don't send anything
1406 if (data_out_stop) {
1407 return;
1408 }
1409
1410 // Wait for a router slot
1412 // Empty body; CC array is volatile
1413 }
1414 const spinnaker_packet_control_byte_t fixed_route_with_payload = {
1415 .payload = true,
1417 };
1419 .control_byte = fixed_route_with_payload.value
1420 };
1422 comms_control->tx_key = key;
1423}
1424
1433 uint32_t current_dma_pointer, uint32_t n_elements_to_send,
1434 uint32_t first_packet_key, uint32_t second_packet_key) {
1435 // send data
1436 for (uint i = 0; i < n_elements_to_send; i++) {
1437 uint32_t current_data = data_out_data_to_transmit[current_dma_pointer][i];
1438
1439 send_fixed_route_packet(first_packet_key, current_data);
1440
1441 // update key to transmit with
1442 if (i == 0) {
1443 first_packet_key = second_packet_key;
1444 } else {
1445 first_packet_key = data_out_basic_data_key;
1446 }
1447 }
1448}
1449
1460static inline void data_out_start_dma_read(
1461 uint32_t dma_tag, void *source, void *destination, uint n_words) {
1463 dma_control->sdram_address = source;
1464 dma_control->tcm_address = destination;
1466 .width = DMA_TRANSFER_DOUBLE_WORD,
1467 .burst = DMA_BURST_SIZE,
1468 .direction = DMA_DIRECTION_READ,
1469 .length_words = n_words
1470 };
1471}
1472
1479static void data_out_read(
1480 uint32_t dma_tag, uint32_t offset, uint32_t items_to_read) {
1481 // set off DMA
1484
1485 address_t data_sdram_position =
1487
1488 // update positions as needed
1489 data_out_position_in_store += items_to_read;
1490 data_out_num_items_read = items_to_read;
1491
1492 // set off DMA
1493 data_out_start_dma_read(dma_tag, data_sdram_position,
1495 items_to_read);
1496}
1497
1502
1510 // set up state
1511 uint32_t current_dma_pointer = data_out_transmit_dma_pointer;
1512 uint32_t key_to_transmit = data_out_basic_data_key;
1513 uint32_t second_key_to_transmit = data_out_basic_data_key;
1514 uint32_t items_read_this_time = data_out_num_items_read;
1515
1516 // put size in bytes if first send
1518 //io_printf(IO_BUF, "in first\n");
1519 data_out_data_to_transmit[current_dma_pointer][0] = data_out_max_seq_num;
1520 data_out_data_to_transmit[current_dma_pointer][1] = data_out_transaction_id;
1521 key_to_transmit = data_out_first_data_key;
1522 second_key_to_transmit = data_out_transaction_id_key;
1524 items_read_this_time += 2;
1525 }
1526
1527 // stopping procedure
1528 // if a full packet, read another and try again
1530 uint32_t num_items_to_read = SDP_PAYLOAD_WORDS;
1531 uint32_t next_position_in_store =
1533
1534 // if less data needed request less data
1535 if (next_position_in_store >= data_out_n_elements_to_read_from_sdram) {
1536 num_items_to_read =
1539 }
1540
1541 // set off another read and transmit DMA'ed one
1542 data_out_read(DMA_TAG_READ_FOR_TRANSMISSION, 0, num_items_to_read);
1543 data_out_send_data_block(current_dma_pointer, items_read_this_time,
1544 key_to_transmit, second_key_to_transmit);
1545 } else {
1546 data_out_send_data_block(current_dma_pointer, items_read_this_time,
1547 key_to_transmit, second_key_to_transmit);
1548
1549 // send end flag.
1551
1552 data_out_has_finished = true;
1554 }
1555
1556 if (TDMA_WAIT_PERIOD != 0) {
1558 }
1559}
1560
1566 uint32_t data[], uint length, uint32_t start_offset) {
1567 for (uint i = start_offset, j = data_out_n_missing_seq_nums_in_sdram;
1568 i < length; i++, j++) {
1570#ifdef DEBUG_DATA_OUT
1571 if (data[i] > data_out_max_seq_num) {
1572 io_printf(IO_BUF, "[WARNING] Storing bad seq num. %d %d\n",
1574 }
1575#endif
1576 }
1577 data_out_n_missing_seq_nums_in_sdram += length - start_offset;
1578}
1579
1590 uint32_t data[], uint length, bool first) {
1591 uint32_t start_reading_offset = START_OF_MISSING_MORE;
1592 if (first) {
1594 data[POSITION_OF_NO_MISSING_SEQ_PACKETS];
1595
1596 uint32_t size_of_data =
1598 + END_FLAG_SIZE;
1599
1603 }
1605
1606 // if not got enough sdram to alllocate all missing seq nums
1608 // biggest sdram block
1609 uint32_t max_bytes = sdram_max_block_size();
1610 // if can't hold more than this packets worth of data, blow up
1611 if (max_bytes < SDP_PAYLOAD_BYTES + END_FLAG_SIZE) {
1613 "[ERROR] Can't allocate SDRAM for missing seq nums\n");
1615 }
1616#ifdef DEBUG_DATA_OUT
1617 io_printf(IO_BUF, "[DEBUG] Activate bacon protocol!\n");
1618#endif
1619 // allocate biggest block
1621 // determine max full seq num packets to store
1622 max_bytes -= END_FLAG_SIZE + SDP_PAYLOAD_BYTES;
1624 + max_bytes / (ITEMS_PER_DATA_PACKET * sizeof(uint));
1625 }
1626 start_reading_offset = START_OF_MISSING_SEQ_NUMS;
1627 }
1629 // write data to SDRAM and update packet counter
1631 data, length, start_reading_offset);
1633#ifdef DEBUG_DATA_OUT
1634 } else {
1635 io_printf(IO_BUF, "[WARNING] Unable to save missing sequence number\n");
1636#endif
1637 }
1638}
1639
1642 // locate where we are in SDRAM
1643 address_t data_sdram_position =
1645
1646 // set off DMA
1648 data_sdram_position, data_out_retransmit_seq_nums,
1650}
1651
1657 // check if at end of read missing sequence numbers
1664 }
1665 return;
1666 }
1667
1668 // get next sequence number to regenerate
1672 // regenerate data
1675 uint32_t left_over_portion =
1678
1679 if (left_over_portion < SDP_PAYLOAD_WORDS) {
1680 data_out_retransmitted_seq_num_items_read = left_over_portion + 1;
1681 data_out_read(DMA_TAG_RETRANSMISSION_READING, 1, left_over_portion);
1682 } else {
1686 }
1687 } else { // finished data send, tell host its done
1693 }
1697 }
1698}
1699
1724
1727#ifdef DEBUG_DATA_OUT
1728 io_printf(IO_BUF, "[INFO] Need to figure what to do here\n");
1729#endif
1730}
1731
1736 sdp_data_out_t *message = (sdp_data_out_t *) msg->data;
1737
1738 switch (message->command) {
1740 // updater transaction id if it hits the cap
1741 if (((data_out_transaction_id + 1) & TRANSACTION_CAP) == 0) {
1744 }
1745
1746 // if transaction id is not as expected. ignore it as its from the past.
1747 // and worthless
1748 if (message->transaction_id != data_out_transaction_id + 1) {
1750 "[WARNING] received start message with unexpected "
1751 "transaction id %d; mine is %d\n",
1753 return;
1754 }
1755
1756 //extract transaction id and update
1759
1760 data_out_stop = false;
1761
1762 // set SDRAM position and length
1764 // state for how many bytes it needs to send, gives approximate
1765 // bandwidth if round number.
1766 uint32_t bytes_to_read_write = message->length;
1767
1768 data_out_max_seq_num = bytes_to_read_write / SDP_PAYLOAD_BYTES;
1769 uint32_t mod = bytes_to_read_write % SDP_PAYLOAD_BYTES;
1770 data_out_max_seq_num += mod > 0;
1771
1772 // reset states
1777 bytes_to_read_write / sizeof(uint);
1778
1782 } else {
1784 }
1786 return;
1787 }
1789 if (message->transaction_id != data_out_transaction_id) {
1791 "[WARNING] received data from a different transaction for "
1792 "start of missing. expected %d got %d\n",
1794 return;
1795 }
1796
1797 // if already in a retransmission phase, don't process as normal
1799#ifdef DEBUG_DATA_OUT
1800 io_printf(IO_BUF, "[INFO] forcing start of retransmission packet\n");
1801#endif
1804 END_FLAG;
1809 return;
1810 }
1811 // fall through
1813 if (message->transaction_id != data_out_transaction_id) {
1815 "[WARNING] received data from different transaction for "
1816 "more missing; expected %d, got %d\n",
1818 return;
1819 }
1820
1821 // reset state, as could be here from multiple attempts
1823 // put missing sequence numbers into SDRAM
1825 msg->data,
1826 (msg->length - LENGTH_OF_SDP_HEADER) / sizeof(uint),
1828
1829 // if got all missing packets, start retransmitting them to host
1831 // packets all received, add finish flag for DMA stoppage
1832
1838
1839 // start DMA off
1842 }
1843 }
1844 }
1845 return;
1846 case SDP_CMD_CLEAR:
1847 if (message->transaction_id != data_out_transaction_id) {
1849 "[WARNING] received data from different transaction for "
1850 "clear; expected %d, got %d\n",
1852 return;
1853 }
1854#ifdef DEBUG_DATA_OUT
1855 io_printf(IO_BUF, "[INFO] data out clear\n");
1856#endif
1857 data_out_stop = true;
1858 break;
1859 default:
1860 io_printf(IO_BUF, "[WARNING] Received unknown SDP packet: %d\n",
1861 message->command);
1862 }
1863}
1864
1872static INT_HANDLER data_out_dma_complete(void) {
1873 // reset the interrupt.
1875 .clear_done_int = true
1876 };
1877 if (!data_out_stop) {
1878 // Only do something if we have not been told to stop
1882 break;
1885 break;
1888 break;
1891 break;
1892 default:
1893 io_printf(IO_BUF, "[ERROR] Invalid DMA callback port: %d\n",
1896 }
1897 }
1898 // and tell VIC we're done
1900}
1901
1903static INT_HANDLER data_out_dma_error(void) {
1904 io_printf(IO_BUF, "[WARNING] DMA failed: 0x%08x\n", dma_control->status);
1906 // Clear the error
1907 .restart = true
1908 };
1911}
1912
1914static INT_HANDLER data_out_dma_timeout(void) {
1915 io_printf(IO_BUF, "[WARNING] DMA timeout: 0x%08x\n", dma_control->status);
1917 .clear_timeout_int = true
1918 };
1920}
1921
1922//-----------------------------------------------------------------------------
1923// common code
1924//-----------------------------------------------------------------------------
1925
1926void __real_sark_int(void *pc);
1928// This function is why this code *can't* use Spin1API.
1929void __wrap_sark_int(void *pc) {
1930 // Get the message from SCAMP and see if t belongs to SARK
1931 if (sark.vcpu->mbox_ap_cmd != SHM_MSG) {
1932 // Run the default callback
1933 __real_sark_int(pc);
1934 return;
1935 }
1936
1937 // Make a copy so we can release the mailbox, and flag as ready for
1938 // interrupt again
1940 //io_printf(IO_BUF, "seq is %d\n", msg->seq);
1942 .security_code = SYSTEM_CONTROLLER_MAGIC_NUMBER,
1943 .select = 1 << sark.phys_cpu,
1944 };
1945 if (msg == NULL) {
1946 return;
1947 }
1948
1949 switch ((msg->dest_port & PORT_MASK) >> PORT_SHIFT) {
1950 case REINJECTION_PORT:
1952 while (!sark_msg_send(msg, 10)) {
1953#ifdef DEBUG_REINJECTOR
1954 io_printf(IO_BUF, "[DEBUG] timeout when sending reinjection reply\n");
1955#endif
1956 }
1958 break;
1959 case DATA_SPEED_UP_OUT_PORT:
1960 // These are all one-way messages; replies are out of band
1963 break;
1966 while (!sark_msg_send(msg, 10)) {
1967#ifdef DEBUG_DATA_IN
1968 io_printf(IO_BUF, "[DEBUG] timeout when sending speedup ctl reply\n");
1969#endif
1970 }
1972 break;
1973 default:
1974 io_printf(IO_BUF, "[WARNING] unexpected port %d\n",
1975 (msg->dest_port & PORT_MASK) >> PORT_SHIFT);
1976 io_printf(IO_BUF,
1977 "[INFO] from:%04x:%02x to:%04x:%02x cmd:%04x len:%d iam:%04x\n",
1978 msg->srce_addr, msg->srce_port,
1979 msg->dest_addr, msg->dest_port,
1980 msg->cmd_rc, msg->length, my_addr);
1981 // Do nothing
1982 }
1983 sark_msg_free(msg);
1984}
1985
1986//-----------------------------------------------------------------------------
1987// initializers
1988//-----------------------------------------------------------------------------
1989
1991static void reinjection_initialise(void) {
1992 // set up config region
1993 // Get the address this core's DTCM data starts at from SRAM
1995
1996 // Setup the CPU interrupt for WDOG
1997 vic_interrupt_control[sark_vec->sark_slot] = (vic_vector_control_t) {
1998 .enable = false
1999 };
2001
2002 // Setup the communications controller interrupt
2004
2005 // Setup the timer interrupt
2007
2008 // Setup the router interrupt as a fast interrupt
2009 sark_vec->fiq_vec = reinjection_dropped_packet_callback;
2011 .router_dump = true
2012 };
2013}
2014
2016static void data_out_initialise(void) {
2019 data_out_new_sequence_key = config->new_seq_key;
2020 data_out_first_data_key = config->first_data_key;
2021 data_out_transaction_id_key = config->transaction_id_key;
2022 data_out_end_flag_key = config->end_flag_key;
2023
2024#ifdef DEBUG_DATA_OUT
2026 "[INFO] new seq key = %d, first data key = %d, transaction id key = %d, "
2027 "end flag key = %d, basic_data_key = %d\n",
2030#endif
2031
2032 // Various DMA callbacks
2036
2037 // configuration for the DMA's by the speed data loader
2039 // Abort pending and active transfers
2040 .uncommit = true,
2041 .abort = true,
2042 .restart = true,
2043 .clear_done_int = true,
2044 .clear_timeout_int = true,
2045 .clear_write_buffer_int = true
2046 };
2048 // clear possible transfer done and restart
2049 .uncommit = true,
2050 .restart = true,
2051 .clear_done_int = true
2052 };
2054 // enable DMA done and error interrupt
2055 .transfer_done_interrupt = true,
2056 .transfer2_done_interrupt = true,
2057 .timeout_interrupt = true,
2058 .crc_error_interrupt = true,
2059 .tcm_error_interrupt = true,
2060 .axi_error_interrupt = true, // SDRAM error
2061 .user_abort_interrupt = true,
2062 .soft_reset_interrupt = true,
2063 .write_buffer_error_interrupt = true
2064 };
2065}
2066
2068static void data_in_initialise(void) {
2073 "[ERROR] failed to allocate SDRAM for application mc router entries\n");
2075 }
2076
2078
2082 // Save the current (application?) state
2084
2085 // load user 1 in case this is a consecutive load
2087
2088 // set up mc interrupts to deal with data writing
2090}
2091
2093static void provenance_initialise(void) {
2095 prov->n_sdp_packets = 0;
2096 prov->n_in_streams = 0;
2097 prov->n_out_streams = 0;
2099}
2100
2101//-----------------------------------------------------------------------------
2103//-----------------------------------------------------------------------------
2104void c_main(void) {
2106
2110 }
2111
2112 // Configure
2113 my_addr = sv->p2p_addr;
2117
2118 // Initialise the statistics
2123
2124 // set up VIC callbacks and interrupts accordingly
2125 // Disable the interrupts that we are configuring (except CPU for WDOG)
2126 const vic_mask_t int_select = {
2127 .timer1 = true,
2128 .router_dump = true,
2129 .dma_done = true,
2130 .dma_error = true,
2131 .dma_timeout = true,
2132 .cc_rx_mc = true,
2133 };
2134 vic_control->int_disable = int_select;
2136
2137 // set up provenance area
2139
2140 // set up reinjection functionality
2142
2143 // set up data speed up functionality
2146
2147 // Enable interrupts and timer
2148 vic_control->int_enable = int_select;
2150 .size = 1,
2151 .interrupt_enable = true,
2152 .periodic_mode = true,
2153 .enable = true
2154 };
2155
2156 io_printf(IO_BUF, "[INFO] extra monitor initialisation complete\n");
2157
2158 // Run until told to exit
2159 while (reinject_run) {
2161 }
2162}
2163// ------------------------------------------------------------------------
@ 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...)
router_entry_t system_router_entries[]
The system (non-app, non-SCAMP) router entries to use for Data In.
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 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
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)
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
vic_mask_t int_enable
interrupt enable set register
uint overflow
more than one packet dumped
static volatile vic_interrupt_handler_t *const vic_interrupt_vector
VIC interrupt handlers. Array of 32 elements.
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.
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
sc_magic_proc_map_t clear_cpu_irq
Writing a 1 clears a processor’s interrupt line.
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.
const router_packet_header_t header
dumped packet control byte and flags
vic_interrupt_handler_t vector_address
current vector address register
uint link
Tx link transmit error caused packet dump.
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
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
uint processor
Fascicle Processor link error caused dump.
@ DMA_DIRECTION_READ
read from system bus (SDRAM)
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