Linux register read arm i.mx257 from userland - devmem not working - c

I'm currently working on a i.mx257 platform and want to read some peripheral registers (the iomux register to be specific) to see how it is configured or if it is set right.
I've read about the devmem from busybox and devmem2, too. Tried both and both get an error. Currently there the custom board is running linux kernel version 4.6.0-rc7 from the meta-fsl-arm yocto meta package. The system is built with yocto.
root#system /]#./tmp/devmem2 0x43fac190
/dev/mem opened.
Unhandled fault: external abort on non-linefetch (0x008) at 0xb6f3a190
pgd = c3334000
[b6f3a190] *pgd=8285e831, *pte=43fac103, *ppte=43facaa2
Memory mapped at address 0xb6f3a000.
Bus error
The tool gets an Signal Err. The CONFIG_STRICT_DEVMEM option is not set in the kernel config.
I found another post http://thread.gmane.org/gmane.linux.ports.arm.kernel/26878 but I can't find some information about these registers for an i-mx25.
Is there another kernel security feature or something I'm missing?
The devmem or devmem2 is only working with values below 0x4000. For all addresses above i get the signal bus error.

Okay,
i found an answer to my own question.
The AIPS control registers have to be added to the devicetree. They are protecting the register i want to read. After i added these patches it worked.
https://github.com/torvalds/linux/commit/24bb244e02a6bead5b854d842002df0d38ae7b7b
https://github.com/torvalds/linux/commit/c33576cbf86bedf9ad3812479c3b4f36d5fadba8#diff-64c444a874c565fd98cf1ab538c1e0cd

Related

PCIe multiple child-devices

I am writing a Linux kernel driver (kernel 4.9) for our custom setup.
We do use a ARM64 based board with a PCIe interface.
Connected to the interface we have an extension board with a FPGA on it.
At this moment I succeed at creating a device that registers my FPGA with some basic functions, like reading the version of the FPGA in a certain register in the FPGA.
In the FPGA we do have some additional "devices" like GPIO, memory regions ... that I would like to add as its own chardevice. We do have existing drivers for these.
Normally, Linux goes over the DTB and calls the correct driver for our FPGA, following the correct drivers for our child devices.
Now I would like to archieve the same with this PCIe interface. To do this, I look for a node in my DTB fpga and add its children.
for_each_available_child_of_node(np, nc) {
subdev = kzalloc(sizeof(*subdev), GFP_KERNEL);
list_add(&subdev->subdev_entry, &priv->subdev_list.subdev_entry);
...
}
list_for_each_entry(subdev, &priv->subdev_list.subdev_entry,
subdev_entry) {
ret = mfd_add_devices(priv->dev, PLATFORM_DEVID_NONE,
subdev->mfd_cell, 1, NULL, irq_base, NULL);
if (ret) {
dev_err(priv->dev, "Failed to add mfd cell\n");
goto err_mfd_add;
}
}
For some reason, the driver is not loaded for its children.
print's in the device drivers probe function shows nothing, not being called.
Added print's to the loops and it shows its children (all properties and values check out with what I set in the DTB).
Yes, the driver is compiled an available in the kernel.
I also tried building the driver as a kmod and load it that way, no change in behaviour. The output of lsmod shows the module is loaded but not used.
Somebody got an idea why my driver is not being loaded?
EDIT:
I also can see the "nodes" from my DTB that should be created as a chardevice.
They can be found in the expected location /sys/class/my_fpga/fpga/device/, in this case GPIO.
Under the GPIO folder I can see the driver_override (which is (null) ), modalias, power, sybsystem and uevent.
So my device (my_fpga) seems to be enumerated, only its children are not created.
A reboot does not solve it, nor a rescan of the PCIe-bus. The extension-board is powered via an external powersupply and is already configured before booting Linux

Cannot write TMC/ETF registers on STM32H753

This question is the follow-up of this one.
I try to configure the ETF in circular mode in order to be able to read the execution trace through the embedded software in case of critical error, on a STM32H753.
I am following the algorithm described in ARM's Trace Memory Controller reference manual (section 2.2.2)
But I cannot write the ETF registers: I unlocked the ETF macrocell by writing the magic number 0xC5ACCE55to register ETF_LAR but when I read thez registers they are all 0 (through debugger or printf) and when I write them they remain at 0.
Any advice on how to write ETF registers ?
There is actually a mistake in the STM32H7 doc:
and few pages later:
My understanding is that the second image is wrong.
Also I had to use the "Component base address (system bus)" and not the "component base address (debugger)". This notion of double address is pretty confusing as for example for ETM there is only one address.
Anyway using 0x5C014000as base address, I can read/write the registers
When accesses are made using the DAP (SWD or JTAG), the debug subsystem should be powered up as part of the handshake with the tools. In a self-hosted debug mode, then device specific control of clocks/power is usually necessary.
For STM32H7, parts:
The ETM is in the same clock/power domain as the core, so it will normally be visible.
CK_DBG_D1 clocks the trace components in the D1 power domain: System
ROM table 2, CoreSight trace funnel, ETF, system CTI and TPIU. It is a
gated version of the D1 domain system clock (CK_HCLK_D1).
Self hosted debug clock and power control uses a dedicated set of registers.
All the debug clocks (except DAPCLK) can be enabled and disabled by
register bits in the DBGMCU.

