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 #ifndef PORT_ASM_H
30 #define PORT_ASM_H
31 
32 typedef void TCB_t;
33 extern volatile TCB_t * volatile pxCurrentTCB;
34 extern void vTaskSwitchContext( void );
35 
36 /*
37  * Saves the stack pointer for one task into its TCB, calls
38  * vTaskSwitchContext() to update the TCB being used, then restores the stack
39  * from the new TCB read to run the task.
40  */
41 void portSWITCH_CONTEXT( void );
42 
43 /*
44  * Load the stack pointer from the TCB of the task which is going to be first
45  * to execute.  Then force an IRET so the registers and IP are popped off the
46  * stack.
47  */
48 void portFIRST_CONTEXT( void );
49 
50 /* There are slightly different versions depending on whether you are building
51 to include debugger information.  If debugger information is used then there
52 are a couple of extra bytes left of the ISR stack (presumably for use by the
53 debugger).  The true stack pointer is then stored in the bp register.  We add
54 2 to the stack pointer to remove the extra bytes before we restore our context. */
55 
56 #define portSWITCH_CONTEXT()                                            \
57                             asm { mov   ax, seg pxCurrentTCB        }   \
58                             asm { mov   ds, ax                      }   \
59                             asm { les   bx, pxCurrentTCB            }   /* Save the stack pointer into the TCB. */      \
60                             asm { mov   es:0x2[ bx ], ss            }   \
61                             asm { mov   es:[ bx ], sp               }   \
62                             asm { call  far ptr vTaskSwitchContext  }   /* Perform the switch. */                       \
63                             asm { mov   ax, seg pxCurrentTCB        }   /* Restore the stack pointer from the TCB. */   \
64                             asm { mov   ds, ax                      }   \
65                             asm { les   bx, dword ptr pxCurrentTCB  }   \
66                             asm { mov   ss, es:[ bx + 2 ]           }   \
67                             asm { mov   sp, es:[ bx ]               }
68 
69 #define portFIRST_CONTEXT()                                             \
70                             __asm { mov ax, seg pxCurrentTCB        }   \
71                             __asm { mov ds, ax                      }   \
72                             __asm { les bx, dword ptr pxCurrentTCB  }   \
73                             __asm { mov ss, es:[ bx + 2 ]           }   \
74                             __asm { mov sp, es:[ bx ]               }   \
75                             __asm { pop bp                          }   \
76                             __asm { pop di                          }   \
77                             __asm { pop si                          }   \
78                             __asm { pop ds                          }   \
79                             __asm { pop es                          }   \
80                             __asm { pop dx                          }   \
81                             __asm { pop cx                          }   \
82                             __asm { pop bx                          }   \
83                             __asm { pop ax                          }   \
84                             __asm { iret                            }
85 
86 
87 #endif
88