aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/ata.c54
-rw-r--r--src/farptr.h27
-rw-r--r--src/ioport.h26
-rw-r--r--src/romlayout.S1
-rw-r--r--src/system.c1
5 files changed, 61 insertions, 48 deletions
diff --git a/src/ata.c b/src/ata.c
index d26eca90..25327fc1 100644
--- a/src/ata.c
+++ b/src/ata.c
@@ -125,46 +125,6 @@ ata_reset(u16 device)
outb(ATA_CB_DC_HD15, iobase2+ATA_CB_DC);
}
-static void
-insw(u16 port, u16 segment, u16 offset, u16 count)
-{
- u16 i;
- for (i=0; i<count; i++) {
- u16 d = inw(port);
- SET_FARVAR(segment, *(u16*)(offset + 2*i), d);
- }
-}
-
-static void
-insl(u16 port, u16 segment, u16 offset, u16 count)
-{
- u16 i;
- for (i=0; i<count; i++) {
- u32 d = inl(port);
- SET_FARVAR(segment, *(u32*)(offset + 4*i), d);
- }
-}
-
-static void
-outsw(u16 port, u16 segment, u16 offset, u16 count)
-{
- u16 i;
- for (i=0; i<count; i++) {
- u16 d = GET_FARVAR(segment, *(u16*)(offset + 2*i));
- outw(d, port);
- }
-}
-
-static void
-outsl(u16 port, u16 segment, u16 offset, u16 count)
-{
- u16 i;
- for (i=0; i<count; i++) {
- u32 d = GET_FARVAR(segment, *(u32*)(offset + 4*i));
- outl(d, port);
- }
-}
-
// ---------------------------------------------------------------------------
// ATA/ATAPI driver : execute a data-in command
@@ -255,9 +215,9 @@ ata_cmd_data_in(u16 device, u16 command, u16 count, u16 cylinder
}
if (mode == ATA_MODE_PIO32)
- insl(iobase1, segment, offset, 512 / 4);
+ insl_seg(iobase1, segment, offset, 512 / 4);
else
- insw(iobase1, segment, offset, 512 / 2);
+ insw_seg(iobase1, segment, offset, 512 / 2);
offset += 512;
current++;
@@ -380,9 +340,9 @@ ata_cmd_data_out(u16 device, u16 command, u16 count, u16 cylinder
}
if (mode == ATA_MODE_PIO32)
- outsl(iobase1, segment, offset, 512 / 4);
+ outsl_seg(iobase1, segment, offset, 512 / 4);
else
- outsw(iobase1, segment, offset, 512 / 2);
+ outsw_seg(iobase1, segment, offset, 512 / 2);
offset += 512;
current++;
@@ -492,7 +452,7 @@ ata_cmd_packet(u16 device, u8 *cmdbuf, u8 cmdlen, u16 header
// Send command to device
irq_enable();
- outsw(iobase1, GET_SEG(SS), (u32)cmdbuf, cmdlen);
+ outsw_seg(iobase1, GET_SEG(SS), (u32)cmdbuf, cmdlen);
if (inout == ATA_DATA_NO) {
await_ide(NOT_BSY, iobase1, IDE_TIMEOUT);
@@ -584,9 +544,9 @@ ata_cmd_packet(u16 device, u8 *cmdbuf, u8 cmdlen, u16 header
inw(iobase1);
if (lmode == ATA_MODE_PIO32)
- insl(iobase1, bufseg, bufoff, lcount);
+ insl_seg(iobase1, bufseg, bufoff, lcount);
else
- insw(iobase1, bufseg, bufoff, lcount);
+ insw_seg(iobase1, bufseg, bufoff, lcount);
for (i=0; i<lafter; i++)
if (lmode == ATA_MODE_PIO32)
diff --git a/src/farptr.h b/src/farptr.h
index 7216f237..e1428437 100644
--- a/src/farptr.h
+++ b/src/farptr.h
@@ -6,6 +6,8 @@
#ifndef __FARPTR_H
#define __FARPTR_H
+#include "ioport.h" // insb
+
#define READ8_SEG(SEG, var) ({ \
u8 __value; \
__asm__ __volatile__("movb %%" #SEG ":%1, %b0" \
@@ -100,4 +102,29 @@ extern void __force_link_error__unknown_type();
#define SET_FARPTR(ptr, val) do { (var) = (val); } while (0)
#endif
+static inline void insb_seg(u16 port, u16 segment, u16 offset, u16 count) {
+ SET_SEG(ES, segment);
+ insb(port, (u8*)(offset+0), count);
+}
+static inline void insw_seg(u16 port, u16 segment, u16 offset, u16 count) {
+ SET_SEG(ES, segment);
+ insw(port, (u16*)(offset+0), count);
+}
+static inline void insl_seg(u16 port, u16 segment, u16 offset, u16 count) {
+ SET_SEG(ES, segment);
+ insl(port, (u32*)(offset+0), count);
+}
+static inline void outsb_seg(u16 port, u16 segment, u16 offset, u16 count) {
+ SET_SEG(ES, segment);
+ outsb(port, (u8*)(offset+0), count);
+}
+static inline void outsw_seg(u16 port, u16 segment, u16 offset, u16 count) {
+ SET_SEG(ES, segment);
+ outsw(port, (u16*)(offset+0), count);
+}
+static inline void outsl_seg(u16 port, u16 segment, u16 offset, u16 count) {
+ SET_SEG(ES, segment);
+ outsl(port, (u32*)(offset+0), count);
+}
+
#endif // farptr.h
diff --git a/src/ioport.h b/src/ioport.h
index d756e340..ba9117b8 100644
--- a/src/ioport.h
+++ b/src/ioport.h
@@ -73,4 +73,30 @@ static inline u32 inl(u16 port) {
return value;
}
+static inline void insb(u16 port, u8 *data, u32 count) {
+ asm volatile("rep insb (%%dx), %%es:(%%di)"
+ : "+c"(count), "+D"(data) : "d"(port) : "memory");
+}
+static inline void insw(u16 port, u16 *data, u32 count) {
+ asm volatile("rep insw (%%dx), %%es:(%%di)"
+ : "+c"(count), "+D"(data) : "d"(port) : "memory");
+}
+static inline void insl(u16 port, u32 *data, u32 count) {
+ asm volatile("rep insl (%%dx), %%es:(%%di)"
+ : "+c"(count), "+D"(data) : "d"(port) : "memory");
+}
+// XXX - outs not limited to es segment
+static inline void outsb(u16 port, u8 *data, u32 count) {
+ asm volatile("rep outsb %%es:(%%si), (%%dx)"
+ : "+c"(count), "+S"(data) : "d"(port) : "memory");
+}
+static inline void outsw(u16 port, u16 *data, u32 count) {
+ asm volatile("rep outsw %%es:(%%si), (%%dx)"
+ : "+c"(count), "+S"(data) : "d"(port) : "memory");
+}
+static inline void outsl(u16 port, u32 *data, u32 count) {
+ asm volatile("rep outsl %%es:(%%si), (%%dx)"
+ : "+c"(count), "+S"(data) : "d"(port) : "memory");
+}
+
#endif // ioport.h
diff --git a/src/romlayout.S b/src/romlayout.S
index 1aa0bbfc..96e2e8b1 100644
--- a/src/romlayout.S
+++ b/src/romlayout.S
@@ -245,6 +245,7 @@ rombios32_gdt:
****************************************************************/
.macro ENTRY cfunc
+ cld
pushal
pushw %es
pushw %ds
diff --git a/src/system.c b/src/system.c
index b1e4fe89..1f34c97a 100644
--- a/src/system.c
+++ b/src/system.c
@@ -174,7 +174,6 @@ handle_1587(struct bregs *regs)
// move CX words from DS:SI to ES:DI
"xorw %%si, %%si\n"
"xorw %%di, %%di\n"
- "cld\n"
"rep movsw\n"
// reset PG bit in CR0 ???