/*
 * Copyright (C) 2016 YunOS Project. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <k_api.h>

void *cpu_task_stack_init(cpu_stack_t *stack_base, size_t stack_size,
                          void *arg, task_entry_t entry)
{
    cpu_stack_t *stk;
    uint32_t temp = (uint32_t)(stack_base + stack_size);

    temp &= 0xFFFFFFF8;

    stk = (cpu_stack_t *)temp;

    *(--stk) = (uint32_t)entry;                 /* Entry Point   */
    *(--stk) = (uint32_t)0x80000140L;           /* PSR           */
    *(--stk) = (uint32_t)0x88888888L;           /* HI            */
    *(--stk) = (uint32_t)0x88888888L;           /* LO            */
    *(--stk) = (uint32_t)krhino_task_deathbed;  /* R15 (LR)      */
    *(--stk) = (uint32_t)0x14141414L;           /* R14           */
    *(--stk) = (uint32_t)0x13131313L;           /* R13           */
    *(--stk) = (uint32_t)0x12121212L;           /* R12           */
    *(--stk) = (uint32_t)0x11111111L;           /* R11           */
    *(--stk) = (uint32_t)0x10101010L;           /* R10           */
    *(--stk) = (uint32_t)0x09090909L;           /* R9            */
    *(--stk) = (uint32_t)0x08080808L;           /* R8            */
    *(--stk) = (uint32_t)0x07070707L;           /* R7            */
    *(--stk) = (uint32_t)0x06060606L;           /* R6            */
    *(--stk) = (uint32_t)0x05050505L;           /* R5            */
    *(--stk) = (uint32_t)0x04040404L;           /* R4            */
    *(--stk) = (uint32_t)0x03030303L;           /* R3            */
    *(--stk) = (uint32_t)arg;                   /* R2 : Argument */
    *(--stk) = (uint32_t)0x01010101L;           /* R1            */

    return stk;
}

