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; --