/*\r
- FreeRTOS V8.1.1 - Copyright (C) 2014 Real Time Engineers Ltd.\r
+ FreeRTOS V9.0.0rc2 - Copyright (C) 2016 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS provides completely free yet professionally developed, *\r
- * robust, strictly quality controlled, supported, and cross *\r
- * platform software that has become a de facto standard. *\r
- * *\r
- * Help yourself get started quickly and support the FreeRTOS *\r
- * project by purchasing a FreeRTOS tutorial book, reference *\r
- * manual, or both from: http://www.FreeRTOS.org/Documentation *\r
- * *\r
- * Thank you! *\r
- * *\r
- ***************************************************************************\r
-\r
This file is part of the FreeRTOS distribution.\r
\r
FreeRTOS is free software; you can redistribute it and/or modify it under\r
the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
+ Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.\r
\r
+ ***************************************************************************\r
>>! NOTE: The modification to the GPL is included to allow you to !<<\r
>>! distribute a combined work that includes FreeRTOS without being !<<\r
>>! obliged to provide the source code for proprietary components !<<\r
>>! outside of the FreeRTOS kernel. !<<\r
+ ***************************************************************************\r
\r
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
- FOR A PARTICULAR PURPOSE. Full license text is available from the following\r
+ FOR A PARTICULAR PURPOSE. Full license text is available on the following\r
link: http://www.freertos.org/a00114.html\r
\r
- 1 tab == 4 spaces!\r
-\r
***************************************************************************\r
* *\r
- * Having a problem? Start by reading the FAQ "My application does *\r
- * not run, what could be wrong?" *\r
+ * FreeRTOS provides completely free yet professionally developed, *\r
+ * robust, strictly quality controlled, supported, and cross *\r
+ * platform software that is more than just the market leader, it *\r
+ * is the industry's de facto standard. *\r
* *\r
- * http://www.FreeRTOS.org/FAQHelp.html *\r
+ * Help yourself get started quickly while simultaneously helping *\r
+ * to support the FreeRTOS project by purchasing a FreeRTOS *\r
+ * tutorial book, reference manual, or both: *\r
+ * http://www.FreeRTOS.org/Documentation *\r
* *\r
***************************************************************************\r
\r
- http://www.FreeRTOS.org - Documentation, books, training, latest versions,\r
- license and Real Time Engineers Ltd. contact details.\r
+ http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading\r
+ the FAQ page "My application does not run, what could be wrong?". Have you\r
+ defined configASSERT()?\r
+\r
+ http://www.FreeRTOS.org/support - In return for receiving this top quality\r
+ embedded software for free we request you assist our global community by\r
+ participating in the support forum.\r
+\r
+ http://www.FreeRTOS.org/training - Investing in training allows your team to\r
+ be as productive as possible as early as possible. Now you can receive\r
+ FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
+ Ltd, and the world's leading authority on the world's leading RTOS.\r
\r
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
\r
- http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High\r
- Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS\r
- licenses offer ticketed support, indemnification and middleware.\r
+ http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
+ Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
+\r
+ http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
+ Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS\r
+ licenses offer ticketed support, indemnification and commercial middleware.\r
\r
http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
engineered and independently SIL3 certified version for use in safety and\r
.extern vTaskSwitchContext\r
.extern vPortIncrementTick\r
.extern xISRStackTop\r
+ .extern ulTaskHasFPUContext\r
\r
.global vPortStartFirstTask\r
.global vPortYieldISR\r
.global vPortTickInterruptHandler\r
+ .global vPortInitialiseFPSCR\r
\r
\r
/******************************************************************/\r
.ent vPortYieldISR\r
vPortYieldISR:\r
\r
- /* Make room for the context. First save the current status so it can be\r
- manipulated, and the cause and EPC registers so thier original values are\r
- captured. */\r
- addiu sp, sp, -portCONTEXT_SIZE\r
- mfc0 k1, _CP0_STATUS\r
-\r
- /* Also save s6 and s5 so they can be used. Any nesting interrupts should\r
- maintain the values of these registers across the ISR. */\r
- sw s6, 44(sp)\r
- sw s5, 40(sp)\r
- sw k1, portSTATUS_STACK_LOCATION(sp)\r
-\r
- /* Prepare to re-enabled interrupts above the kernel priority. */\r
- ins k1, zero, 10, 7 /* Clear IPL bits 0:6. */\r
- ins k1, zero, 18, 1 /* Clear IPL bit 7. It would be an error here if this bit were set anyway. */\r
- ori k1, k1, ( configMAX_SYSCALL_INTERRUPT_PRIORITY << 10 )\r
- ins k1, zero, 1, 4 /* Clear EXL, ERL and UM. */\r
-\r
- /* s5 is used as the frame pointer. */\r
- add s5, zero, sp\r
-\r
- /* Swap to the system stack. This is not conditional on the nesting\r
- count as this interrupt is always the lowest priority and therefore\r
- the nesting is always 0. */\r
- la sp, xISRStackTop\r
- lw sp, (sp)\r
-\r
- /* Set the nesting count. */\r
- la k0, uxInterruptNesting\r
- addiu s6, zero, 1\r
- sw s6, 0(k0)\r
-\r
- /* s6 holds the EPC value, this is saved with the rest of the context\r
- after interrupts are enabled. */\r
- mfc0 s6, _CP0_EPC\r
-\r
- /* Re-enable interrupts above configMAX_SYSCALL_INTERRUPT_PRIORITY. */\r
- mtc0 k1, _CP0_STATUS\r
-\r
- /* Save the context into the space just created. s6 is saved again\r
- here as it now contains the EPC value. */\r
- sw ra, 120(s5)\r
- sw s8, 116(s5)\r
- sw t9, 112(s5)\r
- sw t8, 108(s5)\r
- sw t7, 104(s5)\r
- sw t6, 100(s5)\r
- sw t5, 96(s5)\r
- sw t4, 92(s5)\r
- sw t3, 88(s5)\r
- sw t2, 84(s5)\r
- sw t1, 80(s5)\r
- sw t0, 76(s5)\r
- sw a3, 72(s5)\r
- sw a2, 68(s5)\r
- sw a1, 64(s5)\r
- sw a0, 60(s5)\r
- sw v1, 56(s5)\r
- sw v0, 52(s5)\r
- sw s7, 48(s5)\r
- sw s6, portEPC_STACK_LOCATION(s5)\r
- /* s5 and s6 has already been saved. */\r
- sw s4, 36(s5)\r
- sw s3, 32(s5)\r
- sw s2, 28(s5)\r
- sw s1, 24(s5)\r
- sw s0, 20(s5)\r
- sw $1, 16(s5)\r
-\r
- /* s7 is used as a scratch register as this should always be saved across\r
- nesting interrupts. */\r
-\r
- /* Save the AC0, AC1, AC2 and AC3. */\r
- mfhi s7, $ac1\r
- sw s7, 128(s5)\r
- mflo s7, $ac1\r
- sw s7, 124(s5)\r
-\r
- mfhi s7, $ac2\r
- sw s7, 136(s5)\r
- mflo s7, $ac2\r
- sw s7, 132(s5)\r
-\r
- mfhi s7, $ac3\r
- sw s7, 144(s5)\r
- mflo s7, $ac3\r
- sw s7, 140(s5)\r
-\r
- rddsp s7\r
- sw s7, 148(s5)\r
-\r
- mfhi s7, $ac0\r
- sw s7, 12(s5)\r
- mflo s7, $ac0\r
- sw s7, 8(s5)\r
-\r
- /* Save the stack pointer to the task. */\r
- la s7, pxCurrentTCB\r
- lw s7, (s7)\r
- sw s5, (s7)\r
-\r
- /* Set the interrupt mask to the max priority that can use the API. The\r
- yield handler will only be called at configKERNEL_INTERRUPT_PRIORITY which\r
- is below configMAX_SYSCALL_INTERRUPT_PRIORITY - so this can only ever\r
- raise the IPL value and never lower it. */\r
- di\r
- ehb\r
- mfc0 s7, _CP0_STATUS\r
- ins s7, zero, 10, 7\r
- ins s7, zero, 18, 1\r
- ori s6, s7, ( configMAX_SYSCALL_INTERRUPT_PRIORITY << 10 ) | 1\r
-\r
- /* This mtc0 re-enables interrupts, but only above\r
- configMAX_SYSCALL_INTERRUPT_PRIORITY. */\r
- mtc0 s6, _CP0_STATUS\r
- ehb\r
+ #if ( __mips_hard_float == 1 ) && ( configUSE_TASK_FPU_SUPPORT == 1 )\r
+ /* Code sequence for FPU support, the context save requires advance\r
+ knowledge of the stack frame size and if the current task actually uses the \r
+ FPU. */\r
+\r
+ /* Make room for the context. First save the current status so it can be\r
+ manipulated, and the cause and EPC registers so their original values are\r
+ captured. */\r
+ la k0, ulTaskHasFPUContext\r
+ lw k0, 0(k0)\r
+ beq k0, zero, 1f\r
+ addiu sp, sp, -portCONTEXT_SIZE /* always reserve space for the context. */\r
+ addiu sp, sp, -portFPU_CONTEXT_SIZE /* reserve additional space for the FPU context. */\r
+ 1:\r
+ mfc0 k1, _CP0_STATUS\r
+\r
+ /* Also save s6 and s5 so they can be used. Any nesting interrupts should\r
+ maintain the values of these registers across the ISR. */\r
+ sw s6, 44(sp)\r
+ sw s5, 40(sp)\r
+ sw k1, portSTATUS_STACK_LOCATION(sp)\r
+ sw k0, portTASK_HAS_FPU_STACK_LOCATION(sp)\r
+\r
+ /* Prepare to re-enabled interrupts above the kernel priority. */\r
+ ins k1, zero, 10, 7 /* Clear IPL bits 0:6. */\r
+ ins k1, zero, 18, 1 /* Clear IPL bit 7. It would be an error here if this bit were set anyway. */\r
+ ori k1, k1, ( configMAX_SYSCALL_INTERRUPT_PRIORITY << 10 )\r
+ ins k1, zero, 1, 4 /* Clear EXL, ERL and UM. */\r
+\r
+ /* s5 is used as the frame pointer. */\r
+ add s5, zero, sp\r
+\r
+ /* Swap to the system stack. This is not conditional on the nesting\r
+ count as this interrupt is always the lowest priority and therefore\r
+ the nesting is always 0. */\r
+ la sp, xISRStackTop\r
+ lw sp, (sp)\r
+\r
+ /* Set the nesting count. */\r
+ la k0, uxInterruptNesting\r
+ addiu s6, zero, 1\r
+ sw s6, 0(k0)\r
+\r
+ /* s6 holds the EPC value, this is saved with the rest of the context\r
+ after interrupts are enabled. */\r
+ mfc0 s6, _CP0_EPC\r
+\r
+ /* Re-enable interrupts above configMAX_SYSCALL_INTERRUPT_PRIORITY. */\r
+ mtc0 k1, _CP0_STATUS\r
+\r
+ /* Save the context into the space just created. s6 is saved again\r
+ here as it now contains the EPC value. */\r
+ sw ra, 120(s5)\r
+ sw s8, 116(s5)\r
+ sw t9, 112(s5)\r
+ sw t8, 108(s5)\r
+ sw t7, 104(s5)\r
+ sw t6, 100(s5)\r
+ sw t5, 96(s5)\r
+ sw t4, 92(s5)\r
+ sw t3, 88(s5)\r
+ sw t2, 84(s5)\r
+ sw t1, 80(s5)\r
+ sw t0, 76(s5)\r
+ sw a3, 72(s5)\r
+ sw a2, 68(s5)\r
+ sw a1, 64(s5)\r
+ sw a0, 60(s5)\r
+ sw v1, 56(s5)\r
+ sw v0, 52(s5)\r
+ sw s7, 48(s5)\r
+ sw s6, portEPC_STACK_LOCATION(s5)\r
+ /* s5 and s6 has already been saved. */\r
+ sw s4, 36(s5)\r
+ sw s3, 32(s5)\r
+ sw s2, 28(s5)\r
+ sw s1, 24(s5)\r
+ sw s0, 20(s5)\r
+ sw $1, 16(s5)\r
+\r
+ /* s7 is used as a scratch register as this should always be saved across\r
+ nesting interrupts. */\r
+\r
+ /* Save the AC0, AC1, AC2 and AC3. */\r
+ mfhi s7, $ac1\r
+ sw s7, 128(s5)\r
+ mflo s7, $ac1\r
+ sw s7, 124(s5)\r
+\r
+ mfhi s7, $ac2\r
+ sw s7, 136(s5)\r
+ mflo s7, $ac2\r
+ sw s7, 132(s5)\r
+\r
+ mfhi s7, $ac3\r
+ sw s7, 144(s5)\r
+ mflo s7, $ac3\r
+ sw s7, 140(s5)\r
+\r
+ rddsp s7\r
+ sw s7, 148(s5)\r
+\r
+ mfhi s7, $ac0\r
+ sw s7, 12(s5)\r
+ mflo s7, $ac0\r
+ sw s7, 8(s5)\r
+\r
+ /* Test if FPU context save is required. */\r
+ lw s7, portTASK_HAS_FPU_STACK_LOCATION(s5)\r
+ beq s7, zero, 1f\r
+ nop\r
+\r
+ /* Save the FPU registers above the normal context. */\r
+ portSAVE_FPU_REGS (portCONTEXT_SIZE + 8), s5\r
+\r
+ /* Save the FPU status register */\r
+ cfc1 s7, $f31\r
+ sw s7, ( portCONTEXT_SIZE + portFPCSR_STACK_LOCATION )(s5)\r
+\r
+ 1:\r
+ /* Save the stack pointer to the task. */\r
+ la s7, pxCurrentTCB\r
+ lw s7, (s7)\r
+ sw s5, (s7)\r
+\r
+ /* Set the interrupt mask to the max priority that can use the API. The\r
+ yield handler will only be called at configKERNEL_INTERRUPT_PRIORITY which\r
+ is below configMAX_SYSCALL_INTERRUPT_PRIORITY - so this can only ever\r
+ raise the IPL value and never lower it. */\r
+ di\r
+ ehb\r
+ mfc0 s7, _CP0_STATUS\r
+ ins s7, zero, 10, 7\r
+ ins s7, zero, 18, 1\r
+ ori s6, s7, ( configMAX_SYSCALL_INTERRUPT_PRIORITY << 10 ) | 1\r
+\r
+ /* This mtc0 re-enables interrupts, but only above\r
+ configMAX_SYSCALL_INTERRUPT_PRIORITY. */\r
+ mtc0 s6, _CP0_STATUS\r
+ ehb\r
+\r
+ /* Clear the software interrupt in the core. */\r
+ mfc0 s6, _CP0_CAUSE\r
+ ins s6, zero, 8, 1\r
+ mtc0 s6, _CP0_CAUSE\r
+ ehb\r
+\r
+ /* Clear the interrupt in the interrupt controller. */\r
+ la s6, IFS0CLR\r
+ addiu s4, zero, 2\r
+ sw s4, (s6)\r
+\r
+ jal vTaskSwitchContext\r
+ nop\r
+\r
+ /* Clear the interrupt mask again. The saved status value is still in s7. */\r
+ mtc0 s7, _CP0_STATUS\r
+ ehb\r
+\r
+ /* Restore the stack pointer from the TCB. */\r
+ la s0, pxCurrentTCB\r
+ lw s0, (s0)\r
+ lw s5, (s0)\r
+\r
+ /* Test if the FPU context needs restoring. */\r
+ lw s0, portTASK_HAS_FPU_STACK_LOCATION(s5)\r
+ beq s0, zero, 1f\r
+ nop\r
+\r
+ /* Restore the FPU status register. */\r
+ lw s0, ( portCONTEXT_SIZE + portFPCSR_STACK_LOCATION )(s5)\r
+ ctc1 s0, $f31\r
+\r
+ /* Restore the FPU registers. */\r
+ portLOAD_FPU_REGS ( portCONTEXT_SIZE + 8 ), s5\r
+\r
+ 1:\r
+ /* Restore the rest of the context. */\r
+ lw s0, 128(s5)\r
+ mthi s0, $ac1\r
+ lw s0, 124(s5)\r
+ mtlo s0, $ac1\r
+\r
+ lw s0, 136(s5)\r
+ mthi s0, $ac2\r
+ lw s0, 132(s5)\r
+ mtlo s0, $ac2\r
+\r
+ lw s0, 144(s5)\r
+ mthi s0, $ac3\r
+ lw s0, 140(s5)\r
+ mtlo s0, $ac3\r
+\r
+ lw s0, 148(s5)\r
+ wrdsp s0\r
+\r
+ lw s0, 8(s5)\r
+ mtlo s0, $ac0\r
+ lw s0, 12(s5)\r
+ mthi s0, $ac0\r
+\r
+ lw $1, 16(s5)\r
+ lw s0, 20(s5)\r
+ lw s1, 24(s5)\r
+ lw s2, 28(s5)\r
+ lw s3, 32(s5)\r
+ lw s4, 36(s5)\r
+\r
+ /* s5 is loaded later. */\r
+ lw s6, 44(s5)\r
+ lw s7, 48(s5)\r
+ lw v0, 52(s5)\r
+ lw v1, 56(s5)\r
+ lw a0, 60(s5)\r
+ lw a1, 64(s5)\r
+ lw a2, 68(s5)\r
+ lw a3, 72(s5)\r
+ lw t0, 76(s5)\r
+ lw t1, 80(s5)\r
+ lw t2, 84(s5)\r
+ lw t3, 88(s5)\r
+ lw t4, 92(s5)\r
+ lw t5, 96(s5)\r
+ lw t6, 100(s5)\r
+ lw t7, 104(s5)\r
+ lw t8, 108(s5)\r
+ lw t9, 112(s5)\r
+ lw s8, 116(s5)\r
+ lw ra, 120(s5)\r
+\r
+ /* Protect access to the k registers, and others. */\r
+ di\r
+ ehb\r
+\r
+ /* Set nesting back to zero. As the lowest priority interrupt this\r
+ interrupt cannot have nested. */\r
+ la k0, uxInterruptNesting\r
+ sw zero, 0(k0)\r
+\r
+ /* Switch back to use the real stack pointer. */\r
+ add sp, zero, s5\r
+\r
+ /* Restore the real s5 value. */\r
+ lw s5, 40(sp)\r
+\r
+ /* Pop the FPU context value from the stack */\r
+ lw k0, portTASK_HAS_FPU_STACK_LOCATION(sp)\r
+ la k1, ulTaskHasFPUContext\r
+ sw k0, 0(k1)\r
+ beq k0, zero, 1f\r
+ nop\r
+\r
+ /* task has FPU context so adjust the stack frame after popping the\r
+ status and epc values. */\r
+ lw k1, portSTATUS_STACK_LOCATION(sp)\r
+ lw k0, portEPC_STACK_LOCATION(sp)\r
+ addiu sp, sp, portFPU_CONTEXT_SIZE\r
+ beq zero, zero, 2f\r
+ nop\r
+\r
+ 1:\r
+ /* Pop the status and epc values. */\r
+ lw k1, portSTATUS_STACK_LOCATION(sp)\r
+ lw k0, portEPC_STACK_LOCATION(sp)\r
+\r
+ 2:\r
+ /* Remove stack frame. */\r
+ addiu sp, sp, portCONTEXT_SIZE\r
\r
- /* Clear the software interrupt in the core. */\r
- mfc0 s6, _CP0_CAUSE\r
- ins s6, zero, 8, 1\r
- mtc0 s6, _CP0_CAUSE\r
+ #else\r
+ /* Code sequence for no FPU support, the context save requires advance\r
+ knowledge of the stack frame size when no FPU is being used */\r
+\r
+ /* Make room for the context. First save the current status so it can be\r
+ manipulated, and the cause and EPC registers so thier original values are\r
+ captured. */\r
+ addiu sp, sp, -portCONTEXT_SIZE\r
+ mfc0 k1, _CP0_STATUS\r
+\r
+ /* Also save s6 and s5 so they can be used. Any nesting interrupts should\r
+ maintain the values of these registers across the ISR. */\r
+ sw s6, 44(sp)\r
+ sw s5, 40(sp)\r
+ sw k1, portSTATUS_STACK_LOCATION(sp)\r
+\r
+ /* Prepare to re-enabled interrupts above the kernel priority. */\r
+ ins k1, zero, 10, 7 /* Clear IPL bits 0:6. */\r
+ ins k1, zero, 18, 1 /* Clear IPL bit 7. It would be an error here if this bit were set anyway. */\r
+ ori k1, k1, ( configMAX_SYSCALL_INTERRUPT_PRIORITY << 10 )\r
+ ins k1, zero, 1, 4 /* Clear EXL, ERL and UM. */\r
+\r
+ /* s5 is used as the frame pointer. */\r
+ add s5, zero, sp\r
+\r
+ /* Swap to the system stack. This is not conditional on the nesting\r
+ count as this interrupt is always the lowest priority and therefore\r
+ the nesting is always 0. */\r
+ la sp, xISRStackTop\r
+ lw sp, (sp)\r
+\r
+ /* Set the nesting count. */\r
+ la k0, uxInterruptNesting\r
+ addiu s6, zero, 1\r
+ sw s6, 0(k0)\r
+\r
+ /* s6 holds the EPC value, this is saved with the rest of the context\r
+ after interrupts are enabled. */\r
+ mfc0 s6, _CP0_EPC\r
+\r
+ /* Re-enable interrupts above configMAX_SYSCALL_INTERRUPT_PRIORITY. */\r
+ mtc0 k1, _CP0_STATUS\r
+\r
+ /* Save the context into the space just created. s6 is saved again\r
+ here as it now contains the EPC value. */\r
+ sw ra, 120(s5)\r
+ sw s8, 116(s5)\r
+ sw t9, 112(s5)\r
+ sw t8, 108(s5)\r
+ sw t7, 104(s5)\r
+ sw t6, 100(s5)\r
+ sw t5, 96(s5)\r
+ sw t4, 92(s5)\r
+ sw t3, 88(s5)\r
+ sw t2, 84(s5)\r
+ sw t1, 80(s5)\r
+ sw t0, 76(s5)\r
+ sw a3, 72(s5)\r
+ sw a2, 68(s5)\r
+ sw a1, 64(s5)\r
+ sw a0, 60(s5)\r
+ sw v1, 56(s5)\r
+ sw v0, 52(s5)\r
+ sw s7, 48(s5)\r
+ sw s6, portEPC_STACK_LOCATION(s5)\r
+ /* s5 and s6 has already been saved. */\r
+ sw s4, 36(s5)\r
+ sw s3, 32(s5)\r
+ sw s2, 28(s5)\r
+ sw s1, 24(s5)\r
+ sw s0, 20(s5)\r
+ sw $1, 16(s5)\r
+\r
+ /* s7 is used as a scratch register as this should always be saved across\r
+ nesting interrupts. */\r
+\r
+ /* Save the AC0, AC1, AC2 and AC3. */\r
+ mfhi s7, $ac1\r
+ sw s7, 128(s5)\r
+ mflo s7, $ac1\r
+ sw s7, 124(s5)\r
+\r
+ mfhi s7, $ac2\r
+ sw s7, 136(s5)\r
+ mflo s7, $ac2\r
+ sw s7, 132(s5)\r
+\r
+ mfhi s7, $ac3\r
+ sw s7, 144(s5)\r
+ mflo s7, $ac3\r
+ sw s7, 140(s5)\r
+\r
+ rddsp s7\r
+ sw s7, 148(s5)\r
+\r
+ mfhi s7, $ac0\r
+ sw s7, 12(s5)\r
+ mflo s7, $ac0\r
+ sw s7, 8(s5)\r
+\r
+ /* Save the stack pointer to the task. */\r
+ la s7, pxCurrentTCB\r
+ lw s7, (s7)\r
+ sw s5, (s7)\r
+\r
+ /* Set the interrupt mask to the max priority that can use the API. The\r
+ yield handler will only be called at configKERNEL_INTERRUPT_PRIORITY which\r
+ is below configMAX_SYSCALL_INTERRUPT_PRIORITY - so this can only ever\r
+ raise the IPL value and never lower it. */\r
+ di\r
+ ehb\r
+ mfc0 s7, _CP0_STATUS\r
+ ins s7, zero, 10, 7\r
+ ins s7, zero, 18, 1\r
+ ori s6, s7, ( configMAX_SYSCALL_INTERRUPT_PRIORITY << 10 ) | 1\r
+\r
+ /* This mtc0 re-enables interrupts, but only above\r
+ configMAX_SYSCALL_INTERRUPT_PRIORITY. */\r
+ mtc0 s6, _CP0_STATUS\r
+ ehb\r
+\r
+ /* Clear the software interrupt in the core. */\r
+ mfc0 s6, _CP0_CAUSE\r
+ ins s6, zero, 8, 1\r
+ mtc0 s6, _CP0_CAUSE\r
+ ehb\r
+\r
+ /* Clear the interrupt in the interrupt controller. */\r
+ la s6, IFS0CLR\r
+ addiu s4, zero, 2\r
+ sw s4, (s6)\r
+\r
+ jal vTaskSwitchContext\r
+ nop\r
+\r
+ /* Clear the interrupt mask again. The saved status value is still in s7. */\r
+ mtc0 s7, _CP0_STATUS\r
+ ehb\r
+\r
+ /* Restore the stack pointer from the TCB. */\r
+ la s0, pxCurrentTCB\r
+ lw s0, (s0)\r
+ lw s5, (s0)\r
+\r
+ /* Restore the rest of the context. */\r
+ lw s0, 128(s5)\r
+ mthi s0, $ac1\r
+ lw s0, 124(s5)\r
+ mtlo s0, $ac1\r
+\r
+ lw s0, 136(s5)\r
+ mthi s0, $ac2\r
+ lw s0, 132(s5)\r
+ mtlo s0, $ac2\r
+\r
+ lw s0, 144(s5)\r
+ mthi s0, $ac3\r
+ lw s0, 140(s5)\r
+ mtlo s0, $ac3\r
+\r
+ lw s0, 148(s5)\r
+ wrdsp s0\r
+\r
+ lw s0, 8(s5)\r
+ mtlo s0, $ac0\r
+ lw s0, 12(s5)\r
+ mthi s0, $ac0\r
+\r
+ lw $1, 16(s5)\r
+ lw s0, 20(s5)\r
+ lw s1, 24(s5)\r
+ lw s2, 28(s5)\r
+ lw s3, 32(s5)\r
+ lw s4, 36(s5)\r
+\r
+ /* s5 is loaded later. */\r
+ lw s6, 44(s5)\r
+ lw s7, 48(s5)\r
+ lw v0, 52(s5)\r
+ lw v1, 56(s5)\r
+ lw a0, 60(s5)\r
+ lw a1, 64(s5)\r
+ lw a2, 68(s5)\r
+ lw a3, 72(s5)\r
+ lw t0, 76(s5)\r
+ lw t1, 80(s5)\r
+ lw t2, 84(s5)\r
+ lw t3, 88(s5)\r
+ lw t4, 92(s5)\r
+ lw t5, 96(s5)\r
+ lw t6, 100(s5)\r
+ lw t7, 104(s5)\r
+ lw t8, 108(s5)\r
+ lw t9, 112(s5)\r
+ lw s8, 116(s5)\r
+ lw ra, 120(s5)\r
+\r
+ /* Protect access to the k registers, and others. */\r
+ di\r
+ ehb\r
+\r
+ /* Set nesting back to zero. As the lowest priority interrupt this\r
+ interrupt cannot have nested. */\r
+ la k0, uxInterruptNesting\r
+ sw zero, 0(k0)\r
+\r
+ /* Switch back to use the real stack pointer. */\r
+ add sp, zero, s5\r
+\r
+ /* Restore the real s5 value. */\r
+ lw s5, 40(sp)\r
+\r
+ /* Pop the status and epc values. */\r
+ lw k1, portSTATUS_STACK_LOCATION(sp)\r
+ lw k0, portEPC_STACK_LOCATION(sp)\r
+\r
+ /* Remove stack frame. */\r
+ addiu sp, sp, portCONTEXT_SIZE\r
+\r
+ #endif /* ( __mips_hard_float == 1 ) && ( configUSE_TASK_FPU_SUPPORT == 1 ) */\r
+\r
+ /* Restore the status and EPC registers and return */\r
+ mtc0 k1, _CP0_STATUS\r
+ mtc0 k0, _CP0_EPC\r
ehb\r
-\r
- /* Clear the interrupt in the interrupt controller. */\r
- la s6, IFS0CLR\r
- addiu s4, zero, 2\r
- sw s4, (s6)\r
-\r
- jal vTaskSwitchContext\r
+ eret\r
nop\r
\r
- /* Clear the interrupt mask again. The saved status value is still in s7. */\r
- mtc0 s7, _CP0_STATUS\r
- ehb\r
+ .end vPortYieldISR\r
\r
- /* Restore the stack pointer from the TCB. */\r
- la s0, pxCurrentTCB\r
- lw s0, (s0)\r
- lw s5, (s0)\r
-\r
- /* Restore the rest of the context. */\r
- lw s0, 128(s5)\r
- mthi s0, $ac1\r
- lw s0, 124(s5)\r
- mtlo s0, $ac1\r
-\r
- lw s0, 136(s5)\r
- mthi s0, $ac2\r
- lw s0, 132(s5)\r
- mtlo s0, $ac2\r
-\r
- lw s0, 144(s5)\r
- mthi s0, $ac3\r
- lw s0, 140(s5)\r
- mtlo s0, $ac3\r
-\r
- lw s0, 148(s5)\r
- wrdsp s0\r
-\r
- lw s0, 8(s5)\r
- mtlo s0, $ac0\r
- lw s0, 12(s5)\r
- mthi s0, $ac0\r
-\r
- lw $1, 16(s5)\r
- lw s0, 20(s5)\r
- lw s1, 24(s5)\r
- lw s2, 28(s5)\r
- lw s3, 32(s5)\r
- lw s4, 36(s5)\r
-\r
- /* s5 is loaded later. */\r
- lw s6, 44(s5)\r
- lw s7, 48(s5)\r
- lw v0, 52(s5)\r
- lw v1, 56(s5)\r
- lw a0, 60(s5)\r
- lw a1, 64(s5)\r
- lw a2, 68(s5)\r
- lw a3, 72(s5)\r
- lw t0, 76(s5)\r
- lw t1, 80(s5)\r
- lw t2, 84(s5)\r
- lw t3, 88(s5)\r
- lw t4, 92(s5)\r
- lw t5, 96(s5)\r
- lw t6, 100(s5)\r
- lw t7, 104(s5)\r
- lw t8, 108(s5)\r
- lw t9, 112(s5)\r
- lw s8, 116(s5)\r
- lw ra, 120(s5)\r
-\r
- /* Protect access to the k registers, and others. */\r
- di\r
- ehb\r
+/******************************************************************/\r
\r
- /* Set nesting back to zero. As the lowest priority interrupt this\r
- interrupt cannot have nested. */\r
- la k0, uxInterruptNesting\r
- sw zero, 0(k0)\r
+#if ( __mips_hard_float == 1 ) && ( configUSE_TASK_FPU_SUPPORT == 1 )\r
\r
- /* Switch back to use the real stack pointer. */\r
- add sp, zero, s5\r
+ .macro portFPUSetAndInc reg, dest\r
+ mtc1 \reg, \dest\r
+ cvt.d.w \dest, \dest\r
+ addiu \reg, \reg, 1\r
+ .endm\r
\r
- /* Restore the real s5 value. */\r
- lw s5, 40(sp)\r
+ .set noreorder\r
+ .set noat\r
+ .section .text, code\r
+ .ent vPortInitialiseFPSCR\r
+\r
+vPortInitialiseFPSCR:\r
+\r
+ /* Initialize the floating point status register in CP1. The initial\r
+ value is passed in a0. */\r
+ ctc1 a0, $f31\r
+\r
+ /* Clear the FPU registers */\r
+ addiu a0, zero, 0x0000\r
+ portFPUSetAndInc a0, $f0\r
+ portFPUSetAndInc a0, $f1\r
+ portFPUSetAndInc a0, $f2\r
+ portFPUSetAndInc a0, $f3\r
+ portFPUSetAndInc a0, $f4\r
+ portFPUSetAndInc a0, $f5\r
+ portFPUSetAndInc a0, $f6\r
+ portFPUSetAndInc a0, $f7\r
+ portFPUSetAndInc a0, $f8\r
+ portFPUSetAndInc a0, $f9\r
+ portFPUSetAndInc a0, $f10\r
+ portFPUSetAndInc a0, $f11\r
+ portFPUSetAndInc a0, $f12\r
+ portFPUSetAndInc a0, $f13\r
+ portFPUSetAndInc a0, $f14\r
+ portFPUSetAndInc a0, $f15\r
+ portFPUSetAndInc a0, $f16\r
+ portFPUSetAndInc a0, $f17\r
+ portFPUSetAndInc a0, $f18\r
+ portFPUSetAndInc a0, $f19\r
+ portFPUSetAndInc a0, $f20\r
+ portFPUSetAndInc a0, $f21\r
+ portFPUSetAndInc a0, $f22\r
+ portFPUSetAndInc a0, $f23\r
+ portFPUSetAndInc a0, $f24\r
+ portFPUSetAndInc a0, $f25\r
+ portFPUSetAndInc a0, $f26\r
+ portFPUSetAndInc a0, $f27\r
+ portFPUSetAndInc a0, $f28\r
+ portFPUSetAndInc a0, $f29\r
+ portFPUSetAndInc a0, $f30\r
+ portFPUSetAndInc a0, $f31\r
+\r
+ jr ra\r
+ nop\r
\r
- /* Pop the status and epc values. */\r
- lw k1, portSTATUS_STACK_LOCATION(sp)\r
- lw k0, portEPC_STACK_LOCATION(sp)\r
+ .end vPortInitialiseFPSCR\r
\r
- /* Remove stack frame. */\r
- addiu sp, sp, portCONTEXT_SIZE\r
+#endif /* ( __mips_hard_float == 1 ) && ( configUSE_TASK_FPU_SUPPORT == 1 ) */\r
+ \r
+#if ( __mips_hard_float == 1 ) && ( configUSE_TASK_FPU_SUPPORT == 1 )\r
\r
- mtc0 k1, _CP0_STATUS\r
- mtc0 k0, _CP0_EPC\r
- ehb\r
- eret\r
+ /**********************************************************************/\r
+ /* Test read back */\r
+ /* a0 = address to store registers */\r
+\r
+ .set noreorder\r
+ .set noat\r
+ .section .text, code\r
+ .ent vPortFPUReadback\r
+ .global vPortFPUReadback\r
+\r
+vPortFPUReadback:\r
+ sdc1 $f0, 0(a0)\r
+ sdc1 $f1, 8(a0)\r
+ sdc1 $f2, 16(a0)\r
+ sdc1 $f3, 24(a0)\r
+ sdc1 $f4, 32(a0)\r
+ sdc1 $f5, 40(a0)\r
+ sdc1 $f6, 48(a0)\r
+ sdc1 $f7, 56(a0)\r
+ sdc1 $f8, 64(a0)\r
+ sdc1 $f9, 72(a0)\r
+ sdc1 $f10, 80(a0)\r
+ sdc1 $f11, 88(a0)\r
+ sdc1 $f12, 96(a0)\r
+ sdc1 $f13, 104(a0)\r
+ sdc1 $f14, 112(a0)\r
+ sdc1 $f15, 120(a0)\r
+ sdc1 $f16, 128(a0)\r
+ sdc1 $f17, 136(a0)\r
+ sdc1 $f18, 144(a0)\r
+ sdc1 $f19, 152(a0)\r
+ sdc1 $f20, 160(a0)\r
+ sdc1 $f21, 168(a0)\r
+ sdc1 $f22, 176(a0)\r
+ sdc1 $f23, 184(a0)\r
+ sdc1 $f24, 192(a0)\r
+ sdc1 $f25, 200(a0)\r
+ sdc1 $f26, 208(a0)\r
+ sdc1 $f27, 216(a0)\r
+ sdc1 $f28, 224(a0)\r
+ sdc1 $f29, 232(a0)\r
+ sdc1 $f30, 240(a0)\r
+ sdc1 $f31, 248(a0)\r
+\r
+ jr ra\r
nop\r
\r
- .end vPortYieldISR\r
+ .end vPortFPUReadback\r
+\r
+#endif /* ( __mips_hard_float == 1 ) && ( configUSE_TASK_FPU_SUPPORT == 1 ) */\r
+\r
\r
\r
\r