gem5-users@gem5.org

The gem5 Users mailing list

View all threads

Enabling bus mastering/BMDMA

KJ
Klein Joshua Alexander Harrison
Wed, Nov 13, 2019 1:09 PM

Greetings,

I am building a custom full system configuration (largely influenced by ARM in configs/FSConfig.py) and am running into an issue where the kernel hangs on boot, being unable to access the disk image to mount the root filesystem.  Looking at the kernel boot logs and gem5 call trace, I strongly suspect the culprit has to do with this:

[    0.000005] ata_piix 0000:00:01.0: BMDMA: BAR4 is zero, falling back to PIO

In other words, while a standard ARM FS mode simulation will enable bus mastering on the simulated gem5 (PIIX) IDE controller and use DMA to access the disk, my simulation reverts to PIO instead.  The PCI node of my device tree is the one from ARM’s vexpress (aarch64) dtb. My PCI host/IDE controller setup is also similar to ARM’s setup:

self.cf0 = CowIdeDisk(driveID='master')

self.cf0.childImage(mdesc.disk())

self.pci_host = GenericPciHost(conf_base=0x30000000, conf_size=’256MB’, conf_device_bits=12, pci_pio_base=0x2f000000)

self.pci_ide = IdeController(disks=[self.cf0], pci_dev=1, pci_bus=0)

pci_devices.append(self.pci_ide)

self.pci_host.pio = self.iobus.master

for dev_id, dev in enumerate(pci_devices):

    dev.host = self.pci_host

    dev.pio = self.iobus.master

    dev.dma = self.iobus.slave

The gem5 call trace includes the following (no methods from CowDiskImage are called):

IdeController::Channel::accessCommand: offset = 6, size = 1, read = 0

IdeDisk::updateState: action = 4.

IdeDisk::writeCommand: Write to disk at offset: 0x6 data 0xa0

IdeController::dispatchAccess: Write from offset: 0x2f000016 size: 0x1 data: 0xa0

IdeDisk::readControl: Read to disk at offset: 0x2 data 0x40

IdeController::dispatchAccess: Read from offset: 0x2f000022 size: 0x1 data: 0x40

IdeDisk::writeControl: Write to disk at offset: 0x2 data 0xa

IdeController::dispatchAccess: Write from offset: 0x2f000022 size: 0x1 data: 0xa

I have already verified that my kernel includes drivers for the PIIX, legacy ATA controllers, and BMDMA.  I have also attempted to change the BAR4 value of the IDE controller directly in the system configuration file and update the device tree with a dma-ranges field for the PCI node.  None of these solutions worked.

TL;DR: How do I ensure that my full system configuration supports and enables bus mastering/BMDMA for the IDE controller?  Is there anything special I need to add to the device tree binary?

Best regards,

Joshua Klein

