jtag/drivers/bcm2835gpio: don't touch pad setting on /dev/gpiomem 84/7684/2
authorTomas Vanek <vanekt@fbl.cz>
Tue, 15 Nov 2022 08:47:43 +0000 (09:47 +0100)
committerTomas Vanek <vanekt@fbl.cz>
Wed, 24 May 2023 05:25:28 +0000 (05:25 +0000)
The pads were configured at a wrong memory address
if /dev/gpiomem was mapped.

The pad setting registers are not accessible in mapped /dev/gpiomem,
disable the pads setting if the driver doesn't open /dev/mem.

While on it, do not fail the driver initialization if pad mapping fails
- just emit a warning and work with unchanged pad setting.

Signed-off-by: Tomas Vanek <vanekt@fbl.cz>
Change-Id: I0bce76cade8f7efd75efd9087a7d9ba6511a6239
Reviewed-on: https://review.openocd.org/c/openocd/+/7684
Tested-by: jenkins
Reviewed-by: Jonathan Bell <jonathan@raspberrypi.com>
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
doc/openocd.texi
src/jtag/drivers/bcm2835gpio.c

index f32ef347565ae1e2e92669d4602ad26930f2a83f..f27e17ceac1ea25be20a738d5774f4c2f42219f2 100644 (file)
@@ -3292,8 +3292,12 @@ configuration on exit.
 GPIO numbers >= 32 can't be used for performance reasons. GPIO configuration is
 handled by the generic command @ref{adapter gpio, @command{adapter gpio}}.
 
+/dev/gpiomem is preferred for GPIO mapping with fallback to /dev/mem.
+If /dev/mem is used GPIO 0-27 pads are set to the limited
+slew rate and drive strength is reduced to 4 mA (2 mA on RPi 4).
+
 See @file{interface/raspberrypi-native.cfg} for a sample config and
-pinout.
+@file{interface/raspberrypi-gpio-connector.cfg} for pinout.
 
 @deffn {Config Command} {bcm2835gpio speed_coeffs} @var{speed_coeff} @var{speed_offset}
 Set SPEED_COEFF and SPEED_OFFSET for delay calculations. If unspecified,
index 879ca3c84e709e0204225c18157d9fdb7b382db1..16c76cdb83e549b9feef7ed4a25afe8ff13e924a 100644 (file)
@@ -409,10 +409,13 @@ static int bcm2835gpio_init(void)
                return ERROR_JTAG_INIT_FAILED;
        }
 
+       bool pad_mapping_possible = false;
+
        dev_mem_fd = open("/dev/gpiomem", O_RDWR | O_SYNC);
        if (dev_mem_fd < 0) {
                LOG_DEBUG("Cannot open /dev/gpiomem, fallback to /dev/mem");
                dev_mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
+               pad_mapping_possible = true;
        }
        if (dev_mem_fd < 0) {
                LOG_ERROR("open: %s", strerror(errno));
@@ -428,21 +431,28 @@ static int bcm2835gpio_init(void)
                return ERROR_JTAG_INIT_FAILED;
        }
 
-       pads_base = mmap(NULL, sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE,
+       /* TODO: move pads config to a separate utility */
+       if (pad_mapping_possible) {
+               pads_base = mmap(NULL, sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE,
                                MAP_SHARED, dev_mem_fd, BCM2835_PADS_GPIO_0_27);
 
-       if (pads_base == MAP_FAILED) {
-               LOG_ERROR("mmap: %s", strerror(errno));
-               bcm2835gpio_munmap();
-               close(dev_mem_fd);
-               return ERROR_JTAG_INIT_FAILED;
+               if (pads_base == MAP_FAILED) {
+                       LOG_ERROR("mmap pads: %s", strerror(errno));
+                       LOG_WARNING("Continuing with unchanged GPIO pad settings (drive strength and slew rate)");
+               }
+       } else {
+               pads_base = MAP_FAILED;
        }
 
        close(dev_mem_fd);
 
-       /* set 4mA drive strength, slew rate limited, hysteresis on */
-       initial_drive_strength_etc = pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] & 0x1f;
-       pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] = 0x5a000008 + 1;
+       if (pads_base != MAP_FAILED) {
+               /* set 4mA drive strength, slew rate limited, hysteresis on */
+               initial_drive_strength_etc = pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] & 0x1f;
+LOG_INFO("initial pads conf %08x", pads_base[BCM2835_PADS_GPIO_0_27_OFFSET]);
+               pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] = 0x5a000008 + 1;
+LOG_INFO("pads conf set to %08x", pads_base[BCM2835_PADS_GPIO_0_27_OFFSET]);
+       }
 
        /* Configure JTAG/SWD signals. Default directions and initial states are handled
         * by adapter.c and "adapter gpio" command.
@@ -513,8 +523,10 @@ static int bcm2835gpio_quit(void)
        restore_gpio(ADAPTER_GPIO_IDX_SRST);
        restore_gpio(ADAPTER_GPIO_IDX_LED);
 
-       /* Restore drive strength. MSB is password ("5A") */
-       pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] = 0x5A000000 | initial_drive_strength_etc;
+       if (pads_base != MAP_FAILED) {
+               /* Restore drive strength. MSB is password ("5A") */
+               pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] = 0x5A000000 | initial_drive_strength_etc;
+       }
        bcm2835gpio_munmap();
 
        return ERROR_OK;

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)