aboutsummaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
authorMaxim Uvarov <maxim.uvarov@linaro.org>2015-11-30 12:44:48 +0300
committerMaxim Uvarov <maxim.uvarov@linaro.org>2015-11-30 12:44:48 +0300
commit74785c4e170e035c08476179237d68a36fa23ec3 (patch)
tree2d614f6491c214b138ed72e5568eb611ef68fe19 /platform
parent56e6043816ecbe954e804004f0b13cdad5915341 (diff)
parent6f7fad3acc8254a273a0ed80833bf422ad01d9c0 (diff)
Merge branch 'next'
Diffstat (limited to 'platform')
-rw-r--r--platform/linux-generic/Makefile.am1
-rw-r--r--platform/linux-generic/include/odp/plat/crypto_types.h42
-rw-r--r--platform/linux-generic/include/odp/plat/time_types.h36
-rw-r--r--platform/linux-generic/include/odp/time.h1
-rw-r--r--platform/linux-generic/include/odp_buffer_internal.h2
-rw-r--r--platform/linux-generic/include/odp_cpu_internal.h2
-rw-r--r--platform/linux-generic/include/odp_crypto_internal.h20
-rw-r--r--platform/linux-generic/odp_cpu.c4
-rw-r--r--platform/linux-generic/odp_crypto.c205
-rw-r--r--platform/linux-generic/odp_packet.c32
-rw-r--r--platform/linux-generic/odp_pool.c29
-rw-r--r--platform/linux-generic/odp_queue.c40
-rw-r--r--platform/linux-generic/odp_schedule.c16
-rw-r--r--platform/linux-generic/odp_time.c62
-rw-r--r--platform/linux-generic/odp_timer.c4
15 files changed, 410 insertions, 86 deletions
diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am
index 610e04d9e..70bd8fe85 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -70,6 +70,7 @@ odpplatinclude_HEADERS = \
$(srcdir)/include/odp/plat/strong_types.h \
$(srcdir)/include/odp/plat/thrmask_types.h \
$(srcdir)/include/odp/plat/ticketlock_types.h \
+ $(srcdir)/include/odp/plat/time_types.h \
$(srcdir)/include/odp/plat/timer_types.h \
$(srcdir)/include/odp/plat/version_types.h
diff --git a/platform/linux-generic/include/odp/plat/crypto_types.h b/platform/linux-generic/include/odp/plat/crypto_types.h
index a91d88e6c..0cbbce8bd 100644
--- a/platform/linux-generic/include/odp/plat/crypto_types.h
+++ b/platform/linux-generic/include/odp/plat/crypto_types.h
@@ -27,48 +27,6 @@ extern "C" {
typedef uint64_t odp_crypto_session_t;
typedef ODP_HANDLE_T(odp_crypto_compl_t);
-enum odp_crypto_op_mode {
- ODP_CRYPTO_SYNC,
- ODP_CRYPTO_ASYNC,
-};
-
-enum odp_crypto_op {
- ODP_CRYPTO_OP_ENCODE,
- ODP_CRYPTO_OP_DECODE,
-};
-
-enum odp_cipher_alg {
- ODP_CIPHER_ALG_NULL,
- ODP_CIPHER_ALG_DES,
- ODP_CIPHER_ALG_3DES_CBC,
-};
-
-enum odp_auth_alg {
- ODP_AUTH_ALG_NULL,
- ODP_AUTH_ALG_MD5_96,
-};
-
-enum odp_crypto_ses_create_err {
- ODP_CRYPTO_SES_CREATE_ERR_NONE,
- ODP_CRYPTO_SES_CREATE_ERR_ENOMEM,
- ODP_CRYPTO_SES_CREATE_ERR_INV_CIPHER,
- ODP_CRYPTO_SES_CREATE_ERR_INV_AUTH,
-};
-
-enum crypto_alg_err {
- ODP_CRYPTO_ALG_ERR_NONE,
- ODP_CRYPTO_ALG_ERR_DATA_SIZE,
- ODP_CRYPTO_ALG_ERR_KEY_SIZE,
- ODP_CRYPTO_ALG_ERR_ICV_CHECK,
- ODP_CRYPTO_ALG_ERR_IV_INVALID,
-};
-
-enum crypto_hw_err {
- ODP_CRYPTO_HW_ERR_NONE,
- ODP_CRYPTO_HW_ERR_DMA,
- ODP_CRYPTO_HW_ERR_BP_DEPLETED,
-};
-
/** Get printable format of odp_crypto_session_t */
static inline uint64_t odp_crypto_session_to_u64(odp_crypto_session_t hdl)
{
diff --git a/platform/linux-generic/include/odp/plat/time_types.h b/platform/linux-generic/include/odp/plat/time_types.h
new file mode 100644
index 000000000..9ba1508c7
--- /dev/null
+++ b/platform/linux-generic/include/odp/plat/time_types.h
@@ -0,0 +1,36 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP time service
+ */
+
+#ifndef ODP_TIME_TYPES_H_
+#define ODP_TIME_TYPES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup odp_time
+ * @{
+ **/
+
+typedef uint64_t odp_time_t;
+
+#define ODP_TIME_NULL ((odp_time_t)0)
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/linux-generic/include/odp/time.h b/platform/linux-generic/include/odp/time.h
index 3a3960b02..44e0d0d25 100644
--- a/platform/linux-generic/include/odp/time.h
+++ b/platform/linux-generic/include/odp/time.h
@@ -21,6 +21,7 @@ extern "C" {
+#include <odp/plat/time_types.h>
#include <odp/api/time.h>
#ifdef __cplusplus
diff --git a/platform/linux-generic/include/odp_buffer_internal.h b/platform/linux-generic/include/odp_buffer_internal.h
index 462f4bf3b..74a0b5c4f 100644
--- a/platform/linux-generic/include/odp_buffer_internal.h
+++ b/platform/linux-generic/include/odp_buffer_internal.h
@@ -166,6 +166,8 @@ typedef struct {
/* Forward declarations */
odp_buffer_t buffer_alloc(odp_pool_t pool, size_t size);
+int buffer_alloc_multi(odp_pool_t pool_hdl, size_t size,
+ odp_buffer_t buf[], int num);
#ifdef __cplusplus
}
diff --git a/platform/linux-generic/include/odp_cpu_internal.h b/platform/linux-generic/include/odp_cpu_internal.h
index 5eeabefec..664e2df5d 100644
--- a/platform/linux-generic/include/odp_cpu_internal.h
+++ b/platform/linux-generic/include/odp_cpu_internal.h
@@ -14,7 +14,7 @@ extern "C" {
#include <odp/cpu.h>
static inline
-uint64_t _odp_cpu_cycles_diff(uint64_t c1, uint64_t c2)
+uint64_t _odp_cpu_cycles_diff(uint64_t c2, uint64_t c1)
{
if (odp_likely(c2 >= c1))
return c2 - c1;
diff --git a/platform/linux-generic/include/odp_crypto_internal.h b/platform/linux-generic/include/odp_crypto_internal.h
index ebd6170e2..b9128a426 100644
--- a/platform/linux-generic/include/odp_crypto_internal.h
+++ b/platform/linux-generic/include/odp_crypto_internal.h
@@ -12,6 +12,7 @@ extern "C" {
#endif
#include <openssl/des.h>
+#include <openssl/aes.h>
#define OP_RESULT_MAGIC 0x91919191
@@ -22,20 +23,20 @@ typedef struct odp_crypto_generic_session odp_crypto_generic_session_t;
* Algorithm handler function prototype
*/
typedef
-enum crypto_alg_err (*crypto_func_t)(odp_crypto_op_params_t *params,
- odp_crypto_generic_session_t *session);
+odp_crypto_alg_err_t (*crypto_func_t)(odp_crypto_op_params_t *params,
+ odp_crypto_generic_session_t *session);
/**
* Per crypto session data structure
*/
struct odp_crypto_generic_session {
struct odp_crypto_generic_session *next;
- enum odp_crypto_op op;
+ odp_crypto_op_t op;
odp_bool_t do_cipher_first;
odp_queue_t compl_queue;
odp_pool_t output_pool;
struct {
- enum odp_cipher_alg alg;
+ odp_cipher_alg_t alg;
struct {
uint8_t *data;
size_t len;
@@ -46,16 +47,23 @@ struct odp_crypto_generic_session {
DES_key_schedule ks2;
DES_key_schedule ks3;
} des;
+ struct {
+ AES_KEY key;
+ } aes;
} data;
crypto_func_t func;
} cipher;
struct {
- enum odp_auth_alg alg;
+ odp_auth_alg_t alg;
union {
struct {
uint8_t key[16];
uint32_t bytes;
} md5;
+ struct {
+ uint8_t key[32];
+ uint32_t bytes;
+ } sha256;
} data;
crypto_func_t func;
} auth;
@@ -73,7 +81,7 @@ typedef struct odp_crypto_generic_op_result {
* Per session creation operation result
*/
typedef struct odp_crypto_generic_session_result {
- enum odp_crypto_ses_create_err rc;
+ odp_crypto_ses_create_err_t rc;
odp_crypto_session_t session;
} odp_crypto_generic_session_result_t;
diff --git a/platform/linux-generic/odp_cpu.c b/platform/linux-generic/odp_cpu.c
index e5ec4f08d..636f811f8 100644
--- a/platform/linux-generic/odp_cpu.c
+++ b/platform/linux-generic/odp_cpu.c
@@ -8,7 +8,7 @@
#include <odp/hints.h>
#include <odp_cpu_internal.h>
-uint64_t odp_cpu_cycles_diff(uint64_t c1, uint64_t c2)
+uint64_t odp_cpu_cycles_diff(uint64_t c2, uint64_t c1)
{
- return _odp_cpu_cycles_diff(c1, c2);
+ return _odp_cpu_cycles_diff(c2, c1);
}
diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c
index d49e256d5..17fced930 100644
--- a/platform/linux-generic/odp_crypto.c
+++ b/platform/linux-generic/odp_crypto.c
@@ -66,17 +66,16 @@ void free_session(odp_crypto_generic_session_t *session)
odp_spinlock_unlock(&global->lock);
}
-static
-enum crypto_alg_err null_crypto_routine(
- odp_crypto_op_params_t *params ODP_UNUSED,
- odp_crypto_generic_session_t *session ODP_UNUSED)
+static odp_crypto_alg_err_t
+null_crypto_routine(odp_crypto_op_params_t *params ODP_UNUSED,
+ odp_crypto_generic_session_t *session ODP_UNUSED)
{
return ODP_CRYPTO_ALG_ERR_NONE;
}
static
-enum crypto_alg_err md5_gen(odp_crypto_op_params_t *params,
- odp_crypto_generic_session_t *session)
+odp_crypto_alg_err_t md5_gen(odp_crypto_op_params_t *params,
+ odp_crypto_generic_session_t *session)
{
uint8_t *data = odp_packet_data(params->out_pkt);
uint8_t *icv = data;
@@ -103,8 +102,8 @@ enum crypto_alg_err md5_gen(odp_crypto_op_params_t *params,
}
static
-enum crypto_alg_err md5_check(odp_crypto_op_params_t *params,
- odp_crypto_generic_session_t *session)
+odp_crypto_alg_err_t md5_check(odp_crypto_op_params_t *params,
+ odp_crypto_generic_session_t *session)
{
uint8_t *data = odp_packet_data(params->out_pkt);
uint8_t *icv = data;
@@ -141,10 +140,162 @@ enum crypto_alg_err md5_check(odp_crypto_op_params_t *params,
}
static
-enum crypto_alg_err des_encrypt(odp_crypto_op_params_t *params,
+odp_crypto_alg_err_t sha256_gen(odp_crypto_op_params_t *params,
odp_crypto_generic_session_t *session)
{
uint8_t *data = odp_packet_data(params->out_pkt);
+ uint8_t *icv = data;
+ uint32_t len = params->auth_range.length;
+ uint8_t hash[EVP_MAX_MD_SIZE];
+
+ /* Adjust pointer for beginning of area to auth */
+ data += params->auth_range.offset;
+ icv += params->hash_result_offset;
+
+ /* Hash it */
+ HMAC(EVP_sha256(),
+ session->auth.data.sha256.key,
+ 32,
+ data,
+ len,
+ hash,
+ NULL);
+
+ /* Copy to the output location */
+ memcpy(icv, hash, session->auth.data.sha256.bytes);
+
+ return ODP_CRYPTO_ALG_ERR_NONE;
+}
+
+static
+odp_crypto_alg_err_t sha256_check(odp_crypto_op_params_t *params,
+ odp_crypto_generic_session_t *session)
+{
+ uint8_t *data = odp_packet_data(params->out_pkt);
+ uint8_t *icv = data;
+ uint32_t len = params->auth_range.length;
+ uint32_t bytes = session->auth.data.sha256.bytes;
+ uint8_t hash_in[EVP_MAX_MD_SIZE];
+ uint8_t hash_out[EVP_MAX_MD_SIZE];
+
+ /* Adjust pointer for beginning of area to auth */
+ data += params->auth_range.offset;
+ icv += params->hash_result_offset;
+
+ /* Copy current value out and clear it before authentication */
+ memset(hash_in, 0, sizeof(hash_in));
+ memcpy(hash_in, icv, bytes);
+ memset(icv, 0, bytes);
+ memset(hash_out, 0, sizeof(hash_out));
+
+ /* Hash it */
+ HMAC(EVP_sha256(),
+ session->auth.data.sha256.key,
+ 32,
+ data,
+ len,
+ hash_out,
+ NULL);
+
+ /* Verify match */
+ if (0 != memcmp(hash_in, hash_out, bytes))
+ return ODP_CRYPTO_ALG_ERR_ICV_CHECK;
+
+ /* Matched */
+ return ODP_CRYPTO_ALG_ERR_NONE;
+}
+
+static
+odp_crypto_alg_err_t aes_encrypt(odp_crypto_op_params_t *params,
+ odp_crypto_generic_session_t *session)
+{
+ uint8_t *data = odp_packet_data(params->out_pkt);
+ uint32_t len = params->cipher_range.length;
+ unsigned char iv_enc[AES_BLOCK_SIZE];
+ void *iv_ptr;
+
+ if (params->override_iv_ptr)
+ iv_ptr = params->override_iv_ptr;
+ else if (session->cipher.iv.data)
+ iv_ptr = session->cipher.iv.data;
+ else
+ return ODP_CRYPTO_ALG_ERR_IV_INVALID;
+
+ /*
+ * Create a copy of the IV. The DES library modifies IV
+ * and if we are processing packets on parallel threads
+ * we could get corruption.
+ */
+ memcpy(iv_enc, iv_ptr, AES_BLOCK_SIZE);
+
+ /* Adjust pointer for beginning of area to cipher */
+ data += params->cipher_range.offset;
+ /* Encrypt it */
+ AES_cbc_encrypt(data, data, len, &session->cipher.data.aes.key,
+ iv_enc, AES_ENCRYPT);
+
+ return ODP_CRYPTO_ALG_ERR_NONE;
+}
+
+static
+odp_crypto_alg_err_t aes_decrypt(odp_crypto_op_params_t *params,
+ odp_crypto_generic_session_t *session)
+{
+ uint8_t *data = odp_packet_data(params->out_pkt);
+ uint32_t len = params->cipher_range.length;
+ unsigned char iv_enc[AES_BLOCK_SIZE];
+ void *iv_ptr;
+
+ if (params->override_iv_ptr)
+ iv_ptr = params->override_iv_ptr;
+ else if (session->cipher.iv.data)
+ iv_ptr = session->cipher.iv.data;
+ else
+ return ODP_CRYPTO_ALG_ERR_IV_INVALID;
+
+ /*
+ * Create a copy of the IV. The DES library modifies IV
+ * and if we are processing packets on parallel threads
+ * we could get corruption.
+ */
+ memcpy(iv_enc, iv_ptr, AES_BLOCK_SIZE);
+
+ /* Adjust pointer for beginning of area to cipher */
+ data += params->cipher_range.offset;
+ /* Encrypt it */
+ AES_cbc_encrypt(data, data, len, &session->cipher.data.aes.key,
+ iv_enc, AES_DECRYPT);
+
+ return ODP_CRYPTO_ALG_ERR_NONE;
+}
+
+static
+int process_aes_params(odp_crypto_generic_session_t *session,
+ odp_crypto_session_params_t *params)
+{
+ /* Verify IV len is either 0 or 16 */
+ if (!((0 == params->iv.length) || (16 == params->iv.length)))
+ return -1;
+
+ /* Set function */
+ if (ODP_CRYPTO_OP_ENCODE == params->op) {
+ session->cipher.func = aes_encrypt;
+ AES_set_encrypt_key(params->cipher_key.data, 128,
+ &session->cipher.data.aes.key);
+ } else {
+ session->cipher.func = aes_decrypt;
+ AES_set_decrypt_key(params->cipher_key.data, 128,
+ &session->cipher.data.aes.key);
+ }
+
+ return 0;
+}
+
+static
+odp_crypto_alg_err_t des_encrypt(odp_crypto_op_params_t *params,
+ odp_crypto_generic_session_t *session)
+{
+ uint8_t *data = odp_packet_data(params->out_pkt);
uint32_t len = params->cipher_range.length;
DES_cblock iv;
void *iv_ptr;
@@ -179,8 +330,8 @@ enum crypto_alg_err des_encrypt(odp_crypto_op_params_t *params,
}
static
-enum crypto_alg_err des_decrypt(odp_crypto_op_params_t *params,
- odp_crypto_generic_session_t *session)
+odp_crypto_alg_err_t des_decrypt(odp_crypto_op_params_t *params,
+ odp_crypto_generic_session_t *session)
{
uint8_t *data = odp_packet_data(params->out_pkt);
uint32_t len = params->cipher_range.length;
@@ -262,10 +413,30 @@ int process_md5_params(odp_crypto_generic_session_t *session,
return 0;
}
+static
+int process_sha256_params(odp_crypto_generic_session_t *session,
+ odp_crypto_session_params_t *params,
+ uint32_t bits)
+{
+ /* Set function */
+ if (ODP_CRYPTO_OP_ENCODE == params->op)
+ session->auth.func = sha256_gen;
+ else
+ session->auth.func = sha256_check;
+
+ /* Number of valid bytes */
+ session->auth.data.sha256.bytes = bits / 8;
+
+ /* Convert keys */
+ memcpy(session->auth.data.sha256.key, params->auth_key.data, 32);
+
+ return 0;
+}
+
int
odp_crypto_session_create(odp_crypto_session_params_t *params,
odp_crypto_session_t *session_out,
- enum odp_crypto_ses_create_err *status)
+ odp_crypto_ses_create_err_t *status)
{
int rc;
odp_crypto_generic_session_t *session;
@@ -305,6 +476,9 @@ odp_crypto_session_create(odp_crypto_session_params_t *params,
case ODP_CIPHER_ALG_3DES_CBC:
rc = process_des_params(session, params);
break;
+ case ODP_CIPHER_ALG_AES128_CBC:
+ rc = process_aes_params(session, params);
+ break;
default:
rc = -1;
}
@@ -324,6 +498,9 @@ odp_crypto_session_create(odp_crypto_session_params_t *params,
case ODP_AUTH_ALG_MD5_96:
rc = process_md5_params(session, params, 96);
break;
+ case ODP_AUTH_ALG_SHA256_128:
+ rc = process_sha256_params(session, params, 128);
+ break;
default:
rc = -1;
}
@@ -354,8 +531,8 @@ odp_crypto_operation(odp_crypto_op_params_t *params,
odp_bool_t *posted,
odp_crypto_op_result_t *result)
{
- enum crypto_alg_err rc_cipher = ODP_CRYPTO_ALG_ERR_NONE;
- enum crypto_alg_err rc_auth = ODP_CRYPTO_ALG_ERR_NONE;
+ odp_crypto_alg_err_t rc_cipher = ODP_CRYPTO_ALG_ERR_NONE;
+ odp_crypto_alg_err_t rc_auth = ODP_CRYPTO_ALG_ERR_NONE;
odp_crypto_generic_session_t *session;
odp_crypto_op_result_t local_result;
diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c
index 1b496247f..07c740cfa 100644
--- a/platform/linux-generic/odp_packet.c
+++ b/platform/linux-generic/odp_packet.c
@@ -15,6 +15,7 @@
#include <odp/helper/tcp.h>
#include <odp/helper/udp.h>
+#include <errno.h>
#include <string.h>
#include <stdio.h>
@@ -127,11 +128,42 @@ odp_packet_t odp_packet_alloc(odp_pool_t pool_hdl, uint32_t len)
return packet_alloc(pool_hdl, len, 0);
}
+int odp_packet_alloc_multi(odp_pool_t pool_hdl, uint32_t len,
+ odp_packet_t pkt[], int num)
+{
+ pool_entry_t *pool = odp_pool_to_entry(pool_hdl);
+ size_t pkt_size = len ? len : pool->s.params.buf.size;
+ int count, i;
+
+ if (pool->s.params.type != ODP_POOL_PACKET) {
+ __odp_errno = EINVAL;
+ return -1;
+ }
+
+ count = buffer_alloc_multi(pool_hdl, pkt_size,
+ (odp_buffer_t *)pkt, num);
+
+ for (i = 0; i < count; ++i) {
+ odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt[i]);
+
+ packet_init(pool, pkt_hdr, pkt_size, 0);
+ if (len == 0)
+ pull_tail(pkt_hdr, pkt_size);
+ }
+
+ return count;
+}
+
void odp_packet_free(odp_packet_t pkt)
{
odp_buffer_free((odp_buffer_t)pkt);
}
+void odp_packet_free_multi(const odp_packet_t pkt[], int num)
+{
+ odp_buffer_free_multi((const odp_buffer_t *)pkt, num);
+}
+
int odp_packet_reset(odp_packet_t pkt, uint32_t len)
{
odp_packet_hdr_t *const pkt_hdr = odp_packet_hdr(pkt);
diff --git a/platform/linux-generic/odp_pool.c b/platform/linux-generic/odp_pool.c
index 76a4aa585..9859ff6d9 100644
--- a/platform/linux-generic/odp_pool.c
+++ b/platform/linux-generic/odp_pool.c
@@ -529,12 +529,33 @@ odp_buffer_t buffer_alloc(odp_pool_t pool_hdl, size_t size)
return odp_hdr_to_buf(&buf->buf);
}
+int buffer_alloc_multi(odp_pool_t pool_hdl, size_t size,
+ odp_buffer_t buf[], int num)
+{
+ int count;
+
+ for (count = 0; count < num; ++count) {
+ buf[count] = buffer_alloc(pool_hdl, size);
+ if (buf[count] == ODP_BUFFER_INVALID)
+ break;
+ }
+
+ return count;
+}
+
odp_buffer_t odp_buffer_alloc(odp_pool_t pool_hdl)
{
return buffer_alloc(pool_hdl,
odp_pool_to_entry(pool_hdl)->s.params.buf.size);
}
+int odp_buffer_alloc_multi(odp_pool_t pool_hdl, odp_buffer_t buf[], int num)
+{
+ size_t buf_size = odp_pool_to_entry(pool_hdl)->s.params.buf.size;
+
+ return buffer_alloc_multi(pool_hdl, buf_size, buf, num);
+}
+
void odp_buffer_free(odp_buffer_t buf)
{
odp_buffer_hdr_t *buf_hdr = odp_buf_to_hdr(buf);
@@ -546,6 +567,14 @@ void odp_buffer_free(odp_buffer_t buf)
ret_local_buf(&pool->s.local_cache[local_id], buf_hdr);
}
+void odp_buffer_free_multi(const odp_buffer_t buf[], int len)
+{
+ int i;
+
+ for (i = 0; i < len; ++i)
+ odp_buffer_free(buf[i]);
+}
+
void _odp_flush_caches(void)
{
int i;
diff --git a/platform/linux-generic/odp_queue.c b/platform/linux-generic/odp_queue.c
index a5e60d78c..db3399ce3 100644
--- a/platform/linux-generic/odp_queue.c
+++ b/platform/linux-generic/odp_queue.c
@@ -1063,3 +1063,43 @@ int release_order(queue_entry_t *origin_qe, uint64_t order,
UNLOCK(&origin_qe->s.lock);
return 0;
}
+
+int odp_queue_info(odp_queue_t handle, odp_queue_info_t *info)
+{
+ uint32_t queue_id;
+ queue_entry_t *queue;
+ int status;
+
+ if (odp_unlikely(info == NULL)) {
+ ODP_ERR("Unable to store info, NULL ptr given\n");
+ return -1;
+ }
+
+ queue_id = queue_to_id(handle);
+
+ if (odp_unlikely(queue_id >= ODP_CONFIG_QUEUES)) {
+ ODP_ERR("Invalid queue handle:%" PRIu64 "\n",
+ odp_queue_to_u64(handle));
+ return -1;
+ }
+
+ queue = get_qentry(queue_id);
+
+ LOCK(&queue->s.lock);
+ status = queue->s.status;
+
+ if (odp_unlikely(status == QUEUE_STATUS_FREE ||
+ status == QUEUE_STATUS_DESTROYED)) {
+ UNLOCK(&queue->s.lock);
+ ODP_ERR("Invalid queue status:%d\n", status);
+ return -1;
+ }
+
+ info->name = queue->s.name;
+ info->type = queue->s.type;
+ info->param = queue->s.param;
+
+ UNLOCK(&queue->s.lock);
+
+ return 0;
+}
diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-generic/odp_schedule.c
index 5982f85a4..884ae60fd 100644
--- a/platform/linux-generic/odp_schedule.c
+++ b/platform/linux-generic/odp_schedule.c
@@ -586,10 +586,10 @@ static int schedule_loop(odp_queue_t *out_queue, uint64_t wait,
odp_event_t out_ev[],
unsigned int max_num, unsigned int max_deq)
{
- uint64_t start_cycle, cycle, diff;
+ odp_time_t start_time, time, diff;
int ret;
- start_cycle = 0;
+ start_time = ODP_TIME_NULL;
while (1) {
ret = schedule(out_queue, out_ev, max_num, max_deq);
@@ -603,15 +603,15 @@ static int schedule_loop(odp_queue_t *out_queue, uint64_t wait,
if (wait == ODP_SCHED_NO_WAIT)
break;
- if (start_cycle == 0) {
- start_cycle = odp_time_cycles();
+ if (!odp_time_cmp(ODP_TIME_NULL, start_time)) {
+ start_time = odp_time_local();
continue;
}
- cycle = odp_time_cycles();
- diff = odp_time_diff_cycles(start_cycle, cycle);
+ time = odp_time_local();
+ diff = odp_time_diff(time, start_time);
- if (wait < diff)
+ if (odp_time_cmp(wait, diff) < 0)
break;
}
@@ -652,7 +652,7 @@ void odp_schedule_resume(void)
uint64_t odp_schedule_wait_time(uint64_t ns)
{
- return odp_time_ns_to_cycles(ns);
+ return odp_time_to_u64(odp_time_local_from_ns(ns));
}
diff --git a/platform/linux-generic/odp_time.c b/platform/linux-generic/odp_time.c
index 74f802b83..181d7323e 100644
--- a/platform/linux-generic/odp_time.c
+++ b/platform/linux-generic/odp_time.c
@@ -14,33 +14,73 @@
#define GIGA 1000000000
-uint64_t odp_time_cycles(void)
+static inline
+uint64_t time_to_tick(odp_time_t time)
{
- return odp_cpu_cycles();
+ return (uint64_t)time;
}
-uint64_t odp_time_diff_cycles(uint64_t t1, uint64_t t2)
+static inline
+odp_time_t tick_to_time(uint64_t tick)
{
- return _odp_cpu_cycles_diff(t1, t2);
+ return (odp_time_t)tick;
}
-uint64_t odp_time_cycles_to_ns(uint64_t cycles)
+odp_time_t odp_time_local(void)
+{
+ return tick_to_time(odp_cpu_cycles());
+}
+
+odp_time_t odp_time_diff(odp_time_t t2, odp_time_t t1)
+{
+ return tick_to_time(_odp_cpu_cycles_diff(t2, t1));
+}
+
+uint64_t odp_time_to_ns(odp_time_t time)
{
uint64_t hz = odp_sys_cpu_hz();
+ uint64_t tick = time_to_tick(time);
- if (cycles > (UINT64_MAX / GIGA))
- return (cycles/hz)*GIGA;
+ if (tick > (UINT64_MAX / GIGA))
+ return (tick / hz) * GIGA;
- return (cycles*GIGA)/hz;
+ return (tick * GIGA) / hz;
}
-uint64_t odp_time_ns_to_cycles(uint64_t ns)
+odp_time_t odp_time_local_from_ns(uint64_t ns)
{
uint64_t hz = odp_sys_cpu_hz();
if (ns > (UINT64_MAX / hz))
- return (ns/GIGA)*hz;
+ return tick_to_time((ns / GIGA) * hz);
+
+ return tick_to_time((ns * hz) / GIGA);
+}
+
+int odp_time_cmp(odp_time_t t2, odp_time_t t1)
+{
+ uint64_t tick1 = time_to_tick(t1);
+ uint64_t tick2 = time_to_tick(t2);
- return (ns*hz)/GIGA;
+ if (tick1 < tick2)
+ return 1;
+
+ if (tick1 > tick2)
+ return -1;
+
+ return 0;
+}
+
+odp_time_t odp_time_sum(odp_time_t t1, odp_time_t t2)
+{
+ uint64_t tick1 = time_to_tick(t1);
+ uint64_t tick2 = time_to_tick(t2);
+
+ return tick_to_time(tick1 + tick2);
+}
+
+uint64_t odp_time_to_u64(odp_time_t hdl)
+{
+ return time_to_tick(hdl);
}
diff --git a/platform/linux-generic/odp_timer.c b/platform/linux-generic/odp_timer.c
index 407ccc173..5c1f8ca7e 100644
--- a/platform/linux-generic/odp_timer.c
+++ b/platform/linux-generic/odp_timer.c
@@ -679,8 +679,8 @@ static void itimer_init(odp_timer_pool *tp)
strerror(errno));
res = tp->param.res_ns;
- sec = res / ODP_TIME_SEC;
- nsec = res - sec * ODP_TIME_SEC;
+ sec = res / ODP_TIME_SEC_IN_NS;
+ nsec = res - sec * ODP_TIME_SEC_IN_NS;
ispec.it_interval.tv_sec = (time_t)sec;
ispec.it_interval.tv_nsec = (long)nsec;