Greetings, I am building a custom full system configuration (largely influenced by ARM in configs/FSConfig.py) and am running into an issue where the kernel hangs on boot, being unable to access the disk image to mount the root filesystem. Looking at the kernel boot logs and gem5 call trace, I strongly suspect the culprit has to do with this: [ 0.000005] ata_piix 0000:00:01.0: BMDMA: BAR4 is zero, falling back to PIO In other words, while a standard ARM FS mode simulation will enable bus mastering on the simulated gem5 (PIIX) IDE controller and use DMA to access the disk, my simulation reverts to PIO instead. The PCI node of my device tree is the one from ARM’s vexpress (aarch64) dtb. My PCI host/IDE controller setup is also similar to ARM’s setup: self.cf0 = CowIdeDisk(driveID='master') self.cf0.childImage(mdesc.disk()) self.pci_host = GenericPciHost(conf_base=0x30000000, conf_size=’256MB’, conf_device_bits=12, pci_pio_base=0x2f000000) self.pci_ide = IdeController(disks=[self.cf0], pci_dev=1, pci_bus=0) pci_devices.append(self.pci_ide) … self.pci_host.pio = self.iobus.master for dev_id, dev in enumerate(pci_devices): dev.host = self.pci_host dev.pio = self.iobus.master dev.dma = self.iobus.slave The gem5 call trace includes the following (no methods from CowDiskImage are called): IdeController::Channel::accessCommand: offset = 6, size = 1, read = 0 IdeDisk::updateState: action = 4. IdeDisk::writeCommand: Write to disk at offset: 0x6 data 0xa0 IdeController::dispatchAccess: Write from offset: 0x2f000016 size: 0x1 data: 0xa0 IdeDisk::readControl: Read to disk at offset: 0x2 data 0x40 IdeController::dispatchAccess: Read from offset: 0x2f000022 size: 0x1 data: 0x40 IdeDisk::writeControl: Write to disk at offset: 0x2 data 0xa IdeController::dispatchAccess: Write from offset: 0x2f000022 size: 0x1 data: 0xa I have already verified that my kernel includes drivers for the PIIX, legacy ATA controllers, and BMDMA. I have also attempted to change the BAR4 value of the IDE controller directly in the system configuration file and update the device tree with a dma-ranges field for the PCI node. None of these solutions worked. TL;DR: How do I ensure that my full system configuration supports and enables bus mastering/BMDMA for the IDE controller? Is there anything special I need to add to the device tree binary? Best regards, Joshua Klein
KJ
Klein Joshua Alexander Harrison
Wed, Nov 20, 2019 10:29 AM

Greetings all,

I wanted to post a follow-up and ask another question in case anyone has any insight.  So I learned that the third bit of the Command field in the PCI config can be set to explicitly say bus mastering is available.  The layout and meaning of the Command register can be found here: https://wiki.osdev.org/PCI

Even though I can set the Command value now, the same aforementioned error is present.  Linux assigns BAR4 to zero, and therefore BMDMA is still not utilized.

If I keep the default BARX values of the IdeController (BARX=0x1), the kernel will report during boot:

[    0.000002] pci 0000:00:02.0: [8086:7111] type 00 class 0x010185
[    0.000002] pci 0000:00:02.0: reg 0x10: [io  0x0000-0x0007]
[    0.000002] pci 0000:00:02.0: reg 0x14: [io  0x0000-0x0003]
[    0.000002] pci 0000:00:02.0: reg 0x18: [io  0x0000-0x0007]
[    0.000002] pci 0000:00:02.0: reg 0x1c: [io  0x0000-0x0003]
[    0.000002] pci 0000:00:02.0: reg 0x20: [io  0x0000-0x000f]
[    0.000002] pci 0000:00:02.0: reg 0x30: [mem 0x00000000-0x000007ff pref]
[    0.000002] pci 0000:00:01.0: BAR 0: assigned [mem 0x40000000-0x4001ffff]
[    0.000002] pci 0000:00:01.0: BAR 6: assigned [mem 0x40020000-0x400207ff pref]
[    0.000002] pci 0000:00:02.0: BAR 6: assigned [mem 0x40020800-0x40020fff pref]
[    0.000002] pci 0000:00:02.0: BAR 4: assigned [io  0x0000-0x000f]
[    0.000002] pci 0000:00:02.0: BAR 0: assigned [io  0x0010-0x0017]
[    0.000002] pci 0000:00:02.0: BAR 2: assigned [io  0x0018-0x001f]
[    0.000002] pci 0000:00:02.0: BAR 1: assigned [io  0x0020-0x0023]
[    0.000002] pci 0000:00:02.0: BAR 3: assigned [io  0x0024-0x0027]

However, if I set the following in the IdeController (all values +1 to preserve IO assignment):

    BAR0=0x1011
    BAR1=0x1021
    BAR2=0x1019
    BAR3=0x1025
    BAR4=0x1001

The kernel will report this during boot:

