uboot/drivers/virtio/virtio_rng.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (c) 2019, Linaro Limited
   4 */
   5
   6#include <common.h>
   7#include <dm.h>
   8#include <log.h>
   9#include <rng.h>
  10#include <virtio_types.h>
  11#include <virtio.h>
  12#include <virtio_ring.h>
  13
  14#define BUFFER_SIZE     16UL
  15
  16struct virtio_rng_priv {
  17        struct virtqueue *rng_vq;
  18};
  19
  20static int virtio_rng_read(struct udevice *dev, void *data, size_t len)
  21{
  22        int ret;
  23        unsigned int rsize;
  24        unsigned char buf[BUFFER_SIZE] __aligned(4);
  25        unsigned char *ptr = data;
  26        struct virtio_sg sg;
  27        struct virtio_sg *sgs[1];
  28        struct virtio_rng_priv *priv = dev_get_priv(dev);
  29
  30        while (len) {
  31                sg.addr = buf;
  32                sg.length = min(len, sizeof(buf));
  33                sgs[0] = &sg;
  34
  35                ret = virtqueue_add(priv->rng_vq, sgs, 0, 1);
  36                if (ret)
  37                        return ret;
  38
  39                virtqueue_kick(priv->rng_vq);
  40
  41                while (!virtqueue_get_buf(priv->rng_vq, &rsize))
  42                        ;
  43
  44                memcpy(ptr, buf, rsize);
  45                len -= rsize;
  46                ptr += rsize;
  47        }
  48
  49        return 0;
  50}
  51
  52static int virtio_rng_bind(struct udevice *dev)
  53{
  54        struct virtio_dev_priv *uc_priv = dev_get_uclass_priv(dev->parent);
  55
  56        /* Indicate what driver features we support */
  57        virtio_driver_features_init(uc_priv, NULL, 0, NULL, 0);
  58
  59        return 0;
  60}
  61
  62static int virtio_rng_probe(struct udevice *dev)
  63{
  64        struct virtio_rng_priv *priv = dev_get_priv(dev);
  65        int ret;
  66
  67        ret = virtio_find_vqs(dev, 1, &priv->rng_vq);
  68        if (ret < 0) {
  69                debug("%s: virtio_find_vqs failed\n", __func__);
  70                return ret;
  71        }
  72
  73        return 0;
  74}
  75
  76static const struct dm_rng_ops virtio_rng_ops = {
  77        .read   = virtio_rng_read,
  78};
  79
  80U_BOOT_DRIVER(virtio_rng) = {
  81        .name   = VIRTIO_RNG_DRV_NAME,
  82        .id     = UCLASS_RNG,
  83        .bind   = virtio_rng_bind,
  84        .probe  = virtio_rng_probe,
  85        .remove = virtio_reset,
  86        .ops    = &virtio_rng_ops,
  87        .priv_auto      = sizeof(struct virtio_rng_priv),
  88        .flags  = DM_FLAG_ACTIVE_DMA,
  89};
  90