Thread: [Geekos-devel] Re: IDE driver details
Status: Pre-Alpha
Brought to you by:
daveho
From: David H. <da...@cs...> - 2002-01-29 16:58:05
|
Hi Vishal, On Tue, Jan 29, 2002 at 04:41:19AM -0800, Vishal Soni wrote: > Hi Dave, > > As ATA 1 standard specifies there are two modes of operation > 1. CHS-Cylinder Head Sector > 2. LBA-Logical Block Access (Drive is treated as logical array of > 512byte blocks) > > Which of the following modes u are planning to use for Virtual Memory > implementation?? > > This is necessary for me to make a C interface for the Kernel for > access. I think LBA mode would be a lot nicer to deal with than CHS. Maybe the driver could emulate LBA for drives/controllers that don't support LBA, so that the kernel API for all block devices was LBA. I must admit I really don't know a lot about hard drives (or operating systems :-), so I may not be aware of all of the issues. > We could possibly have a driver that would allow us to use LBA and CHS > mode. I am not sure what modes drives operate in VM systems, ff you have > some idea let me know. I don't think whether or not virtual memory is in use makes a difference, unless you're using DMA (which I think needs physical addresses). Just to double-check: you're working with the experimental version of GeekOS? http://geekos.sourceforge.net/experimental.html All new development will be on that version. > Write now I have modified the kernel boot up code to get some drive > parameters from BIOS Hard Disk drive parameter table. This information > is propagated to the Main() function. Good. Did you add new fields to the boot_info struct? > I have most of the stuff for ATA-1 > driver figured out. The interface C code I am planning to add to the > kernel right now would have some basic functionality of > 1. Initializing drives > 2. Read sectors/blocks > 3. Write sectors/blocks > 4. Querying drive information > 5. Seek > > and some other commands. > > I am not planning to use DMA or interrupts for this initial version of > driver. So it will be strictly Programmed I/0 achieved by communicating > at IN/OUT ports This all sounds great! Let me know if you have any other questions. Also, feel free to send email to the geekos-devel mailing list, that way everyone working on geekos will know what you're doing. -Dave |
From: Parc <ne...@ri...> - 2002-01-29 18:38:02
|
On Tue, Jan 29, 2002 at 11:57:54AM -0500, David Hovemeyer wrote: > Hi Vishal, > > On Tue, Jan 29, 2002 at 04:41:19AM -0800, Vishal Soni wrote: > > Hi Dave, > > > > As ATA 1 standard specifies there are two modes of operation > > 1. CHS-Cylinder Head Sector > > 2. LBA-Logical Block Access (Drive is treated as logical array of > > 512byte blocks) > > > > Which of the following modes u are planning to use for Virtual Memory > > implementation?? > > > > This is necessary for me to make a C interface for the Kernel for > > access. > > I think LBA mode would be a lot nicer to deal with than CHS. > Maybe the driver could emulate LBA for drives/controllers that don't support > LBA, so that the kernel API for all block devices was LBA. > CHS will limit the size of HD you can use. It'll also slow down the driver as it has to do the translations. > I must admit I really don't know a lot about hard drives (or > operating systems :-), so I may not be aware of all of the issues. > > > We could possibly have a driver that would allow us to use LBA and CHS > > mode. I am not sure what modes drives operate in VM systems, ff you have > > some idea let me know. > > I don't think whether or not virtual memory is in use makes a > difference, unless you're using DMA (which I think needs physical > addresses). > This brings up an issue that I've been thinking about for a couple weeks now. The malloc currently in geekos doesn't really know about physical memory. The DMA code is going to need physical addresses to work. Not only that, but physical addresses also cannot cross segment boundries. > Just to double-check: you're working with the experimental > version of GeekOS? http://geekos.sourceforge.net/experimental.html > All new development will be on that version. > > > Write now I have modified the kernel boot up code to get some drive > > parameters from BIOS Hard Disk drive parameter table. This information > > is propagated to the Main() function. > > Good. Did you add new fields to the boot_info struct? > This is a good start, however, it's better to not use BIOS to talk to drives at all. BIOS is going to limit you to the first 1024 cylinders to read from, causing weird issues with large partitions. But then again, it's not ultra important at this point. > > I have most of the stuff for ATA-1 > > driver figured out. The interface C code I am planning to add to the > > kernel right now would have some basic functionality of > > 1. Initializing drives > > 2. Read sectors/blocks > > 3. Write sectors/blocks > > 4. Querying drive information > > 5. Seek > > > > and some other commands. > > > > I am not planning to use DMA or interrupts for this initial version of > > driver. So it will be strictly Programmed I/0 achieved by communicating > > at IN/OUT ports > I've been working on DMA, and I'll post when it's done. Once we geek the memory allocation stuff ready, it'll be a breeze. > This all sounds great! Let me know if you have any other questions. > Also, feel free to send email to the geekos-devel mailing list, > that way everyone working on geekos will know what you're doing. > > -Dave Also, I've got an updated patchset coming here shortly for the timer code. We now have an RTC, although it's useless until I write some syscalls for it... -neal > > _______________________________________________ > Geekos-devel mailing list > Gee...@li... > https://lists.sourceforge.net/lists/listinfo/geekos-devel > |
From: Vishal S. <vis...@ho...> - 2002-01-29 21:56:26
|
Hi, I need a calibrated delay of approx. 400ns for communicating with IDE drives. There are two possible options. Use timer interrupts: I can use them if they are not going to be used by any other components of the kernel. This also is not a good idea because we frequently need to wait for 400ns in IDE -drive communication. This will increase the number of interrupts. Probably couple of them each time u try to access a sector. Second is to use loop with NOP's in it and execute it to get approximately a 400nsecond delay. For eg. if NOP takes 4 clock cycles and my clock has 100ns duty cycle I can get 400ns delay by putting 4 NOP in my delay loop. This works fine if we assume all processors have 100ns clock duty cycle...but this not the case because different versions of Intel/AMD processors have different speeds. If you guys have any Ideas regarding this let me know?? I will try to look into Linux source reference how they handle such situations. I know Linux uses something called BogoMIPS. But I am not sure how it works. Let me know if you guys have some other amazing ideas to handle this situation Thanks, Vishal |
From: 'Parc' <ne...@ri...> - 2002-01-29 22:09:04
|
On Tue, Jan 29, 2002 at 04:06:58PM -0800, Vishal Soni wrote: > Hi, > > I need a calibrated delay of approx. 400ns for communicating with IDE > drives. > > There are two possible options. > > Use timer interrupts: I can use them if they are not going to be used by > any other components of the kernel. This also is not a good idea because > we frequently need to wait for 400ns in IDE -drive communication. This > will increase the number of interrupts. Probably couple of them each > time u try to access a sector. > Give me a little time and I can probably get either an RTC timer or a 8254 secondary timer together. I believe the most common way is with the RTC. > Second is to use loop with NOP's in it and execute it to get > approximately a 400nsecond delay. > For eg. if NOP takes 4 clock cycles and my clock has 100ns duty cycle I > can get 400ns delay by putting 4 NOP in my delay loop. NOP gets optimized out by bochs, and some processors may do odd things. VMWare would also not like it. Another way to do it might be to watch the DRAM refresh status. It runs at 66Mhz, so watch it's flip-flops for enough time. > > This works fine if we assume all processors have 100ns clock duty > cycle...but this not the case because different versions of Intel/AMD > processors have different speeds. > > If you guys have any Ideas regarding this let me know?? I will try to > look into Linux source reference how they handle such situations. I know > Linux uses something called BogoMIPS. But I am not sure how it works. See above. > > Let me know if you guys have some other amazing ideas to handle this > situation The least invasive way right now is to use the DRAM refresh. Look for a nanosleep to appear shortly, since you need it. I imagine the controller can handle longer pauses than required, so you could just sleep(1). Yeah, it's WAY too long, but if it works... > > Thanks, > > Vishal > No prob -parc |
From: David H. <da...@cs...> - 2002-01-29 23:19:53
Attachments:
timer-patch.txt
|
On Tue, Jan 29, 2002 at 04:07:52PM -0600, 'Parc' wrote: > On Tue, Jan 29, 2002 at 04:06:58PM -0800, Vishal Soni wrote: > > Use timer interrupts: I can use them if they are not going to be used by > > any other components of the kernel. This also is not a good idea because > > we frequently need to wait for 400ns in IDE -drive communication. This > > will increase the number of interrupts. Probably couple of them each > > time u try to access a sector. > > > Give me a little time and I can probably get either an RTC timer or a > 8254 secondary timer together. I believe the most common way is with > the RTC. Is the idea that you'd program a one-shot timer, and wait for it to go off? Would the resolution be sufficient? > > Second is to use loop with NOP's in it and execute it to get > > approximately a 400nsecond delay. > > For eg. if NOP takes 4 clock cycles and my clock has 100ns duty cycle I > > can get 400ns delay by putting 4 NOP in my delay loop. > > NOP gets optimized out by bochs, and some processors may do odd things. > VMWare would also not like it. Another way to do it might be to watch > the DRAM refresh status. It runs at 66Mhz, so watch it's flip-flops > for enough time. Interesting idea, although wouldn't it actually be dependent on the motherboard and processor? > > If you guys have any Ideas regarding this let me know?? I will try to > > look into Linux source reference how they handle such situations. I know > > Linux uses something called BogoMIPS. But I am not sure how it works. > > See above. Linux uses a hard coded loop of (roughly) the form: while ( count > 0 ) --count; The BogoMIPS value is the result of a test that calibrates how many iterations of this loop can execute per second. I looked at the Linux BogoMIPS code, and it's pretty hairy. So, I hacked something similar into timer.c; basically, it runs a similar loop, and determines how many iterations occur in one timer tick. The patch is attached to this email. (I'm going to commit it, so you can also just cvs update.) I haven't actually written the delay function yet, since I want to see whether it works on real hardware. (It seems to be pretty stable in Bochs; on my 450 MHz Ultra 60 it can execute 1464 iterations of the loop in one tick :-) I also need to write the loop in assembly so the same code gets executed in the delay function and the timing function. -Dave |
From: 'Parc' <ne...@ri...> - 2002-01-30 01:03:54
|
On Tue, Jan 29, 2002 at 06:19:48PM -0500, David Hovemeyer wrote: [snip] > > Is the idea that you'd program a one-shot timer, and wait for > it to go off? Would the resolution be sufficient? > Yes and no. I'm still researching a bit, but I'll have a design made up pretty soon, and should have an implementation pretty quickly. The basic is that I'm going to fire off the RTC with a 2x divider. That gives me a 8MHz clock. When you nanosleep, I'll fire it up, and turn it off when the timer is done. It looks stupid, though, so I'm still thinking about it. [snip] > > NOP gets optimized out by bochs, and some processors may do odd things. > > VMWare would also not like it. Another way to do it might be to watch > > the DRAM refresh status. It runs at 66Mhz, so watch it's flip-flops > > for enough time. > > Interesting idea, although wouldn't it actually be dependent on > the motherboard and processor? I realized that yes, it would be. Maybe. All my references are for older machines. I'll look some more. > [snip] > > Linux uses a hard coded loop of (roughly) the form: > > while ( count > 0 ) > --count; > > The BogoMIPS value is the result of a test that calibrates how many > iterations of this loop can execute per second. > > I looked at the Linux BogoMIPS code, and it's pretty hairy. > So, I hacked something similar into timer.c; basically, it runs > a similar loop, and determines how many iterations occur in one > timer tick. The patch is attached to this email. (I'm going to > commit it, so you can also just cvs update.) I really don't like that. The compiler can optimize that completely out if it feels like it. Also, CPU caching changes how it behaves. If something invalidates your cache while you're spinning, the timing won't be accurate. > > I haven't actually written the delay function yet, since I want to > see whether it works on real hardware. (It seems to be pretty stable > in Bochs; on my 450 MHz Ultra 60 it can execute 1464 iterations of > the loop in one tick :-) I also need to write the loop in assembly > so the same code gets executed in the delay function and the > timing function. > > -Dave BogoMIPs are just bogus. There are variables that I don't think are good to rely on. Then again, I don't do OS coding for a living, so I could be wrong... :) -parc |
From: David H. <da...@cs...> - 2002-01-30 15:43:27
|
On Tue, Jan 29, 2002 at 07:02:24PM -0600, 'Parc' wrote: > On Tue, Jan 29, 2002 at 06:19:48PM -0500, David Hovemeyer wrote: > [snip] > > > > Is the idea that you'd program a one-shot timer, and wait for > > it to go off? Would the resolution be sufficient? > > > Yes and no. I'm still researching a bit, but I'll have a design > made up pretty soon, and should have an implementation pretty quickly. > The basic is that I'm going to fire off the RTC with a 2x divider. That > gives me a 8MHz clock. When you nanosleep, I'll fire it up, and turn it > off when the timer is done. It looks stupid, though, so I'm still thinking > about it. Sounds good. [snip] > > I looked at the Linux BogoMIPS code, and it's pretty hairy. > > So, I hacked something similar into timer.c; basically, it runs > > a similar loop, and determines how many iterations occur in one > > timer tick. The patch is attached to this email. (I'm going to > > commit it, so you can also just cvs update.) > I really don't like that. The compiler can optimize that completely out > if it feels like it. Also, CPU caching changes how it behaves. If > something invalidates your cache while you're spinning, the timing won't > be accurate. I rewrote the loop in inline volatile asm, so it won't get optimized out. (Will commit this soon.) The code does rely a bit too intimately on gcc to not mess it up. The main dangers are (1) that the stack pointer might change between when the eip is saved and reset by the interrupt handler (which would cause massive lossage), and (2) that the "count" variable might not get allocated in a register, or might occupy different registers at different times, which would result in an invalid timing result. Case (1) is not likely to happen, especially if we compile with optimization. Case (2) is a bit more likely, but I think making the counter a "register" variable solves this case. Anyway, the code works. Regarding a cache invalidation (due to an interrupt occurring?) messing up the timing, yes, this could certainly happen. However, I think that's OK. The semantics of this sort of delay would be "wait for *at least* the specified amount of time". If it waits a bit longer, no big deal. > BogoMIPs are just bogus. There are variables that I don't think are > good to rely on. Here's my take on using a spin loop to delay. This is for really short delays (400 ns is less than a millionth of a second). It's too short a period to schedule another thread, so therefore the processor may as well be completely idle. > Then again, I don't do OS coding for a living, so > I could be wrong... :) I would also like to invoke this disclaimer :-) -Dave |