This is an automated email from Gerrit.

"Tomas Vanek <van...@fbl.cz>" just uploaded a new patch set to Gerrit, which 
you can find at https://review.openocd.org/c/openocd/+/7350

-- gerrit

commit 3b4c81c6c3f9f7ab41d1bada998884a49d988c2d
Author: Tomas Vanek <van...@fbl.cz>
Date:   Tue Nov 15 09:47:43 2022 +0100

    jtag/drivers/bcm2835gpio: deprecate /dev/mem access to GPIO control
    
    Deprecate /dev/mem in favour of /dev/gpiomem.
    /dev/gpiomem is available in Raspberry linux kernel since ~2016
    and unlike /dev/mem doesn't require root access. Also it doesn't need
    a peripheral base address.
    
    However the pads configuration (slew rate, drive strength) requires
    /dev/mem access, no way to set the pads with mapped /dev/gpiomem.
    
    Without this change the driver code preferred /dev/gpiomem and if not
    available falled back /dev/mem.
    The pads were configured at a wrong memory address if gpiomem was mapped.
    
    For the limited time until /dev/mem access is completely dropped
    use 'bcm2835gpio peripheral_base' parameter to choose the memory
    access device.
    
    Without peripheral_base (or peripheral_base 0) use /dev/gpiomem
    If a non-zero peripheral_base is configured, use /dev/mem
    and issue a warning.
    
    Disable the pads setting if the driver doesn't open /dev/mem.
    
    While on it extend peripheral_base to uint64_t
    Raspberry Pi 4 with 64-bit kernel and arm_peri_high=1 config.txt
    parameter has peripheral_base 0x47e000000
    
    Signed-off-by: Tomas Vanek <van...@fbl.cz>
    Change-Id: I60e427bda795d7a13d55d61443590dd31d694832

diff --git a/doc/openocd.texi b/doc/openocd.texi
index e9f93614c9..ace4459074 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -3301,10 +3301,17 @@ speed_coeff defaults to 113714, and speed_offset 
defaults to 28.
 @end deffn
 
 @deffn {Config Command} {bcm2835gpio peripheral_base} @var{base}
-Set the peripheral base register address to access GPIOs. For the RPi1, use
-0x20000000. For RPi2 and RPi3, use 0x3F000000. For RPi4, use 0xFE000000. A full
-list can be found in the
+Deprecated.
+The peripheral base is no more necessary if GPIO registers are accessed
+through '/dev/gpiomem'.
+If you insist on '/dev/mem' access and don't mind the security risk,
+configure the peripheral base address and run openocd as root.
+For the RPi1, use 0x20000000. For RPi2 and RPi3, use 0x3F000000.
+For RPi4, use 0xFE000000 or 0x47E000000 if arm_peri_high=1.
+A full list can be found in the
 
@uref{https://www.raspberrypi.org/documentation/hardware/raspberrypi/peripheral_addresses.md,
 official guide}.
+If the peripheral base is configured, GPIO 0-27 pads are set to the limited
+slew rate and drive strength is reduced to 4 mA (2 mA on RPi 4).
 @end deffn
 
 @end deffn
diff --git a/src/jtag/drivers/bcm2835gpio.c b/src/jtag/drivers/bcm2835gpio.c
index 635d9a5ffc..54a54467f7 100644
--- a/src/jtag/drivers/bcm2835gpio.c
+++ b/src/jtag/drivers/bcm2835gpio.c
@@ -19,7 +19,7 @@
 
 #include <sys/mman.h>
 
-uint32_t bcm2835_peri_base = 0x20000000;
+uint64_t bcm2835_peri_base;
 #define BCM2835_GPIO_BASE      (bcm2835_peri_base + 0x200000) /* GPIO 
controller */
 
 #define BCM2835_PADS_GPIO_0_27         (bcm2835_peri_base + 0x100000)
@@ -303,9 +303,9 @@ COMMAND_HANDLER(bcm2835gpio_handle_speed_coeffs)
 COMMAND_HANDLER(bcm2835gpio_handle_peripheral_base)
 {
        if (CMD_ARGC == 1)
-               COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], bcm2835_peri_base);
+               COMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], bcm2835_peri_base);
 
-       command_print(CMD, "BCM2835 GPIO: peripheral_base = 0x%08x",
+       command_print(CMD, "BCM2835 GPIO: peripheral_base = 0x%08" PRIu64,
                                  bcm2835_peri_base);
        return ERROR_OK;
 }
@@ -409,13 +409,19 @@ static int bcm2835gpio_init(void)
                return ERROR_JTAG_INIT_FAILED;
        }
 
-       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");
+       if (bcm2835_peri_base) {
+               LOG_WARNING("Using /dev/mem is DEPRECATED!");
+               LOG_INFO("Remove 'bcm2835gpio peripheral_base' from your config 
to use /dev/gpiomem");
+               LOG_INFO("/dev/gpiomem works without root access rights.");
+
                dev_mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
+       } else {
+               dev_mem_fd = open("/dev/gpiomem", O_RDWR | O_SYNC);
        }
        if (dev_mem_fd < 0) {
                LOG_ERROR("open: %s", strerror(errno));
+               if (!bcm2835_peri_base && errno == ENOENT)
+                       LOG_INFO("If your kernel lacks '/dev/gpiomem' device, 
please update OS.");
                return ERROR_JTAG_INIT_FAILED;
        }
 
@@ -428,21 +434,30 @@ 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 (bcm2835_peri_base) {
+               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: %s", strerror(errno));
+                       bcm2835gpio_munmap();
+                       close(dev_mem_fd);
+                       return ERROR_JTAG_INIT_FAILED;
+               }
+       } 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 +528,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;

-- 

Reply via email to