Page 1 of 2
Can't find SATA controller.
Posted: Sun May 24, 2015 12:12 pm
by glauxosdev
Hi,
I have tried to find the SATA controller using the BIOS.
Code: Select all
get_ahci_bus_dev_fun:
mov word [interface], 0
.get_ahci_address:
mov si, 0 ; get pci address of first ahci ctrller
mov ax, 0xB103
mov ecx, 0x00010600
mov cl, byte [interface]
int 0x1A
.check_ahci:
cmp ah, 0x86 ; if ah returned 0x86, we failed
jne .copy_bus ; set_protected_mode
.go_to_next_interface:
inc word [interface]
cmp word [interface], 256
jne .get_ahci_address
jmp .save_null
.copy_bus:
movzx eax, bh ; bus is in bh
.copy_dev:
movzx ecx, bl ; dev is in 5 higher bits of bl
shr ecx, 3
.copy_fun:
movzx edx, bl ; fun is in 3 lower bits of bl
and edx, 7
.save_vars:
mov si, 0x1280 ; variables are saved
mov ds, si
mov si, 0
mov dword [ds:si], eax
mov dword [ds:si + 4], ecx
mov dword [ds:si + 8], edx
jmp set_protected_mode
.save_null:
mov si, 0x1280
mov ds, si
mov si, 0
mov dword [ds:si], 0xFFFFFFFF
mov dword [ds:si + 4], 0xFFFFFFFF
mov dword [ds:si + 8], 0xFFFFFFFF
set_protected_mode:
I have also tried to find the SATA controller using PCI. This code is based on BareMetal OS.
Code: Select all
ahci_find_ctrller:
.setup:
mov dword [pci_bus], 0
mov dword [pci_dev], 0
mov dword [pci_fun], 0
mov dword [pci_offset], 8
.probe_next_fun:
call pci_set_config_address
call pci_read_dword
mov eax, dword [pci_data] ; dword [pci_data] contains the pci register value
shr eax, 16
cmp ax, 0x0106
je .return
inc dword [pci_fun]
cmp dword [pci_fun], 8
jb .probe_next_fun
.probe_next_dev:
mov dword [pci_fun], 0
inc dword [pci_dev]
cmp dword [pci_dev], 32
jb .probe_next_fun
.probe_next_bus:
mov dword [pci_dev], 0
inc dword [pci_bus]
cmp dword [pci_bus], 256
jb .probe_next_fun
.return_invalid:
mov dword [ahci_bus], 0xFFFFFFFF
mov dword [ahci_dev], 0xFFFFFFFF
mov dword [ahci_fun], 0xFFFFFFFF
ret
.return:
mov eax, dword [pci_bus]
mov dword [ahci_bus], eax
mov eax, dword [pci_dev]
mov dword [ahci_dev], eax
mov eax, dword [pci_fun]
mov dword [ahci_fun], eax
ret
Every time these functions return invalid addresses (0xFFFFFFFF:0xFFFFFFFF:0xFFFFFFFF), which are supposed to be the output for not found controller. I know my computers have a SATA controller (lspci -vvv).
From that I have read, SATA's class code equals 0x01, subclass equals 0x06, and interface equals 0x01 for AHCI. BareMetal OS doesn't even mention the interface, but again, the controller should be found. I don't exclude the error is assembly code specific, though.
Regards,
glauxosdev
Edit: Before you ask, the PCI calls that I didn't post work, as they are usable for reading/writing the EHCI configuration space.
Re: Can't find SATA controller.
Posted: Sun May 24, 2015 12:23 pm
by Brendan
Hi,
glauxosdev wrote:I have tried to find the SATA controller using the BIOS.
Why? These BIOS functions are slower, I wouldn't assume the BIOS implements these functions correctly (even if they exist they should be considered "never tested"), and it's easier to use the IO ports directly instead.
Also, why? Typically an OS enumerates the PCI bus and starts device drivers for whatever it happens to find (and tells the device driver the details for its device when the driver is started), and there's no need to search for a specific type of device.
Cheers,
Brendan
Re: Can't find SATA controller.
Posted: Sun May 24, 2015 12:27 pm
by glauxosdev
Hi,
My OS is still in pre-alpha, I will clean it up later. But for now, I think I have to get it working, and then get it working better.
I wouldn't assume the BIOS implements these functions correctly
They worked for finding the EHCI controller, but I plan to move from them, anyways. So I am focused on the second function.
Regards,
glauxosdev
Re: Can't find SATA controller.
Posted: Sun May 24, 2015 12:42 pm
by Brendan
Hi,
glauxosdev wrote:My OS is still in pre-alpha, I will clean it up later. But for now, I think I have to get it working, and then get it working better.
I'm not sure I agree. Often "working but needs to be redesigned and rewritten" is worse than "not implemented yet"; because it's too easy to postpone the redesign and too easy to build more code on top that increases the amount of work you'd need to do.
On some computers the SATA controller may be pretending to be something else (for backward compatibility), and you'd want to search for "base class 1, sub-class 6 or 5 or 1" so that you find "SATA pretending to be ATA" and "SATA pretending to be IDE".
Cheers,
Brendan
Re: Can't find SATA controller.
Posted: Sun May 24, 2015 12:46 pm
by glauxosdev
Hi,
On some computers the SATA controller may be pretending to be something else (for backward compatibility), and you'd want to search for "base class 1, sub-class 6 or 5 or 1" so that you find "SATA pretending to be ATA" and "SATA pretending to be IDE".
So it is more complicated than I thought. I will try it. Baremetal OS doesn't take into account backwards compatibility, though.
Glad you were here Brendan,
glauxosdev
Re: Can't find SATA controller.
Posted: Sun May 24, 2015 3:00 pm
by glauxosdev
Hi,
How do I recognize a SATA pretending to be an IDE or an ATA from a genuine IDE or ATA? Sorry if this has been answered before.
Regards,
glauxosdev
Re: Can't find SATA controller.
Posted: Sun May 24, 2015 7:32 pm
by Brendan
Hi,
glauxosdev wrote:How do I recognize a SATA pretending to be an IDE or an ATA from a genuine IDE or ATA? Sorry if this has been answered before.
As far as I can tell it's chipset/controller specific. There's nothing useful in the SATA/AHCI specifications themselves.
I looked at a variety of chipset datasheets. Here's the results:
Intel I/O Controller Hub 10 and Intel I/O Controller Hub 7
Its controlled by a register at offset 0x90 in the SATA controller's PCI configuration space that allows the device to be set to one of 3 modes: "IDE mode" (sub-class = 1), "AHCI mode" (sub-class = 6) or "RAID mode" (sub-class = 4). The datasheets also say that the bits that control the controller's mode must not be modified by the OS, and both AHCI mode and RAID mode can't be enabled when an "MV bit" is clear, and that "MV bit" is a read only and reserved.
Note 1: I assumed ICH8 and ICH9 are probably the same and didn't look at those data sheets.
Note 2: While wandering around the Internet I'm sure I stumbled across something saying that Intel recommends just use "RAID mode" because it supports everything that AHCI does but is more flexible (but can't remember where I saw that). Usually, when you buy a new computer with an Intel chipset it comes with a CD containing drivers that includes SATA drivers for Windows, and I suspect this might be needed to get Windows to use Intel's "RAID mode" properly.
Intel I/O Controller Hub 6
Its controlled by a register at offset 0x90 in the SATA controller's PCI configuration space that allows the device to be set to one of 2 modes: "IDE mode" (sub-class = 1), "AHCI mode" (sub-class = 6)". The bits are different than they are in ICH10 - there's only one bit, there's no "MV bit", etc. The SATA controller also has a "RAID mode" (not supported for the mobile version of ICH7) which is enabled by writing to the device's sub-class field (which is a "write once" register). When in "RAID mode" the register at offset 0x90 is ignored and I don't think it's possible to leave "RAID mode".
Intel I/O Controller Hub 5
The SATA controller only has 2 modes ("IDE mode" and "RAID mode"). I don't think it supports AHCI at all. In this case the mode is controlled by a register in the LPC bridge.
VIA VX800 VX820
Sort of like ICH5 where the SATA controller has "IDE mode" and "RAID mode". There's a bit in "Miscellaneous Control 2" at offset 0x45 in the SATA controller's PCI configuration space which allows (if clear) allows the controller's sub-class to be modified.
Note: To be honest, for this chipset I don't know if modifying the sub-class causes the controller to changes mode or if it just lets you put dodgy numbers in there; but I found no other way to change controller mode.
AMD Bolton
There's a "sub-class code write enable" bit in a "Misc. Control" register at offset 0x40 in the SATA controller's PCI configuration space that (when set) allows the device's sub-class and programming interface fields to be changed. Valid values for sub-class are 1 (IDE), 6 (AHCI) and 4 (RAID).
Note: To be honest, for this chipset I don't know if modifying the sub-class causes the controller to change modes or if it just lets you put dodgy numbers in there; but I found no other way to change controller mode.
Summary
In addition to being chipset/device specific it's possible that there's also other "less than obvious" subtleties (e.g. maybe the firmware's SMM code makes assumptions based on the mode the user configured in the BIOS configuration screen). I'd recommend just leaving it how you found it and not attempting to change the controller's mode (unless you've got specific drivers for specific controllers that rely on the "vendor ID" and "device ID" fields); which means implementing drivers for both AHCI and IDE (and trying to figure out exactly what "RAID mode" actually is in each of the possibly different cases).
Cheers,
Brendan
Re: Can't find SATA controller.
Posted: Mon May 25, 2015 2:54 am
by glauxosdev
Hi,
Now I see how complicated it is.
Maybe it should be included on the wiki?
which means implementing drivers for both AHCI and IDE
Unfortunately I don't have any computers to test my future AHCI driver, so I am probably left with IDE.
Regards,
glauxosdev
Edit: I found an IDE.
Re: Can't find SATA controller.
Posted: Mon May 25, 2015 3:45 am
by iansjack
You might want to try changing the type to AHCI in the BIOS and then see what is detected. I'm not aware of any OS that changes the type set in the BIOS to a different one.
Re: Can't find SATA controller.
Posted: Mon May 25, 2015 3:47 am
by glauxosdev
Hi,
You might want to try changing the type to AHCI in the BIOS and then see what is detected.
I tried, but there was no such option on my computer.
Regards,
glauxosdev
Re: Can't find SATA controller.
Posted: Mon May 25, 2015 4:29 am
by glauxosdev
Hi,
Let's suppose we have a SATA pretending to be an IDE and a genuine IDE. The SATA has connected a hard disk to it and the genuine IDE has connected a CD-ROM to it. How do I detect the SATA instead of the genuine IDE?
I am so confused now, so I don't know where to start from.
Regards,
glauxosdev
Re: Can't find SATA controller.
Posted: Mon May 25, 2015 2:26 pm
by Brendan
Hi,
glauxosdev wrote:Let's suppose we have a SATA pretending to be an IDE and a genuine IDE. The SATA has connected a hard disk to it and the genuine IDE has connected a CD-ROM to it. How do I detect the SATA instead of the genuine IDE?
I think there's only 2 options:
- Don't. Just use IDE for both the IDE controller and the "SATA pretending to be IDE controller", or:
- Have a "motherboard driver" for each different motherboard that knows how to safely change the SATA controller over to "AHCI mode" if that's actually possible (plus an IDE driver for the IDE controller, that can be used for the "SATA pretending to be IDE controller" if it's impossible to change the SATA controller's mode safely - either because there isn't a suitable motherboard driver or because there is a suitable motherboard driver but it knows the SATA controller's mode can't be changed safely).
Note that sooner or later you're going to want to support USB disk drives and USB flash (including UHCI, OHCI, xHCI, EHCI controllers), and SCSI disk controllers, and SATA RAID controllers and.... Basically; the ATA/IDE driver and the AHCI driver are just 2 of many drivers. What this really means is that you need to (e.g.) enumerate PCI buses, and try to find/start device drivers for whatever devices the PCI bus scan detected are present.
Cheers,
Brendan
Re: Can't find SATA controller.
Posted: Tue May 26, 2015 2:21 am
by glauxosdev
Hi,
I'll go will IDE, but I asked something different (maybe my question wasn't clear). Basically, how do I detect the IDE (actually SATA, but not relevant now) which has the hard drive instead of the IDE which has the CD-ROM?
Also, I have already implemented EHCI so I can read a USB flash disk. My computer has 2 EHCI controllers, I initialize the first and I route all the ports to it. With IDE this is not possible, is it?
Regards,
glauxosdev
Re: Can't find SATA controller.
Posted: Tue May 26, 2015 2:36 am
by Combuster
IDE controllers are basically plug-and-play bus controllers. Therefore you ask each of them what devices are connected to them. It might just be that both the CD and the harddisk are connected to the same "IDE controller" and the second one is just sitting there doing nothing.
Before you ask: Nope, you're not getting away that easy without proper discovery
Re: Can't find SATA controller.
Posted: Tue May 26, 2015 3:40 am
by Brendan
Hi,
glauxosdev wrote:I'll go will IDE, but I asked something different (maybe my question wasn't clear). Basically, how do I detect the IDE (actually SATA, but not relevant now) which has the hard drive instead of the IDE which has the CD-ROM?
You don't.
You're starting with the assumption that you want to find one specific device. This assumption is backwards and wrong. Instead, start with the assumption that you want to find all devices the OS supports.
Specifically; find all devices on the PCI bus that the OS supports (e.g. IDE controllers, USB controllers, etc) and load drivers for them, then use those drivers to find whatever devices are connected to them (e.g. disk drives, USB flash, USB sound card, etc) and load drivers for them; then use those drivers to find whatever is connected to those devices (e.g. use the USB sound card driver to determine if there's speakers/microphones connected to the USB sound card); and so on until there's nothing left to find.
Basically; hardware is a hierarchical tree, and you do a recursive search that begins with the PCI host and continues far beyond PCI alone. If there's a coffee cup warmer connected to a USB hub that's plugged into a USB port connected to a USB controller connected to a PCI bus that's connected to a PCI bridge that's connected to the PCI host; then your recursive search finds it (you might not have a driver for the coffee cup warmer, but at least you know it's not a USB flash that contains the root file system).
Also note that this recursive search doesn't necessarily need to stop at hardware alone (even though in most OSs it does). For example, a hard disk driver could check for partitions and start/mount file systems, an ethernet driver could start the networking stack (which could start DHCP client, FTP server, whatever); a video card driver might start the GUI. This mostly means that software (file systems, network stack, GUI) is only started if it's needed, and is started as soon as the hardware it uses is ready (unlike most OSs, where things like GUI might not be started until after all device drivers are ready).
glauxosdev wrote:Also, I have already implemented EHCI so I can read a USB flash disk. My computer has 2 EHCI controllers, I initialize the first and I route all the ports to it. With IDE this is not possible, is it?
That's not even possible with EHCI.
For EHCI, each EHCI controller has "companion controllers" that are used for low speed devices. When a lower speed device is plugged into a port that port has to be routed to the companion controller (because EHCI doesn't support low speed devices), and when a high speed device is plugged into a port that port should be routed to the EHCI controller (because OHCI/UHCI doesn't support high speed so it'd be slow if you don't route those devices to EHCI). You can't route a port to a completely different EHCI controller or route a port to a completely different EHCI controller's companion.
Cheers,
Brendan