aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2013-09-18 21:04:03 -0400
committerKevin O'Connor <kevin@koconnor.net>2013-09-28 22:09:07 -0400
commit7b9f29736aecd3ac35021a8fc24ee15fc01d2c5a (patch)
treef8c139332cdda5f135e6e061b77654ee9df7e53d
parent8b7861c4d4b573ca7e0b43e58bc97ff0244ba9a3 (diff)
downloadseabios-7b9f29736aecd3ac35021a8fc24ee15fc01d2c5a.tar.gz
Move dma code to new file hw/dma.c.
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@koconnor.net>
-rw-r--r--Makefile2
-rw-r--r--src/hw/dma.c56
-rw-r--r--src/hw/floppy.c40
-rw-r--r--src/resume.c13
-rw-r--r--src/util.h5
5 files changed, 67 insertions, 49 deletions
diff --git a/Makefile b/Makefile
index 215e6f58..32189701 100644
--- a/Makefile
+++ b/Makefile
@@ -29,7 +29,7 @@ IASL:=iasl
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/rtc.c hw/dma.c hw/pic.c hw/ps2port.c \
hw/usb.c hw/usb-uhci.c hw/usb-ohci.c hw/usb-ehci.c hw/usb-xhci.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 00000000..2051ab0d
--- /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@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 cf1ab87a..0479ac7e 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 12daf0f4..370bfe3a 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 9c459253..d51e30f7 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;