1 /**************************************************************************/
2 /* */
3 /* Copyright (c) Microsoft Corporation. All rights reserved. */
4 /* */
5 /* This software is licensed under the Microsoft Software License */
6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */
7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
8 /* and in the root directory of this software. */
9 /* */
10 /**************************************************************************/
11
12
13 /**************************************************************************/
14 /**************************************************************************/
15 /** */
16 /** ThreadX Component */
17 /** */
18 /** ThreadX/GHS Event Log (EL) */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23 #define TX_SOURCE_CODE
24 #define TX_EL_SOURCE_CODE
25
26
27 /* Include necessary system files. */
28
29 #include "tx_api.h"
30 #include "tx_el.h"
31 #include "string.h"
32
33
34 /* Define global variables used to manage the event pool. */
35
36 UCHAR *_tx_el_tni_start;
37 UCHAR **_tx_el_current_event;
38 UCHAR *_tx_el_event_area_start;
39 UCHAR *_tx_el_event_area_end;
40 UINT _tx_el_maximum_events;
41 ULONG _tx_el_total_events;
42 UINT _tx_el_event_filter;
43 ULONG _tx_el_time_base_upper;
44 ULONG _tx_el_time_base_lower;
45
46 extern char __ghsbegin_eventlog[];
47 extern char __ghsend_eventlog[];
48
49 extern TX_THREAD *_tx_thread_current_ptr;
50 UINT _tx_thread_interrupt_control(UINT new_posture);
51
52
53 /**************************************************************************/
54 /* */
55 /* FUNCTION RELEASE */
56 /* */
57 /* _tx_el_initialize PORTABLE C */
58 /* 6.1 */
59 /* AUTHOR */
60 /* */
61 /* William E. Lamie, Microsoft Corporation */
62 /* */
63 /* DESCRIPTION */
64 /* */
65 /* This function creates the Event Log (in the format dictated by the */
66 /* GHS Event Analyzer) and sets up various information for subsequent */
67 /* operation. The start and end of the Event Log is determined by the */
68 /* .eventlog section in the linker control file. */
69 /* */
70 /* INPUT */
71 /* */
72 /* None */
73 /* */
74 /* OUTPUT */
75 /* */
76 /* None */
77 /* */
78 /* CALLS */
79 /* */
80 /* None */
81 /* */
82 /* CALLED BY */
83 /* */
84 /* Application Code */
85 /* */
86 /* RELEASE HISTORY */
87 /* */
88 /* DATE NAME DESCRIPTION */
89 /* */
90 /* 09-30-2020 William E. Lamie Initial Version 6.1 */
91 /* */
92 /**************************************************************************/
_tx_el_initialize(VOID)93 VOID _tx_el_initialize(VOID)
94 {
95
96 UCHAR *work_ptr;
97 UCHAR *read_ptr;
98 ULONG event_log_size;
99 UCHAR *end_ptr;
100 UINT i;
101
102
103 /* Clear total event counter. */
104 _tx_el_total_events = 0;
105
106 /* Clear event filter. */
107 _tx_el_event_filter = 0;
108
109 /* First, pickup the starting and ending address of the Event Log memory. */
110 work_ptr = (unsigned char *) __ghsbegin_eventlog;
111 end_ptr = (unsigned char *) __ghsend_eventlog;
112
113 /* Calculate the event log size. */
114 event_log_size = end_ptr - work_ptr;
115
116 /* Subtract off the number of bytes in the header and the TNI area. */
117 event_log_size = event_log_size - (TX_EL_HEADER_SIZE +
118 (TX_EL_TNI_ENTRY_SIZE * TX_EL_TNIS));
119
120 /* Make sure the event log is evenly divisible by the event size. */
121 event_log_size = (event_log_size/TX_EL_EVENT_SIZE) * TX_EL_EVENT_SIZE;
122
123 /* Build the Event Log header. */
124
125 /* Setup the Event Log Version ID. */
126 *((unsigned short *) work_ptr) = (unsigned short) TX_EL_VERSION_ID;
127 work_ptr = work_ptr + sizeof(unsigned short);
128
129 /* Setup the TNIS (number of thread names) field. */
130 *((unsigned short *) work_ptr) = (unsigned short) TX_EL_TNIS;
131 work_ptr = work_ptr + sizeof(unsigned short);
132
133 /* Setup the EVPS (event pool size) field. */
134 *((ULONG *) work_ptr) = event_log_size;
135 work_ptr = work_ptr + sizeof(ULONG);
136
137 /* Remember the maximum number of events. */
138 _tx_el_maximum_events = event_log_size/TX_EL_EVENT_SIZE;
139
140 /* Setup max_events field. */
141 *((ULONG *) work_ptr) = _tx_el_maximum_events;
142 work_ptr = work_ptr + sizeof(ULONG);
143
144 /* Setup the evploc (location of event pool). */
145 *((ULONG *) work_ptr) = (ULONG) (((ULONG) __ghsbegin_eventlog) + TX_EL_HEADER_SIZE +
146 (TX_EL_TNIS * TX_EL_TNI_ENTRY_SIZE));
147 work_ptr = work_ptr + sizeof(ULONG);
148
149 /* Save the current event pointer. */
150 _tx_el_current_event = (UCHAR **) work_ptr;
151
152 /* Setup event_ptr (pointer to oldest event) field to the start
153 of the event pool. */
154 *_tx_el_current_event = (UCHAR *) (((ULONG) __ghsbegin_eventlog) + TX_EL_HEADER_SIZE +
155 (TX_EL_TNIS * TX_EL_TNI_ENTRY_SIZE));
156 work_ptr = work_ptr + sizeof(ULONG);
157
158 /* Setup tbfreq (the number of ticks in a second) field. */
159 *((ULONG *) work_ptr) = TX_EL_TICKS_PER_SECOND;
160 work_ptr = work_ptr + sizeof(ULONG);
161
162 /* At this point we are pointing at the Thread Name Information (TNI) array. */
163
164 /* Remember the start of this for future updates. */
165 _tx_el_tni_start = work_ptr;
166
167 /* Clear the entire TNI array, this is the initial setting. */
168 end_ptr = work_ptr + (TX_EL_TNIS * TX_EL_TNI_ENTRY_SIZE);
169 memset((void *)work_ptr, 0, (TX_EL_TNIS * TX_EL_TNI_ENTRY_SIZE));
170 work_ptr = end_ptr;
171
172 /* At this point, we are pointing at the actual Event Entry area. */
173
174 /* Remember the start of the actual event log area. */
175 _tx_el_event_area_start = work_ptr;
176
177 /* Clear the entire Event area. */
178 end_ptr = work_ptr + event_log_size;
179 memset((void *)work_ptr, 0, event_log_size);
180 work_ptr = end_ptr;
181
182 /* Save the end pointer for later use. */
183 _tx_el_event_area_end = work_ptr;
184
185 /* Setup an entry to resolve all activities from initialization and from
186 an idle system. */
187 work_ptr = _tx_el_tni_start;
188 read_ptr = (UCHAR *) "Initialization/System Idle";
189 i = 0;
190 while ((i < TX_EL_TNI_NAME_SIZE) && (*read_ptr))
191 {
192
193 /* Copy a character of thread's name into TNI area of log. */
194 *work_ptr++ = *read_ptr++;
195
196 /* Increment the character count. */
197 i++;
198 }
199
200 /* Determine if a NULL needs to be inserted. */
201 if (i < TX_EL_TNI_NAME_SIZE)
202 {
203
204 /* Yes, insert a NULL into the event log string. */
205 *work_ptr = (unsigned char) 0;
206 }
207
208 /* Setup the thread ID to NULL. */
209 *((ULONG *) (_tx_el_tni_start + TX_EL_TNI_THREAD_ID_OFFSET)) = (ULONG) TX_NULL;
210
211 /* Set the valid field to indicate the entry is complete. */
212 *((UCHAR *) (_tx_el_tni_start + TX_EL_TNI_VALID_OFFSET)) = (ULONG) TX_EL_VALID_ENTRY;
213
214 /* Clear the time base global variables. */
215 _tx_el_time_base_upper = 0;
216 _tx_el_time_base_lower = 0;
217 }
218
219
220 /**************************************************************************/
221 /* */
222 /* FUNCTION RELEASE */
223 /* */
224 /* _tx_el_thread_register PORTABLE C */
225 /* 6.1 */
226 /* AUTHOR */
227 /* */
228 /* William E. Lamie, Microsoft Corporation */
229 /* */
230 /* DESCRIPTION */
231 /* */
232 /* This function registers a thread in the event log for future */
233 /* display purposes. */
234 /* */
235 /* INPUT */
236 /* */
237 /* thread_ptr Pointer to thread control block */
238 /* */
239 /* OUTPUT */
240 /* */
241 /* TX_SUCCESS Thread was placed in TNI area */
242 /* TX_ERROR No more room in the TNI area */
243 /* */
244 /* CALLS */
245 /* */
246 /* None */
247 /* */
248 /* CALLED BY */
249 /* */
250 /* _tx_thread_create ThreadX thread create function */
251 /* */
252 /* RELEASE HISTORY */
253 /* */
254 /* DATE NAME DESCRIPTION */
255 /* */
256 /* 09-30-2020 William E. Lamie Initial Version 6.1 */
257 /* */
258 /**************************************************************************/
_tx_el_thread_register(TX_THREAD * thread_ptr)259 UINT _tx_el_thread_register(TX_THREAD *thread_ptr)
260 {
261
262 UCHAR *entry_ptr;
263 UCHAR *work_ptr;
264 UCHAR *read_ptr;
265 UINT i;
266
267
268 /* First of all, search for a free slot in the TNI area. */
269 entry_ptr = _tx_el_tni_start;
270 i = 0;
271 while (i < TX_EL_TNIS)
272 {
273
274 /* Determine if this entry is available. */
275 if (*(entry_ptr + TX_EL_TNI_VALID_OFFSET) == TX_EL_INVALID_ENTRY)
276 break;
277
278 /* Otherwise, increment the associated pointers and indices. */
279 i++;
280 entry_ptr = entry_ptr + TX_EL_TNI_ENTRY_SIZE;
281 }
282
283 /* Check to see if there were no more valid entries. */
284 if (i >= TX_EL_TNIS)
285 return(TX_EL_NO_MORE_TNI_ROOM);
286
287 /* Otherwise, we have room in the TNI and a valid record. */
288
289 /* Setup the thread's name. */
290 work_ptr = entry_ptr;
291 read_ptr = (UCHAR *) thread_ptr -> tx_thread_name;
292 i = 0;
293 while ((i < TX_EL_TNI_NAME_SIZE) && (*read_ptr))
294 {
295
296 /* Copy a character of thread's name into TNI area of log. */
297 *work_ptr++ = *read_ptr++;
298
299 /* Increment the character count. */
300 i++;
301 }
302
303 /* Determine if a NULL needs to be inserted. */
304 if (i < TX_EL_TNI_NAME_SIZE)
305 {
306
307 /* Yes, insert a NULL into the event log string. */
308 *work_ptr = (unsigned char) 0;
309 }
310
311 /* Setup the thread ID. */
312 *((ULONG *) (entry_ptr + TX_EL_TNI_THREAD_ID_OFFSET)) = (ULONG) thread_ptr;
313
314 /* Setup the thread priority. */
315 *((ULONG *) (entry_ptr + TX_EL_TNI_THREAD_PRIORITY_OFF)) = (ULONG) thread_ptr -> tx_thread_priority;
316
317 /* Set the valid field to indicate the entry is complete. */
318 *((UCHAR *) (entry_ptr + TX_EL_TNI_VALID_OFFSET)) = (ULONG) TX_EL_VALID_ENTRY;
319
320 /* Thread name has been registered. */
321 return(TX_SUCCESS);
322 }
323
324
325 /**************************************************************************/
326 /* */
327 /* FUNCTION RELEASE */
328 /* */
329 /* _tx_el_thread_unregister PORTABLE C */
330 /* 6.1 */
331 /* AUTHOR */
332 /* */
333 /* William E. Lamie, Microsoft Corporation */
334 /* */
335 /* DESCRIPTION */
336 /* */
337 /* This function unregisters a thread in the event log for future */
338 /* display purposes. */
339 /* */
340 /* INPUT */
341 /* */
342 /* thread_ptr Pointer to thread control block */
343 /* */
344 /* OUTPUT */
345 /* */
346 /* TX_SUCCESS Thread was placed in TNI area */
347 /* TX_ERROR No more room in the TNI area */
348 /* */
349 /* CALLS */
350 /* */
351 /* None */
352 /* */
353 /* CALLED BY */
354 /* */
355 /* _tx_thread_create ThreadX thread create function */
356 /* */
357 /* RELEASE HISTORY */
358 /* */
359 /* DATE NAME DESCRIPTION */
360 /* */
361 /* 09-30-2020 William E. Lamie Initial Version 6.1 */
362 /* */
363 /**************************************************************************/
_tx_el_thread_unregister(TX_THREAD * thread_ptr)364 UINT _tx_el_thread_unregister(TX_THREAD *thread_ptr)
365 {
366
367 UCHAR *entry_ptr;
368 UCHAR *work_ptr;
369 UCHAR *read_ptr;
370 UINT found;
371 UINT i, j;
372
373
374 /* First of all, search for a match in the TNI area. */
375 entry_ptr = _tx_el_tni_start;
376 i = 0;
377 while (i < TX_EL_TNIS)
378 {
379
380 /* Determine if this entry is a match. */
381 work_ptr = entry_ptr;
382 read_ptr = (UCHAR *) thread_ptr -> tx_thread_name;
383 found = TX_TRUE;
384 j = 0;
385 do
386 {
387
388 /* Determine if this character is the same. */
389 if (*work_ptr != *read_ptr)
390 {
391
392 /* Set found to false and fall out of the loop. */
393 found = TX_FALSE;
394 break;
395 }
396 else if (*work_ptr == 0)
397 {
398
399 /* Null terminated, just break the loop. */
400 break;
401 }
402 else
403 {
404
405 /* Copy a character of thread's name into TNI area of log. */
406 *work_ptr++ = *read_ptr++;
407 }
408
409 /* Increment the character count. */
410 j++;
411
412 } while(j < TX_EL_TNIS);
413
414
415 /* Was a match found? */
416 if (found)
417 {
418
419 /* Yes, mark the entry as available now. */
420 *(entry_ptr + TX_EL_TNI_VALID_OFFSET) = TX_EL_INVALID_ENTRY;
421
422 /* Get out of the loop! */
423 break;
424 }
425
426 /* Otherwise, increment the associated pointers and indices. */
427 i++;
428 entry_ptr = entry_ptr + TX_EL_TNI_ENTRY_SIZE;
429 }
430
431 /* Determine status to return. */
432 if (found)
433 return(TX_SUCCESS);
434 else
435 return(TX_EL_NAME_NOT_FOUND);
436 }
437
438
439 /**************************************************************************/
440 /* */
441 /* FUNCTION RELEASE */
442 /* */
443 /* _tx_el_user_event_insert PORTABLE C */
444 /* 6.1 */
445 /* AUTHOR */
446 /* */
447 /* William E. Lamie, Microsoft Corporation */
448 /* */
449 /* DESCRIPTION */
450 /* */
451 /* This function inserts a user event into the event log. */
452 /* If the event log is full, the oldest event is overwritten. */
453 /* */
454 /* INPUT */
455 /* */
456 /* sub_type Event subtype for kernel call */
457 /* info_1 First information field */
458 /* info_2 Second information field */
459 /* info_3 Third information field */
460 /* info_4 Fourth information field */
461 /* */
462 /* OUTPUT */
463 /* */
464 /* None */
465 /* */
466 /* CALLS */
467 /* */
468 /* None */
469 /* */
470 /* CALLED BY */
471 /* */
472 /* ThreadX services */
473 /* */
474 /* RELEASE HISTORY */
475 /* */
476 /* DATE NAME DESCRIPTION */
477 /* */
478 /* 09-30-2020 William E. Lamie Initial Version 6.1 */
479 /* */
480 /**************************************************************************/
_tx_el_user_event_insert(UINT sub_type,ULONG info_1,ULONG info_2,ULONG info_3,ULONG info_4)481 VOID _tx_el_user_event_insert(UINT sub_type, ULONG info_1, ULONG info_2,
482 ULONG info_3, ULONG info_4)
483 {
484
485 TX_INTERRUPT_SAVE_AREA
486
487 UINT upper_tb;
488 UCHAR *entry_ptr;
489
490 /* Disable interrupts. */
491 TX_DISABLE
492
493 /* Increment total event counter. */
494 _tx_el_total_events++;
495
496 /* Setup working entry pointer first. */
497 entry_ptr = *_tx_el_current_event;
498
499 /* Store the event type. */
500 *((unsigned short *) entry_ptr) = (unsigned short) TX_EL_USER_EVENT;
501
502 /* Store the event subtype. */
503 *((unsigned short *) (entry_ptr + TX_EL_EVENT_SUBTYPE_OFFSET)) =
504 (unsigned short) sub_type;
505
506 /* Get time stamp. */
507 do
508 {
509
510 /* Pickup the upper tb. */
511 upper_tb = (ULONG) read_tbu();
512
513 /* Store the upper time stamp. */
514 *((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_UPPER_OFFSET)) =
515 (ULONG) upper_tb;
516
517 /* Store the lower time stamp. */
518 *((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_LOWER_OFFSET)) =
519 (ULONG) read_tbl();
520 } while (upper_tb != (ULONG) read_tbu());
521
522 /* Store the current thread. */
523 *((ULONG *) (entry_ptr + TX_EL_EVENT_THREAD_OFFSET)) =
524 (ULONG) _tx_thread_current_ptr;
525
526 /* Store the first info field. */
527 *((ULONG *) (entry_ptr + TX_EL_EVENT_INFO_1_OFFSET)) =
528 (ULONG) info_1;
529
530 /* Store the second info field. */
531 *((ULONG *) (entry_ptr + TX_EL_EVENT_INFO_2_OFFSET)) =
532 (ULONG) info_2;
533
534 /* Store the third info field. */
535 *((ULONG *) (entry_ptr + TX_EL_EVENT_INFO_3_OFFSET)) =
536 (ULONG) info_3;
537
538 /* Store the fourth info field. */
539 *((ULONG *) (entry_ptr + TX_EL_EVENT_INFO_4_OFFSET)) =
540 (ULONG) info_4;
541
542 /* Now move the current event log pointer. */
543 entry_ptr = entry_ptr + TX_EL_EVENT_SIZE;
544
545 /* Check for a wraparound condition. */
546 if (entry_ptr >= _tx_el_event_area_end)
547 {
548
549 /* Yes, we have wrapped around to the end of the event area.
550 Start back at the top! */
551 entry_ptr = _tx_el_event_area_start;
552 }
553
554 /* Write the entry pointer back into the header. */
555 *_tx_el_current_event = entry_ptr;
556
557 /* Restore interrupts. */
558 TX_RESTORE
559 }
560
561
562 /**************************************************************************/
563 /* */
564 /* FUNCTION RELEASE */
565 /* */
566 /* _tx_el_thread_running PORTABLE C */
567 /* 6.1 */
568 /* AUTHOR */
569 /* */
570 /* William E. Lamie, Microsoft Corporation */
571 /* */
572 /* DESCRIPTION */
573 /* */
574 /* This function inserts a thread change event into the event */
575 /* log, which indicates that a context switch is taking place. */
576 /* If the event log is full, the oldest event is overwritten. */
577 /* */
578 /* INPUT */
579 /* */
580 /* thread_ptr Pointer to thread being */
581 /* scheduled */
582 /* */
583 /* OUTPUT */
584 /* */
585 /* None */
586 /* */
587 /* CALLS */
588 /* */
589 /* None */
590 /* */
591 /* CALLED BY */
592 /* */
593 /* _tx_thread_schedule ThreadX scheduler */
594 /* */
595 /* RELEASE HISTORY */
596 /* */
597 /* DATE NAME DESCRIPTION */
598 /* */
599 /* 09-30-2020 William E. Lamie Initial Version 6.1 */
600 /* */
601 /**************************************************************************/
_tx_el_thread_running(TX_THREAD * thread_ptr)602 VOID _tx_el_thread_running(TX_THREAD *thread_ptr)
603 {
604
605 UINT upper_tb;
606 UCHAR *entry_ptr;
607
608 TX_EL_NO_STATUS_EVENTS
609
610 /* Increment total event counter. */
611 _tx_el_total_events++;
612
613 /* Setup working entry pointer first. */
614 entry_ptr = *_tx_el_current_event;
615
616 /* Store the event type. */
617 *((unsigned short *) entry_ptr) = (unsigned short) TX_EL_THREAD_CHANGE;
618
619 /* Store the event subtype. */
620 *((unsigned short *) (entry_ptr + TX_EL_EVENT_SUBTYPE_OFFSET)) =
621 (unsigned short) 0;
622
623 /* Get time stamp. */
624 do
625 {
626
627 /* Pickup the upper tb. */
628 upper_tb = (ULONG) read_tbu();
629
630 /* Store the upper time stamp. */
631 *((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_UPPER_OFFSET)) =
632 (ULONG) upper_tb;
633
634 /* Store the lower time stamp. */
635 *((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_LOWER_OFFSET)) =
636 (ULONG) read_tbl();
637 } while (upper_tb != (ULONG) read_tbu());
638
639 /* Store the current thread. */
640 *((ULONG *) (entry_ptr + TX_EL_EVENT_THREAD_OFFSET)) =
641 (ULONG) thread_ptr;
642
643 /* Now move the current event log pointer. */
644 entry_ptr = entry_ptr + TX_EL_EVENT_SIZE;
645
646 /* Check for a wraparound condition. */
647 if (entry_ptr >= _tx_el_event_area_end)
648 {
649
650 /* Yes, we have wrapped around to the end of the event area.
651 Start back at the top! */
652 entry_ptr = _tx_el_event_area_start;
653 }
654
655 /* Write the entry pointer back into the header. */
656 *_tx_el_current_event = entry_ptr;
657
658 TX_EL_END_FILTER
659 }
660
661
662 /**************************************************************************/
663 /* */
664 /* FUNCTION RELEASE */
665 /* */
666 /* _tx_el_thread_preempted PORTABLE C */
667 /* 6.1 */
668 /* AUTHOR */
669 /* */
670 /* William E. Lamie, Microsoft Corporation */
671 /* */
672 /* DESCRIPTION */
673 /* */
674 /* This function inserts a thread preempted event into the event */
675 /* log, which indicates that an interrupt occurred that made a higher */
676 /* priority thread ready for execution. In this case, the previously */
677 /* executing thread has an event entered to indicate it is no longer */
678 /* running. */
679 /* */
680 /* INPUT */
681 /* */
682 /* thread_ptr Pointer to thread being */
683 /* scheduled */
684 /* */
685 /* OUTPUT */
686 /* */
687 /* None */
688 /* */
689 /* CALLS */
690 /* */
691 /* None */
692 /* */
693 /* CALLED BY */
694 /* */
695 /* _tx_thread_context_restore ThreadX context restore */
696 /* */
697 /* RELEASE HISTORY */
698 /* */
699 /* DATE NAME DESCRIPTION */
700 /* */
701 /* 09-30-2020 William E. Lamie Initial Version 6.1 */
702 /* */
703 /**************************************************************************/
_tx_el_thread_preempted(TX_THREAD * thread_ptr)704 VOID _tx_el_thread_preempted(TX_THREAD *thread_ptr)
705 {
706
707 UINT upper_tb;
708 UCHAR *entry_ptr;
709
710
711 TX_EL_NO_STATUS_EVENTS
712
713 /* Increment total event counter. */
714 _tx_el_total_events++;
715
716 /* Setup working entry pointer first. */
717 entry_ptr = *_tx_el_current_event;
718
719 /* Store the event type. */
720 *((unsigned short *) entry_ptr) = (unsigned short) TX_EL_THREAD_STATUS_CHANGE;
721
722 /* Store the event subtype. */
723 *((unsigned short *) (entry_ptr + TX_EL_EVENT_SUBTYPE_OFFSET)) =
724 (unsigned short) TX_READY;
725
726 /* Get time stamp. */
727 do
728 {
729
730 /* Pickup the upper tb. */
731 upper_tb = (ULONG) read_tbu();
732
733 /* Store the upper time stamp. */
734 *((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_UPPER_OFFSET)) =
735 (ULONG) upper_tb;
736
737 /* Store the lower time stamp. */
738 *((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_LOWER_OFFSET)) =
739 (ULONG) read_tbl();
740 } while (upper_tb != (ULONG) read_tbu());
741
742 /* Store the current thread. */
743 *((ULONG *) (entry_ptr + TX_EL_EVENT_THREAD_OFFSET)) =
744 (ULONG) _tx_thread_current_ptr;
745
746 /* Now move the current event log pointer. */
747 entry_ptr = entry_ptr + TX_EL_EVENT_SIZE;
748
749 /* Check for a wraparound condition. */
750 if (entry_ptr >= _tx_el_event_area_end)
751 {
752
753 /* Yes, we have wrapped around to the end of the event area.
754 Start back at the top! */
755 entry_ptr = _tx_el_event_area_start;
756 }
757
758 /* Write the entry pointer back into the header. */
759 *_tx_el_current_event = entry_ptr;
760
761 TX_EL_END_FILTER
762 }
763
764
765 /**************************************************************************/
766 /* */
767 /* FUNCTION RELEASE */
768 /* */
769 /* _tx_el_interrupt PORTABLE C */
770 /* 6.1 */
771 /* AUTHOR */
772 /* */
773 /* William E. Lamie, Microsoft Corporation */
774 /* */
775 /* DESCRIPTION */
776 /* */
777 /* This function inserts an interrupt event into the log, which */
778 /* indicates the start of interrupt processing for the specific */
779 /* */
780 /* INPUT */
781 /* */
782 /* interrupt_number Interrupt number supplied by */
783 /* ISR */
784 /* */
785 /* OUTPUT */
786 /* */
787 /* None */
788 /* */
789 /* CALLS */
790 /* */
791 /* None */
792 /* */
793 /* CALLED BY */
794 /* */
795 /* ISR processing */
796 /* */
797 /* RELEASE HISTORY */
798 /* */
799 /* DATE NAME DESCRIPTION */
800 /* */
801 /* 09-30-2020 William E. Lamie Initial Version 6.1 */
802 /* */
803 /**************************************************************************/
_tx_el_interrupt(UINT interrupt_number)804 VOID _tx_el_interrupt(UINT interrupt_number)
805 {
806
807 UINT upper_tb;
808 UCHAR *entry_ptr;
809
810
811 TX_EL_NO_INTERRUPT_EVENTS
812
813 /* Increment total event counter. */
814 _tx_el_total_events++;
815
816 /* Setup working entry pointer first. */
817 entry_ptr = *_tx_el_current_event;
818
819 /* Store the event type. */
820 *((unsigned short *) entry_ptr) = (unsigned short) TX_EL_INTERRUPT;
821
822 /* Store the event subtype. */
823 *((unsigned short *) (entry_ptr + TX_EL_EVENT_SUBTYPE_OFFSET)) =
824 (unsigned short) TX_EL_INTERRUPT_SUB_TYPE;
825
826 /* Get time stamp. */
827 do
828 {
829
830 /* Pickup the upper tb. */
831 upper_tb = (ULONG) read_tbu();
832
833 /* Store the upper time stamp. */
834 *((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_UPPER_OFFSET)) =
835 (ULONG) upper_tb;
836
837 /* Store the lower time stamp. */
838 *((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_LOWER_OFFSET)) =
839 (ULONG) read_tbl();
840 } while (upper_tb != (ULONG) read_tbu());
841
842 /* Store the current thread. */
843 *((ULONG *) (entry_ptr + TX_EL_EVENT_THREAD_OFFSET)) =
844 (ULONG) _tx_thread_current_ptr;
845
846 /* Store the first info word. */
847 *((ULONG *) (entry_ptr + TX_EL_EVENT_INFO_1_OFFSET)) =
848 (ULONG) interrupt_number;
849
850 /* Now move the current event log pointer. */
851 entry_ptr = entry_ptr + TX_EL_EVENT_SIZE;
852
853 /* Check for a wraparound condition. */
854 if (entry_ptr >= _tx_el_event_area_end)
855 {
856
857 /* Yes, we have wrapped around to the end of the event area.
858 Start back at the top! */
859 entry_ptr = _tx_el_event_area_start;
860 }
861
862 /* Write the entry pointer back into the header. */
863 *_tx_el_current_event = entry_ptr;
864
865 TX_EL_END_FILTER
866 }
867
868
869 /**************************************************************************/
870 /* */
871 /* FUNCTION RELEASE */
872 /* */
873 /* _tx_el_interrupt_end PORTABLE C */
874 /* 6.1 */
875 /* AUTHOR */
876 /* */
877 /* William E. Lamie, Microsoft Corporation */
878 /* */
879 /* DESCRIPTION */
880 /* */
881 /* This function inserts an interrupt end event into the log, which */
882 /* indicates the end of interrupt processing for the specific */
883 /* */
884 /* INPUT */
885 /* */
886 /* interrupt_number Interrupt number supplied by */
887 /* ISR */
888 /* */
889 /* OUTPUT */
890 /* */
891 /* None */
892 /* */
893 /* CALLS */
894 /* */
895 /* None */
896 /* */
897 /* CALLED BY */
898 /* */
899 /* ISR processing */
900 /* */
901 /* RELEASE HISTORY */
902 /* */
903 /* DATE NAME DESCRIPTION */
904 /* */
905 /* 09-30-2020 William E. Lamie Initial Version 6.1 */
906 /* */
907 /**************************************************************************/
_tx_el_interrupt_end(UINT interrupt_number)908 VOID _tx_el_interrupt_end(UINT interrupt_number)
909 {
910
911 UINT upper_tb;
912 UCHAR *entry_ptr;
913
914
915 TX_EL_NO_INTERRUPT_EVENTS
916
917 /* Increment total event counter. */
918 _tx_el_total_events++;
919
920 /* Setup working entry pointer first. */
921 entry_ptr = *_tx_el_current_event;
922
923 /* Store the event type. */
924 *((unsigned short *) entry_ptr) = (unsigned short) TX_EL_INTERRUPT;
925
926 /* Store the event subtype. */
927 *((unsigned short *) (entry_ptr + TX_EL_EVENT_SUBTYPE_OFFSET)) =
928 (unsigned short) TX_EL_END_OF_INTERRUPT;
929
930 /* Get time stamp. */
931 do
932 {
933
934 /* Pickup the upper tb. */
935 upper_tb = (ULONG) read_tbu();
936
937 /* Store the upper time stamp. */
938 *((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_UPPER_OFFSET)) =
939 (ULONG) upper_tb;
940
941 /* Store the lower time stamp. */
942 *((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_LOWER_OFFSET)) =
943 (ULONG) read_tbl();
944 } while (upper_tb != (ULONG) read_tbu());
945
946 /* Store the current thread. */
947 *((ULONG *) (entry_ptr + TX_EL_EVENT_THREAD_OFFSET)) =
948 (ULONG) _tx_thread_current_ptr;
949
950 /* Store the first info word. */
951 *((ULONG *) (entry_ptr + TX_EL_EVENT_INFO_1_OFFSET)) =
952 (ULONG) interrupt_number;
953
954 /* Now move the current event log pointer. */
955 entry_ptr = entry_ptr + TX_EL_EVENT_SIZE;
956
957 /* Check for a wraparound condition. */
958 if (entry_ptr >= _tx_el_event_area_end)
959 {
960
961 /* Yes, we have wrapped around to the end of the event area.
962 Start back at the top! */
963 entry_ptr = _tx_el_event_area_start;
964 }
965
966 /* Write the entry pointer back into the header. */
967 *_tx_el_current_event = entry_ptr;
968
969 TX_EL_END_FILTER
970 }
971
972
973 /**************************************************************************/
974 /* */
975 /* FUNCTION RELEASE */
976 /* */
977 /* _tx_el_interrupt_control PORTABLE C */
978 /* 6.1 */
979 /* AUTHOR */
980 /* */
981 /* William E. Lamie, Microsoft Corporation */
982 /* */
983 /* DESCRIPTION */
984 /* */
985 /* This function remaps the tx_interrupt_control service call so that */
986 /* it can be tracked in the event log. */
987 /* */
988 /* INPUT */
989 /* */
990 /* new_posture New interrupt posture */
991 /* */
992 /* OUTPUT */
993 /* */
994 /* old_posture Old interrupt posture */
995 /* */
996 /* CALLS */
997 /* */
998 /* _tx_thread_interrupt_control Interrupt control service */
999 /* */
1000 /* CALLED BY */
1001 /* */
1002 /* ThreadX services */
1003 /* */
1004 /* RELEASE HISTORY */
1005 /* */
1006 /* DATE NAME DESCRIPTION */
1007 /* */
1008 /* 09-30-2020 William E. Lamie Initial Version 6.1 */
1009 /* */
1010 /**************************************************************************/
_tx_el_interrupt_control(UINT new_posture)1011 UINT _tx_el_interrupt_control(UINT new_posture)
1012 {
1013
1014 TX_INTERRUPT_SAVE_AREA
1015 UINT old_posture;
1016
1017
1018 TX_EL_NO_INTERRUPT_EVENTS
1019
1020 TX_DISABLE
1021 TX_EL_KERNEL_CALL_EVENT_INSERT_INFO2(TX_EL_INTERRUPT_CONTROL, _tx_thread_current_ptr, new_posture)
1022 TX_RESTORE
1023
1024 TX_EL_END_FILTER
1025
1026 old_posture = _tx_thread_interrupt_control(new_posture);
1027 return(old_posture);
1028 }
1029
1030
1031 /**************************************************************************/
1032 /* */
1033 /* FUNCTION RELEASE */
1034 /* */
1035 /* _tx_el_event_log_on PORTABLE C */
1036 /* 6.1 */
1037 /* AUTHOR */
1038 /* */
1039 /* William E. Lamie, Microsoft Corporation */
1040 /* */
1041 /* DESCRIPTION */
1042 /* */
1043 /* This function disables all event filters. */
1044 /* */
1045 /* INPUT */
1046 /* */
1047 /* None */
1048 /* */
1049 /* OUTPUT */
1050 /* */
1051 /* None */
1052 /* */
1053 /* CALLS */
1054 /* */
1055 /* None */
1056 /* */
1057 /* CALLED BY */
1058 /* */
1059 /* Application code */
1060 /* */
1061 /* RELEASE HISTORY */
1062 /* */
1063 /* DATE NAME DESCRIPTION */
1064 /* */
1065 /* 09-30-2020 William E. Lamie Initial Version 6.1 */
1066 /* */
1067 /**************************************************************************/
_tx_el_event_log_on(void)1068 VOID _tx_el_event_log_on(void)
1069 {
1070
1071 /* Disable all event filters. */
1072 _tx_el_event_filter = TX_EL_ENABLE_ALL_EVENTS;
1073 }
1074
1075
1076 /**************************************************************************/
1077 /* */
1078 /* FUNCTION RELEASE */
1079 /* */
1080 /* _tx_el_event_log_off PORTABLE C */
1081 /* 6.1 */
1082 /* AUTHOR */
1083 /* */
1084 /* William E. Lamie, Microsoft Corporation */
1085 /* */
1086 /* DESCRIPTION */
1087 /* */
1088 /* This function sets all event filters, thereby turning event */
1089 /* logging off. */
1090 /* */
1091 /* INPUT */
1092 /* */
1093 /* None */
1094 /* */
1095 /* OUTPUT */
1096 /* */
1097 /* None */
1098 /* */
1099 /* CALLS */
1100 /* */
1101 /* None */
1102 /* */
1103 /* CALLED BY */
1104 /* */
1105 /* Application code */
1106 /* */
1107 /* RELEASE HISTORY */
1108 /* */
1109 /* DATE NAME DESCRIPTION */
1110 /* */
1111 /* 09-30-2020 William E. Lamie Initial Version 6.1 */
1112 /* */
1113 /**************************************************************************/
_tx_el_event_log_off(void)1114 VOID _tx_el_event_log_off(void)
1115 {
1116
1117 /* Set all event filters. */
1118 _tx_el_event_filter = TX_EL_FILTER_ALL_EVENTS;
1119 }
1120
1121
1122 /**************************************************************************/
1123 /* */
1124 /* FUNCTION RELEASE */
1125 /* */
1126 /* _tx_el_event_log_set PORTABLE C */
1127 /* 6.1 */
1128 /* AUTHOR */
1129 /* */
1130 /* William E. Lamie, Microsoft Corporation */
1131 /* */
1132 /* DESCRIPTION */
1133 /* */
1134 /* This function sets the events filters specified by the user. */
1135 /* */
1136 /* INPUT */
1137 /* */
1138 /* filter Events to filter */
1139 /* */
1140 /* OUTPUT */
1141 /* */
1142 /* None */
1143 /* */
1144 /* CALLS */
1145 /* */
1146 /* None */
1147 /* */
1148 /* CALLED BY */
1149 /* */
1150 /* Application code */
1151 /* */
1152 /* RELEASE HISTORY */
1153 /* */
1154 /* DATE NAME DESCRIPTION */
1155 /* */
1156 /* 09-30-2020 William E. Lamie Initial Version 6.1 */
1157 /* */
1158 /**************************************************************************/
_tx_el_event_filter_set(UINT filter)1159 VOID _tx_el_event_filter_set(UINT filter)
1160 {
1161
1162 /* Apply the user event filter. */
1163 _tx_el_event_filter = filter;
1164 }
1165
1166