Handling PCI read/write to configuration space in a QEMU device

I'm working on implementing a simple PCI device in QEMU and a kernel driver for it, and I have some trouble with handling pci_read/write_config_* function calls from the device side.
Unlike simple rw operations on a memory mapped bar, where the MemoryRegionOps callbacks receive the exact offset used by the driver, the config_read/write callbacks implemented as members in PCIDevice struct, receive an address that went through some manipulations/mapping that I have a hard time understanding.
Following the code path up to pci_config_host_read/write in QEMU sources, and the same in the kernel side for pci_read/write_config_* functions, didn't provide any clear answers.
Can anyone help me understand how to extract the config offset used by the driver when calling the pci config rw functions?
If you set your PCI device model up to implement the QEMU PCIDevice config_read and config_write methods, the addresses passed to them should be the offsets into the PCI config space (ie starting with the standard 0 == PCI_VENDOR_ID, 2 == PCI_DEVICE_ID, 4 == PCI_COMMAND and so on, and any device-specific stuff after the 64 bytes of standardized config space).

How to observe aarch64 system registers in QEMU?

I have some baremetal AARCH64 software running in QEMU. I connect GDB to it as a remote target. GDB multi-arch shows general purpose registers from x0 to x30, the SP, and PC.
However, I can't find a way to access the system registers to inspect things like the DAIF system register, the Fault Address Register, Fault Syndrome Register, etc. These are essential for debugging. I've tried within QEMU using info all-registers but the output doesn't seem relevant.
Am I missing something obvious?
PS, the QEMU model is the following:
qemu-system-aarch64 -machine virt,gic_version=3 -cpu cortex-a57 -smp 4
-m 4096
No, you dont missing anything: it is impossible to view aarch64 system registers with the stock qemu as a gdb remote target.
But you could add a small changes to qemu to view them.
Gdb client connects to QEMU over GDB RSP protocol. Server part of this protocol implemented at QEMU is called "gdb stub" (also it is common term for many other simulators/embedded software).
At the very beginning of client and stub communications, stub sends to client a target desription - a xml file with all registers that client allowed to request. Here is a such file for qemu aarch64 target. As you can see, info all-registers command at client prints all this registers, not more.
If you simple add required registers to that file it doesn`t work, you also need to add a few lines to aarch64_cpu_gdb_read_register - that functions reads registers from qemu internals and pass them to gdbstub.
After that build qemu, and you got it.
Also that question
will help you to view a client/stub communication details, if something goes wrong.
QEMU 3.x+ exposes the aarch64 system registers in the normal info registers command. For example:
(gdb) info registers
...
MVFR1_EL1 0x12111111 303108369
MDRAR_EL1 0x0 0
OSLSR_EL1 0xa 10
CTR_EL0 0x8444c004 2219098116
REVIDR_EL1 0x0 0
SCTLR 0xc50838 12912696
ACTLR_EL1 0x0 0
CPACR 0x0 0
...
It was implemented in https://github.com/qemu/qemu/commit/200bf5b7ffe.
QEMU tells GDB which registers it knows about by sending XML files in GDB's Target Description format: https://sourceware.org/gdb/onlinedocs/gdb/Target-Descriptions.html#Target-Descriptions
Some of those, are simply tracked in-tree as XML files directly: https://github.com/qemu/qemu/tree/v3.0.0/gdb-xml and may be from the GDB tree: https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=gdb/features/aarch64-core.xml;h=eb6364eb0996313420a4098509cb7f0e0fc32bec
But others are generated on the fly to reflect system configuration.
In particular, system registers are generated on the fly and sent as system-registers.xml, see: https://github.com/qemu/qemu/blob/v3.0.0/target/arm/gdbstub.c#L174
So, whatever registers you are missing, you should add them to that XML, and populate them with the correct values like the others.
And then send a patch to upstream QEMU :-)

Using KSEG2 with wired TLB's in kernel mode

We have some code running in KUSEG and we see the need for more than 2Gb of memory that KUSEG provides. We tried to map some more physical memory into KSEG2 (since we run in kernel mode) by setting up wired TLBs. When I wrote a test application to access and write to the KSEG2 space (address 0xC0000000) I see that it throws a TLBS exception complaining that there is a TLB miss. I have double checked that the TLB's are setup correctly.
Am I missing something here. Has anyone used MIPS KSEG2 in kernel mode.
Thanks a lot in advance.
Vamsi.
On the chip we were using the KSEG2 address needs to have the high order 32 bits set to 1. Programming the virtual address as 0xFFFFFFFFC0000000 solved the problem.

Resources