* PCI+ATA
@ 2008-02-02 18:38 Marco Gerards
2008-02-02 22:25 ` PCI+ATA Robert Millan
2008-02-03 17:42 ` PCI+ATA walt
0 siblings, 2 replies; 5+ messages in thread
From: Marco Gerards @ 2008-02-02 18:38 UTC (permalink / raw)
To: The development of GRUB
[-- Attachment #1: Type: text/plain, Size: 1222 bytes --]
Hi,
Here is a patch for testing purposes. I hope people can test this on
actual hardware. Testing will help a lot for the development of the
ATA driver.
The code to reset the channel was removed, replace with something that
only queries the channel. Code for probing IDE Controllers on the PCI
bus is added. Channels in compatibility mode were supported and are
still supported. Now also more controllers should be used, but I
don't have boxes to test this on and qemu can't be used for this. So
please test.
Please tell me (read this before testing!):
1) Does it work perfectly (yes/no) as in, all devices are detected and
can be accessed. If no: what's the problem.
2) Did it work before applying this patch? (yes/no)
3) "rmmod ata", "insmod biosdisk" can you still access your disks
4) Same as 3, but before applying this patch
5) If there are problems, use:
set debug=ata
insmod ata
Please send me the output (photos are ok for me) and a description +
answers to these question
If the debug messages scroll to fast, use:
set pager=1
The driver is slow, mainly because a low resolution timer is used.
Perhaps we should use PIT channel 2 on i386-pc for the timer.
Thanks a lot for your help!
--
Marco
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: grub2_ata_pci.diff --]
[-- Type: text/x-diff, Size: 8325 bytes --]
? ascii.pff
? bus
? grub-emu
? grub_emu_init.c
? grub_emu_init.h
? unicode.pff
? commands/lspci.c
? include/grub/pci.h
? include/grub/i386/pc/pci.h
Index: disk/ata.c
===================================================================
RCS file: /sources/grub/grub2/disk/ata.c,v
retrieving revision 1.6
diff -u -p -u -p -r1.6 ata.c
--- disk/ata.c 5 Nov 2007 16:15:26 -0000 1.6
+++ disk/ata.c 2 Feb 2008 18:20:27 -0000
@@ -22,6 +22,7 @@
#include <grub/disk.h>
#include <grub/mm.h>
#include <grub/time.h>
+#include <grub/pci.h>
/* XXX: For now this only works on i386. */
#include <grub/cpu/io.h>
@@ -62,7 +63,8 @@ enum grub_ata_commands
GRUB_ATA_CMD_WRITE_SECTORS_EXT = 0x34,
GRUB_ATA_CMD_IDENTIFY_DEVICE = 0xEC,
GRUB_ATA_CMD_IDENTIFY_PACKET_DEVICE = 0xA1,
- GRUB_ATA_CMD_PACKET = 0xA0
+ GRUB_ATA_CMD_PACKET = 0xA0,
+ GRUB_ATA_CMD_EXEC_DEV_DIAGNOSTICS = 0x90
};
struct grub_ata_device
@@ -207,15 +209,13 @@ grub_ata_dumpinfo (struct grub_ata_devic
/* The device information was read, dump it for debugging. */
grub_ata_strncpy (text, info + 20, 20);
- grub_printf ("Serial: %s\n", text);
+ grub_dprintf ("ata", "Serial: %s\n", text);
grub_ata_strncpy (text, info + 46, 8);
- grub_printf ("Firmware: %s\n", text);
+ grub_dprintf ("ata", "Firmware: %s\n", text);
grub_ata_strncpy (text, info + 54, 40);
- grub_printf ("Model: %s\n", text);
-
- grub_printf ("Addressing: %d\n", dev->addr);
- grub_printf ("#sectors: %d\n", dev->size);
+ grub_dprintf ("ata", "Model: %s\n", text);
+ grub_dprintf ("ata", "Addressing: %d #sectors: %d\n", dev->addr, dev->size);
}
static grub_err_t
@@ -330,82 +330,163 @@ grub_ata_identify (struct grub_ata_devic
}
static grub_err_t
-grub_ata_initialize (void)
+grub_ata_device_initialize (int port, int device, int addr, int addr2)
{
struct grub_ata_device *dev;
struct grub_ata_device **devp;
- int port;
- int device;
- for (port = 0; port <= 1; port++)
+ grub_dprintf ("ata", "detecting device %d,%d (0x%x, 0x%x)\n",
+ port, device, addr, addr2);
+
+ dev = grub_malloc (sizeof(*dev));
+ if (! dev)
+ return grub_errno;
+
+ /* Setup the device information. */
+ dev->port = port;
+ dev->device = device;
+ dev->ioaddress = grub_ata_ioaddress[dev->port];
+ dev->ioaddress2 = grub_ata_ioaddress2[dev->port];
+ dev->next = NULL;
+
+ /* Try to detect if the port is in use by writing to it,
+ waiting for a while and reading it again. If the value
+ was preserved, there is a device connected. */
+ grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4);
+ grub_ata_wait ();
+ grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, 0x5A);
+ grub_ata_wait ();
+ if (grub_ata_regget (dev, GRUB_ATA_REG_SECTORS) != 0x5A)
{
- for (device = 0; device <= 1; device++)
- {
- dev = grub_malloc (sizeof(*dev));
- if (! dev)
- return grub_errno;
-
- /* Setup the device information. */
- dev->port = port;
- dev->device = device;
- dev->ioaddress = grub_ata_ioaddress[dev->port];
- dev->ioaddress2 = grub_ata_ioaddress2[dev->port];
- dev->next = NULL;
-
- /* Try to detect if the port is in use by writing to it,
- waiting for a while and reading it again. If the value
- was preserved, there is a device connected. */
- grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4);
- grub_ata_wait ();
- grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, 0x5A);
- grub_ata_wait ();
- if (grub_ata_regget (dev, GRUB_ATA_REG_SECTORS) != 0x5A)
- {
- grub_free(dev);
- continue;
- }
+ grub_free(dev);
+ return 0;
+ }
- /* Detect if the device is present by issuing a reset. */
- grub_ata_regset2 (dev, GRUB_ATA_REG2_CONTROL, 6);
- grub_ata_wait ();
- grub_ata_regset2 (dev, GRUB_ATA_REG2_CONTROL, 2);
- grub_ata_wait ();
- grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4);
- grub_ata_wait ();
+ /* Detect if the device is present by issuing a EXECUTE
+ DEVICE DIAGNOSTICS command. */
+ grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4);
+ grub_ata_regset (dev, GRUB_ATA_REG_CMD,
+ GRUB_ATA_CMD_EXEC_DEV_DIAGNOSTICS);
+ grub_ata_wait ();
- /* XXX: Check some registers to see if the reset worked as
- expected for this device. */
-#if 1
- /* Enable for ATAPI . */
- if (grub_ata_regget (dev, GRUB_ATA_REG_CYLLSB) != 0x14
- || grub_ata_regget (dev, GRUB_ATA_REG_CYLMSB) != 0xeb)
-#endif
- if (grub_ata_regget (dev, GRUB_ATA_REG_STATUS) == 0
- || (grub_ata_regget (dev, GRUB_ATA_REG_CYLLSB) != 0
- && grub_ata_regget (dev, GRUB_ATA_REG_CYLMSB) != 0
- && grub_ata_regget (dev, GRUB_ATA_REG_CYLLSB) != 0x3c
- && grub_ata_regget (dev, GRUB_ATA_REG_CYLLSB) != 0xc3))
- {
- grub_free (dev);
- continue;
- }
+ grub_dprintf ("ata", "Registers: %x %x %x %x\n",
+ grub_ata_regget (dev, GRUB_ATA_REG_SECTORS),
+ grub_ata_regget (dev, GRUB_ATA_REG_LBALOW),
+ grub_ata_regget (dev, GRUB_ATA_REG_LBAMID),
+ grub_ata_regget (dev, GRUB_ATA_REG_LBAHIGH));
+
+ /* Check some registers to see if the channel is used. */
+ if (grub_ata_regget (dev, GRUB_ATA_REG_SECTORS) == 0x01
+ && grub_ata_regget (dev, GRUB_ATA_REG_LBALOW) == 0x01
+ && grub_ata_regget (dev, GRUB_ATA_REG_LBAMID) == 0x14
+ && grub_ata_regget (dev, GRUB_ATA_REG_LBAHIGH) == 0xeb)
+ {
+ grub_dprintf ("ata", "ATAPI signature detected\n");
+ }
+ else if (! (grub_ata_regget (dev, GRUB_ATA_REG_SECTORS) == 0x01
+ && grub_ata_regget (dev, GRUB_ATA_REG_LBALOW) == 0x01
+ && grub_ata_regget (dev, GRUB_ATA_REG_LBAMID) == 0x00
+ && grub_ata_regget (dev, GRUB_ATA_REG_LBAHIGH) == 0x00))
+ {
+ grub_dprintf ("ata", "incorrect signature\n");
+ grub_free (dev);
+ return 0;
+ }
+ else
+ {
+ grub_dprintf ("ata", "ATA detected\n");
+ }
+
+
+ /* Use the IDENTIFY DEVICE command to query the device. */
+ if (grub_ata_identify (dev))
+ {
+ grub_free (dev);
+ return 0;
+ }
- /* Use the IDENTIFY DEVICE command to query the device. */
- if (grub_ata_identify (dev))
+ /* Register the device. */
+ for (devp = &grub_ata_devices; *devp; devp = &(*devp)->next);
+ *devp = dev;
+
+ return 0;
+}
+
+static int
+grub_ata_pciinit (int bus, int device, int func, grub_pci_id_t pciid)
+{
+ static int compat_use[2] = { 0 };
+ grub_pci_address_t addr;
+ grub_uint32_t class;
+ grub_uint32_t bar1;
+ grub_uint32_t bar2;
+ int rega;
+ int regb;
+ int i;
+
+ /* Read class. */
+ addr = grub_pci_make_address (bus, device, func, 2);
+ class = grub_pci_read (addr);
+
+ /* Check if this class ID matches that of a PCI IDE Controller. */
+ if (class >> 16 != 0x0101)
+ return 0;
+
+ for (i = 0; i < 2; i++)
+ {
+ /* Set to 0 when the channel operated in compatibility mode. */
+ int compat = (class >> (2 * i)) & 1;
+
+ rega = 0;
+ regb = 0;
+
+ /* If the channel is in compatibility mode, just assign the
+ default registers. */
+ if (compat == 0 && !compat_use[i])
+ {
+ rega = grub_ata_ioaddress[i];
+ regb = grub_ata_ioaddress2[i];
+ compat_use[i] = 0;
+ }
+ else if (compat)
+ {
+ /* Read the BARs, which either contain a mmapped IO address
+ or the IO port address. */
+ addr = grub_pci_make_address (bus, device, func, 4 + 2 * i);
+ bar1 = grub_pci_read (addr);
+ addr = grub_pci_make_address (bus, device, func, 5 + 2 * i);
+ bar2 = grub_pci_read (addr);
+
+ /* Check if the BARs describe an IO region. */
+ if ((bar1 & 1) && (bar2 & 1))
{
- grub_free (dev);
- continue;
+ rega = bar1 & ~3;
+ regb = bar2 & ~3;
}
+ }
- /* Register the device. */
- for (devp = &grub_ata_devices; *devp; devp = &(*devp)->next);
- *devp = dev;
+ grub_dprintf ("ata",
+ "PCI dev (%d,%d,%d) compat=%d rega=0x%x regb=0x%x\n",
+ bus, device, func, compat, rega, regb);
+
+ if (rega && regb)
+ {
+ grub_ata_device_initialize (i, 0, rega, regb);
+ grub_ata_device_initialize (i, 1, rega, regb);
}
}
return 0;
}
+static grub_err_t
+grub_ata_initialize (void)
+{
+ grub_pci_iterate (grub_ata_pciinit);
+ return 0;
+}
+
+
static void
grub_ata_setlba (struct grub_ata_device *dev, grub_disk_addr_t sector,
grub_size_t size)
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: PCI+ATA
2008-02-02 18:38 PCI+ATA Marco Gerards
@ 2008-02-02 22:25 ` Robert Millan
2008-02-03 17:42 ` PCI+ATA walt
1 sibling, 0 replies; 5+ messages in thread
From: Robert Millan @ 2008-02-02 22:25 UTC (permalink / raw)
To: The development of GRUB 2
On Sat, Feb 02, 2008 at 07:38:43PM +0100, Marco Gerards wrote:
> Hi,
>
> Here is a patch for testing purposes. I hope people can test this on
> actual hardware. Testing will help a lot for the development of the
> ATA driver.
>
> The code to reset the channel was removed, replace with something that
> only queries the channel. Code for probing IDE Controllers on the PCI
> bus is added. Channels in compatibility mode were supported and are
> still supported. Now also more controllers should be used, but I
> don't have boxes to test this on and qemu can't be used for this. So
> please test.
You forgot to remove the `grub_disk_firmware_is_tainted' hack. That prevents
biosdisk from working afterwards (but it doesn't affect my test, see below).
> Please tell me (read this before testing!):
>
> 1) Does it work perfectly (yes/no) as in, all devices are detected and
> can be accessed. If no: what's the problem.
Hangs during init. Messages printed:
disk/ata.c:470: PCI dev (0,6,0) compat=0 rega=0x1f0 regb=0x3f6
disk/ata.c:339: detecting device 0,0 (0x1f0, 0x3f6)
disk/ata.c:376: Registers: 1 1 0 0
disk/ata.c:397: ATA detected
disk/ata.c:212: Serial: 5JXEZS01
disk/ata.c:214: Firmware: 8.01
disk/ata.c:216: Model: ST340014A
disk/ata.c:218: Addressing: 2 #sectors: 78165360
disk/ata.c:339: detecting device 0,1 (0x1f0, 0x3f6)
disk/ata.c:376: Registers: 1 1 0 0
disk/ata.c:397: ATA detected
ctrl-alt-del stops working (scrambled IDT ?)
> 2) Did it work before applying this patch? (yes/no)
It detected my CD drive (ata3), but was unable to access it. The following
command:
ls (ata3)/
just hangs, producing no debugging output, and makes ctrl-alt-del stop
working as well. It _did_ archieve to make the drive spin, though.
> 3) "rmmod ata", "insmod biosdisk" can you still access your disks
N/A
> 4) Same as 3, but before applying this patch
Note: insmodding biosdisk is likely impossible when you can't access the
disks ;-)
When disabling `grub_disk_firmware_is_tainted', and loading both (preloaded
in core.img), I can still access the hard disk via (hd0) (however, note the
hard disk wasn't detected by ata.mod, only the CD).
> 5) If there are problems, use:
> set debug=ata
> insmod ata
In case this helps:
grub> lspci
00:00.0 005e:10de.0 Memory Controller
00:01.0 0050:10de.0 ISA Bridge
00:01.1 0052:10de.1 Serial Bus Controller
00:02.0 005a:10de.0 Serial Bus Controller
00:02.1 005b:10de.1 Serial Bus Controller
00:04.0 0059:10de.0 Multimedia Audio Device
00:06.0 0053:10de.0 IDE Controller
00:07.0 0054:10de.0 IDE Controller
00:08.0 0055:10de.0 IDE Controller
00:09.0 005c:10de.0 PCI-PCI Bridge
00:0a.0 0057:10de.0 Unknown Bridge
00:0b.0 005d:10de.0 PCI-PCI Bridge
00:0c.0 005d:10de.0 PCI-PCI Bridge
00:0d.0 005d:10de.0 PCI-PCI Bridge
00:0e.0 005d:10de.0 PCI-PCI Bridge
00:18.0 1100:1022.0 Host Bridge
00:18.1 1101:1022.1 Host Bridge
00:18.2 1102:1022.2 Host Bridge
00:00.0 94c3:1002.0 VGA Controller
00:00.1 aa10:1002.1 Multimedia device
00:07.0 0002:1102.0 Multimedia Audio Device
00:07.1 7002:1102.1 Unknown Input Device
$ sudo lspci
00:00.0 Memory controller: nVidia Corporation CK804 Memory Controller (rev a3)
00:01.0 ISA bridge: nVidia Corporation CK804 ISA Bridge (rev a3)
00:01.1 SMBus: nVidia Corporation CK804 SMBus (rev a2)
00:02.0 USB Controller: nVidia Corporation CK804 USB Controller (rev a2)
00:02.1 USB Controller: nVidia Corporation CK804 USB Controller (rev a3)
00:04.0 Multimedia audio controller: nVidia Corporation CK804 AC'97 Audio Controller (rev a2)
00:06.0 IDE interface: nVidia Corporation CK804 IDE (rev f2)
00:07.0 IDE interface: nVidia Corporation CK804 Serial ATA Controller (rev f3)
00:08.0 IDE interface: nVidia Corporation CK804 Serial ATA Controller (rev f3)
00:09.0 PCI bridge: nVidia Corporation CK804 PCI Bridge (rev a2)
00:0a.0 Bridge: nVidia Corporation CK804 Ethernet Controller (rev a3)
00:0b.0 PCI bridge: nVidia Corporation CK804 PCIE Bridge (rev a3)
00:0c.0 PCI bridge: nVidia Corporation CK804 PCIE Bridge (rev a3)
00:0d.0 PCI bridge: nVidia Corporation CK804 PCIE Bridge (rev a3)
00:0e.0 PCI bridge: nVidia Corporation CK804 PCIE Bridge (rev a3)
00:18.0 Host bridge: Advanced Micro Devices [AMD] K8 [Athlon64/Opteron] HyperTransport Technology Configuration
00:18.1 Host bridge: Advanced Micro Devices [AMD] K8 [Athlon64/Opteron] Address Map
00:18.2 Host bridge: Advanced Micro Devices [AMD] K8 [Athlon64/Opteron] DRAM Controller
00:18.3 Host bridge: Advanced Micro Devices [AMD] K8 [Athlon64/Opteron] Miscellaneous Control
01:00.0 VGA compatible controller: ATI Technologies Inc Unknown device 94c3
01:00.1 Audio device: ATI Technologies Inc Unknown device aa10
05:07.0 Multimedia audio controller: Creative Labs SB Live! EMU10k1 (rev 04)
05:07.1 Input device controller: Creative Labs SB Live! Game Port (rev 01)
--
Robert Millan
<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call… if you are unable to speak?
(as seen on /.)
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: PCI+ATA
2008-02-02 18:38 PCI+ATA Marco Gerards
2008-02-02 22:25 ` PCI+ATA Robert Millan
@ 2008-02-03 17:42 ` walt
2008-02-03 18:42 ` PCI+ATA walt
1 sibling, 1 reply; 5+ messages in thread
From: walt @ 2008-02-03 17:42 UTC (permalink / raw)
To: grub-devel
Marco Gerards wrote:
> Hi,
>
> Here is a patch for testing purposes. I hope people can test this on
> actual hardware. Testing will help a lot for the development of the
> ATA driver.
> ...
> Please tell me (read this before testing!):
>
> 1) Does it work perfectly (yes/no) as in, all devices are detected and
> can be accessed. If no: what's the problem.
'insmod ata' prints out nothing. Then 'ls' also prints out nothing.
ata.c:470: PCI dev (0,17,1) compat=0 rega=1f0 regb=3f6
ata.c:339: detecting device 0,0 (1f0, 3f6)
ata.c:376: Registers: d0 d0 d0 d0
ata.c:391: incorrect signature
<the same result for device 0,1>
ata.c:470: PCI dev (0,17,1) compat=1 rega=0 regb=0
and that was all.
> 2) Did it work before applying this patch? (yes/no)
'ls' lists the first disk correctly, but the second disk is
just "(ata2)" and nothing else.
I'll also try the patch on my other machine, which has a promise sata
controller.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: PCI+ATA
2008-02-03 17:42 ` PCI+ATA walt
@ 2008-02-03 18:42 ` walt
0 siblings, 0 replies; 5+ messages in thread
From: walt @ 2008-02-03 18:42 UTC (permalink / raw)
To: grub-devel
On Sun, 2008-02-03 at 09:42 -0800, walt wrote:
> Marco Gerards wrote:
> > Hi,
> >
> > Here is a patch for testing purposes. I hope people can test this on
> > actual hardware. Testing will help a lot for the development of the
> > ATA driver.
> > ...
> > Please tell me (read this before testing!):
> >
> > 1) Does it work perfectly (yes/no) as in, all devices are detected and
> > can be accessed. If no: what's the problem.
> ...
> I'll also try the patch on my other machine, which has a promise sata
> controller.
This is the machine with the sata controller and sata disk:
ata.c:470: PCI dev (0,17,1) compat=0 rega=1f0 regb=3f6
ata.c:339: detecting device 0,0 (1f0, 3f6)
ata.c:376: Registers: 1 1 00
ata.c:397: ATA detected
<prints out model, firmware, sectors correctly for the pata drive>
ata.c:339: detecting device 0,1 (1f0, 3f6)
ata.c:376: Registers: 1 1 00
ata.c:397: ATA detected <==== I'm guessing this is the sata drive.
<hangs forever>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: PCI+ATA
2008-05-06 19:57 ` Marco Vega Trucillo
@ 2008-05-06 20:38 ` Marco Vega Trucillo
0 siblings, 0 replies; 5+ messages in thread
From: Marco Vega Trucillo @ 2008-05-06 20:38 UTC (permalink / raw)
To: The development of GRUB 2
I've realised a similar patch there are some difference:
Marco Gerards check if this class and subclass ID matches that of a PCI
IDE Controller.
I instead check only class so I recognize even my sata disk that have the
same class of PCI IDE Controller but different subclass (for example 0x04
and 0x00).
Marco Gerards try to indentify devices only on address of 0x10 and 0x14
registers (BAR0 and BAR1)... I scan even 0x18 and 0x1c registers (BAR2 and
BAR3).
The remaining code is very similar.
I read that someone had problems of hangs: neither I nor Gerars changed
the access code to the device but only recognition. For now about my two
hardware I did not have hangs (on both I have 3 drive, two in fake-raid and
one single, and I recognize and access all of three).
forgive me again for my bad english.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2008-05-06 20:35 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-02-02 18:38 PCI+ATA Marco Gerards
2008-02-02 22:25 ` PCI+ATA Robert Millan
2008-02-03 17:42 ` PCI+ATA walt
2008-02-03 18:42 ` PCI+ATA walt
-- strict thread matches above, loose matches on Subject: below --
2008-05-03 17:35 ata.c and sata disks Marco Vega Trucillo
2008-05-03 22:59 ` Pavel Roskin
2008-05-06 15:05 ` Robert Millan
2008-05-06 19:57 ` Marco Vega Trucillo
2008-05-06 20:38 ` PCI+ATA Marco Vega Trucillo
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.