initial import

internal commit: 14ac2bc2299032fa6714d1fefa7cf0987b3e3085

Signed-off-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Eddie Dong
2018-03-07 20:57:14 +08:00
committed by lijinxia
parent bd31b1c53e
commit 7a3a539b17
156 changed files with 41265 additions and 0 deletions

View 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;
}

View 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.
================================================================================

View 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;
}

View 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__*/

View 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;
}

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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);
}