From nobody Wed Jan 15 07:38:21 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=ilande.co.uk Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 16849628196784.819819301516418; Wed, 24 May 2023 14:13:39 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1q1vn0-0004TJ-8x; Wed, 24 May 2023 17:12:58 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q1vmu-0003sm-8i for qemu-devel@nongnu.org; Wed, 24 May 2023 17:12:54 -0400 Received: from mail.ilande.co.uk ([2001:41c9:1:41f::167]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q1vmr-0002CS-CL for qemu-devel@nongnu.org; Wed, 24 May 2023 17:12:52 -0400 Received: from [2a00:23c4:8bac:6900:b726:cf58:4c12:f013] (helo=kentang.home) by mail.ilande.co.uk with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1q1vmT-0005XR-KU; Wed, 24 May 2023 22:12:29 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=ilande.co.uk; s=20220518; h=Subject:Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:To:From:Sender:Reply-To:Cc: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=LxPU5Duv7NJYWzvnoLQ2MvbWwxzTGsFNAOCjbXc14eI=; b=GeGOR9eBVi7Gs6TaboVIItGSYh ZnwxDZRZji9XAgrR1pQkoWoF9rrttrFNpCtONOlWGYU6uVoI+vycsgVcfz9urLaAN6XKKzeeALpPt 6mmqhaimRdYlk39i1Zy2xuMW8/4gAPeESaFjzrly+eQqDSIvrugsmkXiaWYQOosJ8+CvDJkzp6aXe m79xKWOLz8eY1WPcRSD4wUiJ91mUp2Je2baWzWIAXoP7DjUrAxwv2xpKj9I3amabkT1Vt8zclnNHM 4Am5yWJB+AlstSvK4ri6droIcJnCg5SHXnPbVdL1WCcVeF4AJ1sPzKvSU8LrBMa4236Ak13bKo0zz w+YDUi25EgWeYEJOWX0LzGrbrNeDzpzHG8VQFBee8PQB1P901OGlABWg8JyntfwGm4xZNQpAtdJYw zpjDBAWPMpgynWGZHP8UJwDn+127w9QeFKLOkPpdEYJCNkyIMkjyDMfkoGSU8lK0LPcvfX28mV6Ys eWI/GjiMJjDgmlklsjecZ/ax6GjhdbLn5c7dus94e9Hh8x4y3iAun7L0BBXb7uJD2moURqjrHlOvw aUefA7cZaCya1roaNhq5q42+VdRaykZK1LFhKb10G50dVfzeOFGg6oLjJejAlmXWcq6EEs6T7KWBN 9D42e3D6JWFwQdWXQN2GnJ7YMiDRO9dKRqb0kVH9E=; From: Mark Cave-Ayland To: laurent@vivier.eu, qemu-devel@nongnu.org Date: Wed, 24 May 2023 22:10:54 +0100 Message-Id: <20230524211104.686087-21-mark.cave-ayland@ilande.co.uk> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230524211104.686087-1-mark.cave-ayland@ilande.co.uk> References: <20230524211104.686087-1-mark.cave-ayland@ilande.co.uk> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SA-Exim-Connect-IP: 2a00:23c4:8bac:6900:b726:cf58:4c12:f013 X-SA-Exim-Mail-From: mark.cave-ayland@ilande.co.uk Subject: [PATCH 20/30] swim: update IWM/ISM register block decoding X-SA-Exim-Version: 4.2.1 (built Wed, 08 May 2019 21:11:16 +0000) X-SA-Exim-Scanned: Yes (on mail.ilande.co.uk) Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2001:41c9:1:41f::167; envelope-from=mark.cave-ayland@ilande.co.uk; helo=mail.ilande.co.uk X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1684962821478100012 Content-Type: text/plain; charset="utf-8" Update the IWM/ISM register block decoding to match the description given i= n the "SWIM Chip Users Reference". This allows us to validate the device response= to the guest OS which currently only does just enough to indicate that the flo= ppy drive is unavailable. Signed-off-by: Mark Cave-Ayland --- hw/block/swim.c | 212 +++++++++++++++++++++++++--------------- hw/block/trace-events | 7 +- include/hw/block/swim.h | 8 +- 3 files changed, 143 insertions(+), 84 deletions(-) diff --git a/hw/block/swim.c b/hw/block/swim.c index 735b335883..fd65c59f8a 100644 --- a/hw/block/swim.c +++ b/hw/block/swim.c @@ -21,24 +21,28 @@ #include "hw/qdev-properties.h" #include "trace.h" =20 + +/* IWM latch bits */ + +#define IWMLB_PHASE0 0 +#define IWMLB_PHASE1 1 +#define IWMLB_PHASE2 2 +#define IWMLB_PHASE3 3 +#define IWMLB_MOTORON 4 +#define IWMLB_DRIVESEL 5 +#define IWMLB_L6 6 +#define IWMLB_L7 7 + /* IWM registers */ =20 -#define IWM_PH0L 0 -#define IWM_PH0H 1 -#define IWM_PH1L 2 -#define IWM_PH1H 3 -#define IWM_PH2L 4 -#define IWM_PH2H 5 -#define IWM_PH3L 6 -#define IWM_PH3H 7 -#define IWM_MTROFF 8 -#define IWM_MTRON 9 -#define IWM_INTDRIVE 10 -#define IWM_EXTDRIVE 11 -#define IWM_Q6L 12 -#define IWM_Q6H 13 -#define IWM_Q7L 14 -#define IWM_Q7H 15 +#define IWM_READALLONES 0 +#define IWM_READDATA 1 +#define IWM_READSTATUS0 2 +#define IWM_READSTATUS1 3 +#define IWM_READWHANDSHAKE0 4 +#define IWM_READWHANDSHAKE1 5 +#define IWM_WRITESETMODE 6 +#define IWM_WRITEDATA 7 =20 /* SWIM registers */ =20 @@ -62,8 +66,9 @@ =20 #define REG_SHIFT 9 =20 -#define SWIM_MODE_IWM 0 -#define SWIM_MODE_SWIM 1 +#define SWIM_MODE_STATUS_BIT 6 +#define SWIM_MODE_IWM 0 +#define SWIM_MODE_ISM 1 =20 /* bits in phase register */ =20 @@ -127,10 +132,8 @@ #define SWIM_MOTON 0x80 =20 static const char *iwm_reg_names[] =3D { - "PH0L", "PH0H", "PH1L", "PH1H", - "PH2L", "PH2H", "PH3L", "PH3H", - "MTROFF", "MTRON", "INTDRIVE", "EXTDRIVE", - "Q6L", "Q6H", "Q7L", "Q7H" + "READALLONES", "READDATA", "READSTATUS0", "READSTATUS1", + "READWHANDSHAKE0", "READWHANDSHAKE1", "WRITESETMODE", "WRITEDATA" }; =20 static const char *ism_reg_names[] =3D { @@ -274,68 +277,99 @@ static const TypeInfo swim_bus_info =3D { .instance_size =3D sizeof(SWIMBus), }; =20 -static void iwmctrl_write(void *opaque, hwaddr reg, uint64_t value, +static void iwmctrl_write(void *opaque, hwaddr addr, uint64_t value, unsigned size) { SWIMCtrl *swimctrl =3D opaque; + uint8_t latch, reg, ism_bit; =20 - reg >>=3D REG_SHIFT; + addr >>=3D REG_SHIFT; + + /* A3-A1 select a latch, A0 specifies the value */ + latch =3D (addr >> 1) & 7; + if (addr & 1) { + swimctrl->iwm_latches |=3D (1 << latch); + } else { + swimctrl->iwm_latches &=3D ~(1 << latch); + } + + reg =3D (swimctrl->iwm_latches & 0xc0) >> 5 | + (swimctrl->iwm_latches & 0x10) >> 4; =20 swimctrl->iwmregs[reg] =3D value; trace_swim_iwmctrl_write(reg, iwm_reg_names[reg], size, value); =20 - if (swimctrl->iwmregs[IWM_Q7H]) { - if (swimctrl->iwmregs[IWM_MTRON]) { - /* data register */ - swimctrl->iwm_data =3D value; - } else { - /* mode register */ - swimctrl->iwm_mode =3D value; - /* detect sequence to switch from IWM mode to SWIM mode */ - switch (swimctrl->iwm_switch) { - case 0: - if (value =3D=3D 0x57) { - swimctrl->iwm_switch++; - } - break; - case 1: - if (value =3D=3D 0x17) { - swimctrl->iwm_switch++; - } - break; - case 2: - if (value =3D=3D 0x57) { - swimctrl->iwm_switch++; - } - break; - case 3: - if (value =3D=3D 0x57) { - swimctrl->mode =3D SWIM_MODE_SWIM; - swimctrl->iwm_switch =3D 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; + switch (reg) { + case IWM_WRITESETMODE: + /* detect sequence to switch from IWM mode to SWIM mode */ + ism_bit =3D (value & (1 << SWIM_MODE_STATUS_BIT)); + + switch (swimctrl->iwm_switch) { + case 0: + if (ism_bit) { /* 1 */ + swimctrl->iwm_switch++; + } + break; + case 1: + if (!ism_bit) { /* 0 */ + swimctrl->iwm_switch++; + } + break; + case 2: + if (ism_bit) { /* 1 */ + swimctrl->iwm_switch++; } + break; + case 3: + if (ism_bit) { /* 1 */ + swimctrl->iwm_switch++; + + swimctrl->mode =3D SWIM_MODE_ISM; + swimctrl->swim_mode |=3D (1 << SWIM_MODE_STATUS_BIT); + swimctrl->iwm_switch =3D 0; + trace_swim_switch_to_ism(); + + /* Switch to ISM registers */ + memory_region_del_subregion(&swimctrl->swim, &swimctrl->iw= m); + memory_region_add_subregion(&swimctrl->swim, 0x0, + &swimctrl->ism); + } + break; } + break; + default: + break; } } =20 -static uint64_t iwmctrl_read(void *opaque, hwaddr reg, unsigned size) +static uint64_t iwmctrl_read(void *opaque, hwaddr addr, unsigned size) { SWIMCtrl *swimctrl =3D opaque; - uint16_t value; + uint8_t latch, reg, value; =20 - reg >>=3D REG_SHIFT; + addr >>=3D REG_SHIFT; =20 - value =3D swimctrl->iwmregs[reg]; - trace_swim_iwmctrl_read(reg, iwm_reg_names[reg], size, value); + /* A3-A1 select a latch, A0 specifies the value */ + latch =3D (addr >> 1) & 7; + if (addr & 1) { + swimctrl->iwm_latches |=3D (1 << latch); + } else { + swimctrl->iwm_latches &=3D ~(1 << latch); + } + + reg =3D (swimctrl->iwm_latches & 0xc0) >> 5 | + (swimctrl->iwm_latches & 0x10) >> 4; + + switch (reg) { + case IWM_READALLONES: + value =3D 0xff; + break; + default: + value =3D 0; + break; + } =20 + trace_swim_iwmctrl_read(reg, iwm_reg_names[reg], size, value); return value; } =20 @@ -352,7 +386,7 @@ static void ismctrl_write(void *opaque, hwaddr reg, uin= t64_t value, =20 reg >>=3D REG_SHIFT; =20 - trace_swim_swimctrl_write(reg, ism_reg_names[reg], size, value); + trace_swim_ismctrl_write(reg, ism_reg_names[reg], size, value); =20 switch (reg) { case SWIM_WRITE_PHASE: @@ -360,14 +394,31 @@ static void ismctrl_write(void *opaque, hwaddr reg, u= int64_t value, break; case SWIM_WRITE_MODE0: swimctrl->swim_mode &=3D ~value; + /* Any access to MODE0 register resets PRAM index */ + swimctrl->pram_idx =3D 0; + + if (!(swimctrl->swim_mode & (1 << SWIM_MODE_STATUS_BIT))) { + /* Clearing the mode bit switches to IWM mode */ + swimctrl->mode =3D SWIM_MODE_IWM; + swimctrl->iwm_latches =3D 0; + trace_swim_switch_to_iwm(); + + /* Switch to IWM registers */ + memory_region_del_subregion(&swimctrl->swim, &swimctrl->ism); + memory_region_add_subregion(&swimctrl->swim, 0x0, + &swimctrl->iwm); + } break; case SWIM_WRITE_MODE1: swimctrl->swim_mode |=3D value; break; + case SWIM_WRITE_PARAMETER: + swimctrl->pram[swimctrl->pram_idx++] =3D value; + swimctrl->pram_idx &=3D 0xf; + break; case SWIM_WRITE_DATA: case SWIM_WRITE_MARK: case SWIM_WRITE_CRC: - case SWIM_WRITE_PARAMETER: case SWIM_WRITE_SETUP: break; } @@ -390,16 +441,24 @@ static uint64_t ismctrl_read(void *opaque, hwaddr reg= , unsigned size) value =3D SWIM_SENSE; } break; + case SWIM_READ_PARAMETER: + value =3D swimctrl->pram[swimctrl->pram_idx++]; + swimctrl->pram_idx &=3D 0xf; + break; + case SWIM_READ_STATUS: + value =3D swimctrl->swim_status & ~(1 << SWIM_MODE_STATUS_BIT); + if (swimctrl->swim_mode =3D=3D SWIM_MODE_ISM) { + value |=3D (1 << SWIM_MODE_STATUS_BIT); + } + break; case SWIM_READ_DATA: case SWIM_READ_MARK: case SWIM_READ_ERROR: - case SWIM_READ_PARAMETER: case SWIM_READ_SETUP: - case SWIM_READ_STATUS: break; } =20 - trace_swim_swimctrl_read(reg, ism_reg_names[reg], size, value); + trace_swim_ismctrl_read(reg, ism_reg_names[reg], size, value); return value; } =20 @@ -417,13 +476,11 @@ static void sysbus_swim_reset(DeviceState *d) =20 ctrl->mode =3D 0; ctrl->iwm_switch =3D 0; - ctrl->iwm_data =3D 0; - ctrl->iwm_mode =3D 0; - memset(ctrl->iwmregs, 0, 16); + memset(ctrl->iwmregs, 0, sizeof(ctrl->iwmregs)); =20 ctrl->swim_phase =3D 0; ctrl->swim_mode =3D 0; - memset(ctrl->ismregs, 0, 16); + memset(ctrl->ismregs, 0, sizeof(ctrl->ismregs)); for (i =3D 0; i < SWIM_MAX_FD; i++) { fd_recalibrate(&ctrl->drives[i]); } @@ -472,9 +529,8 @@ static const VMStateDescription vmstate_swim =3D { VMSTATE_INT32(mode, SWIMCtrl), /* IWM mode */ VMSTATE_INT32(iwm_switch, SWIMCtrl), - VMSTATE_UINT8_ARRAY(iwmregs, SWIMCtrl, 16), - VMSTATE_UINT8(iwm_data, SWIMCtrl), - VMSTATE_UINT8(iwm_mode, SWIMCtrl), + VMSTATE_UINT8(iwm_latches, SWIMCtrl), + VMSTATE_UINT8_ARRAY(iwmregs, SWIMCtrl, 8), /* SWIM mode */ VMSTATE_UINT8_ARRAY(ismregs, SWIMCtrl, 16), VMSTATE_UINT8(swim_phase, SWIMCtrl), diff --git a/hw/block/trace-events b/hw/block/trace-events index ea84ad6c77..bab21d3a1c 100644 --- a/hw/block/trace-events +++ b/hw/block/trace-events @@ -92,8 +92,9 @@ m25p80_binding(void *s) "[%p] Binding to IF_MTD drive" m25p80_binding_no_bdrv(void *s) "[%p] No BDRV - binding to RAM" =20 # swim.c -swim_swimctrl_read(int reg, const char *name, unsigned size, uint64_t valu= e) "reg=3D%d [%s] size=3D%u value=3D0x%"PRIx64 -swim_swimctrl_write(int reg, const char *name, unsigned size, uint64_t val= ue) "reg=3D%d [%s] size=3D%u value=3D0x%"PRIx64 +swim_ismctrl_read(int reg, const char *name, unsigned size, uint64_t value= ) "reg=3D%d [%s] size=3D%u value=3D0x%"PRIx64 +swim_ismctrl_write(int reg, const char *name, unsigned size, uint64_t valu= e) "reg=3D%d [%s] size=3D%u value=3D0x%"PRIx64 swim_iwmctrl_read(int reg, const char *name, unsigned size, uint64_t value= ) "reg=3D%d [%s] size=3D%u value=3D0x%"PRIx64 swim_iwmctrl_write(int reg, const char *name, unsigned size, uint64_t valu= e) "reg=3D%d [%s] size=3D%u value=3D0x%"PRIx64 -swim_iwm_switch(void) "switch from IWM to SWIM mode" +swim_switch_to_ism(void) "switch from IWM to ISM mode" +swim_switch_to_iwm(void) "switch from ISM to IWM mode" diff --git a/include/hw/block/swim.h b/include/hw/block/swim.h index 1bc7635d02..5f567e8d59 100644 --- a/include/hw/block/swim.h +++ b/include/hw/block/swim.h @@ -50,13 +50,15 @@ struct SWIMCtrl { int mode; /* IWM mode */ int iwm_switch; - uint8_t iwmregs[16]; - uint8_t iwm_data; - uint8_t iwm_mode; + uint8_t iwm_latches; + uint8_t iwmregs[8]; /* SWIM mode */ uint8_t ismregs[16]; uint8_t swim_phase; uint8_t swim_mode; + uint8_t swim_status; + uint8_t pram[16]; + uint8_t pram_idx; SWIMBus bus; }; =20 --=20 2.30.2