mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-09-21 08:50:27 +00:00
initial import
internal commit: 14ac2bc2299032fa6714d1fefa7cf0987b3e3085 Signed-off-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
163
hypervisor/lib/crypto/hkdf.c
Normal file
163
hypervisor/lib/crypto/hkdf.c
Normal file
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <rtl.h>
|
||||
|
||||
#include "tinycrypt/hmac.h"
|
||||
#include "tinycrypt/sha256.h"
|
||||
|
||||
#define SHA256_HASH_SIZE 32 /* SHA-256 length */
|
||||
|
||||
static uint8_t *hmac_sha256(uint8_t *out, unsigned int out_len,
|
||||
const void *key, size_t key_len,
|
||||
const uint8_t *data, size_t data_len)
|
||||
{
|
||||
struct tc_hmac_state h;
|
||||
|
||||
memset(&h, 0x0, sizeof(h));
|
||||
|
||||
if (!tc_hmac_set_key(&h, key, key_len) ||
|
||||
!tc_hmac_init(&h) ||
|
||||
!tc_hmac_update(&h, data, data_len) ||
|
||||
!tc_hmac_final(out, out_len, &h)) {
|
||||
out = NULL;
|
||||
}
|
||||
|
||||
memset(&h, 0x0, sizeof(h));
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/* This function implements HKDF extract
|
||||
* https://tools.ietf.org/html/rfc5869#section-2.2
|
||||
*/
|
||||
static int hkdf_sha256_extract(uint8_t *out_key, size_t out_len,
|
||||
const uint8_t *secret, size_t secret_len,
|
||||
const uint8_t *salt, size_t salt_len)
|
||||
{
|
||||
uint8_t salt0[SHA256_HASH_SIZE];
|
||||
|
||||
/* salt is optional for hkdf_sha256, it can be NULL.
|
||||
* The implement of tc_hmac_set_key in tinycrypt can't
|
||||
* accept NULL pointer, so salt0 is used here and set
|
||||
* to all 0s
|
||||
*/
|
||||
if (!salt || salt_len == 0) {
|
||||
memset(salt0, 0, SHA256_HASH_SIZE);
|
||||
salt = salt0;
|
||||
salt_len = SHA256_HASH_SIZE;
|
||||
}
|
||||
|
||||
if (!hmac_sha256(out_key, out_len,
|
||||
salt, salt_len,
|
||||
secret, secret_len))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* This function implements HKDF expand
|
||||
* https://tools.ietf.org/html/rfc5869#section-2.3
|
||||
*/
|
||||
static int hkdf_sha256_expand(uint8_t *out_key, size_t out_len,
|
||||
const uint8_t *prk, size_t prk_len,
|
||||
const uint8_t *info, size_t info_len)
|
||||
{
|
||||
const size_t digest_len = SHA256_HASH_SIZE;
|
||||
uint8_t T[SHA256_HASH_SIZE];
|
||||
size_t n, done = 0;
|
||||
unsigned int i;
|
||||
int ret = 0;
|
||||
struct tc_hmac_state h;
|
||||
|
||||
n = (out_len + digest_len - 1) / digest_len;
|
||||
if (n > 255)
|
||||
return 0;
|
||||
|
||||
memset(&h, 0x0, sizeof(h));
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
uint8_t ctr = i + 1;
|
||||
size_t todo;
|
||||
|
||||
tc_hmac_set_key(&h, prk, prk_len);
|
||||
tc_hmac_init(&h);
|
||||
if (i != 0 && (!tc_hmac_update(&h, T, digest_len)))
|
||||
goto out;
|
||||
|
||||
if (!tc_hmac_update(&h, info, info_len) ||
|
||||
!tc_hmac_update(&h, &ctr, 1) ||
|
||||
!tc_hmac_final(T, digest_len, &h)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
todo = digest_len;
|
||||
/* Check if the length of left buffer is smaller than
|
||||
* 32 to make sure no buffer overflow in below memcpy
|
||||
*/
|
||||
if (done + todo > out_len)
|
||||
todo = out_len - done;
|
||||
|
||||
memcpy_s(out_key + done, todo, T, todo);
|
||||
done += todo;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
out:
|
||||
memset(&h, 0x0, sizeof(h));
|
||||
memset(T, 0x0, SHA256_HASH_SIZE);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* https://tools.ietf.org/html/rfc5869#section-2 */
|
||||
int hkdf_sha256(uint8_t *out_key, size_t out_len,
|
||||
const uint8_t *secret, size_t secret_len,
|
||||
const uint8_t *salt, size_t salt_len,
|
||||
const uint8_t *info, size_t info_len)
|
||||
{
|
||||
uint8_t prk[SHA256_HASH_SIZE];
|
||||
size_t prk_len = SHA256_HASH_SIZE;
|
||||
|
||||
if (!hkdf_sha256_extract(prk, prk_len,
|
||||
secret, secret_len,
|
||||
salt, salt_len)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!hkdf_sha256_expand(out_key, out_len,
|
||||
prk, prk_len,
|
||||
info, info_len)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
36
hypervisor/lib/crypto/tinycrypt/COPYRIGHT
Normal file
36
hypervisor/lib/crypto/tinycrypt/COPYRIGHT
Normal file
@@ -0,0 +1,36 @@
|
||||
|
||||
================================================================================
|
||||
|
||||
TinyCrypt Cryptographic Library
|
||||
|
||||
================================================================================
|
||||
|
||||
Copyright (c) 2017, Intel Corporation. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Intel Corporation nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
================================================================================
|
147
hypervisor/lib/crypto/tinycrypt/hmac.c
Normal file
147
hypervisor/lib/crypto/tinycrypt/hmac.c
Normal file
@@ -0,0 +1,147 @@
|
||||
/* hmac.c - TinyCrypt implementation of the HMAC algorithm */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2017 by Intel Corporation, All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of Intel Corporation nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <rtl.h>
|
||||
|
||||
#include "hmac.h"
|
||||
|
||||
static void rekey(uint8_t *key, const uint8_t *new_key, unsigned int key_size)
|
||||
{
|
||||
const uint8_t inner_pad = (uint8_t) 0x36;
|
||||
const uint8_t outer_pad = (uint8_t) 0x5c;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < key_size; ++i) {
|
||||
key[i] = inner_pad ^ new_key[i];
|
||||
key[i + TC_SHA256_BLOCK_SIZE] = outer_pad ^ new_key[i];
|
||||
}
|
||||
for (; i < TC_SHA256_BLOCK_SIZE; ++i) {
|
||||
key[i] = inner_pad; key[i + TC_SHA256_BLOCK_SIZE] = outer_pad;
|
||||
}
|
||||
}
|
||||
|
||||
int tc_hmac_set_key(struct tc_hmac_state *ctx, const uint8_t *key,
|
||||
unsigned int key_size)
|
||||
{
|
||||
|
||||
/* input sanity check: */
|
||||
if (ctx == (struct tc_hmac_state *) 0 ||
|
||||
key == (const uint8_t *) 0 ||
|
||||
key_size == 0) {
|
||||
return TC_CRYPTO_FAIL;
|
||||
}
|
||||
|
||||
const uint8_t dummy_key[key_size];
|
||||
struct tc_hmac_state dummy_state;
|
||||
|
||||
if (key_size <= TC_SHA256_BLOCK_SIZE) {
|
||||
/*
|
||||
* The next three lines consist of dummy calls just to avoid
|
||||
* certain timing attacks. Without these dummy calls,
|
||||
* adversaries would be able to learn whether the key_size is
|
||||
* greater than TC_SHA256_BLOCK_SIZE by measuring the time
|
||||
* consumed in this process.
|
||||
*/
|
||||
(void)tc_sha256_init(&dummy_state.hash_state);
|
||||
(void)tc_sha256_update(&dummy_state.hash_state,
|
||||
dummy_key,
|
||||
key_size);
|
||||
(void)tc_sha256_final(&dummy_state.key[TC_SHA256_DIGEST_SIZE],
|
||||
&dummy_state.hash_state);
|
||||
|
||||
/* Actual code for when key_size <= TC_SHA256_BLOCK_SIZE: */
|
||||
rekey(ctx->key, key, key_size);
|
||||
} else {
|
||||
(void)tc_sha256_init(&ctx->hash_state);
|
||||
(void)tc_sha256_update(&ctx->hash_state, key, key_size);
|
||||
(void)tc_sha256_final(&ctx->key[TC_SHA256_DIGEST_SIZE],
|
||||
&ctx->hash_state);
|
||||
rekey(ctx->key,
|
||||
&ctx->key[TC_SHA256_DIGEST_SIZE],
|
||||
TC_SHA256_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
return TC_CRYPTO_SUCCESS;
|
||||
}
|
||||
|
||||
int tc_hmac_init(struct tc_hmac_state *ctx)
|
||||
{
|
||||
|
||||
/* input sanity check: */
|
||||
if (ctx == (struct tc_hmac_state *) 0)
|
||||
return TC_CRYPTO_FAIL;
|
||||
|
||||
(void) tc_sha256_init(&ctx->hash_state);
|
||||
(void) tc_sha256_update(&ctx->hash_state, ctx->key,
|
||||
TC_SHA256_BLOCK_SIZE);
|
||||
|
||||
return TC_CRYPTO_SUCCESS;
|
||||
}
|
||||
|
||||
int tc_hmac_update(struct tc_hmac_state *ctx,
|
||||
const void *data, unsigned int data_length)
|
||||
{
|
||||
|
||||
/* input sanity check: */
|
||||
if (ctx == (struct tc_hmac_state *) 0)
|
||||
return TC_CRYPTO_FAIL;
|
||||
|
||||
(void)tc_sha256_update(&ctx->hash_state, data, data_length);
|
||||
|
||||
return TC_CRYPTO_SUCCESS;
|
||||
}
|
||||
|
||||
int tc_hmac_final(uint8_t *tag, unsigned int taglen,
|
||||
struct tc_hmac_state *ctx)
|
||||
{
|
||||
|
||||
/* input sanity check: */
|
||||
if (tag == (uint8_t *) 0 ||
|
||||
taglen != TC_SHA256_DIGEST_SIZE ||
|
||||
ctx == (struct tc_hmac_state *) 0) {
|
||||
return TC_CRYPTO_FAIL;
|
||||
}
|
||||
|
||||
(void)tc_sha256_final(tag, &ctx->hash_state);
|
||||
|
||||
(void)tc_sha256_init(&ctx->hash_state);
|
||||
(void)tc_sha256_update(&ctx->hash_state,
|
||||
&ctx->key[TC_SHA256_BLOCK_SIZE],
|
||||
TC_SHA256_BLOCK_SIZE);
|
||||
(void)tc_sha256_update(&ctx->hash_state, tag, TC_SHA256_DIGEST_SIZE);
|
||||
(void)tc_sha256_final(tag, &ctx->hash_state);
|
||||
|
||||
/* destroy the current state */
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
|
||||
return TC_CRYPTO_SUCCESS;
|
||||
}
|
139
hypervisor/lib/crypto/tinycrypt/hmac.h
Normal file
139
hypervisor/lib/crypto/tinycrypt/hmac.h
Normal file
@@ -0,0 +1,139 @@
|
||||
/* hmac.h - TinyCrypt interface to an HMAC implementation */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2017 by Intel Corporation, All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of Intel Corporation nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Interface to an HMAC implementation.
|
||||
*
|
||||
* Overview: HMAC is a message authentication code based on hash functions.
|
||||
* TinyCrypt hard codes SHA-256 as the hash function. A message
|
||||
* authentication code based on hash functions is also called a
|
||||
* keyed cryptographic hash function since it performs a
|
||||
* transformation specified by a key in an arbitrary length data
|
||||
* set into a fixed length data set (also called tag).
|
||||
*
|
||||
* Security: The security of the HMAC depends on the length of the key and
|
||||
* on the security of the hash function. Note that HMAC primitives
|
||||
* are much less affected by collision attacks than their
|
||||
* corresponding hash functions.
|
||||
*
|
||||
* Requires: SHA-256
|
||||
*
|
||||
* Usage: 1) call tc_hmac_set_key to set the HMAC key.
|
||||
*
|
||||
* 2) call tc_hmac_init to initialize a struct hash_state before
|
||||
* processing the data.
|
||||
*
|
||||
* 3) call tc_hmac_update to process the next input segment;
|
||||
* tc_hmac_update can be called as many times as needed to process
|
||||
* all of the segments of the input; the order is important.
|
||||
*
|
||||
* 4) call tc_hmac_final to out put the tag.
|
||||
*/
|
||||
|
||||
#ifndef __TC_HMAC_H__
|
||||
#define __TC_HMAC_H__
|
||||
|
||||
#include "sha256.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct tc_hmac_state {
|
||||
/* the internal state required by h */
|
||||
struct tc_sha256_state hash_state;
|
||||
/* HMAC key schedule */
|
||||
uint8_t key[2*TC_SHA256_BLOCK_SIZE];
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief HMAC set key procedure
|
||||
* Configures ctx to use key
|
||||
* @return returns TC_CRYPTO_SUCCESS (1)
|
||||
* returns TC_CRYPTO_FAIL (0) if
|
||||
* ctx == NULL or
|
||||
* key == NULL or
|
||||
* key_size == 0
|
||||
* @param ctx IN/OUT -- the struct tc_hmac_state to initial
|
||||
* @param key IN -- the HMAC key to configure
|
||||
* @param key_size IN -- the HMAC key size
|
||||
*/
|
||||
int tc_hmac_set_key(struct tc_hmac_state *ctx, const uint8_t *key,
|
||||
unsigned int key_size);
|
||||
|
||||
/**
|
||||
* @brief HMAC init procedure
|
||||
* Initializes ctx to begin the next HMAC operation
|
||||
* @return returns TC_CRYPTO_SUCCESS (1)
|
||||
* returns TC_CRYPTO_FAIL (0) if: ctx == NULL or key == NULL
|
||||
* @param ctx IN/OUT -- struct tc_hmac_state buffer to init
|
||||
*/
|
||||
int tc_hmac_init(struct tc_hmac_state *ctx);
|
||||
|
||||
/**
|
||||
* @brief HMAC update procedure
|
||||
* Mixes data_length bytes addressed by data into state
|
||||
* @return returns TC_CRYPTO_SUCCCESS (1)
|
||||
* returns TC_CRYPTO_FAIL (0) if: ctx == NULL or key == NULL
|
||||
* @note Assumes state has been initialized by tc_hmac_init
|
||||
* @param ctx IN/OUT -- state of HMAC computation so far
|
||||
* @param data IN -- data to incorporate into state
|
||||
* @param data_length IN -- size of data in bytes
|
||||
*/
|
||||
int tc_hmac_update(struct tc_hmac_state *ctx, const void *data,
|
||||
unsigned int data_length);
|
||||
|
||||
/**
|
||||
* @brief HMAC final procedure
|
||||
* Writes the HMAC tag into the tag buffer
|
||||
* @return returns TC_CRYPTO_SUCCESS (1)
|
||||
* returns TC_CRYPTO_FAIL (0) if:
|
||||
* tag == NULL or
|
||||
* ctx == NULL or
|
||||
* key == NULL or
|
||||
* taglen != TC_SHA256_DIGEST_SIZE
|
||||
* @note ctx is erased before exiting. This should never be changed/removed.
|
||||
* @note Assumes the tag bufer is at least sizeof(hmac_tag_size(state)) bytes
|
||||
* state has been initialized by tc_hmac_init
|
||||
* @param tag IN/OUT -- buffer to receive computed HMAC tag
|
||||
* @param taglen IN -- size of tag in bytes
|
||||
* @param ctx IN/OUT -- the HMAC state for computing tag
|
||||
*/
|
||||
int tc_hmac_final(uint8_t *tag, unsigned int taglen,
|
||||
struct tc_hmac_state *ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__TC_HMAC_H__*/
|
217
hypervisor/lib/crypto/tinycrypt/sha256.c
Normal file
217
hypervisor/lib/crypto/tinycrypt/sha256.c
Normal file
@@ -0,0 +1,217 @@
|
||||
/* sha256.c - TinyCrypt SHA-256 crypto hash algorithm implementation */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2017 by Intel Corporation, All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of Intel Corporation nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <rtl.h>
|
||||
|
||||
#include "sha256.h"
|
||||
|
||||
static void compress(unsigned int *iv, const uint8_t *data);
|
||||
|
||||
int tc_sha256_init(struct tc_sha256_state *s)
|
||||
{
|
||||
/* input sanity check: */
|
||||
if (s == (struct tc_sha256_state *) 0)
|
||||
return TC_CRYPTO_FAIL;
|
||||
|
||||
/*
|
||||
* Setting the initial state values.
|
||||
* These values correspond to the first 32 bits of the fractional parts
|
||||
* of the square roots of the first 8 primes: 2, 3, 5, 7, 11, 13, 17
|
||||
* and 19.
|
||||
*/
|
||||
memset((uint8_t *) s, 0x00, sizeof(*s));
|
||||
s->iv[0] = 0x6a09e667;
|
||||
s->iv[1] = 0xbb67ae85;
|
||||
s->iv[2] = 0x3c6ef372;
|
||||
s->iv[3] = 0xa54ff53a;
|
||||
s->iv[4] = 0x510e527f;
|
||||
s->iv[5] = 0x9b05688c;
|
||||
s->iv[6] = 0x1f83d9ab;
|
||||
s->iv[7] = 0x5be0cd19;
|
||||
|
||||
return TC_CRYPTO_SUCCESS;
|
||||
}
|
||||
|
||||
int tc_sha256_update(struct tc_sha256_state *s, const uint8_t *data,
|
||||
size_t datalen)
|
||||
{
|
||||
/* input sanity check: */
|
||||
if (s == (struct tc_sha256_state *) 0 ||
|
||||
data == (void *) 0) {
|
||||
return TC_CRYPTO_FAIL;
|
||||
} else if (datalen == 0) {
|
||||
return TC_CRYPTO_SUCCESS;
|
||||
}
|
||||
|
||||
while (datalen-- > 0) {
|
||||
s->leftover[s->leftover_offset++] = *(data++);
|
||||
if (s->leftover_offset >= TC_SHA256_BLOCK_SIZE) {
|
||||
compress(s->iv, s->leftover);
|
||||
s->leftover_offset = 0;
|
||||
s->bits_hashed += (TC_SHA256_BLOCK_SIZE << 3);
|
||||
}
|
||||
}
|
||||
|
||||
return TC_CRYPTO_SUCCESS;
|
||||
}
|
||||
|
||||
int tc_sha256_final(uint8_t *digest, struct tc_sha256_state *s)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
/* input sanity check: */
|
||||
if (digest == (uint8_t *) 0 ||
|
||||
s == (struct tc_sha256_state *) 0) {
|
||||
return TC_CRYPTO_FAIL;
|
||||
}
|
||||
|
||||
s->bits_hashed += (s->leftover_offset << 3);
|
||||
|
||||
s->leftover[s->leftover_offset++] = 0x80; /* always room for one byte */
|
||||
if (s->leftover_offset > (sizeof(s->leftover) - 8)) {
|
||||
/* there is not room for all the padding in this block */
|
||||
memset(s->leftover + s->leftover_offset, 0x00,
|
||||
sizeof(s->leftover) - s->leftover_offset);
|
||||
compress(s->iv, s->leftover);
|
||||
s->leftover_offset = 0;
|
||||
}
|
||||
|
||||
/* add the padding and the length in big-Endian format */
|
||||
memset(s->leftover + s->leftover_offset, 0x00,
|
||||
sizeof(s->leftover) - 8 - s->leftover_offset);
|
||||
s->leftover[sizeof(s->leftover) - 1] = (uint8_t)(s->bits_hashed);
|
||||
s->leftover[sizeof(s->leftover) - 2] = (uint8_t)(s->bits_hashed >> 8);
|
||||
s->leftover[sizeof(s->leftover) - 3] = (uint8_t)(s->bits_hashed >> 16);
|
||||
s->leftover[sizeof(s->leftover) - 4] = (uint8_t)(s->bits_hashed >> 24);
|
||||
s->leftover[sizeof(s->leftover) - 5] = (uint8_t)(s->bits_hashed >> 32);
|
||||
s->leftover[sizeof(s->leftover) - 6] = (uint8_t)(s->bits_hashed >> 40);
|
||||
s->leftover[sizeof(s->leftover) - 7] = (uint8_t)(s->bits_hashed >> 48);
|
||||
s->leftover[sizeof(s->leftover) - 8] = (uint8_t)(s->bits_hashed >> 56);
|
||||
|
||||
/* hash the padding and length */
|
||||
compress(s->iv, s->leftover);
|
||||
|
||||
/* copy the iv out to digest */
|
||||
for (i = 0; i < TC_SHA256_STATE_BLOCKS; ++i) {
|
||||
unsigned int t = *((unsigned int *) &s->iv[i]);
|
||||
*digest++ = (uint8_t)(t >> 24);
|
||||
*digest++ = (uint8_t)(t >> 16);
|
||||
*digest++ = (uint8_t)(t >> 8);
|
||||
*digest++ = (uint8_t)(t);
|
||||
}
|
||||
|
||||
/* destroy the current state */
|
||||
memset(s, 0, sizeof(*s));
|
||||
|
||||
return TC_CRYPTO_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initializing SHA-256 Hash constant words K.
|
||||
* These values correspond to the first 32 bits of the fractional parts of the
|
||||
* cube roots of the first 64 primes between 2 and 311.
|
||||
*/
|
||||
static const unsigned int k256[64] = {
|
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
|
||||
0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
||||
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
|
||||
0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
|
||||
0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
|
||||
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
|
||||
0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
|
||||
0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
|
||||
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
||||
};
|
||||
|
||||
static inline unsigned int ROTR(unsigned int a, unsigned int n)
|
||||
{
|
||||
return (((a) >> n) | ((a) << (32 - n)));
|
||||
}
|
||||
|
||||
#define Sigma0(a)(ROTR((a), 2) ^ ROTR((a), 13) ^ ROTR((a), 22))
|
||||
#define Sigma1(a)(ROTR((a), 6) ^ ROTR((a), 11) ^ ROTR((a), 25))
|
||||
#define sigma0(a)(ROTR((a), 7) ^ ROTR((a), 18) ^ ((a) >> 3))
|
||||
#define sigma1(a)(ROTR((a), 17) ^ ROTR((a), 19) ^ ((a) >> 10))
|
||||
|
||||
#define Ch(a, b, c)(((a) & (b)) ^ ((~(a)) & (c)))
|
||||
#define Maj(a, b, c)(((a) & (b)) ^ ((a) & (c)) ^ ((b) & (c)))
|
||||
|
||||
static inline unsigned int BigEndian(const uint8_t **c)
|
||||
{
|
||||
unsigned int n = 0;
|
||||
|
||||
n = (((unsigned int)(*((*c)++))) << 24);
|
||||
n |= ((unsigned int)(*((*c)++)) << 16);
|
||||
n |= ((unsigned int)(*((*c)++)) << 8);
|
||||
n |= ((unsigned int)(*((*c)++)));
|
||||
return n;
|
||||
}
|
||||
|
||||
static void compress(unsigned int *iv, const uint8_t *data)
|
||||
{
|
||||
unsigned int a, b, c, d, e, f, g, h;
|
||||
unsigned int s0, s1;
|
||||
unsigned int t1, t2;
|
||||
unsigned int work_space[16];
|
||||
unsigned int n;
|
||||
unsigned int i;
|
||||
|
||||
a = iv[0]; b = iv[1]; c = iv[2]; d = iv[3];
|
||||
e = iv[4]; f = iv[5]; g = iv[6]; h = iv[7];
|
||||
|
||||
for (i = 0; i < 16; ++i) {
|
||||
n = BigEndian(&data);
|
||||
t1 = work_space[i] = n;
|
||||
t1 += h + Sigma1(e) + Ch(e, f, g) + k256[i];
|
||||
t2 = Sigma0(a) + Maj(a, b, c);
|
||||
h = g; g = f; f = e; e = d + t1;
|
||||
d = c; c = b; b = a; a = t1 + t2;
|
||||
}
|
||||
|
||||
for ( ; i < 64; ++i) {
|
||||
s0 = work_space[(i+1)&0x0f];
|
||||
s0 = sigma0(s0);
|
||||
s1 = work_space[(i+14)&0x0f];
|
||||
s1 = sigma1(s1);
|
||||
|
||||
t1 = work_space[i&0xf] += s0 + s1 + work_space[(i+9)&0xf];
|
||||
t1 += h + Sigma1(e) + Ch(e, f, g) + k256[i];
|
||||
t2 = Sigma0(a) + Maj(a, b, c);
|
||||
h = g; g = f; f = e; e = d + t1;
|
||||
d = c; c = b; b = a; a = t1 + t2;
|
||||
}
|
||||
|
||||
iv[0] += a; iv[1] += b; iv[2] += c; iv[3] += d;
|
||||
iv[4] += e; iv[5] += f; iv[6] += g; iv[7] += h;
|
||||
}
|
130
hypervisor/lib/crypto/tinycrypt/sha256.h
Normal file
130
hypervisor/lib/crypto/tinycrypt/sha256.h
Normal file
@@ -0,0 +1,130 @@
|
||||
/* sha256.h - TinyCrypt interface to a SHA-256 implementation */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2017 by Intel Corporation, All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of Intel Corporation nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Interface to a SHA-256 implementation.
|
||||
*
|
||||
* Overview: SHA-256 is a NIST approved cryptographic hashing algorithm
|
||||
* specified in FIPS 180. A hash algorithm maps data of arbitrary
|
||||
* size to data of fixed length.
|
||||
*
|
||||
* Security: SHA-256 provides 128 bits of security against collision attacks
|
||||
* and 256 bits of security against pre-image attacks. SHA-256 does
|
||||
* NOT behave like a random oracle, but it can be used as one if
|
||||
* the string being hashed is prefix-free encoded before hashing.
|
||||
*
|
||||
* Usage: 1) call tc_sha256_init to initialize a struct
|
||||
* tc_sha256_state before hashing a new string.
|
||||
*
|
||||
* 2) call tc_sha256_update to hash the next string segment;
|
||||
* tc_sha256_update can be called as many times as needed to hash
|
||||
* all of the segments of a string; the order is important.
|
||||
*
|
||||
* 3) call tc_sha256_final to out put the digest from a hashing
|
||||
* operation.
|
||||
*/
|
||||
|
||||
#ifndef __TC_SHA256_H__
|
||||
#define __TC_SHA256_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define TC_CRYPTO_SUCCESS 1
|
||||
#define TC_CRYPTO_FAIL 0
|
||||
#define TC_SHA256_BLOCK_SIZE (64)
|
||||
#define TC_SHA256_DIGEST_SIZE (32)
|
||||
#define TC_SHA256_STATE_BLOCKS (TC_SHA256_DIGEST_SIZE/4)
|
||||
|
||||
struct tc_sha256_state {
|
||||
unsigned int iv[TC_SHA256_STATE_BLOCKS];
|
||||
uint64_t bits_hashed;
|
||||
uint8_t leftover[TC_SHA256_BLOCK_SIZE];
|
||||
size_t leftover_offset;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief SHA256 initialization procedure
|
||||
* Initializes s
|
||||
* @return returns TC_CRYPTO_SUCCESS (1)
|
||||
* returns TC_CRYPTO_FAIL (0) if s == NULL
|
||||
* @param s Sha256 state struct
|
||||
*/
|
||||
int tc_sha256_init(struct tc_sha256_state *s);
|
||||
|
||||
/**
|
||||
* @brief SHA256 update procedure
|
||||
* Hashes data_length bytes addressed by data into state s
|
||||
* @return returns TC_CRYPTO_SUCCESS (1)
|
||||
* returns TC_CRYPTO_FAIL (0) if:
|
||||
* s == NULL,
|
||||
* s->iv == NULL,
|
||||
* data == NULL
|
||||
* @note Assumes s has been initialized by tc_sha256_init
|
||||
* @warning The state buffer 'leftover' is left in memory after processing
|
||||
* If your application intends to have sensitive data in this
|
||||
* buffer, remind to erase it after the data has been processed
|
||||
* @param s Sha256 state struct
|
||||
* @param data message to hash
|
||||
* @param datalen length of message to hash
|
||||
*/
|
||||
int tc_sha256_update(struct tc_sha256_state *s, const uint8_t *data,
|
||||
size_t datalen);
|
||||
|
||||
/**
|
||||
* @brief SHA256 final procedure
|
||||
* Inserts the completed hash computation into digest
|
||||
* @return returns TC_CRYPTO_SUCCESS (1)
|
||||
* returns TC_CRYPTO_FAIL (0) if:
|
||||
* s == NULL,
|
||||
* s->iv == NULL,
|
||||
* digest == NULL
|
||||
* @note Assumes: s has been initialized by tc_sha256_init
|
||||
* digest points to at least TC_SHA256_DIGEST_SIZE bytes
|
||||
* @warning The state buffer 'leftover' is left in memory after processing
|
||||
* If your application intends to have sensitive data in this
|
||||
* buffer, remind to erase it after the data has been processed
|
||||
* @param digest unsigned eight bit integer
|
||||
* @param Sha256 state struct
|
||||
*/
|
||||
int tc_sha256_final(uint8_t *digest, struct tc_sha256_state *s);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __TC_SHA256_H__ */
|
137
hypervisor/lib/div.c
Normal file
137
hypervisor/lib/div.c
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <hypervisor.h>
|
||||
#include <hv_lib.h>
|
||||
|
||||
static int do_udiv32(uint32_t dividend, uint32_t divisor,
|
||||
struct udiv_result *res)
|
||||
{
|
||||
|
||||
uint32_t mask;
|
||||
/* dividend is always greater than or equal to the divisor. Neither
|
||||
* divisor nor dividend are 0. Thus: * clz(dividend) and clz(divisor)
|
||||
* are valid * clz(dividend)<=clz(divisor)
|
||||
*/
|
||||
|
||||
mask = clz(divisor) - clz(dividend);
|
||||
/* align divisor and dividend */
|
||||
divisor <<= mask;
|
||||
mask = 1U << mask;
|
||||
/* division loop */
|
||||
do {
|
||||
if (dividend >= divisor) {
|
||||
dividend -= divisor;
|
||||
res->q.dwords.low |= mask;
|
||||
}
|
||||
divisor >>= 1;
|
||||
} while (((mask >>= 1) != 0) && (dividend != 0));
|
||||
/* dividend now contains the reminder */
|
||||
res->r.dwords.low = dividend;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int udiv32(uint32_t dividend, uint32_t divisor, struct udiv_result *res)
|
||||
{
|
||||
|
||||
/* initialize the result */
|
||||
res->q.dwords.low = res->r.dwords.low = 0;
|
||||
/* test for "division by 0" condition */
|
||||
if (divisor == 0) {
|
||||
res->q.dwords.low = 0xffffffff;
|
||||
return !0;
|
||||
}
|
||||
/* trivial case: divisor==dividend */
|
||||
if (divisor == dividend) {
|
||||
res->q.dwords.low = 1;
|
||||
return 0;
|
||||
}
|
||||
/* trivial case: divisor>dividend */
|
||||
if (divisor > dividend) {
|
||||
res->r.dwords.low = dividend;
|
||||
return 0;
|
||||
}
|
||||
/* now that the trivial cases are eliminated we can call the generic
|
||||
* function.
|
||||
*/
|
||||
return do_udiv32(dividend, divisor, res);
|
||||
}
|
||||
|
||||
int udiv64(uint64_t dividend, uint64_t divisor, struct udiv_result *res)
|
||||
{
|
||||
|
||||
uint64_t mask;
|
||||
uint64_t bits;
|
||||
|
||||
/* initialize the result */
|
||||
res->q.qword = res->r.qword = 0;
|
||||
/* test for "division by 0" condition */
|
||||
if (divisor == 0) {
|
||||
res->q.qword = 0xffffffffffffffffull;
|
||||
return -1;
|
||||
}
|
||||
/* trivial case: divisor==dividend */
|
||||
if (divisor == dividend) {
|
||||
res->q.qword = 1;
|
||||
return 0;
|
||||
}
|
||||
/* trivial case: divisor>dividend */
|
||||
if (divisor > dividend) {
|
||||
res->r.qword = dividend;
|
||||
return 0;
|
||||
}
|
||||
/* simplified case: only 32 bit operands Note that the preconditions
|
||||
* for do_udiv32() are fulfilled, since the tests were made above.
|
||||
*/
|
||||
if (((divisor >> 32) == 0) && ((dividend >> 32) == 0))
|
||||
return do_udiv32((uint32_t) dividend, (uint32_t) divisor, res);
|
||||
|
||||
/* dividend is always greater than or equal to the divisor. Neither
|
||||
* divisor nor dividend are 0. Thus: * clz(dividend) and clz(divisor)
|
||||
* are valid * clz(dividend)<=clz(divisor)
|
||||
*/
|
||||
|
||||
/* align divisor and dividend. */
|
||||
bits = clz64(divisor) - clz64(dividend);
|
||||
divisor <<= bits;
|
||||
mask = 1ULL << bits;
|
||||
/* division loop */
|
||||
do {
|
||||
if (dividend >= divisor) {
|
||||
dividend -= divisor;
|
||||
res->q.qword |= mask;
|
||||
}
|
||||
divisor >>= 1;
|
||||
mask >>= 1;
|
||||
} while ((bits-- != 0) && (dividend != 0));
|
||||
|
||||
res->r.qword = dividend;
|
||||
return 0;
|
||||
}
|
41
hypervisor/lib/mdelay.c
Normal file
41
hypervisor/lib/mdelay.c
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <hypervisor.h>
|
||||
#include <hv_lib.h>
|
||||
|
||||
void mdelay(uint32_t loop_count)
|
||||
{
|
||||
/* Loop until done */
|
||||
while (loop_count-- != 0) {
|
||||
/* Delay for 1 ms */
|
||||
udelay(1000);
|
||||
}
|
||||
}
|
324
hypervisor/lib/mem_mgt.c
Normal file
324
hypervisor/lib/mem_mgt.c
Normal file
@@ -0,0 +1,324 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <hypervisor.h>
|
||||
#include <hv_lib.h>
|
||||
#include <acrn_common.h>
|
||||
#include <hv_arch.h>
|
||||
#include <hv_debug.h>
|
||||
|
||||
/************************************************************************/
|
||||
/* Memory pool declaration (block size = MALLOC_ALIGN) */
|
||||
/************************************************************************/
|
||||
#define __bss_noinit __attribute__((__section__(".bss_noinit")))
|
||||
|
||||
static uint8_t __bss_noinit Malloc_Heap[HEAP_SIZE] __aligned(MALLOC_ALIGN);
|
||||
|
||||
#define MALLOC_HEAP_BUFF_SIZE MALLOC_ALIGN
|
||||
#define MALLOC_HEAP_TOTAL_BUFF (HEAP_SIZE/MALLOC_HEAP_BUFF_SIZE)
|
||||
#define MALLOC_HEAP_BITMAP_SIZE \
|
||||
INT_DIV_ROUNDUP(MALLOC_HEAP_TOTAL_BUFF, BITMAP_WORD_SIZE)
|
||||
static uint32_t Malloc_Heap_Bitmap[MALLOC_HEAP_BITMAP_SIZE];
|
||||
static uint32_t Malloc_Heap_Contiguity_Bitmap[MALLOC_HEAP_BITMAP_SIZE];
|
||||
|
||||
struct mem_pool Memory_Pool = {
|
||||
.start_addr = Malloc_Heap,
|
||||
.spinlock = {.head = 0, .tail = 0},
|
||||
.size = HEAP_SIZE,
|
||||
.buff_size = MALLOC_HEAP_BUFF_SIZE,
|
||||
.total_buffs = MALLOC_HEAP_TOTAL_BUFF,
|
||||
.bmp_size = MALLOC_HEAP_BITMAP_SIZE,
|
||||
.bitmap = Malloc_Heap_Bitmap,
|
||||
.contiguity_bitmap = Malloc_Heap_Contiguity_Bitmap
|
||||
};
|
||||
|
||||
/************************************************************************/
|
||||
/* Memory pool declaration (block size = CPU_PAGE_SIZE) */
|
||||
/************************************************************************/
|
||||
static uint8_t __bss_noinit
|
||||
Paging_Heap[NUM_ALLOC_PAGES][CPU_PAGE_SIZE] __aligned(CPU_PAGE_SIZE);
|
||||
|
||||
#define PAGING_HEAP_BUFF_SIZE CPU_PAGE_SIZE
|
||||
#define PAGING_HEAP_TOTAL_BUFF NUM_ALLOC_PAGES
|
||||
#define PAGING_HEAP_BITMAP_SIZE \
|
||||
INT_DIV_ROUNDUP(PAGING_HEAP_TOTAL_BUFF, BITMAP_WORD_SIZE)
|
||||
static uint32_t Paging_Heap_Bitmap[PAGING_HEAP_BITMAP_SIZE];
|
||||
static uint32_t Paging_Heap_Contiguity_Bitmap[MALLOC_HEAP_BITMAP_SIZE];
|
||||
|
||||
struct mem_pool Paging_Memory_Pool = {
|
||||
.start_addr = Paging_Heap,
|
||||
.spinlock = {.head = 0, .tail = 0},
|
||||
.size = NUM_ALLOC_PAGES * CPU_PAGE_SIZE,
|
||||
.buff_size = PAGING_HEAP_BUFF_SIZE,
|
||||
.total_buffs = PAGING_HEAP_TOTAL_BUFF,
|
||||
.bmp_size = PAGING_HEAP_BITMAP_SIZE,
|
||||
.bitmap = Paging_Heap_Bitmap,
|
||||
.contiguity_bitmap = Paging_Heap_Contiguity_Bitmap
|
||||
};
|
||||
|
||||
static void *allocate_mem(struct mem_pool *pool, unsigned int num_bytes)
|
||||
{
|
||||
|
||||
void *memory = NULL;
|
||||
uint32_t idx, bit_idx;
|
||||
uint32_t requested_buffs;
|
||||
|
||||
/* Check if provided memory pool exists */
|
||||
if (pool == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Acquire the pool lock */
|
||||
spinlock_obtain(&pool->spinlock);
|
||||
|
||||
/* Calculate number of buffers to be allocated from memory pool */
|
||||
requested_buffs = INT_DIV_ROUNDUP(num_bytes, pool->buff_size);
|
||||
|
||||
for (idx = 0; idx < pool->bmp_size; idx++) {
|
||||
/* Find the first occurrence of requested_buffs number of free
|
||||
* buffers. The 0th bit in bitmap represents a free buffer.
|
||||
*/
|
||||
for (bit_idx = get_first_zero_bit(pool->bitmap[idx]);
|
||||
bit_idx < BITMAP_WORD_SIZE; bit_idx++) {
|
||||
/* Check if selected buffer is free */
|
||||
if (pool->bitmap[idx] & (1 << bit_idx))
|
||||
continue;
|
||||
|
||||
/* Declare temporary variables to be used locally in
|
||||
* this block
|
||||
*/
|
||||
uint32_t i;
|
||||
uint32_t tmp_bit_idx = bit_idx;
|
||||
uint32_t tmp_idx = idx;
|
||||
|
||||
/* Check requested_buffs number of buffers availability
|
||||
* in memory-pool right after selected buffer
|
||||
*/
|
||||
for (i = 1; i < requested_buffs; i++) {
|
||||
/* Check if tmp_bit_idx is out-of-range */
|
||||
if (++tmp_bit_idx == BITMAP_WORD_SIZE) {
|
||||
/* Break the loop if tmp_idx is
|
||||
* out-of-range
|
||||
*/
|
||||
if (++tmp_idx == pool->bmp_size)
|
||||
break;
|
||||
/* Reset tmp_bit_idx */
|
||||
tmp_bit_idx = 0;
|
||||
}
|
||||
|
||||
/* Break if selected buffer is not free */
|
||||
if (pool->bitmap[tmp_idx] & (1 << tmp_bit_idx))
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check if requested_buffs number of free contiguous
|
||||
* buffers are found in memory pool
|
||||
*/
|
||||
if (i == requested_buffs) {
|
||||
/* Get start address of first buffer among
|
||||
* selected free contiguous buffer in the
|
||||
* memory pool
|
||||
*/
|
||||
memory = (char *)pool->start_addr +
|
||||
pool->buff_size * (idx * BITMAP_WORD_SIZE +
|
||||
bit_idx);
|
||||
|
||||
/* Update allocation bitmaps information for
|
||||
* selected buffers
|
||||
*/
|
||||
for (i = 0; i < requested_buffs; i++) {
|
||||
/* Set allocation bit in bitmap for
|
||||
* this buffer
|
||||
*/
|
||||
pool->bitmap[idx] |= (1 << bit_idx);
|
||||
|
||||
/* Set contiguity information for this
|
||||
* buffer in contiguity-bitmap
|
||||
*/
|
||||
if (i < (requested_buffs - 1)) {
|
||||
/* Set contiguity bit to 1 if
|
||||
* this buffer is not the last
|
||||
* of selected contiguous
|
||||
* buffers array
|
||||
*/
|
||||
pool->contiguity_bitmap[idx] |=
|
||||
(1 << bit_idx);
|
||||
} else {
|
||||
/* Set contiguity bit to 0 if
|
||||
* this buffer is not the last
|
||||
* of selected contiguous
|
||||
* buffers array
|
||||
*/
|
||||
pool->contiguity_bitmap[idx] &=
|
||||
~(1 << bit_idx);
|
||||
}
|
||||
|
||||
/* Check if bit_idx is out-of-range */
|
||||
if (++bit_idx == BITMAP_WORD_SIZE) {
|
||||
/* Increment idx */
|
||||
idx++;
|
||||
/* Reset bit_idx */
|
||||
bit_idx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Release the pool lock. */
|
||||
spinlock_release(&pool->spinlock);
|
||||
|
||||
return memory;
|
||||
}
|
||||
/* Update bit_idx and idx */
|
||||
bit_idx = tmp_bit_idx;
|
||||
idx = tmp_idx;
|
||||
}
|
||||
}
|
||||
|
||||
/* Release the pool lock. */
|
||||
spinlock_release(&pool->spinlock);
|
||||
|
||||
return (void *)NULL;
|
||||
}
|
||||
|
||||
static void deallocate_mem(struct mem_pool *pool, void *ptr)
|
||||
{
|
||||
uint32_t *bitmask, *contiguity_bitmask;
|
||||
uint32_t bmp_idx, bit_idx, buff_idx;
|
||||
|
||||
if ((pool != NULL) && (ptr != NULL)) {
|
||||
/* Acquire the pool lock */
|
||||
spinlock_obtain(&pool->spinlock);
|
||||
|
||||
/* Map the buffer address to its index. */
|
||||
buff_idx = ((char *)ptr - (char *)pool->start_addr) /
|
||||
pool->buff_size;
|
||||
|
||||
/* De-allocate all allocated contiguous memory buffers */
|
||||
while (buff_idx < pool->total_buffs) {
|
||||
/* Translate the buffer index to bitmap index. */
|
||||
bmp_idx = buff_idx / BITMAP_WORD_SIZE;
|
||||
bit_idx = buff_idx % BITMAP_WORD_SIZE;
|
||||
|
||||
/* Get bitmap's reference for this buffer */
|
||||
bitmask = &pool->bitmap[bmp_idx];
|
||||
contiguity_bitmask = &pool->contiguity_bitmap[bmp_idx];
|
||||
|
||||
/* Mark the buffer as free */
|
||||
if (*bitmask & (1 << bit_idx))
|
||||
*bitmask ^= (1 << bit_idx);
|
||||
else
|
||||
break;
|
||||
|
||||
/* Reset the Contiguity bit of buffer */
|
||||
if (*contiguity_bitmask & (1 << bit_idx))
|
||||
*contiguity_bitmask ^= (1 << bit_idx);
|
||||
else
|
||||
break;
|
||||
|
||||
/* Increment buff_idx */
|
||||
buff_idx++;
|
||||
}
|
||||
|
||||
/* Release the pool lock. */
|
||||
spinlock_release(&pool->spinlock);
|
||||
}
|
||||
}
|
||||
|
||||
void *malloc(unsigned int num_bytes)
|
||||
{
|
||||
void *memory = NULL;
|
||||
|
||||
/* Check if bytes requested extend page-size */
|
||||
if (num_bytes < CPU_PAGE_SIZE) {
|
||||
/* Request memory allocation from smaller segmented memory pool
|
||||
*/
|
||||
memory = allocate_mem(&Memory_Pool, num_bytes);
|
||||
} else {
|
||||
int page_num =
|
||||
(num_bytes + CPU_PAGE_SIZE - 1) >> CPU_PAGE_SHIFT;
|
||||
/* Request memory allocation through alloc_page */
|
||||
memory = alloc_pages(page_num);
|
||||
}
|
||||
|
||||
/* Check if memory allocation is successful */
|
||||
ASSERT(memory != NULL, "");
|
||||
|
||||
/* Return memory pointer to caller */
|
||||
return memory;
|
||||
}
|
||||
|
||||
void *alloc_pages(unsigned int page_num)
|
||||
{
|
||||
void *memory = NULL;
|
||||
|
||||
/* Request memory allocation from Page-aligned memory pool */
|
||||
memory = allocate_mem(&Paging_Memory_Pool, page_num * CPU_PAGE_SIZE);
|
||||
|
||||
/* Check if memory allocation is successful */
|
||||
ASSERT(memory != NULL, "");
|
||||
|
||||
return memory;
|
||||
}
|
||||
|
||||
void *alloc_page(void)
|
||||
{
|
||||
return alloc_pages(1);
|
||||
}
|
||||
|
||||
void *calloc(unsigned int num_elements, unsigned int element_size)
|
||||
{
|
||||
void *memory = malloc(num_elements * element_size);
|
||||
|
||||
/* Determine if memory was allocated */
|
||||
if (memory != NULL) {
|
||||
/* Zero all the memory */
|
||||
memset(memory, 0, num_elements * element_size);
|
||||
}
|
||||
|
||||
/* Return pointer to memory */
|
||||
return memory;
|
||||
}
|
||||
|
||||
void free(void *ptr)
|
||||
{
|
||||
/* Check if ptr belongs to 16-Bytes aligned Memory Pool */
|
||||
if ((Memory_Pool.start_addr < ptr) &&
|
||||
(ptr < (Memory_Pool.start_addr +
|
||||
(Memory_Pool.total_buffs * Memory_Pool.buff_size)))) {
|
||||
/* Free buffer in 16-Bytes aligned Memory Pool */
|
||||
deallocate_mem(&Memory_Pool, ptr);
|
||||
}
|
||||
/* Check if ptr belongs to page aligned Memory Pool */
|
||||
else if ((Paging_Memory_Pool.start_addr < ptr) &&
|
||||
(ptr < (Paging_Memory_Pool.start_addr +
|
||||
(Paging_Memory_Pool.total_buffs *
|
||||
Paging_Memory_Pool.buff_size)))) {
|
||||
/* Free buffer in page aligned Memory Pool */
|
||||
deallocate_mem(&Paging_Memory_Pool, ptr);
|
||||
}
|
||||
}
|
46
hypervisor/lib/memchr.c
Normal file
46
hypervisor/lib/memchr.c
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <rtl.h>
|
||||
|
||||
void *memchr(const void *void_s, int c, size_t n)
|
||||
{
|
||||
unsigned char val = (unsigned char)c;
|
||||
unsigned char *ptr = (unsigned char *)void_s;
|
||||
unsigned char *end = ptr + n;
|
||||
|
||||
while (ptr < end) {
|
||||
|
||||
if (*ptr++ == val)
|
||||
return ((void *)(ptr - 1));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
115
hypervisor/lib/memcpy.c
Normal file
115
hypervisor/lib/memcpy.c
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <hv_lib.h>
|
||||
#include <acrn_common.h>
|
||||
#include <hv_arch.h>
|
||||
#include <hv_debug.h>
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* FUNCTION
|
||||
*
|
||||
* memcpy_s
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Copies at most slen bytes from src address to dest address,
|
||||
* up to dmax.
|
||||
*
|
||||
* INPUTS
|
||||
*
|
||||
* d pointer to Destination address
|
||||
* dmax maximum length of dest
|
||||
* s pointer to Source address
|
||||
* slen maximum number of bytes of src to copy
|
||||
*
|
||||
* OUTPUTS
|
||||
*
|
||||
* void * pointer to destination address
|
||||
*
|
||||
***********************************************************************/
|
||||
void *memcpy_s(void *d, size_t dmax, const void *s, size_t slen)
|
||||
{
|
||||
|
||||
uint8_t *dest8;
|
||||
uint8_t *src8;
|
||||
|
||||
/*same memory block, no need to copy*/
|
||||
if (d == s)
|
||||
return d;
|
||||
|
||||
ASSERT((slen != 0) && (dmax != 0) && (dmax >= slen),
|
||||
"invalid slen or dmax.");
|
||||
|
||||
ASSERT(((d > s) && (d > s + slen - 1))
|
||||
|| ((d < s) && (s > d + dmax - 1)),
|
||||
"overlap happened.");
|
||||
|
||||
dest8 = (uint8_t *)d;
|
||||
src8 = (uint8_t *)s;
|
||||
|
||||
/*small data block*/
|
||||
if (slen < 8) {
|
||||
while (slen) {
|
||||
*dest8++ = *src8++;
|
||||
slen--;
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
/*make sure 8bytes-aligned for at least one addr.*/
|
||||
if ((!MEM_ALIGNED_CHECK(src8, 8)) && (!MEM_ALIGNED_CHECK(dest8, 8))) {
|
||||
for (; slen && (((uint64_t)src8) & 7); slen--)
|
||||
*dest8++ = *src8++;
|
||||
}
|
||||
|
||||
/*copy main data blocks, with rep prefix*/
|
||||
if (slen > 8) {
|
||||
uint32_t ecx;
|
||||
|
||||
asm volatile ("cld; rep; movsq"
|
||||
: "=&c"(ecx), "=&D"(dest8), "=&S"(src8)
|
||||
: "0" (slen / 8), "1" (dest8), "2" (src8)
|
||||
: "memory");
|
||||
|
||||
slen = slen % 8;
|
||||
}
|
||||
|
||||
/*tail bytes*/
|
||||
while (slen) {
|
||||
*dest8++ = *src8++;
|
||||
slen--;
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
59
hypervisor/lib/memset.c
Normal file
59
hypervisor/lib/memset.c
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <rtl.h>
|
||||
#include <util.h>
|
||||
#include <macros.h>
|
||||
|
||||
void *memset(void *base, uint8_t v, size_t n)
|
||||
{
|
||||
uint8_t *dest_p;
|
||||
size_t n_q;
|
||||
size_t count;
|
||||
|
||||
dest_p = (uint8_t *)base;
|
||||
|
||||
if ((dest_p == NULL) || (n == 0))
|
||||
return NULL;
|
||||
|
||||
/*do the few bytes to get uint64_t alignment*/
|
||||
count = n;
|
||||
for (; count && ((uint64_t)dest_p & 7); count--)
|
||||
*dest_p++ = v;
|
||||
|
||||
/*64-bit mode*/
|
||||
n_q = count >> 3;
|
||||
asm volatile("cld ; rep ; stosq ; movl %3,%%ecx ; rep ; stosb"
|
||||
: "+c"(n_q), "+D"(dest_p)
|
||||
: "a" (v * 0x0101010101010101U),
|
||||
"r"((unsigned int)count & 7));
|
||||
|
||||
return (void *)dest_p;
|
||||
}
|
59
hypervisor/lib/spinlock.c
Normal file
59
hypervisor/lib/spinlock.c
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <hv_lib.h>
|
||||
|
||||
inline int spinlock_init(spinlock_t *lock)
|
||||
{
|
||||
memset(lock, 0, sizeof(spinlock_t));
|
||||
return 0;
|
||||
}
|
||||
int spinlock_obtain(spinlock_t *lock)
|
||||
{
|
||||
|
||||
/* The lock function atomically increments and exchanges the head
|
||||
* counter of the queue. If the old head of the queue is equal to the
|
||||
* tail, we have locked the spinlock. Otherwise we have to wait.
|
||||
*/
|
||||
|
||||
asm volatile (" lock xaddl %%eax,%[head]\n"
|
||||
" cmpl %%eax,%[tail]\n"
|
||||
" jz 1f\n"
|
||||
"2: pause\n"
|
||||
" cmpl %%eax,%[tail]\n"
|
||||
" jnz 2b\n"
|
||||
"1:\n"
|
||||
:
|
||||
: "a" (1),
|
||||
[head] "m"(lock->head),
|
||||
[tail] "m"(lock->tail)
|
||||
: "cc", "memory");
|
||||
return 0;
|
||||
}
|
62
hypervisor/lib/stdlib.c
Normal file
62
hypervisor/lib/stdlib.c
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <hypervisor.h>
|
||||
#include <hv_lib.h>
|
||||
|
||||
char hexdigit(int decimal_val)
|
||||
{
|
||||
static const char hexdigits[] = { '0', '1', '2', '3', '4', '5', '6',
|
||||
'7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
|
||||
|
||||
/* Return hex character */
|
||||
return hexdigits[decimal_val & 0x0F];
|
||||
}
|
||||
|
||||
int strcmp(const char *s1, const char *s2)
|
||||
{
|
||||
while (*s1 && *s2 && *s1 == *s2) {
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
|
||||
return *s1 - *s2;
|
||||
}
|
||||
|
||||
int strncmp(const char *s1, const char *s2, size_t n)
|
||||
{
|
||||
while (n - 1 && *s1 && *s2 && *s1 == *s2) {
|
||||
s1++;
|
||||
s2++;
|
||||
n--;
|
||||
}
|
||||
|
||||
return *s1 - *s2;
|
||||
}
|
39
hypervisor/lib/strchr.c
Normal file
39
hypervisor/lib/strchr.c
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <rtl.h>
|
||||
|
||||
char *strchr(const char *s, int ch)
|
||||
{
|
||||
while (*s && (*s != ch))
|
||||
++s;
|
||||
|
||||
return (*s) ? ((char *)s) : 0;
|
||||
}
|
98
hypervisor/lib/strcpy.c
Normal file
98
hypervisor/lib/strcpy.c
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <hv_lib.h>
|
||||
#include <acrn_common.h>
|
||||
#include <hv_arch.h>
|
||||
#include <hv_debug.h>
|
||||
|
||||
/**
|
||||
*strcpy_s
|
||||
*
|
||||
* description:
|
||||
* This function copies the string pointed to by s to a buffer
|
||||
* pointed by d.
|
||||
*
|
||||
*
|
||||
* input:
|
||||
* d pointer to dest buffer.
|
||||
*
|
||||
* dmax maximum length of dest buffer
|
||||
*
|
||||
* s pointer to the source string
|
||||
*
|
||||
* return value:
|
||||
* dest pointer to dest string if string is copied
|
||||
* successfully,or else return null.
|
||||
*
|
||||
* notes:
|
||||
* 1) both d and s shall not be null pointers.
|
||||
* 2) dmax shall not 0.
|
||||
*/
|
||||
char *strcpy_s(char *d, size_t dmax, const char *s)
|
||||
{
|
||||
|
||||
char *dest_base;
|
||||
size_t dest_avail;
|
||||
uint64_t overlap_guard;
|
||||
|
||||
ASSERT(s != NULL, "invalid input s.");
|
||||
ASSERT((d != NULL) && (dmax != 0), "invalid input d or dmax.");
|
||||
|
||||
if (s == d)
|
||||
return d;
|
||||
|
||||
overlap_guard = (uint64_t)((d > s) ? (d - s - 1) : (s - d - 1));
|
||||
|
||||
dest_avail = dmax;
|
||||
dest_base = d;
|
||||
|
||||
while (dest_avail > 0) {
|
||||
ASSERT(overlap_guard != 0, "overlap happened.");
|
||||
|
||||
*d = *s;
|
||||
if (*d == '\0')
|
||||
return dest_base;
|
||||
|
||||
d++;
|
||||
s++;
|
||||
dest_avail--;
|
||||
overlap_guard--;
|
||||
}
|
||||
|
||||
ASSERT(false, "dest buffer has no enough space.");
|
||||
|
||||
/*
|
||||
* to avoid a string that is not
|
||||
* null-terminated in dest buffer
|
||||
*/
|
||||
dest_base[dmax - 1] = '\0';
|
||||
return NULL;
|
||||
}
|
107
hypervisor/lib/strncpy.c
Normal file
107
hypervisor/lib/strncpy.c
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <hv_lib.h>
|
||||
#include <acrn_common.h>
|
||||
#include <hv_arch.h>
|
||||
#include <hv_debug.h>
|
||||
|
||||
/*
|
||||
* strncpy_s
|
||||
*
|
||||
* description:
|
||||
* This function copies maximum 'slen'characters from string pointed
|
||||
* by s to a buffer pointed by d.
|
||||
*
|
||||
* input:
|
||||
* d pointer to dest buffer.
|
||||
*
|
||||
* dmax maximum length of dest buffer.
|
||||
*
|
||||
* s pointer to the source string.
|
||||
*
|
||||
* slen the maximum number of characters to copy from source
|
||||
* string.
|
||||
*
|
||||
* return value:
|
||||
* dest pointer to dest string if source string is copied
|
||||
* successfully, or else return null.
|
||||
*
|
||||
* notes:
|
||||
* 1) both dmax and slen should not be 0.
|
||||
* 2) both d and s should not be null pointers.
|
||||
* 3) will assert() if overlap happens or dest buffer has no
|
||||
* enough space.
|
||||
*/
|
||||
char *strncpy_s(char *d, size_t dmax, const char *s, size_t slen)
|
||||
{
|
||||
char *dest_base;
|
||||
size_t dest_avail;
|
||||
uint64_t overlap_guard;
|
||||
|
||||
ASSERT((d != NULL) && (s != NULL), "invlaid input d or s");
|
||||
ASSERT((dmax != 0) && (slen != 0), "invlaid input dmax or slen");
|
||||
|
||||
if (d == s)
|
||||
return d;
|
||||
|
||||
overlap_guard = (uint64_t)((d > s) ? (d - s - 1) : (s - d - 1));
|
||||
|
||||
dest_base = d;
|
||||
dest_avail = dmax;
|
||||
|
||||
while (dest_avail > 0) {
|
||||
ASSERT(overlap_guard != 0, "overlap happened.");
|
||||
|
||||
if (slen == 0) {
|
||||
*d = '\0';
|
||||
return dest_base;
|
||||
}
|
||||
|
||||
*d = *s;
|
||||
if (*d == '\0')
|
||||
return dest_base;
|
||||
|
||||
d++;
|
||||
s++;
|
||||
slen--;
|
||||
dest_avail--;
|
||||
overlap_guard--;
|
||||
}
|
||||
|
||||
ASSERT(false, "dest buffer has no enough space.");
|
||||
|
||||
/*
|
||||
* to avoid a string that is not
|
||||
* null-terminated in dest buffer
|
||||
*/
|
||||
dest_base[dmax - 1] = '\0';
|
||||
return NULL;
|
||||
}
|
71
hypervisor/lib/strnlen.c
Normal file
71
hypervisor/lib/strnlen.c
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <rtl.h>
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* strnlen_s
|
||||
*
|
||||
* description:
|
||||
* The function calculates the length of the string pointed
|
||||
* to by str.
|
||||
*
|
||||
*
|
||||
* input:
|
||||
* str pointer to the null-terminated string to be examined.
|
||||
*
|
||||
* dmax maximum number of characer to examine.
|
||||
*
|
||||
*
|
||||
* return value:
|
||||
* string length, excluding the null character.
|
||||
* will return 0 if str is null.
|
||||
*/
|
||||
size_t strnlen_s(const char *str, size_t maxlen)
|
||||
{
|
||||
size_t count;
|
||||
|
||||
if (str == NULL)
|
||||
return 0;
|
||||
|
||||
count = 0;
|
||||
while (*str) {
|
||||
if (maxlen == 0)
|
||||
break;
|
||||
|
||||
count++;
|
||||
maxlen--;
|
||||
str++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
377
hypervisor/lib/strtol.c
Normal file
377
hypervisor/lib/strtol.c
Normal file
@@ -0,0 +1,377 @@
|
||||
/*
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. [rescinded 22 July 1999]
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* FIXME: It'd be nice to configure around these, but the include files are too
|
||||
* painful. These macros should at least be more portable than hardwired hex
|
||||
* constants.
|
||||
*/
|
||||
|
||||
#include <types.h>
|
||||
|
||||
/* Categories. */
|
||||
|
||||
enum {
|
||||
/* In C99 */
|
||||
_sch_isblank = 0x0001, /* space \t */
|
||||
_sch_iscntrl = 0x0002, /* nonprinting characters */
|
||||
_sch_isdigit = 0x0004, /* 0-9 */
|
||||
_sch_islower = 0x0008, /* a-z */
|
||||
_sch_isprint = 0x0010, /* any printing character including ' ' */
|
||||
_sch_ispunct = 0x0020, /* all punctuation */
|
||||
_sch_isspace = 0x0040, /* space \t \n \r \f \v */
|
||||
_sch_isupper = 0x0080, /* A-Z */
|
||||
_sch_isxdigit = 0x0100, /* 0-9A-Fa-f */
|
||||
|
||||
/* Extra categories useful to cpplib. */
|
||||
_sch_isidst = 0x0200, /* A-Za-z_ */
|
||||
_sch_isvsp = 0x0400, /* \n \r */
|
||||
_sch_isnvsp = 0x0800, /* space \t \f \v \0 */
|
||||
|
||||
/* Combinations of the above. */
|
||||
_sch_isalpha = _sch_isupper|_sch_islower, /* A-Za-z */
|
||||
_sch_isalnum = _sch_isalpha|_sch_isdigit, /* A-Za-z0-9 */
|
||||
_sch_isidnum = _sch_isidst|_sch_isdigit, /* A-Za-z0-9_ */
|
||||
_sch_isgraph = _sch_isalnum|_sch_ispunct, /* isprint and not space */
|
||||
_sch_iscppsp = _sch_isvsp|_sch_isnvsp, /* isspace + \0 */
|
||||
/* basic charset of ISO C (plus ` and @) */
|
||||
_sch_isbasic = _sch_isprint|_sch_iscppsp
|
||||
};
|
||||
|
||||
/* Shorthand */
|
||||
#define bl _sch_isblank
|
||||
#define cn _sch_iscntrl
|
||||
#define di _sch_isdigit
|
||||
#define is _sch_isidst
|
||||
#define lo _sch_islower
|
||||
#define nv _sch_isnvsp
|
||||
#define pn _sch_ispunct
|
||||
#define pr _sch_isprint
|
||||
#define sp _sch_isspace
|
||||
#define up _sch_isupper
|
||||
#define vs _sch_isvsp
|
||||
#define xd _sch_isxdigit
|
||||
|
||||
/* Masks. */
|
||||
#define L ((const uint16_t)(lo | is | pr)) /* lower case letter */
|
||||
#define XL ((const uint16_t)(lo | is | xd | pr))/* lowercase hex digit */
|
||||
#define U ((const uint16_t)(up | is | pr)) /* upper case letter */
|
||||
#define XU ((const uint16_t)(up | is | xd | pr))/* uppercase hex digit */
|
||||
#define D ((const uint16_t)(di | xd | pr)) /* decimal digit */
|
||||
#define P ((const uint16_t)(pn | pr)) /* punctuation */
|
||||
#define _ ((const uint16_t)(pn | is | pr)) /* underscore */
|
||||
|
||||
#define C ((const uint16_t)(cn)) /* control character */
|
||||
#define Z ((const uint16_t)(nv | cn)) /* NUL */
|
||||
#define M ((const uint16_t)(nv | sp | cn)) /* cursor movement: \f \v */
|
||||
#define V ((const uint16_t)(vs | sp | cn)) /* vertical space: \r \n */
|
||||
#define T ((const uint16_t)(nv | sp | bl | cn))/* tab */
|
||||
#define S ((const uint16_t)(nv | sp | bl | pr))/* space */
|
||||
|
||||
/* Character classification. */
|
||||
const uint16_t _sch_istable[256] = {
|
||||
Z, C, C, C, C, C, C, C, /* NUL SOH STX ETX EOT ENQ ACK BEL */
|
||||
C, T, V, M, M, V, C, C, /* BS HT LF VT FF CR SO SI */
|
||||
C, C, C, C, C, C, C, C, /* DLE DC1 DC2 DC3 DC4 NAK SYN ETB */
|
||||
C, C, C, C, C, C, C, C, /* CAN EM SUB ESC FS GS RS US */
|
||||
S, P, P, P, P, P, P, P, /* SP ! " # $ % & ' */
|
||||
P, P, P, P, P, P, P, P, /* ( ) * + , - . / */
|
||||
D, D, D, D, D, D, D, D, /* 0 1 2 3 4 5 6 7 */
|
||||
D, D, P, P, P, P, P, P, /* 8 9 : ; < = > ? */
|
||||
P, XU, XU, XU, XU, XU, XU, U, /* @ A B C D E F G */
|
||||
U, U, U, U, U, U, U, U, /* H I J K L M N O */
|
||||
U, U, U, U, U, U, U, U, /* P Q R S T U V W */
|
||||
U, U, U, P, P, P, P, _, /* X Y Z [ \ ] ^ _ */
|
||||
P, XL, XL, XL, XL, XL, XL, L, /* ` a b c d e f g */
|
||||
L, L, L, L, L, L, L, L, /* h i j k l m n o */
|
||||
L, L, L, L, L, L, L, L, /* p q r s t u v w */
|
||||
L, L, L, P, P, P, P, C, /* x y z { | } ~ DEL */
|
||||
|
||||
/* high half of unsigned char is locale-specific, so all tests are
|
||||
* false in "C" locale
|
||||
*/
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
#define _sch_test(c, bit) (_sch_istable[(c) & 0xff] & (uint16_t)(bit))
|
||||
|
||||
#define ISALPHA(c) _sch_test(c, _sch_isalpha)
|
||||
#define ISALNUM(c) _sch_test(c, _sch_isalnum)
|
||||
#define ISBLANK(c) _sch_test(c, _sch_isblank)
|
||||
#define ISCNTRL(c) _sch_test(c, _sch_iscntrl)
|
||||
#define ISDIGIT(c) _sch_test(c, _sch_isdigit)
|
||||
#define ISGRAPH(c) _sch_test(c, _sch_isgraph)
|
||||
#define ISLOWER(c) _sch_test(c, _sch_islower)
|
||||
#define ISPRINT(c) _sch_test(c, _sch_isprint)
|
||||
#define ISPUNCT(c) _sch_test(c, _sch_ispunct)
|
||||
#define ISSPACE(c) _sch_test(c, _sch_isspace)
|
||||
#define ISUPPER(c) _sch_test(c, _sch_isupper)
|
||||
#define ISXDIGIT(c) _sch_test(c, _sch_isxdigit)
|
||||
|
||||
#define ISIDNUM(c) _sch_test(c, _sch_isidnum)
|
||||
#define ISIDST(c) _sch_test(c, _sch_isidst)
|
||||
#define IS_ISOBASIC(c) _sch_test(c, _sch_isbasic)
|
||||
#define IS_VSPACE(c) _sch_test(c, _sch_isvsp)
|
||||
#define IS_NVSPACE(c) _sch_test(c, _sch_isnvsp)
|
||||
#define IS_SPACE_OR_NUL(c) _sch_test(c, _sch_iscppsp)
|
||||
|
||||
/* Character transformation. */
|
||||
const uint8_t _sch_tolower[256] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
||||
64,
|
||||
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
|
||||
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||
|
||||
91, 92, 93, 94, 95, 96,
|
||||
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
|
||||
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||
|
||||
123, 124, 125, 126, 127,
|
||||
|
||||
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
|
||||
142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155,
|
||||
156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169,
|
||||
170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183,
|
||||
184, 185, 186, 187, 188, 189, 190, 191,
|
||||
|
||||
192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205,
|
||||
206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
|
||||
220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233,
|
||||
234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247,
|
||||
248, 249, 250, 251, 252, 253, 254, 255,
|
||||
};
|
||||
|
||||
const uint8_t _sch_toupper[256] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
||||
64,
|
||||
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
||||
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||
|
||||
91, 92, 93, 94, 95, 96,
|
||||
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
||||
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||
|
||||
123, 124, 125, 126, 127,
|
||||
|
||||
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
|
||||
142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155,
|
||||
156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169,
|
||||
170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183,
|
||||
184, 185, 186, 187, 188, 189, 190, 191,
|
||||
|
||||
192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205,
|
||||
206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
|
||||
220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233,
|
||||
234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247,
|
||||
248, 249, 250, 251, 252, 253, 254, 255,
|
||||
};
|
||||
#define TOUPPER(c) _sch_toupper[(c) & 0xff]
|
||||
#define TOLOWER(c) _sch_tolower[(c) & 0xff]
|
||||
|
||||
#ifndef ULONG_MAX
|
||||
#define ULONG_MAX ((uint64_t)(~0L)) /* 0xFFFFFFFF */
|
||||
#endif
|
||||
|
||||
#ifndef LONG_MAX
|
||||
#define LONG_MAX ((long)(ULONG_MAX >> 1)) /* 0x7FFFFFFF */
|
||||
#endif
|
||||
|
||||
#ifndef LONG_MIN
|
||||
#define LONG_MIN ((long)(~LONG_MAX)) /* 0x80000000 */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Convert a string to a long integer.
|
||||
*
|
||||
* Ignores `locale' stuff. Assumes that the upper and lower case
|
||||
* alphabets and digits are each contiguous.
|
||||
*/
|
||||
long
|
||||
strtol(const char *nptr, char **endptr, register int base)
|
||||
{
|
||||
register const char *s = nptr;
|
||||
register uint64_t acc;
|
||||
register int c;
|
||||
register uint64_t cutoff;
|
||||
register int neg = 0, any, cutlim;
|
||||
|
||||
/*
|
||||
* Skip white space and pick up leading +/- sign if any.
|
||||
* If base is 0, allow 0x for hex and 0 for octal, else
|
||||
* assume decimal; if base is already 16, allow 0x.
|
||||
*/
|
||||
do {
|
||||
c = *s++;
|
||||
} while (ISSPACE(c));
|
||||
if (c == '-') {
|
||||
neg = 1;
|
||||
c = *s++;
|
||||
} else if (c == '+')
|
||||
c = *s++;
|
||||
if ((base == 0 || base == 16) &&
|
||||
c == '0' && (*s == 'x' || *s == 'X')) {
|
||||
c = s[1];
|
||||
s += 2;
|
||||
base = 16;
|
||||
}
|
||||
if (base == 0)
|
||||
base = c == '0' ? 8 : 10;
|
||||
|
||||
/*
|
||||
* Compute the cutoff value between legal numbers and illegal
|
||||
* numbers. That is the largest legal value, divided by the
|
||||
* base. An input number that is greater than this value, if
|
||||
* followed by a legal input character, is too big. One that
|
||||
* is equal to this value may be valid or not; the limit
|
||||
* between valid and invalid numbers is then based on the last
|
||||
* digit. For instance, if the range for longs is
|
||||
* [-2147483648..2147483647] and the input base is 10,
|
||||
* cutoff will be set to 214748364 and cutlim to either
|
||||
* 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
|
||||
* a value > 214748364, or equal but the next digit is > 7 (or 8),
|
||||
* the number is too big, and we will return a range error.
|
||||
*
|
||||
* Set any if any `digits' consumed; make it negative to indicate
|
||||
* overflow.
|
||||
*/
|
||||
cutoff = neg ? -(uint64_t)LONG_MIN : LONG_MAX;
|
||||
cutlim = cutoff % (uint64_t)base;
|
||||
cutoff /= (uint64_t)base;
|
||||
for (acc = 0, any = 0;; c = *s++) {
|
||||
if (ISDIGIT(c))
|
||||
c -= '0';
|
||||
else if (ISALPHA(c))
|
||||
c -= ISUPPER(c) ? 'A' - 10 : 'a' - 10;
|
||||
else
|
||||
break;
|
||||
if (c >= base)
|
||||
break;
|
||||
if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
|
||||
any = -1;
|
||||
else {
|
||||
any = 1;
|
||||
acc *= base;
|
||||
acc += c;
|
||||
}
|
||||
}
|
||||
if (any < 0)
|
||||
acc = neg ? LONG_MIN : LONG_MAX;
|
||||
else if (neg)
|
||||
acc = -acc;
|
||||
if (endptr != 0)
|
||||
*endptr = (char *) (any ? s - 1 : nptr);
|
||||
return acc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a string to an uint64_t integer.
|
||||
*
|
||||
* Ignores `locale' stuff. Assumes that the upper and lower case
|
||||
* alphabets and digits are each contiguous.
|
||||
*/
|
||||
uint64_t
|
||||
strtoul(const char *nptr, char **endptr, register int base)
|
||||
{
|
||||
register const char *s = nptr;
|
||||
register uint64_t acc;
|
||||
register int c;
|
||||
register uint64_t cutoff;
|
||||
register int neg = 0, any, cutlim;
|
||||
|
||||
/*
|
||||
* See strtol for comments as to the logic used.
|
||||
*/
|
||||
do {
|
||||
c = *s++;
|
||||
} while (ISSPACE(c));
|
||||
if (c == '-') {
|
||||
neg = 1;
|
||||
c = *s++;
|
||||
} else if (c == '+')
|
||||
c = *s++;
|
||||
if ((base == 0 || base == 16) &&
|
||||
c == '0' && (*s == 'x' || *s == 'X')) {
|
||||
c = s[1];
|
||||
s += 2;
|
||||
base = 16;
|
||||
}
|
||||
if (base == 0)
|
||||
base = c == '0' ? 8 : 10;
|
||||
cutoff = (uint64_t)ULONG_MAX / (uint64_t)base;
|
||||
cutlim = (uint64_t)ULONG_MAX % (uint64_t)base;
|
||||
for (acc = 0, any = 0;; c = *s++) {
|
||||
if (ISDIGIT(c))
|
||||
c -= '0';
|
||||
else if (ISALPHA(c))
|
||||
c -= ISUPPER(c) ? 'A' - 10 : 'a' - 10;
|
||||
else
|
||||
break;
|
||||
if (c >= base)
|
||||
break;
|
||||
if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
|
||||
any = -1;
|
||||
else {
|
||||
any = 1;
|
||||
acc *= base;
|
||||
acc += c;
|
||||
}
|
||||
}
|
||||
if (any < 0)
|
||||
acc = ULONG_MAX;
|
||||
else if (neg)
|
||||
acc = -acc;
|
||||
if (endptr != 0)
|
||||
*endptr = (char *) (any ? s - 1 : nptr);
|
||||
return acc;
|
||||
}
|
||||
|
||||
int
|
||||
atoi(const char *str)
|
||||
{
|
||||
return (int)strtol(str, (char **)NULL, 10);
|
||||
}
|
45
hypervisor/lib/udelay.c
Normal file
45
hypervisor/lib/udelay.c
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <hypervisor.h>
|
||||
#include <hv_lib.h>
|
||||
|
||||
void udelay(int loop_count)
|
||||
{
|
||||
uint64_t dest_tsc, delta_tsc;
|
||||
|
||||
/* Calculate number of ticks to wait */
|
||||
delta_tsc = TIME_MS_DELTA * loop_count;
|
||||
dest_tsc = rdtsc() + delta_tsc;
|
||||
|
||||
/* Loop until time expired */
|
||||
while
|
||||
(rdtsc() < dest_tsc);
|
||||
}
|
Reference in New Issue
Block a user