[SeaBIOS] [PATCH 3/4] Move dma code to new file hw/dma.c.

Kevin O'Connor kevin at koconnor.net
Thu Sep 19 03:59:21 CEST 2013


Move the DMA controller code in resume.c and hw/floppy.c to a new file
hw/dma.c.  This centralizes the DMA controller code into one place.

Also, don't unmask the floppy DRQ during floppy setup - there is no
reason to unmask the DRQ prior to a command being programmed into the
DMA controller.

Signed-off-by: Kevin O'Connor <kevin at koconnor.net>
---
 Makefile        |  2 +-
 src/hw/dma.c    | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/hw/floppy.c | 40 ++++++----------------------------------
 src/resume.c    | 13 -------------
 src/util.h      |  5 ++++-
 5 files changed, 67 insertions(+), 49 deletions(-)
 create mode 100644 src/hw/dma.c

diff --git a/Makefile b/Makefile
index 0cdb6d3..4c78d69 100644
--- a/Makefile
+++ b/Makefile
@@ -11,7 +11,7 @@ OUT=out/
 SRCBOTH=misc.c stacks.c output.c string.c x86.c block.c cdrom.c mouse.c kbd.c \
     serial.c clock.c resume.c pnpbios.c vgahooks.c pcibios.c apm.c \
     fw/smp.c \
-    hw/pci.c hw/timer.c hw/rtc.c hw/pic.c hw/ps2port.c \
+    hw/pci.c hw/timer.c hw/dma.c hw/rtc.c hw/pic.c hw/ps2port.c \
     hw/usb.c hw/usb-uhci.c hw/usb-ohci.c hw/usb-ehci.c \
     hw/usb-hid.c hw/usb-msc.c hw/usb-uas.c \
     hw/blockcmd.c hw/floppy.c hw/ata.c hw/ahci.c hw/ramdisk.c \
diff --git a/src/hw/dma.c b/src/hw/dma.c
new file mode 100644
index 0000000..2051ab0
--- /dev/null
+++ b/src/hw/dma.c
@@ -0,0 +1,56 @@
+// Code to support legacy Intel 8237 DMA chip.
+//
+// Copyright (C) 2008,2009  Kevin O'Connor <kevin at koconnor.net>
+// Copyright (C) 2002  MandrakeSoft S.A.
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "ioport.h" // PORT_DMA1_MASK_REG
+#include "util.h" // dma_setup
+
+// Setup the DMA controller for a floppy transfer.
+int
+dma_floppy(u32 addr, int count, int isWrite)
+{
+    // check for 64K boundary overrun
+    u16 end = count - 1;
+    u32 last_addr = addr + end;
+    if ((addr >> 16) != (last_addr >> 16))
+        return -1;
+
+    u8 mode_register = 0x46; // single mode, increment, autoinit disable,
+    if (isWrite)
+        mode_register = 0x4a;
+
+    outb(0x06, PORT_DMA1_MASK_REG);
+    outb(0x00, PORT_DMA1_CLEAR_FF_REG); // clear flip-flop
+    outb(addr, PORT_DMA_ADDR_2);
+    outb(addr>>8, PORT_DMA_ADDR_2);
+    outb(0x00, PORT_DMA1_CLEAR_FF_REG); // clear flip-flop
+    outb(end, PORT_DMA_CNT_2);
+    outb(end>>8, PORT_DMA_CNT_2);
+
+    // port 0b: DMA-1 Mode Register
+    // transfer type=write, channel 2
+    outb(mode_register, PORT_DMA1_MODE_REG);
+
+    // port 81: DMA-1 Page Register, channel 2
+    outb(addr>>16, PORT_DMA_PAGE_2);
+
+    outb(0x02, PORT_DMA1_MASK_REG); // unmask channel 2
+
+    return 0;
+}
+
+// Reset DMA controller
+void
+dma_setup(void)
+{
+    // first reset the DMA controllers
+    outb(0, PORT_DMA1_MASTER_CLEAR);
+    outb(0, PORT_DMA2_MASTER_CLEAR);
+
+    // then initialize the DMA controllers
+    outb(0xc0, PORT_DMA2_MODE_REG);
+    outb(0x00, PORT_DMA2_MASK_REG);
+}
diff --git a/src/hw/floppy.c b/src/hw/floppy.c
index cf1ab87..0479ac7 100644
--- a/src/hw/floppy.c
+++ b/src/hw/floppy.c
@@ -153,8 +153,6 @@ floppy_setup(void)
             addFloppy(1, type);
     }
 