[    0.000002] pci 0000:00:02.0: [8086:7111] type 00 class 0x010185
[    0.000002] pci 0000:00:02.0: reg 0x10: [io  0x1010-0x1017]
[    0.000002] pci 0000:00:02.0: reg 0x14: [io  0x1020-0x1023]
[    0.000002] pci 0000:00:02.0: reg 0x18: [io  0x1018-0x101f]
[    0.000002] pci 0000:00:02.0: reg 0x1c: [io  0x1024-0x1027]
[    0.000002] pci 0000:00:02.0: reg 0x20: [io  0x1000-0x100f]
[    0.000002] pci 0000:00:02.0: reg 0x30: [mem 0x00000000-0x000007ff pref]
[    0.000003] pci 0000:00:01.0: BAR 0: assigned [mem 0x40000000-0x4001ffff]
[    0.000003] pci 0000:00:01.0: BAR 6: assigned [mem 0x40020000-0x400207ff pref]
[    0.000003] pci 0000:00:02.0: BAR 6: assigned [mem 0x40020800-0x40020fff pref]
[    0.000003] pci 0000:00:02.0: BAR 4: assigned [io  0x0000-0x000f]
[    0.000003] pci 0000:00:02.0: BAR 0: assigned [io  0x0010-0x0017]
[    0.000003] pci 0000:00:02.0: BAR 2: assigned [io  0x0018-0x001f]
[    0.000003] pci 0000:00:02.0: BAR 1: assigned [io  0x0020-0x0023]
[    0.000003] pci 0000:00:02.0: BAR 3: assigned [io  0x0024-0x0027]

You can see that even though the registers of the PCI configuration are read to have changed, the Linux BAR assignment remains unchanged.  So now my question is, how can I convince Linux to change the BAR assignment?

Best regards,
Joshua Klein


From: gem5-users <gem5-users-bounces(a)gem5.org> on behalf of Klein Joshua Alexander Harrison <joshua.klein(a)epfl.ch>
Sent: Wednesday, November 13, 2019 2:09:18 PM
To: gem5-users(a)gem5.org
Subject: [gem5-users] Enabling bus mastering/BMDMA

Greetings,

I am building a custom full system configuration (largely influenced by ARM in configs/FSConfig.py) and am running into an issue where the kernel hangs on boot, being unable to access the disk image to mount the root filesystem.  Looking at the kernel boot logs and gem5 call trace, I strongly suspect the culprit has to do with this:

[    0.000005] ata_piix 0000:00:01.0: BMDMA: BAR4 is zero, falling back to PIO

In other words, while a standard ARM FS mode simulation will enable bus mastering on the simulated gem5 (PIIX) IDE controller and use DMA to access the disk, my simulation reverts to PIO instead.  The PCI node of my device tree is the one from ARM’s vexpress (aarch64) dtb. My PCI host/IDE controller setup is also similar to ARM’s setup:

self.cf0 = CowIdeDisk(driveID='master')

self.cf0.childImage(mdesc.disk())

self.pci_host = GenericPciHost(conf_base=0x30000000, conf_size=’256MB’, conf_device_bits=12, pci_pio_base=0x2f000000)

self.pci_ide = IdeController(disks=[self.cf0], pci_dev=1, pci_bus=0)

pci_devices.append(self.pci_ide)

self.pci_host.pio = self.iobus.master

for dev_id, dev in enumerate(pci_devices):

    dev.host = self.pci_host

    dev.pio = self.iobus.master

    dev.dma = self.iobus.slave

The gem5 call trace includes the following (no methods from CowDiskImage are called):

IdeController::Channel::accessCommand: offset = 6, size = 1, read = 0

IdeDisk::updateState: action = 4.

IdeDisk::writeCommand: Write to disk at offset: 0x6 data 0xa0

IdeController::dispatchAccess: Write from offset: 0x2f000016 size: 0x1 data: 0xa0

