1 /*
2  * FreeRTOS Kernel V11.1.0
3  * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4  *
5  * SPDX-License-Identifier: MIT
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy of
8  * this software and associated documentation files (the "Software"), to deal in
9  * the Software without restriction, including without limitation the rights to
10  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11  * the Software, and to permit persons to whom the Software is furnished to do so,
12  * subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in all
15  * copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * https://www.FreeRTOS.org
25  * https://github.com/FreeRTOS
26  *
27  */
28 
29 typedef void TCB_t;
30 extern volatile TCB_t * volatile pxCurrentTCB;
31 extern void vTaskSwitchContext( void );
32 
33 /*
34  * Saves the stack pointer for one task into its TCB, calls
35  * vTaskSwitchContext() to update the TCB being used, then restores the stack
36  * from the new TCB read to run the task.
37  */
38 void portSWITCH_CONTEXT( void );
39 
40 /*
41  * Load the stack pointer from the TCB of the task which is going to be first
42  * to execute.  Then force an IRET so the registers and IP are popped off the
43  * stack.
44  */
45 void portFIRST_CONTEXT( void );
46 
47 #define portSWITCH_CONTEXT()                                         \
48                         asm { mov   ax, seg pxCurrentTCB        } \
49                             asm { mov   ds, ax                      }  \
50                             asm { les   bx, pxCurrentTCB            }   /* Save the stack pointer into the TCB. */    \
51                             asm { mov   es:0x2[ bx ], ss            }   \
52                             asm { mov   es:[ bx ], sp               }   \
53                             asm { call  far ptr vTaskSwitchContext  }   /* Perform the switch. */   \
54                             asm { mov   ax, seg pxCurrentTCB        }   /* Restore the stack pointer from the TCB. */  \
55                             asm { mov   ds, ax                      }   \
56                             asm { les   bx, dword ptr pxCurrentTCB  }   \
57                             asm { mov   ss, es:[ bx + 2 ]           }      \
58                             asm { mov   sp, es:[ bx ]               }
59 
60 #define portFIRST_CONTEXT()                                             \
61                             asm { mov   ax, seg pxCurrentTCB        }   \
62                             asm { mov   ds, ax                      }   \
63                             asm { les   bx, dword ptr pxCurrentTCB  }   \
64                             asm { mov   ss, es:[ bx + 2 ]           }   \
65                             asm { mov   sp, es:[ bx ]               }   \
66                             asm { pop   bp                          }   \
67                             asm { pop   di                          }   \
68                             asm { pop   si                          }   \
69                             asm { pop   ds                          }   \
70                             asm { pop   es                          }   \
71                             asm { pop   dx                          }   \
72                             asm { pop   cx                          }   \
73                             asm { pop   bx                          }   \
74                             asm { pop   ax                          }   \
75                             asm { iret                              }
76