Permalink
Browse files

add OTP peripheral (fuses)

  • Loading branch information...
frederic committed Mar 1, 2018
1 parent 00ce276 commit 70c8b2088c6e24d7863609a2368e3591859a114d
Showing with 123 additions and 1 deletion.
  1. +5 −0 hw/arm/exynos4210.c
  2. +1 −1 hw/misc/Makefile.objs
  3. +110 −0 hw/misc/exynos4210_otp.c
  4. +7 −0 include/hw/misc/exynos4210_otp.h
@@ -39,6 +39,9 @@

#define EXYNOS4210_CHIPID_ADDR 0x10000000

/* OTP */
#define EXYNOS4210_OTP_BASE_ADDR 0x10100000

/* PWM */
#define EXYNOS4210_PWM_BASE_ADDR 0x139D0000

@@ -302,6 +305,8 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem)
NULL, "exynos4210.chipid", sizeof(chipid_and_omr));
memory_region_add_subregion(system_mem, EXYNOS4210_CHIPID_ADDR,
&s->chipid_mem);
/* OTP Memory (fuses) */
sysbus_create_simple("exynos4210.otp", EXYNOS4210_OTP_BASE_ADDR, NULL);

/* Internal ROM */
memory_region_init_ram(&s->irom_mem, NULL, "exynos4210.irom",
@@ -27,7 +27,7 @@ obj-$(CONFIG_IVSHMEM_DEVICE) += ivshmem.o
obj-$(CONFIG_REALVIEW) += arm_sysctl.o
obj-$(CONFIG_NSERIES) += cbus.o
obj-$(CONFIG_ECCMEMCTL) += eccmemctl.o
obj-$(CONFIG_EXYNOS4) += exynos4210_pmu.o exynos4210_clk.o exynos4210_rng.o
obj-$(CONFIG_EXYNOS4) += exynos4210_pmu.o exynos4210_clk.o exynos4210_rng.o exynos4210_otp.o
obj-$(CONFIG_IMX) += imx_ccm.o
obj-$(CONFIG_IMX) += imx31_ccm.o
obj-$(CONFIG_IMX) += imx25_ccm.o
@@ -0,0 +1,110 @@
/*
* Exynos4210 One-Time Programmable memory emulation
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/

#include "qemu/osdep.h"
#include "hw/sysbus.h"
#include "qemu/log.h"
#include "hw/misc/exynos4210_otp.h"

#define DEBUG_OTP 1
#define DEBUG_OTP_EXTEND 1

#ifndef DEBUG_OTP
#define DEBUG_OTP 0
#endif

#ifndef DEBUG_OTP_EXTEND
#define DEBUG_OTP_EXTEND 0
#endif

#if DEBUG_OTP
#define PRINT_DEBUG(fmt, args...) \
do { \
fprintf(stderr, " [%s:%d] "fmt, __func__, __LINE__, ##args); \
} while (0)

#if DEBUG_OTP_EXTEND
#define PRINT_DEBUG_EXTEND(fmt, args...) \
do { \
fprintf(stderr, " [%s:%d] "fmt, __func__, __LINE__, ##args); \
} while (0)
#else
#define PRINT_DEBUG_EXTEND(fmt, args...) do {} while (0)
#endif /* EXTEND */

#else
#define PRINT_DEBUG(fmt, args...) do {} while (0)
#define PRINT_DEBUG_EXTEND(fmt, args...) do {} while (0)
#endif

#define TYPE_EXYNOS4210_OTP "exynos4210.otp"
#define EXYNOS4210_OTP(obj) \
OBJECT_CHECK(Exynos4210OtpState, (obj), TYPE_EXYNOS4210_OTP)

typedef struct Exynos4210OtpState {
SysBusDevice parent_obj;
MemoryRegion otp_mem;
} Exynos4210OtpState;

static uint64_t exynos4210_otp_read(void *opaque, hwaddr offset, unsigned size)
{
PRINT_DEBUG("Read OTP @0x%lx (0x%x)\n", offset, size);
uint64_t ret;
assert(size < sizeof(uint64_t));
assert(offset + size <= EXYNOS4210_OTP_SIZE);
memcpy(&ret, &otp_data[offset], size);
return ret;
}

static void exynos4210_otp_write(void *opaque, hwaddr offset, uint64_t value, unsigned size)
{
PRINT_DEBUG("[UNSUPPORTED]Write OTP @0x%lx = %lx, (0x%x)\n", offset, value, size);
return;
}

const MemoryRegionOps exynos4210_otp_ops = {
.read = exynos4210_otp_read,
.write = exynos4210_otp_write,
.endianness = DEVICE_NATIVE_ENDIAN,
.impl = {
.min_access_size = 1,
.max_access_size = 4,
}
};

static void exynos4210_otp_init(Object *obj)
{
Exynos4210OtpState *s = EXYNOS4210_OTP(obj);
SysBusDevice *dev = SYS_BUS_DEVICE(obj);

memory_region_init_io(&s->otp_mem, obj, &exynos4210_otp_ops, NULL, TYPE_EXYNOS4210_OTP, EXYNOS4210_OTP_SIZE);
sysbus_init_mmio(dev, &s->otp_mem);
}

static const TypeInfo exynos4210_otp_info = {
.name = TYPE_EXYNOS4210_OTP,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_init = exynos4210_otp_init,
.instance_size = sizeof(Exynos4210OtpState),
};

static void exynos4210_otp_register(void)
{
type_register_static(&exynos4210_otp_info);
}

type_init(exynos4210_otp_register)
@@ -0,0 +1,7 @@
#define EXYNOS4210_OTP_SIZE sizeof(otp_data)

const uint8_t otp_data[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xD7, 0xEF, 0xD5, 0x1A, 0x81, 0xB5, 0xC4, 0xD2, 0xE0, 0xDC, 0xDF, 0xD1, 0x8E, 0xD5, 0xEE, 0x53, 0x37, 0x28, 0x40, 0x18,
0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00
};

0 comments on commit 70c8b20

Please sign in to comment.