Configuring pinmux in am335x (beaglebone) can't be done from user mode
Hi all, I've been experimenting with seL4 running on a Ninjablocks (https://www.engadget.com/2013/05/01/ninja-blocks/) that I had lying around. Inside there is a beaglebone, with a custom shield (or cape) containing a microcontroller (atmega328p), some LEDs and a radio. The beaglebone (which normally runs linux) sends json-encoded commands over a serial connection to the on-cape microcontroller, which runs firmware that decodes these commands and controls the LEDs and radio. The complication is that the am335x pins connected to the custom shield are multiplexed, and don't connect to a uart device by default (they are gpio pins by default). The "Control Module" in the am335x can be used to configure pin multiplexing, but it can't be written to in user-mode. From the am335x manual (http://www.ti.com/lit/ug/spruh73q/spruh73q.pdf, page 1449): "Note: For writingto the controlmoduleregisters,the MPUwill need to be in privileged modeof operationand writes will not work fromusermode." To test that the rest of my app works I added the control module to the beaglebone device tree overlay and hacked the kernel to configure the relevant pins to connect to the uart device during boot: https://github.com/stevebob/seL4/commit/4295035ac7fd720fb531b7e0893f1f1191ec... And now I have a little rootserver that can control the colours of LEDs on the shield: https://github.com/stevebob/sel4ninja/blob/master/apps/hello-ninja/src/main.... What would be the right way of configuring the control module in a seL4-based system, given that it has to happen in kernel mode? To configure the uart pins when running linux on the board, I had to add the following to the device tree: scm@0 { ... pinmux@800 { ... pinmux_uart0_pins { // <-- this was already here pinctrl-single,pins = <0x170 0x30 0x174 0x00>; phandle = <0x20>; }; pinmux_uart1_pins { // <-- I had to add this pinctrl-single,pins = <0x180 0x30 0x184 0x00>; phandle = <0x60>; }; The (seL4) kernel build system already has basic support for interpreting device trees. Would a reasonable solution to my problem be extending this support with a minimal statically-generated control module driver that configures pinmux during boot based on the device tree? There would still be a problem where each board could only have a single pinmux config (as specified by that board's device tree). It seems like an easy fix for this would be a config variable passed to the build system (similar to -DPLATFORM) that overrides the default device tree file. That way projects that want non-standard pinmux configs could bring their own device trees. Cheers, Steve
Hi Steve, When we have encountered this in the past we typically do one of the following: - Get an earlier stage boot loader to set up the device. Either uboot, or modifying the ELFLoader to set up a static pinmux configuration during initialization that seL4 and userlevel doesn't need to modify. In these scenarios UBoot or the ELFloader already have mechanisms for parsing a device tree and doing platform specific initialization. - Add the initialization to a kernel platform init function. In some cases where a kernel driver such as a timer needs to depend on some additional configuration then this is added to the device's platform initialization functions. The am335x platform already has some of this in am335x-timer.c and plat/am335x/machine/hardware.c. This approach is usually used when there is a reasonably unambiguous configuration requirement that the kernel has such as disabling a reset watchdog timer. - Pick a different platform that doesn't use additional physical memory protection on hardware registers that limits access from unprivileged processor modes. This additional limitation that some platforms have is a bit outside of seL4's assumptions of what mechanisms in the ISA's system architecture are available for it to use. This is similar to how seL4 can't support platforms that don't have a memory management unit. In your case, adding an initialization model to the kernel or to the elfloader would be an option. It would likely be better to target the ELFloader as it's where we try and put most platform initialization that the kernel doesn't have to be aware of. Cheers, Kent.
participants (2)
-
Mcleod, Kent (Data61, Kensington NSW)
-
Stephen Sherratt