/*
 * Copyright (C) 2016, Samsung Electronics Co., Ltd.
 *
 * Custom Handler. Interface to invoke Secure-kernel functions
 * Header file
 */

#ifndef __KERNEL_API_H__
#define __KERNEL_API_H__

#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>

/* Create secure mapping */
#define VMA_NON_SECURE (1 << 1)

/* Create non-cached mapping */
#define VMA_NON_CACHED (1 << 2)

/*
 * Declaration of the main handler function
 * Example:
 *   DECLARE_HANDLER_MAIN(unsigned int fid, struct custom_handler_params *params)
 *   {
 *   }
 */
#ifdef CONFIG_SDK40

#define DECLARE_HANDLER_MAIN(...) \
    void custom_handler_func(__VA_ARGS__)

#define vm_map_phys_buffer_dev	vm_map_phys_buffer

/* Custom handler API available for handler */
void printf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
void *vm_map_phys_buffer(unsigned long *pfns, unsigned int num_pages, unsigned int flags);
void vm_unmap_phys_buffer(unsigned long start, unsigned int size);
void panic(unsigned int code);
void *memset(void *s, int c, size_t n);
void *memcpy(void *dest, const void *src, size_t n);
int memcmp(const void *s1, const void *s2, size_t n);
char *strcpy(char *dest, const char *src);
int strcmp(const char *s1, const char *s2);
int strncmp(const char *s1, const char *s2, size_t n);
size_t strlen(const char *s);

#else

#define DECLARE_HANDLER_MAIN(...) \
	void smc_handler_main(__VA_ARGS__) __attribute__ ((section(".startup"))); \
	void smc_handler_main(__VA_ARGS__)

#define DECLARE_SK_FUNC(index, fn_name, ret_type, ...)    \
    enum { FN_##fn_name = index };               \
    typedef ret_type (* FT_##fn_name)(__VA_ARGS__)

#define CALL_SK_FUNC(fn_name, ...)  \
    ((FT_##fn_name)get_fptr(FN_##fn_name))(__VA_ARGS__)

unsigned long get_fptr(int index);

/*
 * Declare function prototypes
 */
DECLARE_SK_FUNC(0, printf, void, const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
DECLARE_SK_FUNC(1, vm_map_phys_buffer, void*, unsigned long* pfn_pages_array, unsigned int num_pages, unsigned int flags);
DECLARE_SK_FUNC(2, vm_unmap_phys_buffer, void, unsigned long start, unsigned int num_pages);
DECLARE_SK_FUNC(3, memset, void*, void *s, int c, size_t n);
DECLARE_SK_FUNC(4, memcpy, void*, void * dst, const void * src, size_t size);
DECLARE_SK_FUNC(5, memcmp, int, const void * buff1, const void * buff2, size_t size);
DECLARE_SK_FUNC(6, strcpy, char*, char * dest,const char * src);
DECLARE_SK_FUNC(7, strcmp, int, const char * str1, const char * str2);
DECLARE_SK_FUNC(8, strncmp, int, const char * str1, const char * str2, size_t size);
DECLARE_SK_FUNC(9, strlen, size_t, const char * src_str);
DECLARE_SK_FUNC(10, vm_map_phys_buffer_dev, void*, unsigned long* pfn_pages_array, unsigned int num_pages, unsigned int flags);
DECLARE_SK_FUNC(11, kernel_panic, void, void);

/*
 * Declare function wrappers
 */
#define printf(...)                CALL_SK_FUNC(printf, __VA_ARGS__)
#define vm_map_phys_buffer(...)    CALL_SK_FUNC(vm_map_phys_buffer, __VA_ARGS__)
#define vm_unmap_phys_buffer(...)  CALL_SK_FUNC(vm_unmap_phys_buffer, __VA_ARGS__)
#define memset(...)                CALL_SK_FUNC(memset, __VA_ARGS__)
#define memcpy(...)                CALL_SK_FUNC(memcpy, __VA_ARGS__)
#define memcmp(...)                CALL_SK_FUNC(memcmp, __VA_ARGS__)
#define strcpy(...)                CALL_SK_FUNC(strcpy, __VA_ARGS__)
#define strcmp(...)                CALL_SK_FUNC(strcmp, __VA_ARGS__)
#define strncmp(...)               CALL_SK_FUNC(strncmp, __VA_ARGS__)
#define strlen(...)                CALL_SK_FUNC(strlen, __VA_ARGS__)
#define vm_map_phys_buffer_dev(...)    CALL_SK_FUNC(vm_map_phys_buffer_dev, __VA_ARGS__)
#define kernel_panic(...)          CALL_SK_FUNC(kernel_panic, __VA_ARGS__)

#endif
#endif  /* __KERNEL_API_H__ */
