qemu-riscv
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [RFC PATCH 1/2] hw/riscv: sifive_u: Add file-backed OTP. softmmu/vl:


From: Bin Meng
Subject: Re: [RFC PATCH 1/2] hw/riscv: sifive_u: Add file-backed OTP. softmmu/vl: add otp-file to boot option
Date: Fri, 24 Jul 2020 22:20:01 +0800

Hi Green,

On Fri, Jul 24, 2020 at 5:51 PM Green Wan <green.wan@sifive.com> wrote:
>
> Add a file-backed implementation for OTP of sifive_u machine. Use
> '-boot otp-file=xxx' to enable it. Do file open, mmap and close
> for every OTP read/write in case keep the update-to-date snapshot
> of OTP.
>
> Signed-off-by: Green Wan <green.wan@sifive.com>
> ---
>  hw/riscv/sifive_u_otp.c         | 88 ++++++++++++++++++++++++++++++++-
>  include/hw/riscv/sifive_u_otp.h |  2 +
>  qemu-options.hx                 |  3 +-
>  softmmu/vl.c                    |  6 ++-
>  4 files changed, 96 insertions(+), 3 deletions(-)
>
> diff --git a/hw/riscv/sifive_u_otp.c b/hw/riscv/sifive_u_otp.c
> index f6ecbaa2ca..26e1965821 100644
> --- a/hw/riscv/sifive_u_otp.c
> +++ b/hw/riscv/sifive_u_otp.c
> @@ -24,6 +24,72 @@
>  #include "qemu/log.h"
>  #include "qemu/module.h"
>  #include "hw/riscv/sifive_u_otp.h"
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include <sys/mman.h>
> +#include <string.h>
> +
> +#define TRACE_PREFIX            "FU540_OTP: "
> +#define SIFIVE_FU540_OTP_SIZE   (SIFIVE_U_OTP_NUM_FUSES * 4)
> +
> +static int otp_backed_fd;
> +static unsigned int *otp_mmap;
> +
> +static void sifive_u_otp_backed_load(const char *filename);
> +static uint64_t sifive_u_otp_backed_read(uint32_t fuseidx);
> +static void sifive_u_otp_backed_write(uint32_t fuseidx,
> +                                      uint32_t paio,
> +                                      uint32_t pdin);
> +static void sifive_u_otp_backed_unload(void);
> +
> +void sifive_u_otp_backed_load(const char *filename)
> +{
> +    if (otp_backed_fd < 0) {
> +
> +        otp_backed_fd = open(filename, O_RDWR);
> +
> +        if (otp_backed_fd < 0)
> +            qemu_log_mask(LOG_TRACE,
> +                          TRACE_PREFIX "Warning: can't open otp file\n");
> +        else {
> +
> +            otp_mmap = (unsigned int *)mmap(0,
> +                                            SIFIVE_FU540_OTP_SIZE,
> +                                            PROT_READ | PROT_WRITE | 
> PROT_EXEC,
> +                                            MAP_FILE | MAP_SHARED,
> +                                            otp_backed_fd,
> +                                            0);
> +
> +            if (otp_mmap == MAP_FAILED)
> +                qemu_log_mask(LOG_TRACE,
> +                              TRACE_PREFIX "Warning: can't mmap otp file\n");
> +        }
> +    }
> +
> +}
> +
> +uint64_t sifive_u_otp_backed_read(uint32_t fuseidx)
> +{
> +    return (uint64_t)(otp_mmap[fuseidx]);
> +}
> +
> +void sifive_u_otp_backed_write(uint32_t fuseidx, uint32_t paio, uint32_t 
> pdin)
> +{
> +    otp_mmap[fuseidx] &= ~(pdin << paio);
> +    otp_mmap[fuseidx] |= (pdin << paio);
> +}
> +
> +
> +void sifive_u_otp_backed_unload(void)
> +{
> +    munmap(otp_mmap, SIFIVE_FU540_OTP_SIZE);
> +    close(otp_backed_fd);
> +    otp_backed_fd = -1;
> +}
>
>  static uint64_t sifive_u_otp_read(void *opaque, hwaddr addr, unsigned int 
> size)
>  {
> @@ -46,7 +112,17 @@ static uint64_t sifive_u_otp_read(void *opaque, hwaddr 
> addr, unsigned int size)
>          if ((s->pce & SIFIVE_U_OTP_PCE_EN) &&
>              (s->pdstb & SIFIVE_U_OTP_PDSTB_EN) &&
>              (s->ptrim & SIFIVE_U_OTP_PTRIM_EN)) {
> -            return s->fuse[s->pa & SIFIVE_U_OTP_PA_MASK];
> +
> +            if (otp_file) {
> +                uint64_t val;
> +
> +                sifive_u_otp_backed_load(otp_file);
> +                val = sifive_u_otp_backed_read(s->pa);
> +                sifive_u_otp_backed_unload();
> +
> +                return val;
> +            } else
> +                return s->fuse[s->pa & SIFIVE_U_OTP_PA_MASK];
>          } else {
>              return 0xff;
>          }
> @@ -123,6 +199,12 @@ static void sifive_u_otp_write(void *opaque, hwaddr addr,
>          s->ptrim = val32;
>          break;
>      case SIFIVE_U_OTP_PWE:
> +        if (otp_file) {
> +            sifive_u_otp_backed_load(otp_file);
> +            sifive_u_otp_backed_write(s->pa, s->paio, s->pdin);
> +            sifive_u_otp_backed_unload();
> +        }
> +
>          s->pwe = val32;
>          break;
>      default:
> @@ -165,6 +247,10 @@ static void sifive_u_otp_reset(DeviceState *dev)
>      /* Make a valid content of serial number */
>      s->fuse[SIFIVE_U_OTP_SERIAL_ADDR] = s->serial;
>      s->fuse[SIFIVE_U_OTP_SERIAL_ADDR + 1] = ~(s->serial);
> +
> +    /* Initialize file mmap and descriptor. */
> +    otp_mmap = NULL;
> +    otp_backed_fd = -1;
>  }
>
>  static void sifive_u_otp_class_init(ObjectClass *klass, void *data)
> diff --git a/include/hw/riscv/sifive_u_otp.h b/include/hw/riscv/sifive_u_otp.h
> index 639297564a..1342bd7342 100644
> --- a/include/hw/riscv/sifive_u_otp.h
> +++ b/include/hw/riscv/sifive_u_otp.h
> @@ -52,6 +52,8 @@
>  #define SIFIVE_U_OTP(obj) \
>      OBJECT_CHECK(SiFiveUOTPState, (obj), TYPE_SIFIVE_U_OTP)
>
> +extern const char *otp_file;
> +
>  typedef struct SiFiveUOTPState {
>      /*< private >*/
>      SysBusDevice parent_obj;
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 708583b4ce..eb9a54f4ed 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -415,10 +415,11 @@ ERST
>
>  DEF("boot", HAS_ARG, QEMU_OPTION_boot,
>      "-boot [order=drives][,once=drives][,menu=on|off]\n"
> -    "      
> [,splash=sp_name][,splash-time=sp_time][,reboot-timeout=rb_time][,strict=on|off]\n"
> +    "      
> [,splash=sp_name][,splash-time=sp_time][,reboot-timeout=rb_time][,strict=on|off][,otp-file=otp_file]\n"
>      "                'drives': floppy (a), hard disk (c), CD-ROM (d), 
> network (n)\n"
>      "                'sp_name': the file's name that would be passed to bios 
> as logo picture, if menu=on\n"
>      "                'sp_time': the period that splash picture last if 
> menu=on, unit is ms\n"
> +    "                'otp_file': the file name backed OTP\n"
>      "                'rb_timeout': the timeout before guest reboot when boot 
> failed, unit is ms\n",

Instead of touching generic codes, could we add such property at the
board level?

>      QEMU_ARCH_ALL)
>  SRST

Regards,
Bin



reply via email to

[Prev in Thread] Current Thread [Next in Thread]