cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

fifo8.c (2670B)


      1/*
      2 * Generic FIFO component, implemented as a circular buffer.
      3 *
      4 * Copyright (c) 2012 Peter A. G. Crosthwaite
      5 *
      6 * This program is free software; you can redistribute it and/or
      7 * modify it under the terms of the GNU General Public License
      8 * as published by the Free Software Foundation; either version
      9 * 2 of the License, or (at your option) any later version.
     10 *
     11 * You should have received a copy of the GNU General Public License along
     12 * with this program; if not, see <http://www.gnu.org/licenses/>.
     13 */
     14
     15#include "qemu/osdep.h"
     16#include "migration/vmstate.h"
     17#include "qemu/fifo8.h"
     18
     19void fifo8_create(Fifo8 *fifo, uint32_t capacity)
     20{
     21    fifo->data = g_new(uint8_t, capacity);
     22    fifo->capacity = capacity;
     23    fifo->head = 0;
     24    fifo->num = 0;
     25}
     26
     27void fifo8_destroy(Fifo8 *fifo)
     28{
     29    g_free(fifo->data);
     30}
     31
     32void fifo8_push(Fifo8 *fifo, uint8_t data)
     33{
     34    assert(fifo->num < fifo->capacity);
     35    fifo->data[(fifo->head + fifo->num) % fifo->capacity] = data;
     36    fifo->num++;
     37}
     38
     39void fifo8_push_all(Fifo8 *fifo, const uint8_t *data, uint32_t num)
     40{
     41    uint32_t start, avail;
     42
     43    assert(fifo->num + num <= fifo->capacity);
     44
     45    start = (fifo->head + fifo->num) % fifo->capacity;
     46
     47    if (start + num <= fifo->capacity) {
     48        memcpy(&fifo->data[start], data, num);
     49    } else {
     50        avail = fifo->capacity - start;
     51        memcpy(&fifo->data[start], data, avail);
     52        memcpy(&fifo->data[0], &data[avail], num - avail);
     53    }
     54
     55    fifo->num += num;
     56}
     57
     58uint8_t fifo8_pop(Fifo8 *fifo)
     59{
     60    uint8_t ret;
     61
     62    assert(fifo->num > 0);
     63    ret = fifo->data[fifo->head++];
     64    fifo->head %= fifo->capacity;
     65    fifo->num--;
     66    return ret;
     67}
     68
     69const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *num)
     70{
     71    uint8_t *ret;
     72
     73    assert(max > 0 && max <= fifo->num);
     74    *num = MIN(fifo->capacity - fifo->head, max);
     75    ret = &fifo->data[fifo->head];
     76    fifo->head += *num;
     77    fifo->head %= fifo->capacity;
     78    fifo->num -= *num;
     79    return ret;
     80}
     81
     82void fifo8_reset(Fifo8 *fifo)
     83{
     84    fifo->num = 0;
     85    fifo->head = 0;
     86}
     87
     88bool fifo8_is_empty(Fifo8 *fifo)
     89{
     90    return (fifo->num == 0);
     91}
     92
     93bool fifo8_is_full(Fifo8 *fifo)
     94{
     95    return (fifo->num == fifo->capacity);
     96}
     97
     98uint32_t fifo8_num_free(Fifo8 *fifo)
     99{
    100    return fifo->capacity - fifo->num;
    101}
    102
    103uint32_t fifo8_num_used(Fifo8 *fifo)
    104{
    105    return fifo->num;
    106}
    107
    108const VMStateDescription vmstate_fifo8 = {
    109    .name = "Fifo8",
    110    .version_id = 1,
    111    .minimum_version_id = 1,
    112    .fields = (VMStateField[]) {
    113        VMSTATE_VBUFFER_UINT32(data, Fifo8, 1, NULL, capacity),
    114        VMSTATE_UINT32(head, Fifo8),
    115        VMSTATE_UINT32(num, Fifo8),
    116        VMSTATE_END_OF_LIST()
    117    }
    118};