From nobody Fri Apr 19 07:46:52 2024 Delivered-To: importer@patchew.org Received-SPF: none (zoho.com: 80.81.252.135 is neither permitted nor denied by domain of seabios.org) client-ip=80.81.252.135; envelope-from=seabios-bounces@seabios.org; helo=mail.coreboot.org; Authentication-Results: mx.zohomail.com; spf=none (zoho.com: 80.81.252.135 is neither permitted nor denied by domain of seabios.org) smtp.mailfrom=seabios-bounces@seabios.org Return-Path: Received: from mail.coreboot.org (mail.coreboot.org [80.81.252.135]) by mx.zohomail.com with SMTPS id 1517283839076282.1768315666361; Mon, 29 Jan 2018 19:43:59 -0800 (PST) Received: from [127.0.0.1] (helo=ra.coreboot.org) by mail.coreboot.org with esmtp (Exim 4.86_2) (envelope-from ) id 1egMrx-0005ZH-10; Tue, 30 Jan 2018 04:46:01 +0100 Received: from [78.83.148.119] (helo=fedoradesktop.localdomain) by mail.coreboot.org with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.86_2) (envelope-from ) id 1egMri-0005X1-8f for seabios@seabios.org; Tue, 30 Jan 2018 04:45:58 +0100 Received: from fedoradesktop.localdomain (localhost [127.0.0.1]) by fedoradesktop.localdomain (8.15.2/8.15.2) with ESMTP id w0U3hHeY006128; Tue, 30 Jan 2018 05:43:17 +0200 Received: (from nickysn@localhost) by fedoradesktop.localdomain (8.15.2/8.15.2/Submit) id w0U3hHPF006127; Tue, 30 Jan 2018 05:43:17 +0200 From: Nikolay Nikolov To: seabios@seabios.org Date: Tue, 30 Jan 2018 05:41:47 +0200 Message-Id: <20180130034147.6058-1-nickysn@users.sourceforge.net> X-Mailer: git-send-email 2.14.3 X-Spam-Score: -1.9 (-) Subject: [SeaBIOS] [PATCH] Fixes to the floppy driver, so it works on real (not emulated) hardware X-BeenThere: seabios@seabios.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SeaBIOS mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: seabios-bounces@seabios.org Sender: "SeaBIOS" X-Duff: Orig. Duff, Duff Lite, Duff Dry, Duff Dark, Raspberry Duff, Lady Duff, Red Duff, Tartar Control Duff X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Several fixes to the floppy driver, so it works on a real floppy controller with a real floppy. Tested with Coreboot on a motherboard with an ITE IT8712 Super I/O chip (and its built-in floppy controller) and a 1.44MB floppy. Only one floppy is supported for now and only 1.44MB, but more formats will= be added in the future. Signed-off-by: Nikolay Nikolov --- src/hw/floppy.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++------= ---- 1 file changed, 69 insertions(+), 14 deletions(-) diff --git a/src/hw/floppy.c b/src/hw/floppy.c index f2577c5..674909d 100644 --- a/src/hw/floppy.c +++ b/src/hw/floppy.c @@ -34,6 +34,11 @@ #define FLOPPY_GAPLEN 0x1B #define FLOPPY_FORMAT_GAPLEN 0x6c #define FLOPPY_PIO_TIMEOUT 1000 +#define FLOPPY_IRQ_TIMEOUT 5000 +#define FLOPPY_STARTUP_TIME 8 +#define FLOPPY_MOTOR_HOLD 255 // Magic value, means motor must not be turn= ed off +#define FLOPPY_SPECIFY1 0xAF // step rate 12ms, head unload 240ms +#define FLOPPY_SPECIFY2 0x02 // head load time 4ms, DMA used =20 // New diskette parameter table adding 3 parameters from IBM // Since no provisions are made for multiple drive types, most @@ -191,7 +196,8 @@ static void floppy_disable_controller(void) { dprintf(2, "Floppy_disable_controller\n"); - floppy_dor_write(0x00); + // Clear the reset bit (enter reset state) and clear 'enable IRQ and D= MA' + floppy_dor_write(GET_LOW(FloppyDOR) & ~0x0c); } =20 static int @@ -199,8 +205,9 @@ floppy_wait_irq(void) { u8 frs =3D GET_BDA(floppy_recalibration_status); SET_BDA(floppy_recalibration_status, frs & ~FRS_IRQ); + u32 end =3D timer_calc(FLOPPY_IRQ_TIMEOUT); for (;;) { - if (!GET_BDA(floppy_motor_counter)) { + if (timer_check(end)) { warn_timeout(); floppy_disable_controller(); return DISK_RET_ETIMEOUT; @@ -226,6 +233,7 @@ floppy_wait_irq(void) #define FC_READ (0xe6 | (8<<8) | (7<<12) | FCF_WAITIRQ) #define FC_WRITE (0xc5 | (8<<8) | (7<<12) | FCF_WAITIRQ) #define FC_FORMAT (0x4d | (5<<8) | (7<<12) | FCF_WAITIRQ) +#define FC_SPECIFY (0x03 | (2<<8) | (0<<12)) =20 // Send the specified command and it's parameters to the floppy controller. static int @@ -302,9 +310,12 @@ static int floppy_enable_controller(void) { dprintf(2, "Floppy_enable_controller\n"); - SET_BDA(floppy_motor_counter, FLOPPY_MOTOR_TICKS); - floppy_dor_write(0x00); - floppy_dor_write(0x0c); + // Clear the reset bit (enter reset state), but set 'enable IRQ and DM= A' + floppy_dor_write((GET_LOW(FloppyDOR) & ~0x04) | 0x08); + // Real hardware needs a 4 microsecond delay + udelay(4); + // Set the reset bit (normal operation) and keep 'enable IRQ and DMA' = on + floppy_dor_write(GET_LOW(FloppyDOR) | 0x0c); int ret =3D floppy_wait_irq(); if (ret) return ret; @@ -313,6 +324,30 @@ floppy_enable_controller(void) return floppy_pio(FC_CHECKIRQ, param); } =20 +static void +floppy_turn_on_motor(u8 floppyid) +{ + // prevent the motor from being turned off + SET_BDA(floppy_motor_counter, FLOPPY_MOTOR_HOLD); + + u8 motor_mask =3D 0x10 << floppyid; + if (GET_LOW(FloppyDOR) & motor_mask) { + // If the motor has been started, there's no need to wait for it a= gain + floppy_dor_write(motor_mask | 0x0c | floppyid); + } else { + floppy_dor_write(motor_mask | 0x0c | floppyid); + + msleep(FLOPPY_STARTUP_TIME * 125); + } +} + +static void +floppy_turn_off_motor_delayed(void) +{ + // reset the disk motor timeout value of INT 08 + SET_BDA(floppy_motor_counter, FLOPPY_MOTOR_TICKS); +} + // Activate a drive and send a command to it. static int floppy_drive_pio(u8 floppyid, int command, u8 *param) @@ -324,11 +359,8 @@ floppy_drive_pio(u8 floppyid, int command, u8 *param) return ret; } =20 - // reset the disk motor timeout value of INT 08 - SET_BDA(floppy_motor_counter, FLOPPY_MOTOR_TICKS); - - // Turn on motor of selected drive, DMA & int enabled, normal operation - floppy_dor_write((floppyid ? 0x20 : 0x10) | 0x0c | floppyid); + // Turn on motor of selected drive and wait for it to get up to speed + floppy_turn_on_motor(floppyid); =20 // Send command. int ret =3D floppy_pio(command, param); @@ -363,6 +395,15 @@ floppy_drive_recal(u8 floppyid) return DISK_RET_SUCCESS; } =20 +static int +floppy_drive_specify(void) +{ + u8 param[2]; + param[0] =3D FLOPPY_SPECIFY1; + param[1] =3D FLOPPY_SPECIFY2; + return floppy_pio(FC_SPECIFY, param); +} + static int floppy_drive_readid(u8 floppyid, u8 data_rate, u8 head) { @@ -433,13 +474,23 @@ floppy_prep(struct drive_s *drive_gf, u8 cylinder) !(GET_BDA(floppy_media_state[floppyid]) & FMS_MEDIA_DRIVE_ESTABLIS= HED)) { // Recalibrate drive. int ret =3D floppy_drive_recal(floppyid); - if (ret) + if (ret) { + floppy_turn_off_motor_delayed(); return ret; + } =20 // Sense media. ret =3D floppy_media_sense(drive_gf); - if (ret) + if (ret) { + floppy_turn_off_motor_delayed(); + return ret; + } + + ret =3D floppy_drive_specify(); + if (ret) { + floppy_turn_off_motor_delayed(); return ret; + } } =20 // Seek to cylinder if needed. @@ -449,8 +500,10 @@ floppy_prep(struct drive_s *drive_gf, u8 cylinder) param[0] =3D floppyid; param[1] =3D cylinder; int ret =3D floppy_drive_pio(floppyid, FC_SEEK, param); - if (ret) + if (ret) { + floppy_turn_off_motor_delayed(); return ret; + } SET_BDA(floppy_track[floppyid], cylinder); } =20 @@ -489,9 +542,11 @@ floppy_dma_cmd(struct disk_op_s *op, int count, int co= mmand, u8 *param) dprintf(1, "floppy error: %02x %02x %02x %02x %02x %02x %02x\n" , param[0], param[1], param[2], param[3] , param[4], param[5], param[6]); + floppy_turn_off_motor_delayed(); return DISK_RET_ECONTROLLER; } =20 + floppy_turn_off_motor_delayed(); return DISK_RET_SUCCESS; } =20 @@ -663,7 +718,7 @@ floppy_tick(void) =20 // time to turn off drive(s)? u8 fcount =3D GET_BDA(floppy_motor_counter); - if (fcount) { + if (fcount && (fcount !=3D FLOPPY_MOTOR_HOLD)) { fcount--; SET_BDA(floppy_motor_counter, fcount); if (fcount =3D=3D 0) --=20 2.14.3 _______________________________________________ SeaBIOS mailing list SeaBIOS@seabios.org https://mail.coreboot.org/mailman/listinfo/seabios