From patchwork Thu Sep 10 16:29:47 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?5q2m55SwID0/SVNPLTIwMjItSlA/Qj9JQnNrUWoxVFRHa2JLRUk9Pz0=?= X-Patchwork-Id: 33373 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by bilbo.ozlabs.org (Postfix) with ESMTPS id C59FAB7067 for ; Fri, 11 Sep 2009 02:35:06 +1000 (EST) Received: from localhost ([127.0.0.1]:47769 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Mlmbv-0005jk-M6 for incoming@patchwork.ozlabs.org; Thu, 10 Sep 2009 12:35:03 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MlmXK-0003vV-0o for qemu-devel@nongnu.org; Thu, 10 Sep 2009 12:30:18 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MlmXF-0003tW-SN for qemu-devel@nongnu.org; Thu, 10 Sep 2009 12:30:17 -0400 Received: from [199.232.76.173] (port=34710 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MlmXF-0003tN-IC for qemu-devel@nongnu.org; Thu, 10 Sep 2009 12:30:13 -0400 Received: from smtp-vip.mem.interq.net ([210.157.1.50]:58841 helo=smtp02.mem.internal-gmo) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1MlmXE-0003v0-LY for qemu-devel@nongnu.org; Thu, 10 Sep 2009 12:30:13 -0400 Received: (from root@localhost) by smtp02.mem.internal-gmo (8.13.8/8.12.6) id n8AGTvgq011694 for qemu-devel@nongnu.org; Fri, 11 Sep 2009 01:29:57 +0900 (JST) Received: from YOUR-BD18D6DD63.m1.interq.or.jp (ntymns034018.ymns.nt.ftth.ppp.infoweb.ne.jp [211.2.27.18]) by smtp02.mem.internal-gmo with ESMTP id n8AGTuck011688; (me101664 for with PLAIN) Fri, 11 Sep 2009 01:29:57 +0900 (JST) Message-Id: <200909101629.AA00099@YOUR-BD18D6DD63.m1.interq.or.jp> From: t-takeda@m1.interq.or.jp (=?ISO-2022-JP?B?GyRCSXBFRBsoQg==?= =?ISO-2022-JP?B?IBskQj1TTGkbKEI=?=) Date: Fri, 11 Sep 2009 01:29:47 +0900 To: Alexander Graf In-Reply-To: References: MIME-Version: 1.0 X-Mailer: AL-Mail32 Version 1.13 X-detected-operating-system: by monty-python.gnu.org: Solaris 10 (beta) Cc: qemu-devel Subject: [Qemu-devel] Re: [PATCH 06/14] fdc: support NEC PC-9821 family X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Dear Alex, >On 09.09.2009, at 17:42, 武田 俊也 wrote: > >> This patch is to add NEC PC-9821 family i/o to fdc. >> >> diff -ur a/hw/fdc.c b/hw/fdc.c >> --- a/hw/fdc.c Tue Sep 8 21:26:50 2009 >> +++ b/hw/fdc.c Wed Sep 9 21:51:23 2009 >> @@ -85,6 +85,7 @@ >> /* Drive status */ >> fdrive_type_t drive; >> uint8_t perpendicular; /* 2.88 MB access mode */ >> + uint8_t seek_result; >> /* Position */ >> uint8_t head; >> uint8_t track; >> @@ -175,6 +176,7 @@ >> drv->head = 0; >> drv->track = 0; >> drv->sect = 1; >> + drv->seek_result = 0; >> } >> >> /* Recognize floppy formats */ >> @@ -387,6 +389,7 @@ >> }; >> >> enum { >> + FD_SR0_NOTRDY = 0x08, >> FD_SR0_EQPMT = 0x10, >> FD_SR0_SEEK = 0x20, >> FD_SR0_ABNTERM = 0x40, >> @@ -507,8 +510,10 @@ >> uint8_t pwrd; >> /* Sun4m quirks? */ >> int sun4m; >> + /* NEC PC-98x1 quirks? */ >> + int pc98; >> /* Floppy drives */ >> - fdrive_t drives[MAX_FD]; >> + fdrive_t drives[4]; > >Just change MAX_FD? Thank you very much for comments. I tried the patch to support changing the drive number for each machine. This patch does not includes PC-98x1 features. If this direction is acceptable, I reimplement PC-98x1 patch based on it. Now the drive number is initialized to MAX_FD for each machine, but we need to consider the meaning of MAX_FD. diff -ur a/hw/fdc.c b/hw/fdc.c --- a/hw/fdc.c Thu Sep 10 22:27:13 2009 +++ b/hw/fdc.c Fri Sep 11 00:54:56 2009 @@ -52,6 +52,8 @@ /********************************************************/ /* Floppy drive emulation */ +#define MAX_FD_BUFFER 4 + #define GET_CUR_DRV(fdctrl) ((fdctrl)->cur_drv) #define SET_CUR_DRV(fdctrl, drive) ((fdctrl)->cur_drv = (drive)) @@ -424,11 +426,6 @@ }; enum { -#if MAX_FD == 4 - FD_DOR_SELMASK = 0x03, -#else - FD_DOR_SELMASK = 0x01, -#endif FD_DOR_nRESET = 0x04, FD_DOR_DMAEN = 0x08, FD_DOR_MOTEN0 = 0x10, @@ -437,13 +434,8 @@ FD_DOR_MOTEN3 = 0x80, }; -enum { -#if MAX_FD == 4 - FD_TDR_BOOTSEL = 0x0c, -#else - FD_TDR_BOOTSEL = 0x04, -#endif -}; +#define FD_DOR_SELMASK(fdctrl) (fdctrl->max_fd - 1) +#define FD_TDR_BOOTSEL(fdctrl) ((fdctrl->max_fd - 1) << 2) enum { FD_DSR_DRATEMASK= 0x03, @@ -473,6 +465,8 @@ struct fdctrl_t { /* Controller's identification */ uint8_t version; + /* Max drives (must be 2 or 4) */ + uint8_t max_fd; /* HW */ qemu_irq irq; int dma_chann; @@ -508,7 +502,7 @@ /* Sun4m quirks? */ int sun4m; /* Floppy drives */ - fdrive_t drives[MAX_FD]; + fdrive_t drives[MAX_FD_BUFFER]; int reset_sensei; }; @@ -637,7 +631,6 @@ static void fdc_save (QEMUFile *f, void *opaque) { fdctrl_t *s = opaque; - uint8_t tmp; int i; uint8_t dor = s->dor | GET_CUR_DRV(s); @@ -666,9 +659,8 @@ qemu_put_8s(f, &s->lock); qemu_put_8s(f, &s->pwrd); - tmp = MAX_FD; - qemu_put_8s(f, &tmp); - for (i = 0; i < MAX_FD; i++) + qemu_put_8s(f, &s->max_fd); + for (i = 0; i < s->max_fd; i++) fd_save(f, &s->drives[i]); } @@ -694,8 +686,8 @@ qemu_get_8s(f, &s->sra); qemu_get_8s(f, &s->srb); qemu_get_8s(f, &s->dor); - SET_CUR_DRV(s, s->dor & FD_DOR_SELMASK); - s->dor &= ~FD_DOR_SELMASK; + SET_CUR_DRV(s, s->dor & FD_DOR_SELMASK(s)); + s->dor &= ~FD_DOR_SELMASK(s); qemu_get_8s(f, &s->tdr); qemu_get_8s(f, &s->dsr); qemu_get_8s(f, &s->msr); @@ -718,8 +710,9 @@ qemu_get_8s(f, &s->pwrd); qemu_get_8s(f, &n); - if (n > MAX_FD) + if (n > MAX_FD_BUFFER) return -EINVAL; + s->max_fd = n; for (i = 0; i < n; i++) { ret = fd_load(f, &s->drives[i]); @@ -803,7 +796,7 @@ fdctrl->data_len = 0; fdctrl->data_state = 0; fdctrl->data_dir = FD_DIR_WRITE; - for (i = 0; i < MAX_FD; i++) + for (i = 0; i < fdctrl->max_fd; i++) fd_recalibrate(&fdctrl->drives[i]); fdctrl_reset_fifo(fdctrl); if (do_irq) { @@ -814,21 +807,22 @@ static inline fdrive_t *drv0 (fdctrl_t *fdctrl) { - return &fdctrl->drives[(fdctrl->tdr & FD_TDR_BOOTSEL) >> 2]; + return &fdctrl->drives[(fdctrl->tdr & FD_TDR_BOOTSEL(fdctrl)) >> 2]; } static inline fdrive_t *drv1 (fdctrl_t *fdctrl) { - if ((fdctrl->tdr & FD_TDR_BOOTSEL) < (1 << 2)) + if ((fdctrl->tdr & FD_TDR_BOOTSEL(fdctrl)) < (1 << 2)) return &fdctrl->drives[1]; else return &fdctrl->drives[0]; } -#if MAX_FD == 4 static inline fdrive_t *drv2 (fdctrl_t *fdctrl) { - if ((fdctrl->tdr & FD_TDR_BOOTSEL) < (2 << 2)) + if (fdctrl->max_fd != 4) + return NULL; + else if ((fdctrl->tdr & FD_TDR_BOOTSEL(fdctrl)) < (2 << 2)) return &fdctrl->drives[2]; else return &fdctrl->drives[1]; @@ -836,22 +830,21 @@ static inline fdrive_t *drv3 (fdctrl_t *fdctrl) { - if ((fdctrl->tdr & FD_TDR_BOOTSEL) < (3 << 2)) + if (fdctrl->max_fd != 4) + return NULL; + else if ((fdctrl->tdr & FD_TDR_BOOTSEL(fdctrl)) < (3 << 2)) return &fdctrl->drives[3]; else return &fdctrl->drives[2]; } -#endif static fdrive_t *get_cur_drv (fdctrl_t *fdctrl) { switch (fdctrl->cur_drv) { case 0: return drv0(fdctrl); case 1: return drv1(fdctrl); -#if MAX_FD == 4 case 2: return drv2(fdctrl); case 3: return drv3(fdctrl); -#endif default: return NULL; } } @@ -921,7 +914,7 @@ } } /* Selected drive */ - fdctrl->cur_drv = value & FD_DOR_SELMASK; + fdctrl->cur_drv = value & FD_DOR_SELMASK(fdctrl); fdctrl->dor = value; } @@ -945,7 +938,7 @@ } FLOPPY_DPRINTF("tape drive register set to 0x%02x\n", value); /* Disk boot selection indicator */ - fdctrl->tdr = value & FD_TDR_BOOTSEL; + fdctrl->tdr = value & FD_TDR_BOOTSEL(fdctrl); /* Tape indicators: never allow */ } @@ -1003,10 +996,8 @@ if (fdctrl_media_changed(drv0(fdctrl)) || fdctrl_media_changed(drv1(fdctrl)) -#if MAX_FD == 4 - || fdctrl_media_changed(drv2(fdctrl)) - || fdctrl_media_changed(drv3(fdctrl)) -#endif + || (fdctrl->max_fd == 4 && fdctrl_media_changed(drv2(fdctrl))) + || (fdctrl->max_fd == 4 && fdctrl_media_changed(drv3(fdctrl))) ) retval |= FD_DIR_DSKCHG; if (retval != 0) @@ -1109,7 +1100,7 @@ uint8_t kh, kt, ks; int did_seek = 0; - SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK); + SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK(fdctrl)); cur_drv = get_cur_drv(fdctrl); kt = fdctrl->fifo[2]; kh = fdctrl->fifo[3]; @@ -1379,7 +1370,7 @@ fdrive_t *cur_drv; uint8_t kh, kt, ks; - SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK); + SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK(fdctrl)); cur_drv = get_cur_drv(fdctrl); kt = fdctrl->fifo[6]; kh = fdctrl->fifo[7]; @@ -1450,13 +1441,13 @@ /* Drives position */ fdctrl->fifo[0] = drv0(fdctrl)->track; fdctrl->fifo[1] = drv1(fdctrl)->track; -#if MAX_FD == 4 - fdctrl->fifo[2] = drv2(fdctrl)->track; - fdctrl->fifo[3] = drv3(fdctrl)->track; -#else - fdctrl->fifo[2] = 0; - fdctrl->fifo[3] = 0; -#endif + if (fdctrl->max_fd == 4) { + fdctrl->fifo[2] = drv2(fdctrl)->track; + fdctrl->fifo[3] = drv3(fdctrl)->track; + } else { + fdctrl->fifo[2] = 0; + fdctrl->fifo[3] = 0; + } /* timers */ fdctrl->fifo[4] = fdctrl->timer0; fdctrl->fifo[5] = (fdctrl->timer1 << 1) | (fdctrl->dor & FD_DOR_DMAEN ? 1 : 0); @@ -1488,10 +1479,10 @@ /* Drives position */ drv0(fdctrl)->track = fdctrl->fifo[3]; drv1(fdctrl)->track = fdctrl->fifo[4]; -#if MAX_FD == 4 - drv2(fdctrl)->track = fdctrl->fifo[5]; - drv3(fdctrl)->track = fdctrl->fifo[6]; -#endif + if (fdctrl->max_fd == 4) { + drv2(fdctrl)->track = fdctrl->fifo[5]; + drv3(fdctrl)->track = fdctrl->fifo[6]; + } /* timers */ fdctrl->timer0 = fdctrl->fifo[7]; fdctrl->timer1 = fdctrl->fifo[8]; @@ -1513,13 +1504,13 @@ /* Drives position */ fdctrl->fifo[2] = drv0(fdctrl)->track; fdctrl->fifo[3] = drv1(fdctrl)->track; -#if MAX_FD == 4 - fdctrl->fifo[4] = drv2(fdctrl)->track; - fdctrl->fifo[5] = drv3(fdctrl)->track; -#else - fdctrl->fifo[4] = 0; - fdctrl->fifo[5] = 0; -#endif + if (fdctrl->max_fd == 4) { + fdctrl->fifo[4] = drv2(fdctrl)->track; + fdctrl->fifo[5] = drv3(fdctrl)->track; + } else { + fdctrl->fifo[4] = 0; + fdctrl->fifo[5] = 0; + } /* timers */ fdctrl->fifo[6] = fdctrl->timer0; fdctrl->fifo[7] = fdctrl->timer1; @@ -1548,7 +1539,7 @@ { fdrive_t *cur_drv; - SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK); + SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK(fdctrl)); cur_drv = get_cur_drv(fdctrl); fdctrl->data_state |= FD_STATE_FORMAT; if (fdctrl->fifo[0] & 0x80) @@ -1589,7 +1580,7 @@ { fdrive_t *cur_drv; - SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK); + SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK(fdctrl)); cur_drv = get_cur_drv(fdctrl); cur_drv->head = (fdctrl->fifo[1] >> 2) & 1; /* 1 Byte status back */ @@ -1605,7 +1596,7 @@ { fdrive_t *cur_drv; - SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK); + SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK(fdctrl)); cur_drv = get_cur_drv(fdctrl); fd_recalibrate(cur_drv); fdctrl_reset_fifo(fdctrl); @@ -1639,7 +1630,7 @@ { fdrive_t *cur_drv; - SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK); + SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK(fdctrl)); cur_drv = get_cur_drv(fdctrl); fdctrl_reset_fifo(fdctrl); if (fdctrl->fifo[2] > cur_drv->max_track) { @@ -1708,7 +1699,7 @@ { fdrive_t *cur_drv; - SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK); + SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK(fdctrl)); cur_drv = get_cur_drv(fdctrl); if (fdctrl->fifo[2] + cur_drv->track >= cur_drv->max_track) { cur_drv->track = cur_drv->max_track - 1; @@ -1724,7 +1715,7 @@ { fdrive_t *cur_drv; - SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK); + SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK(fdctrl)); cur_drv = get_cur_drv(fdctrl); if (fdctrl->fifo[2] > cur_drv->track) { cur_drv->track = 0; @@ -1865,7 +1856,7 @@ { unsigned int i; - for (i = 0; i < MAX_FD; i++) { + for (i = 0; i < fdctrl->max_fd; i++) { fd_init(&fdctrl->drives[i], fds[i]); fd_revalidate(&fdctrl->drives[i]); } @@ -1881,7 +1872,9 @@ dev = isa_create_simple("isa-fdc", io_base, 0, isairq, -1); fdctrl = &(DO_UPCAST(fdctrl_isabus_t, busdev, dev)->state); + fdctrl->max_fd = MAX_FD; fdctrl->dma_chann = dma_chann; + DMA_register_channel(dma_chann, &fdctrl_transfer_handler, fdctrl); fdctrl_connect_drives(fdctrl, fds); @@ -1904,7 +1897,9 @@ sysbus_connect_irq(&sys->busdev, 0, irq); sysbus_mmio_map(&sys->busdev, 0, mmio_base); + fdctrl->max_fd = MAX_FD; fdctrl->dma_chann = dma_chann; + DMA_register_channel(dma_chann, &fdctrl_transfer_handler, fdctrl); fdctrl_connect_drives(fdctrl, fds); @@ -1926,6 +1921,7 @@ sysbus_mmio_map(&sys->busdev, 0, io_base); *fdc_tc = qdev_get_gpio_in(dev, 0); + fdctrl->max_fd = MAX_FD; fdctrl->dma_chann = -1; fdctrl_connect_drives(fdctrl, fds); @@ -1979,6 +1975,8 @@ &fdctrl_write_port, fdctrl); isa_init_irq(&isa->busdev, &fdctrl->irq); + fdctrl->max_fd = MAX_FD; + return fdctrl_init_common(fdctrl); } @@ -1992,6 +1990,8 @@ sysbus_init_irq(dev, &fdctrl->irq); qdev_init_gpio_in(&dev->qdev, fdctrl_handle_tc, 1); + fdctrl->max_fd = MAX_FD; + return fdctrl_init_common(fdctrl); } @@ -2006,7 +2006,9 @@ sysbus_init_irq(dev, &fdctrl->irq); qdev_init_gpio_in(&dev->qdev, fdctrl_handle_tc, 1); + fdctrl->max_fd = MAX_FD; fdctrl->sun4m = 1; + return fdctrl_init_common(fdctrl); }