SpiNNFrontEndCommon  development
Common support code for user-facing front end systems.
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 
70 enum {
79  SDP_PAYLOAD_BYTES = SDP_PAYLOAD_WORDS * sizeof(uint)
80 };
81 
82 //-----------------------------------------------------------------------------
84 //-----------------------------------------------------------------------------
85 
86 typedef enum data_out_sdp_commands {
95  SDP_CMD_CLEAR = 2000
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 
156 enum {
158  CPU_SLOT = SLOT_0,
160  CC_SLOT = SLOT_1,
162  TIMER_SLOT = SLOT_2,
164  DMA_SLOT = SLOT_3,
166  DMA_ERROR_SLOT = SLOT_4,
170  MC_PAYLOAD_SLOT = SLOT_6
171 };
172 
173 // ------------------------------------------------------------------------
174 // structs used in system
175 // ------------------------------------------------------------------------
176 
178 typedef struct dumped_packet_t {
180  uint key;
181  uint pld;
183 
185 typedef struct pkt_queue_t {
186  uint head;
187  uint tail;
190 } pkt_queue_t;
191 
203 };
204 
206 typedef struct sdp_data_out_t {
216  uint length;
218 
220 typedef struct router_entry_t {
221  uint32_t key;
222  uint32_t mask;
223  uint32_t route;
225 
227 typedef struct data_in_data_items {
229  uint32_t address_mc_key;
231  uint32_t data_mc_key;
233  uint32_t boundary_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 
280 typedef struct reinject_config_t {
293  uint reinjection_base_mc_key;
295 
298  REINJECTION_PORT = 4,
299  DATA_SPEED_UP_OUT_PORT = 5,
301 };
302 
313 };
314 
323 };
324 
326 typedef struct data_speed_out_config_t {
328  uint my_key;
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 
396 static bool reinject_mc;
397 
399 static bool reinject_pp;
400 
402 static bool reinject_nn;
403 
405 static bool reinject_fr;
406 
408 static bool reinject_run = true;
409 
410 // ------------------------------------------------------------------------
411 // global variables for data speed up in functionality
412 // ------------------------------------------------------------------------
413 
414 // data in variables
418 
420 static uint data_in_address_key = 0;
421 
423 static uint data_in_data_key = 0;
424 
426 static uint data_in_boundary_key = 0;
427 
430 
433 
436 
439 
440 // ------------------------------------------------------------------------
441 // global variables for data speed up out functionality
442 // ------------------------------------------------------------------------
443 
444 // transmission stuff
445 
448 
451 static uint32_t data_out_transmit_dma_pointer = 0;
452 
454 static uint32_t data_out_position_in_store = 0;
455 
457 static uint32_t data_out_num_items_read = 0;
458 
463 static uint32_t data_out_transaction_id = 0;
464 
466 static bool data_out_first_transmission = true;
467 
469 static bool data_out_has_finished = false;
470 
473 
474 // retransmission stuff
475 
477 static uint32_t data_out_n_missing_seq_packets = 0;
478 
481 
484 
487 
489 static uint32_t data_out_max_seq_num = 0;
490 
491 // retransmission DMA stuff
492 
497 
500 
503 
506 static uint32_t data_out_read_data_position = 0;
507 
509 static uint32_t data_out_dma_port_last_used = 0;
510 
513 
516 
518 static uint32_t data_out_basic_data_key = 0;
519 
521 static uint32_t data_out_new_sequence_key = 0;
522 
524 static uint32_t data_out_first_data_key = 0;
525 
527 static uint32_t data_out_transaction_id_key = 0;
528 
530 static uint32_t data_out_end_flag_key = 0;
531 
533 static bool data_out_stop = false;
534 
535 // ------------------------------------------------------------------------
536 // support functions and variables
537 // ------------------------------------------------------------------------
538 
540 extern INT_HANDLER sark_int_han(void);
541 
545 static ushort my_addr;
546 
548 static vcpu_t *const _sark_virtual_processor_info = (vcpu_t *) SV_VCPU;
549 
552 
555 
562 static inline void *dse_block(uint index) {
564 }
565 
573  _sark_virtual_processor_info[sark.virt_cpu].user1 = transaction_id;
574 }
575 
579 static 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 
586 static 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 
593 static inline uint sdram_max_block_size(void) {
594  return sark_heap_max(sv->sdram_heap, ALLOC_LOCK);
595 }
596 
600 static inline sdp_msg_t *get_message_from_mailbox(void) {
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);
607  sark.vcpu->mbox_ap_cmd = SHM_IDLE;
608  return msg;
609 }
610 
612 static inline void vic_interrupt_done(void) {
614 }
615 
620 static inline void set_vic_callback(
621  uint8_t slot, uint type, vic_interrupt_handler_t callback) {
622  vic_interrupt_vector[slot] = callback;
624  .source = type,
625  .enable = true
626  };
627 }
628 
629 // ------------------------------------------------------------------------
630 // reinjector main functions
631 // ------------------------------------------------------------------------
632 
635 static inline void reinjection_enable_comms_interrupt(void) {
637  .cc_tx_not_full = true
638  };
639 }
640 
643 static inline void reinjection_disable_comms_interrupt(void) {
645  .cc_tx_not_full = true
646  };
647 }
648 
651 static inline bool reinjection_can_send_now(void) {
653 }
654 
656 static INT_HANDLER reinjection_timer_callback(void) {
657  // clear interrupt in timer,
659 
660  // check if router not blocked
661  if (reinjection_can_send_now()) {
662  // access packet queue with FIQ disabled,
663  uint cpsr = cpu_fiq_disable();
664 
665  // if queue not empty turn on packet bouncing,
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 
684 static 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,
696  (spinnaker_packet_control_byte_t) pkt->hdr.control;
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 
710 static INT_HANDLER reinjection_ready_to_send_callback(void) {
711  // TODO: may need to deal with packet timestamp.
712 
713  // check if router not blocked
714  if (reinjection_can_send_now()) {
715  // access packet queue with FIQ disabled,
716  uint cpsr = cpu_fiq_disable();
717 
718  // if queue not empty bounce packet,
720  // dequeue packet and update queue pointer
721  dumped_packet_t pkt =
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 
747 static 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 
769 static 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;
777  router_dump_status_t rtr_dstat = router_control->dump.status;
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,
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 
858  io_printf(IO_BUF,
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 
870 static inline void reinjection_set_wait1_timeout(uint payload) {
873 }
874 
877 static inline void reinjection_set_wait2_timeout(uint payload) {
880 }
881 
889 static 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 
913 static inline int reinjection_set_emergency_timeout_sdp(sdp_msg_t *msg) {
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 
934 static inline int reinjection_set_packet_types(sdp_msg_t *msg) {
935  reinject_mc = msg->arg1;
936  reinject_pp = msg->arg2;
937  reinject_fr = msg->arg3;
938  reinject_nn = msg->data[0];
940 
941  io_printf(IO_BUF,
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 
955 static 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 
991 static 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 
1009 static 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 
1027 static void reinjection_clear(void) {
1028  // Disable FIQ for queue access
1029  uint cpsr = cpu_fiq_disable();
1030  // Clear any stored dropped packets
1033  // restore FIQ after queue access,
1034  cpu_int_restore(cpsr);
1035  // and disable communications controller interrupts
1037 }
1038 
1043 static 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 
1055 static uint reinjection_sdp_command(sdp_msg_t *msg) {
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);
1075  case CMD_DPRI_GET_STATUS:
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 
1104 static void reinjection_configure_timer(void) {
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 
1124 static void reinjection_configure_router(void) {
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 
1153 static 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 
1171 static inline void data_in_process_boundary(void) {
1172  if (data_in_write_address) {
1173 #ifdef DEBUG_DATA_IN
1174  io_printf(IO_BUF, "[DEBUG] Wrote %u words\n",
1176 #endif
1177  data_in_write_address = NULL;
1178  }
1180 }
1181 
1184 static inline void data_in_process_address(uint data) {
1185  if (data_in_write_address) {
1187  }
1188 #ifdef DEBUG_DATA_IN
1189  io_printf(IO_BUF, "[DEBUG] Setting write address to 0x%08x\n", data);
1190 #endif
1192 }
1193 
1196 static 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");
1201  rt_error(RTE_SWERR);
1202  }
1205 }
1206 
1217 static INT_HANDLER process_mc_payload_packet(void) {
1218  // get data from comm controller
1219  uint data = comms_control->rx_data;
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 {
1236  io_printf(IO_BUF,
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) {
1258  io_printf(IO_BUF,
1259  "[ERROR] Received error with requesting %u router entries.\n",
1260  n_entries);
1261  rt_error(RTE_SWERR);
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
1272  io_printf(IO_BUF,
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 
1291 static 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
1303  data_in_application_table_n_valid_entries].key = router_entry.key;
1305  data_in_application_table_n_valid_entries].mask = router_entry.mask;
1307  data_in_application_table_n_valid_entries].route = router_entry.route;
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 
1355 static uint data_in_speed_up_command(sdp_msg_t *msg) {
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
1372  io_printf(IO_BUF,
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:
1384  io_printf(IO_BUF,
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 
1399 static 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
1411  while (!comms_control->tx_control.not_full) {
1412  // Empty body; CC array is volatile
1413  }
1414  const spinnaker_packet_control_byte_t fixed_route_with_payload = {
1415  .payload = true,
1416  .type = SPINNAKER_PACKET_TYPE_FR
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 
1460 static inline void data_out_start_dma_read(
1461  uint32_t dma_tag, void *source, void *destination, uint n_words) {
1462  data_out_dma_port_last_used = dma_tag;
1463  dma_control->sdram_address = source;
1464  dma_control->tcm_address = destination;
1467  .burst = DMA_BURST_SIZE,
1468  .direction = DMA_DIRECTION_READ,
1469  .length_words = n_words
1470  };
1471 }
1472 
1479 static 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 
1499 static void data_out_send_end_flag(void) {
1501 }
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) {
1557  sark_delay_us(TDMA_WAIT_PERIOD);
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) {
1612  io_printf(IO_BUF,
1613  "[ERROR] Can't allocate SDRAM for missing seq nums\n");
1614  rt_error(RTE_SWERR);
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 
1704  // set sequence number as first element
1707 #ifdef DEBUG_DATA_OUT
1709  io_printf(IO_BUF,
1710  "[WARNING] Got some bad seq num here; max is %d, got %d\n",
1712  }
1713 #endif
1714 
1715  // send new data back to host
1720 
1723 }
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) {
1749  io_printf(IO_BUF,
1750  "[WARNING] received start message with unexpected "
1751  "transaction id %d; mine is %d\n",
1752  message->transaction_id, data_out_transaction_id + 1);
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  }
1785  prov->n_out_streams++;
1786  return;
1787  }
1789  if (message->transaction_id != data_out_transaction_id) {
1790  io_printf(IO_BUF,
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
1798  if (data_out_n_missing_seq_packets != 0) {
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) {
1814  io_printf(IO_BUF,
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
1830  if (data_out_n_missing_seq_packets == 0) {
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) {
1848  io_printf(IO_BUF,
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 
1872 static 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
1879  switch (data_out_dma_port_last_used) {
1882  break;
1885  break;
1888  break;
1891  break;
1892  default:
1893  io_printf(IO_BUF, "[ERROR] Invalid DMA callback port: %d\n",
1895  rt_error(RTE_SWERR);
1896  }
1897  }
1898  // and tell VIC we're done
1900 }
1901 
1903 static 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  };
1910  rt_error(RTE_DABT);
1911 }
1912 
1914 static 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 
1926 void __real_sark_int(void *pc);
1928 // This function is why this code *can't* use Spin1API.
1929 void __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
1939  sdp_msg_t *msg = get_message_from_mailbox();
1940  //io_printf(IO_BUF, "seq is %d\n", msg->seq);
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  }
1957  prov->n_sdp_packets++;
1958  break;
1959  case DATA_SPEED_UP_OUT_PORT:
1960  // These are all one-way messages; replies are out of band
1962  prov->n_sdp_packets++;
1963  break;
1964  case DATA_SPEED_UP_IN_PORT:
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  }
1971  prov->n_sdp_packets++;
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 
1991 static 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 
2016 static void data_out_initialise(void) {
2018  data_out_basic_data_key = config->my_key;
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
2025  io_printf(IO_BUF,
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 
2068 static void data_in_initialise(void) {
2072  io_printf(IO_BUF,
2073  "[ERROR] failed to allocate SDRAM for application mc router entries\n");
2074  rt_error(RTE_SWERR);
2075  }
2076 
2078 
2080  data_in_data_key = items->data_mc_key;
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 
2093 static void provenance_initialise(void) {
2095  prov->n_sdp_packets = 0;
2096  prov->n_in_streams = 0;
2097  prov->n_out_streams = 0;
2098  prov->n_router_changes = 0;
2099 }
2100 
2101 //-----------------------------------------------------------------------------
2103 //-----------------------------------------------------------------------------
2104 void c_main(void) {
2105  sark_cpu_state(CPU_STATE_RUN);
2106 
2109  rt_error(RTE_SWERR);
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.
static void * data_specification_get_region(uint32_t region, data_specification_metadata_t *ds_regions)
Gets the address of a region.
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.
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.
dumped_packet_t queue[PKT_QUEUE_SIZE]
Circular buffer used to implement the queue of packets to reinject.
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 void * sdram_alloc(uint size)
allocate a block of SDRAM (to be freed with sdram_free())
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 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 void * dse_block(uint index)
Get the DSG region with the given index.
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 head
Index of head of queue in circular buffer.
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 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
static sdp_msg_t * get_message_from_mailbox(void)
How to get an SDP message out of the mailbox correctly.
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.
#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.
packet queue type
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.
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
Extra definitions of things on SpiNNaker chips that aren't already mentioned in spinnaker....
router_control_t control
Router control register.
Definition: spinn_extra.h:927
static volatile system_controller_t *const system_control
System controller registers.
Definition: spinn_extra.h:1801
const router_dump_status_t status
dumped packet status
Definition: spinn_extra.h:952
uint dump_interrupt_enable
enable dump packet interrupt
Definition: spinn_extra.h:723
uint output_stage
Router output stage status (see router_output_stage)
Definition: spinn_extra.h:753
uint enable
enable counter/timer (1 = enabled)
Definition: spinn_extra.h:258
static volatile router_t *const router_control
Router controller registers.
Definition: spinn_extra.h:1073
comms_tx_control_t tx_control
Controls packet transmission.
Definition: spinn_extra.h:667
uint p2p_source_id
16-bit chip source ID for P2P packets
Definition: spinn_extra.h:655
uint clear_timeout_int
clear Timeout interrupt request
Definition: spinn_extra.h:378
uint width
transfer width, see dma_transfer_unit_t
Definition: spinn_extra.h:344
vic_mask_t int_enable
interrupt enable set register
Definition: spinn_extra.h:188
uint overflow
more than one packet dumped
Definition: spinn_extra.h:851
static volatile vic_interrupt_handler_t *const vic_interrupt_vector
VIC interrupt handlers. Array of 32 elements.
Definition: spinn_extra.h:224
uint size
0 = 16 bit, 1 = 32 bit
Definition: spinn_extra.h:248
dma_global_control_t global_control
Control of the DMA device.
Definition: spinn_extra.h:492
const dma_status_t status
Status of DMA and other transfers.
Definition: spinn_extra.h:490
const router_status_t status
Router status.
Definition: spinn_extra.h:929
static volatile comms_ctl_t *const comms_control
Communications controller registers.
Definition: spinn_extra.h:690
uint control_byte
control byte of next sent packet
Definition: spinn_extra.h:611
static volatile vic_control_t *const vic_control
VIC registers.
Definition: spinn_extra.h:220
vic_mask_t int_select
interrupt select register
Definition: spinn_extra.h:186
void * sdram_address
DMA address on the system interface.
Definition: spinn_extra.h:482
@ DMA_TRANSFER_DOUBLE_WORD
Transfer in double-words.
Definition: spinn_extra.h:364
@ SYSTEM_CONTROLLER_MAGIC_NUMBER
Magic number for enabling writing to critical fields.
Definition: spinn_extra.h:1785
timer_control_t control
Timer control register.
Definition: spinn_extra.h:288
const router_error_status_t status
error packet status
Definition: spinn_extra.h:939
dma_description_t description
DMA transfer descriptor; note that setting this commits a DMA.
Definition: spinn_extra.h:486
void * tcm_address
DMA address on the TCM interface.
Definition: spinn_extra.h:484
const router_dump_outputs_t outputs
dumped packet intended destinations
Definition: spinn_extra.h:950
const uint key
dumped packet routing word
Definition: spinn_extra.h:946
uint drop_wait_time
wait2; wait time before dropping packet after entering emergency routing
Definition: spinn_extra.h:741
@ SPINNAKER_PACKET_TYPE_NN
Nearest-neighbour packet.
Definition: spinn_extra.h:601
@ SPINNAKER_PACKET_TYPE_FR
Fixed-route packet.
Definition: spinn_extra.h:603
@ SPINNAKER_PACKET_TYPE_P2P
Peer-to-peer packet.
Definition: spinn_extra.h:599
@ SPINNAKER_PACKET_TYPE_MC
Multicast packet.
Definition: spinn_extra.h:597
uint count_parity_errors
enable count of packet parity errors
Definition: spinn_extra.h:729
uint uncommit
setting this bit uncommits a queued transfer
Definition: spinn_extra.h:370
sc_magic_proc_map_t clear_cpu_irq
Writing a 1 clears a processor’s interrupt line.
Definition: spinn_extra.h:1723
uint enable
interrupt enable
Definition: spinn_extra.h:210
uint background_load_value
Background load value for Timer.
Definition: spinn_extra.h:296
uint load_value
Load value for Timer.
Definition: spinn_extra.h:284
uint tx_key
Send MC key/P2P dest ID & seq code; writing this commits a send.
Definition: spinn_extra.h:671
uint transfer_done_interrupt
interrupt if dma_status_t::transfer_done set
Definition: spinn_extra.h:432
const router_packet_header_t header
dumped packet control byte and flags
Definition: spinn_extra.h:944
vic_interrupt_handler_t vector_address
current vector address register
Definition: spinn_extra.h:200
uint link
Tx link transmit error caused packet dump.
Definition: spinn_extra.h:835
static volatile vic_vector_control_t *const vic_interrupt_control
VIC individual interrupt control. Array of 32 elements.
Definition: spinn_extra.h:227
uint count_framing_errors
enable count of packet framing errors
Definition: spinn_extra.h:727
uint count_timestamp_errors
enable count of packet time stamp errors
Definition: spinn_extra.h:725
dma_control_t control
Control DMA transfer.
Definition: spinn_extra.h:488
comms_source_addr_t source_addr
P2P source address.
Definition: spinn_extra.h:680
@ ROUTER_OUTPUT_STAGE_EMPTY
output stage is empty
Definition: spinn_extra.h:767
vic_mask_t int_disable
interrupt enable clear register
Definition: spinn_extra.h:190
uint clear_done_int
clear Done interrupt request
Definition: spinn_extra.h:376
uint restart
resume transfer (clears DMA errors)
Definition: spinn_extra.h:374
uint security_code
SYSTEM_CONTROLLER_MAGIC_NUMBER to enable write
Definition: spinn_extra.h:1470
static volatile timer_controller_t *const timer1_control
Timer 1 control registers.
Definition: spinn_extra.h:305
static volatile dma_t *const dma_control
DMA control registers.
Definition: spinn_extra.h:527
const uint rx_data
32-bit received data
Definition: spinn_extra.h:675
const uint rx_key
Received MC key/P2P source ID & seq code; reading this clears the received packet.
Definition: spinn_extra.h:678
const uint payload
dumped packet data payload
Definition: spinn_extra.h:948
uint not_full
Tx buffer not full, so it is safe to send a packet.
Definition: spinn_extra.h:615
uint tx_data
32-bit data for transmission
Definition: spinn_extra.h:669
uint processor
Fascicle Processor link error caused dump.
Definition: spinn_extra.h:837
@ DMA_DIRECTION_READ
read from system bus (SDRAM)
Definition: spinn_extra.h:354
uint source
interrupt source
Definition: spinn_extra.h:208
void(* vic_interrupt_handler_t)(void)
The type of an interrupt handler.
Definition: spinn_extra.h:102
uint begin_emergency_wait_time
wait1; wait time before emergency routing
Definition: spinn_extra.h:739
uint interrupt_clear
Interrupt clear (any value may be written)
Definition: spinn_extra.h:290
P2P source address.
Definition: spinn_extra.h:653
Controls packet transmission.
Definition: spinn_extra.h:607
DMA control register.
Definition: spinn_extra.h:368
DMA descriptor.
Definition: spinn_extra.h:330
DMA global control register.
Definition: spinn_extra.h:426
Router control register.
Definition: spinn_extra.h:717
Router dump outputs.
Definition: spinn_extra.h:833
Router dump status.
Definition: spinn_extra.h:843
System controller processor select.
Definition: spinn_extra.h:1464
Timer control register.
Definition: spinn_extra.h:244
VIC individual vector control.
Definition: spinn_extra.h:206
Router error/dump header.
Definition: spinn_extra.h:777
The control byte of a SpiNNaker packet.
Definition: spinn_extra.h:539
Mask describing interrupts that can be selected.
Definition: spinn_extra.h:105
Wait for interrupt.
static void wait_for_interrupt(void)
Wait for any interrupt to occur.
Definition: wfi.h:32