[bootlin/training-materials updates] master: IO memory: improve explanations (4b149e43)
Michael Opdenacker
michael.opdenacker at bootlin.com
Mon Feb 8 11:49:42 CET 2021
Repository : https://github.com/bootlin/training-materials
On branch : master
Link : https://github.com/bootlin/training-materials/commit/4b149e43ecf4ffbde7dd42b23d1248868d564c87
>---------------------------------------------------------------
commit 4b149e43ecf4ffbde7dd42b23d1248868d564c87
Author: Michael Opdenacker <michael.opdenacker at bootlin.com>
Date: Mon Feb 8 11:49:42 2021 +0100
IO memory: improve explanations
- Replace the __raw_writel example by writel (4x more frequently used)
- Mention that readl, writel, etc. contain barriers
- Try to explain why readl, writel have little-endian
convertion. Don't hesitate to correct me if you disagree!
Signed-off-by: Michael Opdenacker <michael.opdenacker at bootlin.com>
>---------------------------------------------------------------
4b149e43ecf4ffbde7dd42b23d1248868d564c87
.../kernel-driver-development-io-memory.tex | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/slides/kernel-driver-development-io-memory/kernel-driver-development-io-memory.tex b/slides/kernel-driver-development-io-memory/kernel-driver-development-io-memory.tex
index 65a5d22d..dfb88447 100644
--- a/slides/kernel-driver-development-io-memory/kernel-driver-development-io-memory.tex
+++ b/slides/kernel-driver-development-io-memory/kernel-driver-development-io-memory.tex
@@ -210,7 +210,7 @@ sha_dd->io_base = devm_ioremap_resource(&pdev->dev, sha_res);
\kfunc{ioremap} (\emph{pointer dereferencing}) may not work on some
architectures.
\item To do PCI-style, little-endian accesses, conversion being done
- automatically
+ automatically:
\begin{minted}{c}
unsigned read[bwl](void *addr);
void write[bwl](unsigned val, void *addr);
@@ -220,12 +220,14 @@ void write[bwl](unsigned val, void *addr);
unsigned __raw_read[bwl](void *addr);
void __raw_write[bwl](unsigned val, void *addr);
\end{minted}
+ \item Little-endian is more frequent and also easier
+ to use in drivers. Even if you just read the least significant
+ byte of a 32-bit register, it's still at the same address.
\item Example
\begin{itemize}
- \item 32 bits write
+ \item 32 bit write (\kfile{drivers/tty/serial/uartlite.c}):
\begin{minted}{c}
-__raw_writel(1 << KS8695_IRQ_UART_TX,
- membase + KS8695_INTST);
+writel(c & 0xff, port->membase + 4);
\end{minted}
\end{itemize}
\end{itemize}
@@ -246,10 +248,11 @@ __raw_writel(1 << KS8695_IRQ_UART_TX,
cross the barrier
\item \kfunc{wmb} is a write memory barrier
\item \kfunc{mb} is a read-write memory barrier
+ \item Starts to be a problem with CPUs that reorder instructions and
+ with SMP. See \kerneldoctext{memory-barriers.txt} for details.
\end{itemize}
- \item Starts to be a problem with CPUs that reorder instructions and
- SMP.
- \item See \kerneldoctext{memory-barriers.txt} for details
+ \item Note that \kfunc{readl}, \kfunc{writel} and similar functions
+ already contain barriers (safer), while the raw ones don't.
\end{itemize}
\end{frame}
More information about the training-materials-updates
mailing list