How to invalidate CPU cache ?

Hello, All!

I have the following situation, hope somebody will help me:

PCI hardware have LUT data in system memory for the DMA scatter/gather,
which is disabled by default. When LUT’s entries contains of all zeroes
adapter will ignore data in it, when LUT table’s entries are not all zero
adapter will start to cache data of physical addresses, which are just
entries in the LUT. So if LUT will be enabled with LUT data in system memory
which are not cleared, adapter will begin DMA transfers using wrong and/or
bad physical addresses.

My code looks like this (it’s for x86 platform only !):

memset(ctx->pcie_lut, 0x00,ctx->pcie_lut_size);
asm volatile (“wbinvd”: : :“memory”);
EnableLUT(ctx);

I’m using wbinvd CPU command to be sure, that memset clearing will be done
and all LUT data already cleared before I engage LUT engine. Otherwise
without using wbinvd it is exist probability when LUT engine will be enabled
before all CPU caches are flushed with delayed writeback writes.

But driver segfaults when executing wbinvd CPU command with GP #0, even when
all IOs are permitted by using ThreadCtl(_NTO_TCTL_IO, …

Is it possible somehow to flush all delayed writes in the CPU caches in QNX
6.3 SP3 for x86 ?

Thanks in advance !

With best regards, Mike Gorchak. E-mail: mike@malva.ua

Hello, Mike!

MG> Is it possible somehow to flush all delayed writes in the CPU caches in
MG> QNX 6.3 SP3 for x86 ?

As far as I can interpret the silence, the way only to hook INT 0 timer
interrupt, do the wbinvd instruction in the interrupt handler and then
immediately free the timer interrupt hook. Something tell’s me this will
work, but it is wrong way to do such things … :-/

With best regards, Mike Gorchak. E-mail: mike@malva.ua

Mike Gorchak <mike@malva.ua> wrote:

Hello, All!



I’m using wbinvd CPU command to be sure, that memset clearing will be done
and all LUT data already cleared before I engage LUT engine. Otherwise
without using wbinvd it is exist probability when LUT engine will be enabled
before all CPU caches are flushed with delayed writeback writes.

But driver segfaults when executing wbinvd CPU command with GP #0, even when
all IOs are permitted by using ThreadCtl(_NTO_TCTL_IO, …

wbinvd may be a ring 0 operation, TCTL_IO allows ring 1. Only the kernel
operates at ring 0.

Is it possible somehow to flush all delayed writes in the CPU caches in QNX
6.3 SP3 for x86 ?

Have you looked at the cache contral API? I don’t know if it allows flushing
of all cache – but it does allow it for configured/controlled areas.

Look at cache_fini(), CACHE_FLUSH().

-David

David Gibbs
QNX Training Services
dagibbs@qnx.com

Hello, David!

I’m using wbinvd CPU command to be sure, that memset clearing will be
done and all LUT data already cleared before I engage LUT engine.
Otherwise without using wbinvd it is exist probability when LUT engine
will be enabled before all CPU caches are flushed with delayed writeback
writes.
But driver segfaults when executing wbinvd CPU command with GP #0, even
when all IOs are permitted by using ThreadCtl(_NTO_TCTL_IO, …
DG> wbinvd may be a ring 0 operation, TCTL_IO allows ring 1. Only the

DG> kernel operates at ring 0.

Yep, it is.

Is it possible somehow to flush all delayed writes in the CPU caches in
QNX 6.3 SP3 for x86 ?
DG> Have you looked at the cache contral API?

I have missed it, since cache control API appeared in QNX 6.3.0 SP2 first
time.

DG> I don’t know if it allows flushing of all cache – but it does allow it
DG> for configured/controlled areas.
DG> Look at cache_fini(), CACHE_FLUSH().

Thank you for guidance ! Region range cache flush will be enough in my case.
Thanks one more!

P.S. It would be cool to have MTRR API and library also released some good
day :slight_smile:

With best regards, Mike Gorchak. E-mail: mike@malva.ua