IdeDisk::readControl: Read to disk at offset: 0x2 data 0x40

IdeController::dispatchAccess: Read from offset: 0x2f000022 size: 0x1 data: 0x40

IdeDisk::writeControl: Write to disk at offset: 0x2 data 0xa

IdeController::dispatchAccess: Write from offset: 0x2f000022 size: 0x1 data: 0xa

I have already verified that my kernel includes drivers for the PIIX, legacy ATA controllers, and BMDMA.  I have also attempted to change the BAR4 value of the IDE controller directly in the system configuration file and update the device tree with a dma-ranges field for the PCI node.  None of these solutions worked.

TL;DR: How do I ensure that my full system configuration supports and enables bus mastering/BMDMA for the IDE controller?  Is there anything special I need to add to the device tree binary?

Best regards,

Joshua Klein

Greetings all, I wanted to post a follow-up and ask another question in case anyone has any insight. So I learned that the third bit of the Command field in the PCI config can be set to explicitly say bus mastering is available. The layout and meaning of the Command register can be found here: https://wiki.osdev.org/PCI Even though I can set the Command value now, the same aforementioned error is present. Linux assigns BAR4 to zero, and therefore BMDMA is still not utilized. If I keep the default BARX values of the IdeController (BARX=0x1), the kernel will report during boot: [ 0.000002] pci 0000:00:02.0: [8086:7111] type 00 class 0x010185 [ 0.000002] pci 0000:00:02.0: reg 0x10: [io 0x0000-0x0007] [ 0.000002] pci 0000:00:02.0: reg 0x14: [io 0x0000-0x0003] [ 0.000002] pci 0000:00:02.0: reg 0x18: [io 0x0000-0x0007] [ 0.000002] pci 0000:00:02.0: reg 0x1c: [io 0x0000-0x0003] [ 0.000002] pci 0000:00:02.0: reg 0x20: [io 0x0000-0x000f] [ 0.000002] pci 0000:00:02.0: reg 0x30: [mem 0x00000000-0x000007ff pref] [ 0.000002] pci 0000:00:01.0: BAR 0: assigned [mem 0x40000000-0x4001ffff] [ 0.000002] pci 0000:00:01.0: BAR 6: assigned [mem 0x40020000-0x400207ff pref] [ 0.000002] pci 0000:00:02.0: BAR 6: assigned [mem 0x40020800-0x40020fff pref] [ 0.000002] pci 0000:00:02.0: BAR 4: assigned [io 0x0000-0x000f] [ 0.000002] pci 0000:00:02.0: BAR 0: assigned [io 0x0010-0x0017] [ 0.000002] pci 0000:00:02.0: BAR 2: assigned [io 0x0018-0x001f] [ 0.000002] pci 0000:00:02.0: BAR 1: assigned [io 0x0020-0x0023] [ 0.000002] pci 0000:00:02.0: BAR 3: assigned [io 0x0024-0x0027] However, if I set the following in the IdeController (all values +1 to preserve IO assignment): BAR0=0x1011 BAR1=0x1021 BAR2=0x1019 BAR3=0x1025 BAR4=0x1001 The kernel will report this during boot: [ 0.000002] pci 0000:00:02.0: [8086:7111] type 00 class 0x010185 [ 0.000002] pci 0000:00:02.0: reg 0x10: [io 0x1010-0x1017] [ 0.000002] pci 0000:00:02.0: reg 0x14: [io 0x1020-0x1023] [ 0.000002] pci 0000:00:02.0: reg 0x18: [io 0x1018-0x101f] [ 0.000002] pci 0000:00:02.0: reg 0x1c: [io 0x1024-0x1027] [ 0.000002] pci 0000:00:02.0: reg 0x20: [io 0x1000-0x100f] [ 0.000002] pci 0000:00:02.0: reg 0x30: [mem 0x00000000-0x000007ff pref] [ 0.000003] pci 0000:00:01.0: BAR 0: assigned [mem 0x40000000-0x4001ffff] [ 0.000003] pci 0000:00:01.0: BAR 6: assigned [mem 0x40020000-0x400207ff pref] [ 0.000003] pci 0000:00:02.0: BAR 6: assigned [mem 0x40020800-0x40020fff pref] [ 0.000003] pci 0000:00:02.0: BAR 4: assigned [io 0x0000-0x000f] [ 0.000003] pci 0000:00:02.0: BAR 0: assigned [io 0x0010-0x0017] [ 0.000003] pci 0000:00:02.0: BAR 2: assigned [io 0x0018-0x001f] [ 0.000003] pci 0000:00:02.0: BAR 1: assigned [io 0x0020-0x0023] [ 0.000003] pci 0000:00:02.0: BAR 3: assigned [io 0x0024-0x0027] You can see that even though the registers of the PCI configuration are read to have changed, the Linux BAR assignment remains unchanged. So now my question is, how can I convince Linux to change the BAR assignment? Best regards, Joshua Klein ________________________________ From: gem5-users <gem5-users-bounces(a)gem5.org> on behalf of Klein Joshua Alexander Harrison <joshua.klein(a)epfl.ch> Sent: Wednesday, November 13, 2019 2:09:18 PM To: gem5-users(a)gem5.org Subject: [gem5-users] Enabling bus mastering/BMDMA Greetings, I am building a custom full system configuration (largely influenced by ARM in configs/FSConfig.py) and am running into an issue where the kernel hangs on boot, being unable to access the disk image to mount the root filesystem. Looking at the kernel boot logs and gem5 call trace, I strongly suspect the culprit has to do with this: [ 0.000005] ata_piix 0000:00:01.0: BMDMA: BAR4 is zero, falling back to PIO In other words, while a standard ARM FS mode simulation will enable bus mastering on the simulated gem5 (PIIX) IDE controller and use DMA to access the disk, my simulation reverts to PIO instead. The PCI node of my device tree is the one from ARM’s vexpress (aarch64) dtb. My PCI host/IDE controller setup is also similar to ARM’s setup: self.cf0 = CowIdeDisk(driveID='master') self.cf0.childImage(mdesc.disk()) self.pci_host = GenericPciHost(conf_base=0x30000000, conf_size=’256MB’, conf_device_bits=12, pci_pio_base=0x2f000000) self.pci_ide = IdeController(disks=[self.cf0], pci_dev=1, pci_bus=0) pci_devices.append(self.pci_ide) … self.pci_host.pio = self.iobus.master for dev_id, dev in enumerate(pci_devices): dev.host = self.pci_host dev.pio = self.iobus.master dev.dma = self.iobus.slave The gem5 call trace includes the following (no methods from CowDiskImage are called): IdeController::Channel::accessCommand: offset = 6, size = 1, read = 0 IdeDisk::updateState: action = 4. IdeDisk::writeCommand: Write to disk at offset: 0x6 data 0xa0 IdeController::dispatchAccess: Write from offset: 0x2f000016 size: 0x1 data: 0xa0 IdeDisk::readControl: Read to disk at offset: 0x2 data 0x40 IdeController::dispatchAccess: Read from offset: 0x2f000022 size: 0x1 data: 0x40 IdeDisk::writeControl: Write to disk at offset: 0x2 data 0xa IdeController::dispatchAccess: Write from offset: 0x2f000022 size: 0x1 data: 0xa I have already verified that my kernel includes drivers for the PIIX, legacy ATA controllers, and BMDMA. I have also attempted to change the BAR4 value of the IDE controller directly in the system configuration file and update the device tree with a dma-ranges field for the PCI node. None of these solutions worked. TL;DR: How do I ensure that my full system configuration supports and enables bus mastering/BMDMA for the IDE controller? Is there anything special I need to add to the device tree binary? Best regards, Joshua Klein