diff options
-rw-r--r-- | src/ata.c | 54 | ||||
-rw-r--r-- | src/farptr.h | 27 | ||||
-rw-r--r-- | src/ioport.h | 26 | ||||
-rw-r--r-- | src/romlayout.S | 1 | ||||
-rw-r--r-- | src/system.c | 1 |
5 files changed, 61 insertions, 48 deletions
@@ -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 ??? |