Physical and DRAM base addresses of the S905X ARM SOC


My intention is to use the Le Potato as a substitute for the Raspberry Pi 2B/3B+. I’ve gone a long way already because I had the following goals in mind:

  • Must be as much as possible “looking” like a Raspberry Pi. Hence, I ran the Libre Computer Raspbian Portability script to bring it as close as possible to the Raspberry Pi

  • I wanted to have the I2C up and running “automatically”. Hence, I added the i2c-ao.dts to the default device tree overlay so that at start up I2C is enabled by default

  • I wanted to have 8 extra I2C busses available because my application needs this. Hence, I created a device tree source file fo the PCA9548 (8-channel I2C switch) called i2c-ao-pca9548.dts and was able to compile, install and also add it to the startup sequence of the Le Potato. And it works brilliant!
    See this link about a small “experience report” I wrote about the PCA9548 switch and how to get it up and running.

Next step is to hopefully use some very interesting and famous libraries, among others the pigpio library, as a HAL (hardware abstraction layer) so that I can use my favourite Java framework for the Raspberry Pi, called Pi4J.

However, the pigpio library is tailored to the Broadcom chipset that is used in the Raspberry Pi. In Le Potato, an AML ARM core is used and because of this, the pigpio library won’t work “out of the box”. Reason? To start with, the address ranges are different between the two SOCs.

And that’s where my question is coming in. In the pigpio code, the creator has two important base addresses:

  • Physical address, which starts at 0x2000_0000 for the Broadcom BCM2835 SOC, 0x3F00_0000 for the BCM2836/37 and 0xFE00_0000 for the BCM2711
  • DRam address which starts at 0x4000_0000 for the BCM2835, 0xC000_0000 for the BCM2836/37 and BCM2711

I do have the datasheet for the am-s905x (that is, I think it’s the correct one…) called S905X Datasheet, revision 0.2 / release date 3/14/2017.
Not sure if that’s the latest but I don’t think there’s much changed since then.

Question: I can’t really find a “counterpart” for the BCM addresses in the S905X datasheet. So, what should I look for? Or better yet: what are the corresponding physical and DRAM base addresses for the S905X and how should I look for them in the datasheet?

PS: Although it’s open source, I still want to ask permission to the owner of the pigpio code if (s)he’s willing to allow me to do this. But then, I still need the replacement base addresses for the S905X.

Any help/input much appreciated!

1 Like

The design of Pi4J is inherently non-portable as it uses native APIs. Also it does some things that are big no-no’s in terms of proper design.

  1. It should never have direct access to memory. This is a huge NO and a massive security vulnerability.
  2. It should use proper kernel GPIO and other APIs. The kernel has the gpio character devices /dev/gpiochipX that are to be controlled through libgpiod. Any proper Java native implementation should go through libgpiod.
  3. For GPIO mapping, you can use the lgpio tool pre-installed on the images to get the chip and line number to use with libgpiod.
  4. For other pinmux functions, we have the ldto tool. However, hardware should not just be toggled on and off because there are implications for the kernel’s internal state machine as well as the device hardware states. Functions should only be enabled or disabled at boot time.

There are many libraries and hacks out there for Raspberry Pi and most are very poorly done. We do not recommend using or porting them. There are guides on this hub about how to enable and use each interface correctly. Stick to them when possible.

1 Like

Ok, I’m busy studying the libgpiod approach a bit now. Can you elaborate on the 2 gpiochip “instances” I see when running gpioinfo?

  • What is gpiochip0 and how are those 11 lines connected to it?
  • What is gpiochip1 and how are those 100 lines connected to it?
  • Why are some pins of header 7J1 allocated to lines in gpiochip0 and (most of) the others to gpiochip1?
  • Why is pin 11 of header 7J1 not part of one of the gpiochipX? It’s the only one I cannot find in the output produced by the command gpioinfo.
  • Who is defining there are two gpiochipX instances and the content of them? Is this Libre Computer? Is this AML? Based on what?

Also, suppose I want to write a JNI interface to “talk” to the libgpiod from a Java application, will I get the speed I currently have with my Raspberry Pi to manipulate/observe/control/… the hardware pins since some libraries (pigpio, to name one) on the Raspberry Pi are using directly physical and DRAM access?

  1. gpiochip0 and gpiochip1 are just how the GPIOs are connected in the hardware. There’s two separate devices that control two different banks.
  2. If you want to learn how the hardware and the software controlling it works, look through the kernel source code regarding pinctrl.
  3. Because that’s how the hardware is laid out in the schematic. GPIOs control a lot more than just the pins. They control most of the onboard devices as well.
  4. See the schematic and GPIO map to understand how GPIO pin 11 works. This is already documented.
  5. This is based on hardware design.

With regards to JNI, never ever allow direct memory access. It breaks every bit of OSI and KASLR security. If you want to physically do a memory map and toggle the registers for pinctrl through Java, then go ahead and do that but we recommend warning your users about the pitfalls we mentioned. You can find the S905X datasheets online and how to set the registers to setup pinctrl. Toggling the GPIOs will be faster but not safe and since you’re not using a soft-RT kernel, kind of pointless.

That’s not what I said and what I want to do. I said I’m thinking to make a JNI file so that I can call the C-functions from the libgpiod from within Java. That’s all.
So, yes, I want to go the libgpiod way because of the reasons you mentioned before.

Going through libgpiod via JNI is the proper way.