Path: blob/main/sys/contrib/vchiq/interface/compat/vchi_bsd.h
48383 views
/*-1* Copyright (c) 2010 Max Khon <[email protected]>2* Copyright (c) 2012 Oleksandr Tymoshenko <[email protected]>3* Copyright (c) 2013 Jared D. McNeill <[email protected]>4* All rights reserved.5*6* Redistribution and use in source and binary forms, with or without7* modification, are permitted provided that the following conditions8* are met:9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11* 2. Redistributions in binary form must reproduce the above copyright12* notice, this list of conditions and the following disclaimer in the13* documentation and/or other materials provided with the distribution.14*15* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND16* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE17* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE18* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE19* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL20* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS21* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)22* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT23* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY24* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF25* SUCH DAMAGE.26*/27#ifndef __VCHI_BSD_H__28#define __VCHI_BSD_H__2930#include <sys/param.h>31#include <sys/systm.h>32#include <sys/bus.h>33#include <sys/conf.h>34#include <sys/lock.h>35#include <sys/kernel.h>36#include <sys/kthread.h>37#include <sys/mutex.h>38#include <sys/rwlock.h>39#include <sys/sx.h>40#include <sys/sema.h>41#include <sys/malloc.h>42#include <sys/proc.h>43#include <sys/types.h>44#include <sys/ioccom.h>4546/*47* Copy from/to user API48*/49#define copy_from_user(to, from, n) copyin((from), (to), (n))50#define copy_to_user(to, from, n) copyout((from), (to), (n))5152/*53* Bit API54*/5556static __inline int57test_and_set_bit(int nr, volatile void *addr)58{59int val;6061do {62val = *(volatile int *) addr;63} while (atomic_cmpset_int(addr, val, val | (1 << nr)) == 0);64return (val & (1 << nr));65}6667static __inline__68int test_and_clear_bit(int nr, volatile void *addr)69{70int val;7172do {73val = *(volatile int *) addr;74} while (atomic_cmpset_int(addr, val, val & ~(1 << nr)) == 0);75return (val & (1 << nr));76}7778/*79* Atomic API80*/81typedef volatile unsigned atomic_t;8283#define atomic_set(p, v) (*(p) = (v))84#define atomic_read(p) (*(p))85#define atomic_inc(p) atomic_add_int(p, 1)86#define atomic_dec(p) atomic_subtract_int(p, 1)87#define atomic_dec_and_test(p) (atomic_fetchadd_int(p, -1) == 1)88#define atomic_inc_return(v) atomic_add_return(1, (v))89#define atomic_dec_return(v) atomic_sub_return(1, (v))90#define atomic_add(v, p) atomic_add_int(p, v)91#define atomic_sub(v, p) atomic_subtract_int(p, v)9293#define ATOMIC_INIT(v) (v)9495static inline int96atomic_add_return(int i, atomic_t *v)97{98return i + atomic_fetchadd_int(v, i);99}100101static inline int102atomic_sub_return(int i, atomic_t *v)103{104return atomic_fetchadd_int(v, -i) - i;105}106107static inline int108atomic_cmpxchg(atomic_t *v, int oldv, int newv)109{110if (atomic_cmpset_rel_int(v, oldv, newv))111return newv;112else113return *v;114}115116static inline int117atomic_xchg(atomic_t *v, int newv)118{119int oldv;120if (newv == 0)121return atomic_readandclear_int(v);122else {123do {124oldv = atomic_load_acq_int(v);125} while (!atomic_cmpset_rel_int(v, oldv, newv));126}127128return (oldv);129}130131/*132* Spinlock API133*/134typedef struct mtx spinlock_t;135136#define DEFINE_SPINLOCK(name) \137struct mtx name138#define spin_lock_init(lock) mtx_init(lock, "VCHI spinlock " # lock, NULL, MTX_DEF)139#define spin_lock_destroy(lock) mtx_destroy(lock)140#define spin_lock(lock) mtx_lock(lock)141#define spin_unlock(lock) mtx_unlock(lock)142#define spin_lock_bh(lock) spin_lock(lock)143#define spin_unlock_bh(lock) spin_unlock(lock)144145/*146* Mutex API147*/148struct mutex {149struct sx mtx;150};151152#define lmutex_init(lock) sx_init(&(lock)->mtx, #lock)153#define lmutex_lock(lock) sx_xlock(&(lock)->mtx)154#define lmutex_unlock(lock) sx_unlock(&(lock)->mtx)155#define lmutex_destroy(lock) sx_destroy(&(lock)->mtx)156157#define lmutex_lock_interruptible(lock) sx_xlock_sig(&(lock)->mtx)158159/*160* Rwlock API161*/162typedef struct rwlock rwlock_t;163164#define DEFINE_RWLOCK(name) \165struct rwlock name; \166SX_SYSINIT(name, &name, #name)167#define rwlock_init(rwlock) rw_init(rwlock, "VCHI rwlock")168#define read_lock(rwlock) rw_rlock(rwlock)169#define read_unlock(rwlock) rw_unlock(rwlock)170171#define write_lock(rwlock) rw_wlock(rwlock)172#define write_unlock(rwlock) rw_unlock(rwlock)173#define write_lock_irqsave(rwlock, flags) \174do { \175rw_wlock(rwlock); \176(void) &(flags); \177} while (0)178#define write_unlock_irqrestore(rwlock, flags) \179rw_unlock(rwlock)180181#define read_lock_bh(rwlock) rw_rlock(rwlock)182#define read_unlock_bh(rwlock) rw_unlock(rwlock)183#define write_lock_bh(rwlock) rw_wlock(rwlock)184#define write_unlock_bh(rwlock) rw_unlock(rwlock)185186/*187* Timer API188*/189struct timer_list {190struct mtx mtx;191struct callout callout;192193unsigned long expires;194void (*function)(unsigned long);195unsigned long data;196};197198void vchiq_init_timer(struct timer_list *t);199void vchiq_setup_timer(struct timer_list *t, void (*function)(unsigned long), unsigned long data);200void vchiq_mod_timer(struct timer_list *t, unsigned long expires);201void vchiq_add_timer(struct timer_list *t);202int vchiq_del_timer(struct timer_list *t);203int vchiq_del_timer_sync(struct timer_list *t);204205/*206* Completion API207*/208struct completion {209struct cv cv;210struct mtx lock;211int done;212};213214void init_completion(struct completion *c);215void destroy_completion(struct completion *c);216int try_wait_for_completion(struct completion *);217int wait_for_completion_interruptible(struct completion *);218int wait_for_completion_interruptible_timeout(struct completion *, unsigned long ticks);219int wait_for_completion_killable(struct completion *);220void wait_for_completion(struct completion *c);221void complete(struct completion *c);222void complete_all(struct completion *c);223void INIT_COMPLETION_locked(struct completion *c);224225#define INIT_COMPLETION(x) INIT_COMPLETION_locked(&(x))226227/*228* Semaphore API229*/230struct semaphore {231struct mtx mtx;232struct cv cv;233int value;234int waiters;235};236237#define DEFINE_SEMAPHORE(name) \238struct semaphore name; \239SYSINIT(name##_sema_sysinit, SI_SUB_LOCK, SI_ORDER_MIDDLE, \240sema_sysinit, &name); \241SYSUNINIT(name##_sema_sysuninit, SI_SUB_LOCK, SI_ORDER_MIDDLE, \242_sema_destroy, __DEVOLATILE(void *, &(name)))243244void sema_sysinit(void *arg);245void _sema_init(struct semaphore *s, int value);246void _sema_destroy(struct semaphore *s);247void down(struct semaphore *s);248int down_interruptible(struct semaphore *s);249int down_trylock(struct semaphore *s);250void up(struct semaphore *s);251252/*253* Logging and assertions API254*/255void rlprintf(int pps, const char *fmt, ...)256__printflike(2, 3);257258void259device_rlprintf(int pps, device_t dev, const char *fmt, ...)260__printflike(3, 4);261262#define might_sleep()263264#define WARN(condition, msg) \265({ \266int __ret_warn_on = !!(condition); \267if (unlikely(__ret_warn_on)) \268printf((msg)); \269unlikely(__ret_warn_on); \270})271272273274#define WARN_ON(condition) \275({ \276int __ret_warn_on = !!(condition); \277if (unlikely(__ret_warn_on)) \278printf("WARN_ON: " #condition "\n"); \279unlikely(__ret_warn_on); \280})281282#define WARN_ON_ONCE(condition) ({ \283static int __warned; \284int __ret_warn_once = !!(condition); \285\286if (unlikely(__ret_warn_once)) \287if (WARN_ON(!__warned)) \288__warned = 1; \289unlikely(__ret_warn_once); \290})291292#define BUG_ON(cond) \293do { \294if (cond) \295panic("BUG_ON: " #cond); \296} while (0)297298#define BUG() \299do { \300panic("BUG: %s:%d", __FILE__, __LINE__); \301} while (0)302303#define vchiq_static_assert(cond) CTASSERT(cond)304305#define KERN_EMERG "<0>" /* system is unusable */306#define KERN_ALERT "<1>" /* action must be taken immediately */307#define KERN_CRIT "<2>" /* critical conditions */308#define KERN_ERR "<3>" /* error conditions */309#define KERN_WARNING "<4>" /* warning conditions */310#define KERN_NOTICE "<5>" /* normal but significant condition */311#define KERN_INFO "<6>" /* informational */312#define KERN_DEBUG "<7>" /* debug-level messages */313#define KERN_CONT ""314315#define printk(fmt, args...) printf(fmt, ##args)316#define vprintk(fmt, args) vprintf(fmt, args)317318/*319* Malloc API320*/321#define GFP_KERNEL 0322#define GFP_ATOMIC 0323324MALLOC_DECLARE(M_VCHI);325326#define kmalloc(size, flags) malloc((size), M_VCHI, M_NOWAIT | M_ZERO)327#define kcalloc(n, size, flags) mallocarray((n), (size), M_VCHI, \328M_NOWAIT | M_ZERO)329#define kzalloc(a, b) kcalloc(1, (a), (b))330#define kfree(p) free(p, M_VCHI)331332/*333* Kernel module API334*/335#define __init336#define __exit337#define __devinit338#define __devexit339#define __devinitdata340341/*342* Time API343*/344#if 1345/* emulate jiffies */346static inline unsigned long347_jiffies(void)348{349struct timeval tv;350351microuptime(&tv);352return tvtohz(&tv);353}354355static inline unsigned long356msecs_to_jiffies(unsigned long msecs)357{358struct timeval tv;359360tv.tv_sec = msecs / 1000000UL;361tv.tv_usec = msecs % 1000000UL;362return tvtohz(&tv);363}364365#define jiffies _jiffies()366#else367#define jiffies ticks368#endif369#define HZ hz370371#define udelay(usec) DELAY(usec)372#define mdelay(msec) DELAY((msec) * 1000)373374#define schedule_timeout(jiff) pause("dhdslp", jiff)375376#if defined(msleep)377#undef msleep378#endif379#define msleep(msec) mdelay(msec)380381#define time_after(a, b) ((a) > (b))382#define time_after_eq(a, b) ((a) >= (b))383#define time_before(a, b) time_after((b), (a))384385/*386* kthread API (we use proc)387*/388typedef struct proc * VCHIQ_THREAD_T;389390VCHIQ_THREAD_T vchiq_thread_create(int (*threadfn)(void *data),391void *data,392const char namefmt[], ...);393void set_user_nice(VCHIQ_THREAD_T p, int nice);394void wake_up_process(VCHIQ_THREAD_T p);395396/*397* Proc APIs398*/399void flush_signals(VCHIQ_THREAD_T);400int fatal_signal_pending(VCHIQ_THREAD_T);401402/*403* mbox API404*/405void bcm_mbox_write(int channel, uint32_t data);406407/*408* Misc API409*/410411#define ENODATA EINVAL412413#define __user414415#define likely(x) __builtin_expect(!!(x), 1)416#define unlikely(x) __builtin_expect(!!(x), 0)417#define current curproc418#define EXPORT_SYMBOL(x)419#define PAGE_ALIGN(addr) round_page(addr)420421typedef void irqreturn_t;422typedef off_t loff_t;423424#define BCM2835_MBOX_CHAN_VCHIQ 3425426#define smp_mb wmb427#define smp_rmb rmb428#define smp_wmb wmb429430#define device_print_prettyname(dev) device_printf((dev), "")431432#endif /* __VCHI_BSD_H__ */433434435