What is the purpose of io_wait, and what does it do?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
Mikumiku747
Member
Member
Posts: 64
Joined: Thu Apr 16, 2015 7:37 am

What is the purpose of io_wait, and what does it do?

Post by Mikumiku747 »

Hello,

I've been looking to implementing interrupts in my OS, and I was looking at the basic IO functions the wiki provides. I've written my own versions of inx and outx in full assembly instead of inline, since I'm more comfortable with full assembly and it looks cleaner, and now I need to implement the io_wait function if I'm going to follow the advice of the wiki when it comes to programming the PICs. My question is, what does the io_wait function on the wiki do, and why is it required when reprogramming the PICs? I implemented cursor movement in text mode using the VGA registers, which are accessed by ports, and they don't seem to require any kind of explicit waiting period, so what makes the PICs unique?

Also, the code on the wiki, http://wiki.osdev.org/Inline_Assembly/Examples#IO_WAIT shows 2 methods of implementing a wait function, one apparently just doing 2 consecutive jumps and the other writing to an unused port. How do each of these methods actually work, and if I were to implement something in full assembly, what would be the *best* way of going about it?

I think my OS code isn't really relevant to this question, but I can provide it if necessary.

Thanks for reading,
Mikumiku747
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: What is the purpose of io_wait, and what does it do?

Post by iansjack »

Note the presence of io_wait() calls, on older machines its necessary to give the PIC some time to react to commands as they might not be processed quickly
User avatar
BrightLight
Member
Member
Posts: 901
Joined: Sat Dec 27, 2014 9:11 am
Location: Maadi, Cairo, Egypt
Contact:

Re: What is the purpose of io_wait, and what does it do?

Post by BrightLight »

iansjack wrote:
Note the presence of io_wait() calls, on older machines its necessary to give the PIC some time to react to commands as they might not be processed quickly
IMHO, and in my OS, it should be used after every OUT instruction for a device that doesn't have a way of "acknowledging" the data. This includes the PIC, CMOS, VGA, and definitely others.
For example, here's iowait in my OS:

Code: Select all

; iowait:
; Waits for an I/O operation to complete

iowait:
	pushaq

	push 0x28
	push .next
	retf

.next:
	nop
	nop
	nop
	nop
	pause

	push 0x28
	push .next2
	retf

.next2:
	nop
	nop
	nop
	nop
	pause

	push 0x28
	push .next3
	retf

.next3:
	nop
	nop
	nop
	nop
	pause

	push 0x28
	push .next4
	retf

.next4:
	out 0x80, al
	out 0x80, al

	popaq
	ret
You know your OS is advanced when you stop using the Intel programming guide as a reference.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: What is the purpose of io_wait, and what does it do?

Post by Brendan »

Hi,

Once upon a time there was a computer that used a ~5 MHz CPU bus. Devices were designed to handle the timing for that bus, and everything was good (for a while).

Then faster computers/CPUs came along. On a CPU with a 10 MHz bus, devices that were designed to handle the timing for a ~5 MHz bus got all broken - you'd send something (e.g. a command) to a device, then get something (e.g. status) from the same device, but the device was designed for a slower bus and hasn't had enough time to handle the previous data and gave you stale/dodgy results. Programmers worked around the problem by inserting IO delays, to give the older devices more time.

Of course this was just a silly hack to work around a motherboard flaw. Motherboard manufacturers added "wait states" into hardware to fix the problem. Some motherboards added wait states for everything (even though it's only needed when accessing the same device), some motherboards used more complicated schemes (only use wait states when the device is the same as last time) to improve performance. In addition, the older hardware that was designed for ~5 MHz got replaced with newer hardware that handled faster buses properly. This complicated things and for some computers there was a "IO wait time" BIOS setting that the user could adjust to suit whatever devices got plugged into the motherboard (but like all user settings, this just means the user can mis-configure it in a misguided attempt to make their computer faster).

Meanwhile; programmers had no way to know what the hardware did, so they just continued inserting their "IO delays". Backward compatibility; better to be safe than sorry.

By the time 80486 came along the silly hack to work around motherboard flaws in software wasn't needed any more. Programmers kept doing it due to a combination of "standard practice from yesteryear" and paranoia, and because it was easier than trying to figure out why it was ever needed.

Note that for PIC initialisation you can interleave accesses - e.g. write to "master PIC", then give master PIC time to handle it by writing to slave PIC, then give slave PIC time to handle it by writing to master PIC, and so on. Not only is the "IO wait" completely unnecessary for modern (80486+) hardware, it's also unnecessary for PIC initialisation on ancient dodgy hardware (because you're interleaving accesses).


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Post Reply