2

This is the function that call's insl.

void ide_read_buffer(unsigned char channel, unsigned char reg, unsigned int buffer,
                     unsigned int quads) {
   /* WARNING: This code contains a serious bug. The inline assembly trashes ES and
    *           ESP for all of the code the compiler generates between the inline
    *           assembly blocks.
    */
   if (reg > 0x07 && reg < 0x0C)
      ide_write(channel, ATA_REG_CONTROL, 0x80 | channels[channel].nIEN);
   asm("pushw %es; movw %ds, %ax; movw %ax, %es");
   if (reg < 0x08)
      insl(channels[channel].base  + reg - 0x00, buffer, quads);
   else if (reg < 0x0C)
      insl(channels[channel].base  + reg - 0x06, buffer, quads);
   else if (reg < 0x0E)
      insl(channels[channel].ctrl  + reg - 0x0A, buffer, quads);
   else if (reg < 0x16)
      insl(channels[channel].bmide + reg - 0x0E, buffer, quads);
   asm("popw %es;");
   if (reg > 0x07 && reg < 0x0C)
      ide_write(channel, ATA_REG_CONTROL, channels[channel].nIEN);
}

The link is here, https://wiki.osdev.org/PCI_IDE_Controller#Commands.

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
mike
  • 100
  • 7
  • 2
    I assume it's a wrapper for `rep insl`, the AT&T syntax instruction name for `insd`. That's the dword operand-size version of `ins`. https://www.felixcloutier.com/x86/ins:insb:insw:insd / https://www.felixcloutier.com/x86/rep:repe:repz:repne:repnz. There's a definition in `io.h` mentioned in this Q&A: [include io.h header file meet some problem, the io.h file has no struct \_finddata\_t](https://stackoverflow.com/q/53363068) – Peter Cordes Jun 28 '20 at 21:26

1 Answers1

6

What does the function insl do in Os Dev's PCI IDE tutorial?

void ide_read_buffer(... unsigned int buffer ...)

It is clear why you don't understand the code:

unsigned int buffer is obviously a bug in the tutorial code. It should be unsigned int * buffer.

Now it is clear what insl does: It reads quad times from the port given in the first argument and writes the results to the array buffer.

The black-box behaviour of the function could be explained the following way:

void insl(unsigned reg, unsigned int *buffer, int quads)
{
    int index;
    for(index = 0; index < quads; index++)
    {
        buffer[index] = inl(reg);
    }
}
Martin Rosenau
  • 17,897
  • 3
  • 19
  • 38