.global task_switch
.global task_get_current
.global task_set_current
+.global task_move_stack
task_prepare:
/*
1: movl 4(%esp), %ecx
movl %ecx, OFFSET_CPU_CTASK(%eax)
ret
+
+task_move_stack:
+ /*
+ * void task_move_stack(void *dst, void *src, u32_t size)
+ *
+ * dst = 4(%esp)
+ * src = 8(%esp)
+ * size = 12(%esp)
+ */
+
+ /*
+ * For the sake of performance, don't copy the entire stack
+ * but just the portion that was actually used, i.e. the
+ * following:
+ *
+ * +-----+ <- src + size
+ * | |
+ * | |
+ * +-----+ <- ESP
+ * | |
+ * | |
+ * +-----+ <- src
+ */
+
+ /* compute the offset into the new stack */
+ movl %esp, %edi
+ subl 8(%esp), %edi /* ESP - src = offset */
+ addl 4(%esp), %edi /* offset + dst = nESP */
+
+ /* put ESP into ESI so we can copy from ESI to EDI */
+ movl %esp, %esi
+
+ /* calculate the upper limit for EDI and put it into EDX */
+ movl 4(%esp), %edx
+ addl 12(%esp), %edx
+
+ /*
+ * Update the stack pointers now, since we won't need the
+ * stack anymore afterwards. To update EBP, we need to subtract
+ * the old base and add the new one, so do that before updating
+ * ESP.
+ */
+ subl 8(%esp), %ebp
+ addl 4(%esp), %ebp
+ movl %edi, %esp
+
+ /*
+ * To copy the stack, keep copying from %(esi) to (%edi),
+ * increasing the two pointers, until %edi reaches %edx
+ */
+
+0: cmpl %edx, %edi
+ jge 1f
+
+ movl (%esi), %eax
+ movl %eax, (%edi)
+ addl $4, %esi
+ addl $4, %edi
+ jmp 0b
+
+ /* iterate over the new stack, adjusting pointers */
+1: movl %esp, %edi
+ movl %edx, %esi
+ movl 8(%esp), %ecx /* lower bound */
+ movl %ecx, %edx
+ addl 12(%esp), %edx /* upper bound */
+
+2: cmpl %esi, %edi
+ jge 4f
+
+ movl (%edi), %eax
+ cmpl %ecx, %eax
+ jl 3f
+ cmpl %edx, %eax
+ jge 3f
+
+ /* adjust the pointer */
+ subl %ecx, %eax
+ addl 4(%esp), %eax
+ /* store it on the stack */
+ movl %eax, (%edi)
+3: addl $4, %edi
+ jmp 2b
+
+ /* Stacks have been copied and stack pointers updated. We're done. */
+4: ret
task_t* task_get_current(void);
void task_set_current(task_t*);
+void task_move_stack(void*, void*, u32_t);
/*
* Definitions, types, and prototypes related to paging