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