* 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 "hw/hw.h"
+
+#include "qemu/osdep.h"
+#include "hw/irq.h"
#include "hw/arm/sharpsl.h"
#include "hw/sysbus.h"
-
-#undef REG_FMT
-#define REG_FMT "0x%02lx"
+#include "migration/vmstate.h"
+#include "qemu/module.h"
+#include "qemu/log.h"
+#include "qom/object.h"
/* SCOOP devices */
-typedef struct ScoopInfo ScoopInfo;
+#define TYPE_SCOOP "scoop"
+OBJECT_DECLARE_SIMPLE_TYPE(ScoopInfo, SCOOP)
+
struct ScoopInfo {
- SysBusDevice busdev;
+ SysBusDevice parent_obj;
+
qemu_irq handler[16];
MemoryRegion iomem;
uint16_t status;
level = s->gpio_level & s->gpio_dir;
for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
- bit = ffs(diff) - 1;
+ bit = ctz32(diff);
qemu_set_irq(s->handler[bit], (level >> bit) & 1);
}
case SCOOP_GPRR:
return s->gpio_level;
default:
- zaurus_printf("Bad register offset " REG_FMT "\n", (unsigned long)addr);
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "scoop_read: bad register offset 0x%02" HWADDR_PRIx "\n",
+ addr);
}
return 0;
scoop_gpio_handler_update(s);
break;
default:
- zaurus_printf("Bad register offset " REG_FMT "\n", (unsigned long)addr);
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "scoop_write: bad register offset 0x%02" HWADDR_PRIx "\n",
+ addr);
}
}
s->gpio_level &= ~(1 << line);
}
-static int scoop_init(SysBusDevice *dev)
+static void scoop_init(Object *obj)
{
- ScoopInfo *s = FROM_SYSBUS(ScoopInfo, dev);
+ DeviceState *dev = DEVICE(obj);
+ ScoopInfo *s = SCOOP(obj);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
s->status = 0x02;
- qdev_init_gpio_out(&s->busdev.qdev, s->handler, 16);
- qdev_init_gpio_in(&s->busdev.qdev, scoop_gpio_set, 16);
- memory_region_init_io(&s->iomem, OBJECT(s), &scoop_ops, s, "scoop", 0x1000);
-
- sysbus_init_mmio(dev, &s->iomem);
+ qdev_init_gpio_out(dev, s->handler, 16);
+ qdev_init_gpio_in(dev, scoop_gpio_set, 16);
+ memory_region_init_io(&s->iomem, obj, &scoop_ops, s, "scoop", 0x1000);
- return 0;
+ sysbus_init_mmio(sbd, &s->iomem);
}
static int scoop_post_load(void *opaque, int version_id)
return version_id == 0;
}
+static bool vmstate_scoop_validate(void *opaque, int version_id)
+{
+ ScoopInfo *s = opaque;
+
+ return !(s->prev_level & 0xffff0000) &&
+ !(s->gpio_level & 0xffff0000) &&
+ !(s->gpio_dir & 0xffff0000);
+}
+
static const VMStateDescription vmstate_scoop_regs = {
.name = "scoop",
.version_id = 1,
.minimum_version_id = 0,
- .minimum_version_id_old = 0,
.post_load = scoop_post_load,
- .fields = (VMStateField []) {
+ .fields = (VMStateField[]) {
VMSTATE_UINT16(status, ScoopInfo),
VMSTATE_UINT16(power, ScoopInfo),
VMSTATE_UINT32(gpio_level, ScoopInfo),
VMSTATE_UINT32(gpio_dir, ScoopInfo),
VMSTATE_UINT32(prev_level, ScoopInfo),
+ VMSTATE_VALIDATE("irq levels are 16 bit", vmstate_scoop_validate),
VMSTATE_UINT16(mcr, ScoopInfo),
VMSTATE_UINT16(cdr, ScoopInfo),
VMSTATE_UINT16(ccr, ScoopInfo),
},
};
-static Property scoop_sysbus_properties[] = {
- DEFINE_PROP_END_OF_LIST(),
-};
-
static void scoop_sysbus_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
- k->init = scoop_init;
dc->desc = "Scoop2 Sharp custom ASIC";
dc->vmsd = &vmstate_scoop_regs;
- dc->props = scoop_sysbus_properties;
}
static const TypeInfo scoop_sysbus_info = {
- .name = "scoop",
+ .name = TYPE_SCOOP,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(ScoopInfo),
+ .instance_init = scoop_init,
.class_init = scoop_sysbus_class_init,
};