10d163575Sopenharmony_ci/* 20d163575Sopenharmony_ci * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. 30d163575Sopenharmony_ci * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. 40d163575Sopenharmony_ci * 50d163575Sopenharmony_ci * Redistribution and use in source and binary forms, with or without modification, 60d163575Sopenharmony_ci * are permitted provided that the following conditions are met: 70d163575Sopenharmony_ci * 80d163575Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, this list of 90d163575Sopenharmony_ci * conditions and the following disclaimer. 100d163575Sopenharmony_ci * 110d163575Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, this list 120d163575Sopenharmony_ci * of conditions and the following disclaimer in the documentation and/or other materials 130d163575Sopenharmony_ci * provided with the distribution. 140d163575Sopenharmony_ci * 150d163575Sopenharmony_ci * 3. Neither the name of the copyright holder nor the names of its contributors may be used 160d163575Sopenharmony_ci * to endorse or promote products derived from this software without specific prior written 170d163575Sopenharmony_ci * permission. 180d163575Sopenharmony_ci * 190d163575Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 200d163575Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 210d163575Sopenharmony_ci * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 220d163575Sopenharmony_ci * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 230d163575Sopenharmony_ci * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 240d163575Sopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 250d163575Sopenharmony_ci * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 260d163575Sopenharmony_ci * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 270d163575Sopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 280d163575Sopenharmony_ci * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 290d163575Sopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 300d163575Sopenharmony_ci */ 310d163575Sopenharmony_ci 320d163575Sopenharmony_ci#include <arch/sys_arch.h> 330d163575Sopenharmony_ci#include <lwip/sys.h> 340d163575Sopenharmony_ci#include <lwip/debug.h> 350d163575Sopenharmony_ci#include <los_task.h> 360d163575Sopenharmony_ci#include <los_sys_pri.h> 370d163575Sopenharmony_ci#include <los_tick.h> 380d163575Sopenharmony_ci#include <los_queue.h> 390d163575Sopenharmony_ci#include <los_sem.h> 400d163575Sopenharmony_ci#include <los_mux.h> 410d163575Sopenharmony_ci#include <los_spinlock.h> 420d163575Sopenharmony_ci 430d163575Sopenharmony_ci#ifdef LOSCFG_KERNEL_SMP 440d163575Sopenharmony_ciSPIN_LOCK_INIT(arch_protect_spin); 450d163575Sopenharmony_cistatic u32_t lwprot_thread = LOS_ERRNO_TSK_ID_INVALID; 460d163575Sopenharmony_cistatic int lwprot_count = 0; 470d163575Sopenharmony_ci#endif /* LOSCFG_KERNEL_SMP */ 480d163575Sopenharmony_ci 490d163575Sopenharmony_ci#define ROUND_UP_DIV(val, div) (((val) + (div) - 1) / (div)) 500d163575Sopenharmony_ci 510d163575Sopenharmony_ci/** 520d163575Sopenharmony_ci * Thread and System misc 530d163575Sopenharmony_ci */ 540d163575Sopenharmony_ci 550d163575Sopenharmony_cisys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stackSize, int prio) 560d163575Sopenharmony_ci{ 570d163575Sopenharmony_ci UINT32 taskID = LOS_ERRNO_TSK_ID_INVALID; 580d163575Sopenharmony_ci UINT32 ret; 590d163575Sopenharmony_ci TSK_INIT_PARAM_S task = {0}; 600d163575Sopenharmony_ci 610d163575Sopenharmony_ci /* Create host Task */ 620d163575Sopenharmony_ci task.pfnTaskEntry = (TSK_ENTRY_FUNC)thread; 630d163575Sopenharmony_ci task.uwStackSize = stackSize; 640d163575Sopenharmony_ci task.pcName = (char *)name; 650d163575Sopenharmony_ci task.usTaskPrio = prio; 660d163575Sopenharmony_ci task.auwArgs[0] = (UINTPTR)arg; 670d163575Sopenharmony_ci task.uwResved = LOS_TASK_STATUS_DETACHED; 680d163575Sopenharmony_ci ret = LOS_TaskCreate(&taskID, &task); 690d163575Sopenharmony_ci if (ret != LOS_OK) { 700d163575Sopenharmony_ci LWIP_DEBUGF(SYS_DEBUG, ("sys_thread_new: LOS_TaskCreate error %u\n", ret)); 710d163575Sopenharmony_ci return -1; 720d163575Sopenharmony_ci } 730d163575Sopenharmony_ci 740d163575Sopenharmony_ci return taskID; 750d163575Sopenharmony_ci} 760d163575Sopenharmony_ci 770d163575Sopenharmony_civoid sys_init(void) 780d163575Sopenharmony_ci{ 790d163575Sopenharmony_ci /* set rand seed to make random sequence diff on every startup */ 800d163575Sopenharmony_ci UINT32 seedhsb, seedlsb; 810d163575Sopenharmony_ci LOS_GetCpuCycle(&seedhsb, &seedlsb); 820d163575Sopenharmony_ci srand(seedlsb); 830d163575Sopenharmony_ci} 840d163575Sopenharmony_ci 850d163575Sopenharmony_ciu32_t sys_now(void) 860d163575Sopenharmony_ci{ 870d163575Sopenharmony_ci /* Lwip docs mentioned like wraparound is not a problem in this function */ 880d163575Sopenharmony_ci return (u32_t)((LOS_TickCountGet() * OS_SYS_MS_PER_SECOND) / LOSCFG_BASE_CORE_TICK_PER_SECOND); 890d163575Sopenharmony_ci} 900d163575Sopenharmony_ci 910d163575Sopenharmony_ci#if (LWIP_CHKSUM_ALGORITHM == 4) /* version #4, asm based */ 920d163575Sopenharmony_ci#include "in_cksum.h" 930d163575Sopenharmony_ciu16_t lwip_standard_chksum(const void *dataptr, int len) 940d163575Sopenharmony_ci{ 950d163575Sopenharmony_ci return ~(u16_t)(in_cksum(dataptr, len)); 960d163575Sopenharmony_ci} 970d163575Sopenharmony_ci#endif 980d163575Sopenharmony_ci 990d163575Sopenharmony_ci 1000d163575Sopenharmony_ci/** 1010d163575Sopenharmony_ci * Protector 1020d163575Sopenharmony_ci */ 1030d163575Sopenharmony_ci 1040d163575Sopenharmony_cisys_prot_t sys_arch_protect(void) 1050d163575Sopenharmony_ci{ 1060d163575Sopenharmony_ci#ifdef LOSCFG_KERNEL_SMP 1070d163575Sopenharmony_ci /* Note that we are using spinlock instead of mutex for LiteOS-SMP here: 1080d163575Sopenharmony_ci * 1. spinlock is more effective for short critical region protection. 1090d163575Sopenharmony_ci * 2. this function is called only in task context, not in interrupt handler. 1100d163575Sopenharmony_ci * so it's not needed to disable interrupt. 1110d163575Sopenharmony_ci */ 1120d163575Sopenharmony_ci if (lwprot_thread != LOS_CurTaskIDGet()) { 1130d163575Sopenharmony_ci /* We are locking the spinlock where it has not been locked before 1140d163575Sopenharmony_ci * or is being locked by another thread */ 1150d163575Sopenharmony_ci LOS_SpinLock(&arch_protect_spin); 1160d163575Sopenharmony_ci lwprot_thread = LOS_CurTaskIDGet(); 1170d163575Sopenharmony_ci lwprot_count = 1; 1180d163575Sopenharmony_ci } else { 1190d163575Sopenharmony_ci /* It is already locked by THIS thread */ 1200d163575Sopenharmony_ci lwprot_count++; 1210d163575Sopenharmony_ci } 1220d163575Sopenharmony_ci#else 1230d163575Sopenharmony_ci LOS_TaskLock(); 1240d163575Sopenharmony_ci#endif /* LOSCFG_KERNEL_SMP */ 1250d163575Sopenharmony_ci return 0; /* return value is unused */ 1260d163575Sopenharmony_ci} 1270d163575Sopenharmony_ci 1280d163575Sopenharmony_civoid sys_arch_unprotect(sys_prot_t pval) 1290d163575Sopenharmony_ci{ 1300d163575Sopenharmony_ci LWIP_UNUSED_ARG(pval); 1310d163575Sopenharmony_ci#ifdef LOSCFG_KERNEL_SMP 1320d163575Sopenharmony_ci if (lwprot_thread == LOS_CurTaskIDGet()) { 1330d163575Sopenharmony_ci lwprot_count--; 1340d163575Sopenharmony_ci if (lwprot_count == 0) { 1350d163575Sopenharmony_ci lwprot_thread = LOS_ERRNO_TSK_ID_INVALID; 1360d163575Sopenharmony_ci LOS_SpinUnlock(&arch_protect_spin); 1370d163575Sopenharmony_ci } 1380d163575Sopenharmony_ci } 1390d163575Sopenharmony_ci#else 1400d163575Sopenharmony_ci LOS_TaskUnlock(); 1410d163575Sopenharmony_ci#endif /* LOSCFG_KERNEL_SMP */ 1420d163575Sopenharmony_ci} 1430d163575Sopenharmony_ci 1440d163575Sopenharmony_ci 1450d163575Sopenharmony_ci/** 1460d163575Sopenharmony_ci * MessageBox 1470d163575Sopenharmony_ci */ 1480d163575Sopenharmony_ci 1490d163575Sopenharmony_cierr_t sys_mbox_new(sys_mbox_t *mbox, int size) 1500d163575Sopenharmony_ci{ 1510d163575Sopenharmony_ci CHAR qName[] = "lwIP"; 1520d163575Sopenharmony_ci UINT32 ret = LOS_QueueCreate(qName, (UINT16)size, mbox, 0, sizeof(void *)); 1530d163575Sopenharmony_ci switch (ret) { 1540d163575Sopenharmony_ci case LOS_OK: 1550d163575Sopenharmony_ci return ERR_OK; 1560d163575Sopenharmony_ci case LOS_ERRNO_QUEUE_CB_UNAVAILABLE: 1570d163575Sopenharmony_ci case LOS_ERRNO_QUEUE_CREATE_NO_MEMORY: 1580d163575Sopenharmony_ci return ERR_MEM; 1590d163575Sopenharmony_ci default: 1600d163575Sopenharmony_ci break; 1610d163575Sopenharmony_ci } 1620d163575Sopenharmony_ci LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_QueueCreate error %u\n", __FUNCTION__, ret)); 1630d163575Sopenharmony_ci return ERR_ARG; 1640d163575Sopenharmony_ci} 1650d163575Sopenharmony_ci 1660d163575Sopenharmony_civoid sys_mbox_post(sys_mbox_t *mbox, void *msg) 1670d163575Sopenharmony_ci{ 1680d163575Sopenharmony_ci /* Caution: the second parameter is NOT &msg */ 1690d163575Sopenharmony_ci UINT32 ret = LOS_QueueWrite(*mbox, msg, sizeof(char *), LOS_WAIT_FOREVER); 1700d163575Sopenharmony_ci if (ret != LOS_OK) { 1710d163575Sopenharmony_ci LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_QueueWrite error %u\n", __FUNCTION__, ret)); 1720d163575Sopenharmony_ci } 1730d163575Sopenharmony_ci} 1740d163575Sopenharmony_ci 1750d163575Sopenharmony_cierr_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) 1760d163575Sopenharmony_ci{ 1770d163575Sopenharmony_ci /* Caution: the second parameter is NOT &msg */ 1780d163575Sopenharmony_ci UINT32 ret = LOS_QueueWrite(*mbox, msg, sizeof(char *), 0); 1790d163575Sopenharmony_ci switch (ret) { 1800d163575Sopenharmony_ci case LOS_OK: 1810d163575Sopenharmony_ci return ERR_OK; 1820d163575Sopenharmony_ci case LOS_ERRNO_QUEUE_ISFULL: 1830d163575Sopenharmony_ci return ERR_MEM; 1840d163575Sopenharmony_ci default: 1850d163575Sopenharmony_ci break; 1860d163575Sopenharmony_ci } 1870d163575Sopenharmony_ci LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_QueueWrite error %u\n", __FUNCTION__, ret)); 1880d163575Sopenharmony_ci return ERR_ARG; 1890d163575Sopenharmony_ci} 1900d163575Sopenharmony_ci 1910d163575Sopenharmony_cierr_t sys_mbox_trypost_fromisr(sys_mbox_t *mbox, void *msg); 1920d163575Sopenharmony_ci 1930d163575Sopenharmony_ciu32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeoutMs) 1940d163575Sopenharmony_ci{ 1950d163575Sopenharmony_ci void *ignore = 0; /* if msg==NULL, the fetched msg should be dropped */ 1960d163575Sopenharmony_ci UINT64 tick = ROUND_UP_DIV((UINT64)timeoutMs * LOSCFG_BASE_CORE_TICK_PER_SECOND, OS_SYS_MS_PER_SECOND); 1970d163575Sopenharmony_ci UINT32 ret = LOS_QueueRead(*mbox, msg ? msg : &ignore, sizeof(void *), tick ? (UINT32)tick : LOS_WAIT_FOREVER); 1980d163575Sopenharmony_ci switch (ret) { 1990d163575Sopenharmony_ci case LOS_OK: 2000d163575Sopenharmony_ci return ERR_OK; 2010d163575Sopenharmony_ci case LOS_ERRNO_QUEUE_ISEMPTY: 2020d163575Sopenharmony_ci case LOS_ERRNO_QUEUE_TIMEOUT: 2030d163575Sopenharmony_ci return SYS_ARCH_TIMEOUT; 2040d163575Sopenharmony_ci default: 2050d163575Sopenharmony_ci break; 2060d163575Sopenharmony_ci } 2070d163575Sopenharmony_ci LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_QueueRead error %u\n", __FUNCTION__, ret)); 2080d163575Sopenharmony_ci return SYS_ARCH_TIMEOUT; /* Errors should be treated as timeout */ 2090d163575Sopenharmony_ci} 2100d163575Sopenharmony_ci 2110d163575Sopenharmony_ciu32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) 2120d163575Sopenharmony_ci{ 2130d163575Sopenharmony_ci void *ignore = 0; /* if msg==NULL, the fetched msg should be dropped */ 2140d163575Sopenharmony_ci UINT32 ret = LOS_QueueRead(*mbox, msg ? msg : &ignore, sizeof(void *), 0); 2150d163575Sopenharmony_ci switch (ret) { 2160d163575Sopenharmony_ci case LOS_OK: 2170d163575Sopenharmony_ci return ERR_OK; 2180d163575Sopenharmony_ci case LOS_ERRNO_QUEUE_ISEMPTY: 2190d163575Sopenharmony_ci return SYS_MBOX_EMPTY; 2200d163575Sopenharmony_ci case LOS_ERRNO_QUEUE_TIMEOUT: 2210d163575Sopenharmony_ci return SYS_ARCH_TIMEOUT; 2220d163575Sopenharmony_ci default: 2230d163575Sopenharmony_ci break; 2240d163575Sopenharmony_ci } 2250d163575Sopenharmony_ci LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_QueueRead error %u\n", __FUNCTION__, ret)); 2260d163575Sopenharmony_ci return SYS_MBOX_EMPTY; /* Errors should be treated as timeout */ 2270d163575Sopenharmony_ci} 2280d163575Sopenharmony_ci 2290d163575Sopenharmony_civoid sys_mbox_free(sys_mbox_t *mbox) 2300d163575Sopenharmony_ci{ 2310d163575Sopenharmony_ci (void)LOS_QueueDelete(*mbox); 2320d163575Sopenharmony_ci} 2330d163575Sopenharmony_ci 2340d163575Sopenharmony_ciint sys_mbox_valid(sys_mbox_t *mbox) 2350d163575Sopenharmony_ci{ 2360d163575Sopenharmony_ci QUEUE_INFO_S queueInfo; 2370d163575Sopenharmony_ci return LOS_OK == LOS_QueueInfoGet(*mbox, &queueInfo); 2380d163575Sopenharmony_ci} 2390d163575Sopenharmony_ci 2400d163575Sopenharmony_civoid sys_mbox_set_invalid(sys_mbox_t *mbox) 2410d163575Sopenharmony_ci{ 2420d163575Sopenharmony_ci *mbox = LOSCFG_BASE_IPC_QUEUE_LIMIT; 2430d163575Sopenharmony_ci} 2440d163575Sopenharmony_ci 2450d163575Sopenharmony_ci 2460d163575Sopenharmony_ci/** 2470d163575Sopenharmony_ci * Semaphore 2480d163575Sopenharmony_ci */ 2490d163575Sopenharmony_ci 2500d163575Sopenharmony_cierr_t sys_sem_new(sys_sem_t *sem, u8_t count) 2510d163575Sopenharmony_ci{ 2520d163575Sopenharmony_ci UINT32 ret = LOS_SemCreate(count, sem); 2530d163575Sopenharmony_ci if (ret != LOS_OK) { 2540d163575Sopenharmony_ci return ERR_ARG; 2550d163575Sopenharmony_ci } 2560d163575Sopenharmony_ci 2570d163575Sopenharmony_ci return ERR_OK; 2580d163575Sopenharmony_ci} 2590d163575Sopenharmony_ci 2600d163575Sopenharmony_civoid sys_sem_signal(sys_sem_t *sem) 2610d163575Sopenharmony_ci{ 2620d163575Sopenharmony_ci (void)LOS_SemPost(*sem); 2630d163575Sopenharmony_ci} 2640d163575Sopenharmony_ci 2650d163575Sopenharmony_ciu32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeoutMs) 2660d163575Sopenharmony_ci{ 2670d163575Sopenharmony_ci UINT64 tick = ROUND_UP_DIV((UINT64)timeoutMs * LOSCFG_BASE_CORE_TICK_PER_SECOND, OS_SYS_MS_PER_SECOND); 2680d163575Sopenharmony_ci UINT32 ret = LOS_SemPend(*sem, tick ? (UINT32)tick : LOS_WAIT_FOREVER); // timeoutMs 0 means wait forever 2690d163575Sopenharmony_ci switch (ret) { 2700d163575Sopenharmony_ci case LOS_OK: 2710d163575Sopenharmony_ci return ERR_OK; 2720d163575Sopenharmony_ci case LOS_ERRNO_SEM_TIMEOUT: 2730d163575Sopenharmony_ci return SYS_ARCH_TIMEOUT; 2740d163575Sopenharmony_ci default: 2750d163575Sopenharmony_ci break; 2760d163575Sopenharmony_ci } 2770d163575Sopenharmony_ci LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_SemPend error %u\n", __FUNCTION__, ret)); 2780d163575Sopenharmony_ci return SYS_ARCH_TIMEOUT; /* Errors should be treated as timeout */ 2790d163575Sopenharmony_ci} 2800d163575Sopenharmony_ci 2810d163575Sopenharmony_civoid sys_sem_free(sys_sem_t *sem) 2820d163575Sopenharmony_ci{ 2830d163575Sopenharmony_ci (void)LOS_SemDelete(*sem); 2840d163575Sopenharmony_ci} 2850d163575Sopenharmony_ci 2860d163575Sopenharmony_ciint sys_sem_valid(sys_sem_t *sem) 2870d163575Sopenharmony_ci{ 2880d163575Sopenharmony_ci return *sem != LOSCFG_BASE_IPC_SEM_LIMIT; 2890d163575Sopenharmony_ci} 2900d163575Sopenharmony_ci 2910d163575Sopenharmony_civoid sys_sem_set_invalid(sys_sem_t *sem) 2920d163575Sopenharmony_ci{ 2930d163575Sopenharmony_ci *sem = LOSCFG_BASE_IPC_SEM_LIMIT; 2940d163575Sopenharmony_ci} 2950d163575Sopenharmony_ci 2960d163575Sopenharmony_ci 2970d163575Sopenharmony_ci/** 2980d163575Sopenharmony_ci * Mutex 2990d163575Sopenharmony_ci */ 3000d163575Sopenharmony_ci 3010d163575Sopenharmony_cierr_t sys_mutex_new(sys_mutex_t *mutex) 3020d163575Sopenharmony_ci{ 3030d163575Sopenharmony_ci UINT32 ret = LOS_MuxInit(mutex, NULL); 3040d163575Sopenharmony_ci if (ret != LOS_OK) { 3050d163575Sopenharmony_ci return ERR_ARG; 3060d163575Sopenharmony_ci } 3070d163575Sopenharmony_ci 3080d163575Sopenharmony_ci return ERR_OK; 3090d163575Sopenharmony_ci} 3100d163575Sopenharmony_ci 3110d163575Sopenharmony_civoid sys_mutex_lock(sys_mutex_t *mutex) 3120d163575Sopenharmony_ci{ 3130d163575Sopenharmony_ci (void)LOS_MuxLock(mutex, LOS_WAIT_FOREVER); 3140d163575Sopenharmony_ci} 3150d163575Sopenharmony_ci 3160d163575Sopenharmony_civoid sys_mutex_unlock(sys_mutex_t *mutex) 3170d163575Sopenharmony_ci{ 3180d163575Sopenharmony_ci (void)LOS_MuxUnlock(mutex); 3190d163575Sopenharmony_ci} 3200d163575Sopenharmony_ci 3210d163575Sopenharmony_civoid sys_mutex_free(sys_mutex_t *mutex) 3220d163575Sopenharmony_ci{ 3230d163575Sopenharmony_ci (void)LOS_MuxDestroy(mutex); 3240d163575Sopenharmony_ci} 3250d163575Sopenharmony_ci 3260d163575Sopenharmony_ciint sys_mutex_valid(sys_mutex_t *mutex) 3270d163575Sopenharmony_ci{ 3280d163575Sopenharmony_ci return LOS_MuxIsValid(mutex); 3290d163575Sopenharmony_ci} 3300d163575Sopenharmony_ci 3310d163575Sopenharmony_civoid sys_mutex_set_invalid(sys_mutex_t *mutex) 3320d163575Sopenharmony_ci{ 3330d163575Sopenharmony_ci (void)LOS_MuxDestroy(mutex); 3340d163575Sopenharmony_ci} 335