-    outb(0x02, PORT_DMA1_MASK_REG);
-
     enable_hwirq(6, FUNC16(entry_0e));
 }
 
@@ -433,7 +431,7 @@ check_recal_drive(struct drive_s *drive_g)
 
 
 /****************************************************************
- * Floppy DMA
+ * Floppy DMA transfer
  ****************************************************************/
 
 // Perform a floppy transfer command (setup DMA and issue PIO).
@@ -444,39 +442,13 @@ floppy_cmd(struct disk_op_s *op, int blocksize, struct floppy_pio_s *pio)
     if (ret)
         return ret;
 
-    // es:bx = pointer to where to place information from diskette
-    u32 addr = (u32)op->buf_fl;
-    int count = op->count * blocksize;
-
-    // check for 64K boundary overrun
-    u16 end = count - 1;
-    u32 last_addr = addr + end;
-    if ((addr >> 16) != (last_addr >> 16))
+    // Setup DMA controller
+    int isWrite = pio->data[0] != 0xe6;
+    ret = dma_floppy((u32)op->buf_fl, op->count * blocksize, isWrite);
+    if (ret)
         return DISK_RET_EBOUNDARY;
 
-    u8 mode_register = 0x4a; // single mode, increment, autoinit disable,
-    if (pio->data[0] == 0xe6)
-        // read
-        mode_register = 0x46;
-
-    //DEBUGF("floppy dma c2\n");
-    outb(0x06, PORT_DMA1_MASK_REG);
-    outb(0x00, PORT_DMA1_CLEAR_FF_REG); // clear flip-flop
-    outb(addr, PORT_DMA_ADDR_2);
-    outb(addr>>8, PORT_DMA_ADDR_2);
-    outb(0x00, PORT_DMA1_CLEAR_FF_REG); // clear flip-flop
-    outb(end, PORT_DMA_CNT_2);
-    outb(end>>8, PORT_DMA_CNT_2);
-
-    // port 0b: DMA-1 Mode Register
-    // transfer type=write, channel 2
-    outb(mode_register, PORT_DMA1_MODE_REG);
-
-    // port 81: DMA-1 Page Register, channel 2
-    outb(addr>>16, PORT_DMA_PAGE_2);
-
-    outb(0x02, PORT_DMA1_MASK_REG); // unmask channel 2
-
+    // Invoke floppy controller
     ret = floppy_select_drive(pio->data[1] & 1);
     if (ret)
         return ret;
diff --git a/src/resume.c b/src/resume.c
index 12daf0f..370bfe3 100644
--- a/src/resume.c
+++ b/src/resume.c
@@ -21,19 +21,6 @@
 // Indicator if POST phase has been run.
 int HaveRunPost VARFSEG;
 
-// Reset DMA controller
-void
-dma_setup(void)
-{
-    // first reset the DMA controllers
-    outb(0, PORT_DMA1_MASTER_CLEAR);
-    outb(0, PORT_DMA2_MASTER_CLEAR);
-
-    // then initialize the DMA controllers
-    outb(0xc0, PORT_DMA2_MODE_REG);
-    outb(0x00, PORT_DMA2_MASK_REG);
-}
-
 // Handler for post calls that look like a resume.
 void VISIBLE16
 handle_resume(void)
diff --git a/src/util.h b/src/util.h
index 9c45925..d51e30f 100644
--- a/src/util.h
+++ b/src/util.h
@@ -124,6 +124,10 @@ void wrmsr_smp(u32 index, u64 val);
 void smp_setup(void);
 int apic_id_is_present(u8 apic_id);
 
+// hw/dma.c
+int dma_floppy(u32 addr, int count, int isWrite);
+void dma_setup(void);
+
 // hw/floppy.c
 extern struct floppy_ext_dbt_s diskette_param_table2;
 void floppy_setup(void);
@@ -204,7 +208,6 @@ void reloc_preinit(void *f, void *arg);
 
 // resume.c
 extern int HaveRunPost;
-void dma_setup(void);
 
 // romlayout.S
 void reset_vector(void) __noreturn;
-- 
1.8.3.1




More information about the SeaBIOS mailing list