qemu/hw/timer/digic-timer.c
Philippe Mathieu-Daudé 883f2c591f bulk: Rename TARGET_FMT_plx -> HWADDR_FMT_plx
The 'hwaddr' type is defined in "exec/hwaddr.h" as:

    hwaddr is the type of a physical address
   (its size can be different from 'target_ulong').

All definitions use the 'HWADDR_' prefix, except TARGET_FMT_plx:

 $ fgrep define include/exec/hwaddr.h
 #define HWADDR_H
 #define HWADDR_BITS 64
 #define HWADDR_MAX UINT64_MAX
 #define TARGET_FMT_plx "%016" PRIx64
         ^^^^^^
 #define HWADDR_PRId PRId64
 #define HWADDR_PRIi PRIi64
 #define HWADDR_PRIo PRIo64
 #define HWADDR_PRIu PRIu64
 #define HWADDR_PRIx PRIx64
 #define HWADDR_PRIX PRIX64

Since hwaddr's size can be *different* from target_ulong, it is
very confusing to read one of its format using the 'TARGET_FMT_'
prefix, normally used for the target_long / target_ulong types:

$ fgrep TARGET_FMT_ include/exec/cpu-defs.h
 #define TARGET_FMT_lx "%08x"
 #define TARGET_FMT_ld "%d"
 #define TARGET_FMT_lu "%u"
 #define TARGET_FMT_lx "%016" PRIx64
 #define TARGET_FMT_ld "%" PRId64
 #define TARGET_FMT_lu "%" PRIu64

Apparently this format was missed during commit a8170e5e97
("Rename target_phys_addr_t to hwaddr"), so complete it by
doing a bulk-rename with:

 $ sed -i -e s/TARGET_FMT_plx/HWADDR_FMT_plx/g $(git grep -l TARGET_FMT_plx)

Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-Id: <20230110212947.34557-1-philmd@linaro.org>
[thuth: Fix some warnings from checkpatch.pl along the way]
Signed-off-by: Thomas Huth <thuth@redhat.com>
2023-01-18 11:14:34 +01:00

186 lines
4.9 KiB
C

/*
* QEMU model of the Canon DIGIC timer block.
*
* Copyright (C) 2013 Antony Pavlov <antonynpavlov@gmail.com>
*
* This model is based on reverse engineering efforts
* made by CHDK (http://chdk.wikia.com) and
* Magic Lantern (http://www.magiclantern.fm) projects
* contributors.
*
* See "Timer/Clock Module" docs here:
* http://magiclantern.wikia.com/wiki/Register_Map
*
* The QEMU model of the OSTimer in PKUnity SoC by Guan Xuetao
* is used as a template.
*
* 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.
*
*/
#include "qemu/osdep.h"
#include "hw/sysbus.h"
#include "hw/ptimer.h"
#include "qemu/module.h"
#include "qemu/log.h"
#include "hw/timer/digic-timer.h"
#include "migration/vmstate.h"
static const VMStateDescription vmstate_digic_timer = {
.name = "digic.timer",
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
VMSTATE_PTIMER(ptimer, DigicTimerState),
VMSTATE_UINT32(control, DigicTimerState),
VMSTATE_UINT32(relvalue, DigicTimerState),
VMSTATE_END_OF_LIST()
}
};
static void digic_timer_reset(DeviceState *dev)
{
DigicTimerState *s = DIGIC_TIMER(dev);
ptimer_transaction_begin(s->ptimer);
ptimer_stop(s->ptimer);
ptimer_transaction_commit(s->ptimer);
s->control = 0;
s->relvalue = 0;
}
static uint64_t digic_timer_read(void *opaque, hwaddr offset, unsigned size)
{
DigicTimerState *s = opaque;
uint64_t ret = 0;
switch (offset) {
case DIGIC_TIMER_CONTROL:
ret = s->control;
break;
case DIGIC_TIMER_RELVALUE:
ret = s->relvalue;
break;
case DIGIC_TIMER_VALUE:
ret = ptimer_get_count(s->ptimer) & 0xffff;
break;
default:
qemu_log_mask(LOG_UNIMP,
"digic-timer: read access to unknown register 0x"
HWADDR_FMT_plx "\n", offset);
}
return ret;
}
static void digic_timer_write(void *opaque, hwaddr offset,
uint64_t value, unsigned size)
{
DigicTimerState *s = opaque;
switch (offset) {
case DIGIC_TIMER_CONTROL:
if (value & DIGIC_TIMER_CONTROL_RST) {
digic_timer_reset((DeviceState *)s);
break;
}
ptimer_transaction_begin(s->ptimer);
if (value & DIGIC_TIMER_CONTROL_EN) {
ptimer_run(s->ptimer, 0);
}
s->control = (uint32_t)value;
ptimer_transaction_commit(s->ptimer);
break;
case DIGIC_TIMER_RELVALUE:
s->relvalue = extract32(value, 0, 16);
ptimer_transaction_begin(s->ptimer);
ptimer_set_limit(s->ptimer, s->relvalue, 1);
ptimer_transaction_commit(s->ptimer);
break;
case DIGIC_TIMER_VALUE:
break;
default:
qemu_log_mask(LOG_UNIMP,
"digic-timer: read access to unknown register 0x"
HWADDR_FMT_plx "\n", offset);
}
}
static const MemoryRegionOps digic_timer_ops = {
.read = digic_timer_read,
.write = digic_timer_write,
.impl = {
.min_access_size = 4,
.max_access_size = 4,
},
.endianness = DEVICE_NATIVE_ENDIAN,
};
static void digic_timer_tick(void *opaque)
{
/* Nothing to do on timer rollover */
}
static void digic_timer_init(Object *obj)
{
DigicTimerState *s = DIGIC_TIMER(obj);
s->ptimer = ptimer_init(digic_timer_tick, NULL, PTIMER_POLICY_LEGACY);
/*
* FIXME: there is no documentation on Digic timer
* frequency setup so let it always run at 1 MHz
*/
ptimer_transaction_begin(s->ptimer);
ptimer_set_freq(s->ptimer, 1 * 1000 * 1000);
ptimer_transaction_commit(s->ptimer);
memory_region_init_io(&s->iomem, OBJECT(s), &digic_timer_ops, s,
TYPE_DIGIC_TIMER, 0x100);
sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
}
static void digic_timer_finalize(Object *obj)
{
DigicTimerState *s = DIGIC_TIMER(obj);
ptimer_free(s->ptimer);
}
static void digic_timer_class_init(ObjectClass *klass, void *class_data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->reset = digic_timer_reset;
dc->vmsd = &vmstate_digic_timer;
}
static const TypeInfo digic_timer_info = {
.name = TYPE_DIGIC_TIMER,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(DigicTimerState),
.instance_init = digic_timer_init,
.instance_finalize = digic_timer_finalize,
.class_init = digic_timer_class_init,
};
static void digic_timer_register_type(void)
{
type_register_static(&digic_timer_info);
}
type_init(digic_timer_register_type)