richardghirst / PiBits

819 stars 565 forks source link

Wrong mem_flag on Pi Zero #108

Closed usedbytes closed 3 years ago

usedbytes commented 6 years ago

Hi,

I've been building a stepper motor pulse generator using similar techniques to servod - and borrowing some of the code.

I've run in to a problem - it seems like the board model detection is broken (at least on my setup)

My board is a Pi Zero, fairly recent raspbian

$ uname -a
Linux raspberrypi 4.14.34+ #1110 Mon Apr 16 14:51:42 BST 2018 armv6l GNU/Linux
$ cat /proc/cpuinfo
processor       : 0
model name      : ARMv6-compatible processor rev 7 (v6l)
BogoMIPS        : 697.95
Features        : half thumb fastmult vfp edsp java tls
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xb76
CPU revision    : 7

Hardware        : BCM2835
Revision        : 900092
Serial          : XXXXXXXXXXXXXXX

servod detects this as a board_model == 2, when it should be board_model == 1, and so servod sets mem_flag = 0x04 when it should be 0x0c.

I think this causes me problems because mem_virt_to_phys() returns bus addresses (GPU L2 cached) - so the DMA engine is using the L2, but the CPU mapping is mem_flag = 0x04 which is "direct" and so bypasses the cache - and it ends up with the DMA and CPU being inconsistent.

If there's a real reason to use an L2-cached mapping then I think the board_model detection needs tweaking. However, I expect the gains from using the L2 cache are really minimal (I understand that misses in the GPU L2 are actually more expensive than direct memory - so it only helps for hits), and so perhaps mem_virt_to_phys() should just always return physical addresses, and the CPU mapping always be non-cached (DIRECT).

For my code, I've copied the board detection from pigpio which uses the CPU architecture to determine the board revision.

richardghirst commented 3 years ago

This is resolved in the most recent update to servoblaster.