#define SWIM_HEDSEL 0x20
#define SWIM_MOTON 0x80
-static const char *swim_reg_names[] = {
+static const char *iwm_reg_names[] = {
+ "PH0L", "PH0H", "PH1L", "PH1H",
+ "PH2L", "PH2H", "PH3L", "PH3H",
+ "MTROFF", "MTRON", "INTDRIVE", "EXTDRIVE",
+ "Q6L", "Q6H", "Q7L", "Q7H"
+};
+
+static const char *ism_reg_names[] = {
"WRITE_DATA", "WRITE_MARK", "WRITE_CRC", "WRITE_PARAMETER",
"WRITE_PHASE", "WRITE_SETUP", "WRITE_MODE0", "WRITE_MODE1",
"READ_DATA", "READ_MARK", "READ_ERROR", "READ_PARAMETER",
reg >>= REG_SHIFT;
- swimctrl->regs[reg >> 1] = reg & 1;
- trace_swim_iwmctrl_write((reg >> 1), size, (reg & 1));
+ swimctrl->iwmregs[reg] = value;
+ trace_swim_iwmctrl_write(reg, iwm_reg_names[reg], size, value);
- if (swimctrl->regs[IWM_Q6] &&
- swimctrl->regs[IWM_Q7]) {
- if (swimctrl->regs[IWM_MTR]) {
+ if (swimctrl->iwmregs[IWM_Q7H]) {
+ if (swimctrl->iwmregs[IWM_MTRON]) {
/* data register */
swimctrl->iwm_data = value;
} else {
swimctrl->mode = SWIM_MODE_SWIM;
swimctrl->iwm_switch = 0;
trace_swim_iwm_switch();
+
+ /* Switch to ISM registers */
+ memory_region_del_subregion(&swimctrl->swim,
+ &swimctrl->iwm);
+ memory_region_add_subregion(&swimctrl->swim, 0x0,
+ &swimctrl->ism);
}
break;
}
static uint64_t iwmctrl_read(void *opaque, hwaddr reg, unsigned size)
{
SWIMCtrl *swimctrl = opaque;
+ uint8_t value;
reg >>= REG_SHIFT;
- swimctrl->regs[reg >> 1] = reg & 1;
+ value = swimctrl->iwmregs[reg];
+ trace_swim_iwmctrl_read(reg, iwm_reg_names[reg], size, value);
- trace_swim_iwmctrl_read((reg >> 1), size, (reg & 1));
- return 0;
+ return value;
}
-static void swimctrl_write(void *opaque, hwaddr reg, uint64_t value,
- unsigned size)
+static const MemoryRegionOps swimctrl_iwm_ops = {
+ .write = iwmctrl_write,
+ .read = iwmctrl_read,
+ .endianness = DEVICE_BIG_ENDIAN,
+};
+
+static void ismctrl_write(void *opaque, hwaddr reg, uint64_t value,
+ unsigned size)
{
SWIMCtrl *swimctrl = opaque;
- if (swimctrl->mode == SWIM_MODE_IWM) {
- iwmctrl_write(opaque, reg, value, size);
- return;
- }
-
reg >>= REG_SHIFT;
- trace_swim_swimctrl_write(reg, swim_reg_names[reg], size, value);
+ trace_swim_swimctrl_write(reg, ism_reg_names[reg], size, value);
switch (reg) {
case SWIM_WRITE_PHASE:
}
}
-static uint64_t swimctrl_read(void *opaque, hwaddr reg, unsigned size)
+static uint64_t ismctrl_read(void *opaque, hwaddr reg, unsigned size)
{
SWIMCtrl *swimctrl = opaque;
uint32_t value = 0;
- if (swimctrl->mode == SWIM_MODE_IWM) {
- return iwmctrl_read(opaque, reg, size);
- }
-
reg >>= REG_SHIFT;
switch (reg) {
break;
}
- trace_swim_swimctrl_read(reg, swim_reg_names[reg], size, value);
+ trace_swim_swimctrl_read(reg, ism_reg_names[reg], size, value);
return value;
}
-static const MemoryRegionOps swimctrl_mem_ops = {
- .write = swimctrl_write,
- .read = swimctrl_read,
- .endianness = DEVICE_NATIVE_ENDIAN,
+static const MemoryRegionOps swimctrl_ism_ops = {
+ .write = ismctrl_write,
+ .read = ismctrl_read,
+ .endianness = DEVICE_BIG_ENDIAN,
};
static void sysbus_swim_reset(DeviceState *d)
ctrl->mode = 0;
ctrl->iwm_switch = 0;
- for (i = 0; i < 8; i++) {
- ctrl->regs[i] = 0;
- }
ctrl->iwm_data = 0;
ctrl->iwm_mode = 0;
+ memset(ctrl->iwmregs, 0, 16);
+
ctrl->swim_phase = 0;
ctrl->swim_mode = 0;
+ memset(ctrl->ismregs, 0, 16);
for (i = 0; i < SWIM_MAX_FD; i++) {
fd_recalibrate(&ctrl->drives[i]);
}
Swim *sbs = SWIM(obj);
SWIMCtrl *swimctrl = &sbs->ctrl;
- memory_region_init_io(&swimctrl->iomem, obj, &swimctrl_mem_ops, swimctrl,
- "swim", 0x2000);
- sysbus_init_mmio(sbd, &swimctrl->iomem);
+ memory_region_init(&swimctrl->swim, obj, "swim", 0x2000);
+ memory_region_init_io(&swimctrl->iwm, obj, &swimctrl_iwm_ops, swimctrl,
+ "iwm", 0x2000);
+ memory_region_init_io(&swimctrl->ism, obj, &swimctrl_ism_ops, swimctrl,
+ "ism", 0x2000);
+ sysbus_init_mmio(sbd, &swimctrl->swim);
}
static void sysbus_swim_realize(DeviceState *dev, Error **errp)
qbus_init(&swimctrl->bus, sizeof(SWIMBus), TYPE_SWIM_BUS, dev, NULL);
swimctrl->bus.ctrl = swimctrl;
+
+ /* Default register set is IWM */
+ memory_region_add_subregion(&swimctrl->swim, 0x0, &swimctrl->iwm);
}
static const VMStateDescription vmstate_fdrive = {
VMSTATE_INT32(mode, SWIMCtrl),
/* IWM mode */
VMSTATE_INT32(iwm_switch, SWIMCtrl),
- VMSTATE_UINT16_ARRAY(regs, SWIMCtrl, 8),
+ VMSTATE_UINT8_ARRAY(iwmregs, SWIMCtrl, 16),
VMSTATE_UINT8(iwm_data, SWIMCtrl),
VMSTATE_UINT8(iwm_mode, SWIMCtrl),
/* SWIM mode */
+ VMSTATE_UINT8_ARRAY(ismregs, SWIMCtrl, 16),
VMSTATE_UINT8(swim_phase, SWIMCtrl),
VMSTATE_UINT8(swim_mode, SWIMCtrl),
/* Drives */