Hello
We have a Cobra Sentec board with a MCF5329 ColdFire processor. It runs an ucLinux pretty well. Now, we want to use the PWM module, but we are not able to acces to the PWM module registers. We can read and write them without error but we always read 0 in all registers. All reads/writes are byte accesses.
Any other reads from other modules on the MCF5329 are working.
I did not find anything like a module activation bit, but has the PWM module anything like that?
Any idea on what to look for?
Thank you in advance,
Jose
Hi
I had forgotten it. Some processor registers are not accesible from userspace: we have to program them through drivers. I don´t know why some of them are accesibles and the other not. Both are processor user registers, but some way uclinux hiddens some of them.
Changing one driver to read that registers, I can see now good values... I think. I test now the PWM.
Sorry and thanks,
Jose
> Some processor registers are not accesible from userspace:
> I don´t know why some of them are accesibles and the other not
That's the whole point of Supervisor and User mode, to stop the User code from wrecking anything.
The CPU Registers you can get to from User Mode are listed in "Table 3-1. ColdFire Core Programming Model". It also lists the Supervisor-only ones.
You can program the Coldfire CPUs to get to all memory "flat" and in the same way, but it runs really slowly. In order to get any performance you have to turn the Cache on. That involves setting up the CACR, ACR1 and ACR2. You want the RAM (and optionally the FLASH, unless you want to write to it) cached but you have to have the Peripheral Space uncached. The CPU doesn't do this automatically for you - you have to do this manually.
Ideally (and simply) you'd have three control registers defining cache modes and protections, with one mapping RAM, one mapping FLASH and the third mapping the Peripherals. A few more for other memory-mapped devices would be nice. But this CPU only has TWO such registers. So you use the CACR settings to default one of the three spaces and let ACR1 and ACR2 cover the other ones. These are usually enough, but it's a restriction we really didn't need.
It looks like ucLinux is using one of the ACRs to map the Peripherals, and has User access disabled. That is "the linux way".
If it makes things easier for you, then you can probably locate the code that sets it up that way and change it to allow user access. Or you can write a small Supervisor function that simple rewrites the ACRs to allow user access. This is harder than it should be as they're write-only, so you need to find what is normally being written to them if you want to change it. Does ucLinux support some sort of "mmap()" call that might do this already?
Tom
Tom Evans escribió:
It looks like ucLinux is using one of the ACRs to map the Peripherals, and has User access disabled. That is "the linux way".
If it makes things easier for you, then you can probably locate the code that sets it up that way and change it to allow user access. Or you can write a small Supervisor function that simple rewrites the ACRs to allow user access. This is harder than it should be as they're write-only, so you need to find what is normally being written to them if you want to change it. Does ucLinux support some sort of "mmap()" call that might do this already?
Tom
Thanks Tom
Sounds good. Your explanation seems to adjust to the facts. I will look for it at uClinux code.
I already access to the registers through a kernel driver. I implemented two additional commands to read and write any register.
Thank you again,
Jose
Hello
No luck.
I think I found the CACHE_ENABLE code in mcfcache.h:
movel #0x01000000,%d0 /* invalidate cache cmd */
movec %d0,%CACR /* do invalidate cache */
nop
movel #0x4001C000,%d0 /* set SDRAM cached (write-thru) */
movec %d0,%ACR0
movel #0x00000000,%d0 /* no other regions cached */
movec %d0,%ACR1
movel #0x80000200,%d0 /* setup cache mask */
movec %d0,%CACR /* enable cache */
nop
It only caches the SDRAM region. And I can not find other ACRx write in code.
I am now looking thorugh the uclinx code searching if SCM or eDMA is used to block some memory region.
Best regards,
Jose
Hello
I can not find it. SCM does not limit the PWM module to supervisor access and I do not see that DMA affects this access.
PWM module is at address FC09_0xxx. EPORT is at address FC09_4xxx. I can access the EPORT user registers from userspace, but I can not readwrite the PWM user registers.
I have found that some modules, FlexCAN for example, can be configured for user or supervisor access. But the PWM seems to be only user access registers.
Thank you,
Jose
I just searched the Reference Manual for all matches on "Supervisor" and found a section I haven't read before.
Check:
11.2.1 Master Privilege Register 0 (MPR0)
11.2.3 Peripheral Access Control Registers (PACRx)
Especially PACR36 in PACRE, which sets the PWM register access.
These default out of reset to all devices only allowing Supervisor Access. If User access is required, these registers have to be changed. I wouldn't expect there's be any code that would change this.
It is somewhat redundant for the FlexCAN module to separately have User/Supervisor control bits, but I suppose they're useful when used in a CPU that doesn't have PACR registers.
If you try to access a register from user space where it is blocked, the manual says "the access is terminated with an error response". That should trap to the OS with an Access Exception. This may be happening and the OS may be recovering from that and giving the result you're seeing. See if you can find what the Access Exception handler does.
Tom
Hello
All MPROTn fileds have a 0x7 value. All the PACRn fields have 0x00 value. This implies user access with no restrictions. But that registers can not be read. Some other thing is blocking the read from user space.
Thanks
Jose