code:
==========================================
Xillybus driver for generic FPGA interface
==========================================

:Author: Eli Billauer, Xillybus Ltd. (http://xillybus.com)
:Email:  eli.billauer@gmail.com or as advertised on Xillybus' site.

.. Contents:

 - Introduction
  -- Background
  -- Xillybus Overview

 - Usage
  -- User interface
  -- Synchronization
  -- Seekable pipes

 - Internals
  -- Source code organization
  -- Pipe attributes
  -- Host never reads from the FPGA
  -- Channels, pipes, and the message channel
  -- Data streaming
  -- Data granularity
  -- Probing
  -- Buffer allocation
  -- The "nonempty" message (supporting poll)

Introduction
============

Background
----------

An FPGA (Field Programmable Gate Array) is a piece of logic hardware, which
can be programmed to become virtually anything that is usually found as a
dedicated chipset: For instance, a display adapter, network interface card,
or even a processor with its peripherals. FPGAs are the LEGO of hardware:
Based upon certain building blocks, you make your own toys the way you like
them. It's usually pointless to reimplement something that is already
available on the market as a chipset, so FPGAs are mostly used when some
special functionality is needed, and the production volume is relatively low
(hence not justifying the development of an ASIC).

The challenge with FPGAs is that everything is implemented at a very low
level, even lower than assembly language. In order to allow FPGA designers to
focus on their specific project, and not reinvent the wheel over and over
again, pre-designed building blocks, IP cores, are often used. These are the
FPGA parallels of library functions. IP cores may implement certain
mathematical functions, a functional unit (e.g. a USB interface), an entire
processor (e.g. ARM) or anything that might come handy. Think of them as a
building block, with electrical wires dangling on the sides for connection to
other blocks.

One of the daunting tasks in FPGA design is communicating with a fullblown
operating system (actually, with the processor running it): Implementing the
low-level bus protocol and the somewhat higher-level interface with the host
(registers, interrupts, DMA etc.) is a project in itself. When the FPGA's
function is a well-known one (e.g. a video adapter card, or a NIC), it can
make sense to design the FPGA's interface logic specifically for the project.
A special driver is then written to present the FPGA as a well-known interface
to the kernel and/or user space. In that case, there is no reason to treat the
FPGA differently than any device on the bus.

It's however common that the desired data communication doesn't fit any well-
known peripheral function. Also, the effort of designing an elegant
abstraction for the data exchange is often considered too big. In those cases,
a quicker and possibly less elegant solution is sought: The driver is
effectively written as a user space program, leaving the kernel space part
with just elementary data transport. This still requires designing some
interface logic for the FPGA, and write a simple ad-hoc driver for the kernel.

Xillybus Overview
-----------------

Xillybus is an IP core and a Linux driver. Together, they form a kit for
elementary data transport between an FPGA and the host, providing pipe-like
data streams with a straightforward user interface. It's intended as a low-
effort solution for mixed FPGA-host projects, for which it makes sense to
have the project-specific part of the driver running in a user-space program.

Since the communication requirements may vary significantly from one FPGA
project to another (the number of data pipes needed in each direction and
their attributes), there isn't one specific chunk of logic being the Xillybus
IP core. Rather, the IP core is configured and built based upon a
specification given by its end user.

Xillybus presents independent data streams, which resemble pipes or TCP/IP
communication to the user. At the host side, a character device file is used
just like any pipe file. On the FPGA side, hardware FIFOs are used to stream
the data. This is contrary to a common method of communicating through fixed-
sized buffers (even though such buffers are used by Xillybus under the hood).
There may be more than a hundred of these streams on a single IP core, but
also no more than one, depending on the configuration.

In order to ease the deployment of the Xillybus IP core, it contains a simple
data structure which completely defines the core's configuration. The Linux
driver fetches this data structure during its initialization process, and sets
up the DMA buffers and character devices accordingly. As a result, a single
driver is used to work out of the box with any Xillybus IP core.

The data structure just mentioned should not be confused with PCI's
configuration space or the Flattened Device Tree.

Usage
=====

User interface
--------------

On the host, all interface with Xillybus is done through /dev/xillybus_*
device files, which are generated automatically as the drivers loads. The
names of these files depend on the IP core that is loaded in the FPGA (see
Probing below). To communicate with the FPGA, open the device file that
corresponds to the hardware FIFO you want to send data or receive data from,
and use plain write() or read() calls, just like with a regular pipe. In
particular, it makes perfect sense to go::

	$ cat mydata > /dev/xillybus_thisfifo

	$ cat /dev/xillybus_thatfifo > hisdata

possibly pressing CTRL-C as some stage, even though the xillybus_* pipes have
the capability to send an EOF (but may not use it).

The driver and hardware are designed to behave sensibly as pipes, including:

* Supporting non-blocking I/O (by setting O_NONBLOCK on open() ).

* Supporting poll() and select().

* Being bandwidth efficient under load (using DMA) but also handle small
  pieces of data sent across (like TCP/IP) by autoflushing.

A device file can be read only, write only or bidirectional. Bidirectional
device files are treated like two independent pipes (except for sharing a
"channel" structure in the implementation code).

Synchronization
---------------

Xillybus pipes are configured (on the IP core) to be either synchronous or
asynchronous. For a synchronous pipe, write() returns successfully only after
some data has been submitted and acknowledged by the FPGA. This slows down
bulk data transfers, and is nearly impossible for use with streams that
require data at a constant rate: There is no data transmitted to the FPGA
between write() calls, in particular when the process loses the CPU.

When a pipe is configured asynchronous, write() returns if there was enough
room in the buffers to store any of the data in the buffers.

For FPGA to host pipes, asynchronous pipes allow data transfer from the FPGA
as soon as the respective device file is opened, regardless of if the data
has been requested by a read() call. On synchronous pipes, only the amount
of data requested by a read() call is transmitted.

In summary, for synchronous pipes, data between the host and FPGA is
transmitted only to satisfy the read() or write() call currently handled
by the driver, and those calls wait for the transmission to complete before
returning.

Note that the synchronization attribute has nothing to do with the possibility
that read() or write() completes less bytes than requested. There is a
separate configuration flag ("allowpartial") that determines whether such a
partial completion is allowed.

Seekable pipes
--------------

A synchronous pipe can be configured to have the stream's position exposed
to the user logic at the FPGA. Such a pipe is also seekable on the host API.
With this feature, a memory or register interface can be attached on the
FPGA side to the seekable stream. Reading or writing to a certain address in
the attached memory is done by seeking to the desired address, and calling
read() or write() as required.

Internals
=========

Source code organization
------------------------

The Xillybus driver consists of a core module, xillybus_core.c, and modules
that depend on the specific bus interface (xillybus_of.c and xillybus_pcie.c).

The bus specific modules are those probed when a suitable device is found by
the kernel. Since the DMA mapping and synchronization functions, which are bus
dependent by their nature, are used by the core module, a
xilly_endpoint_hardware structure is passed to the core module on
initialization. This structure is populated with pointers to wrapper functions
which execute the DMA-related operations on the bus.

Pipe attributes
---------------

Each pipe has a number of attributes which are set when the FPGA component
(IP core) is built. They are fetched from the IDT (the data structure which
defines the core's configuration, see Probing below) by xilly_setupchannels()
in xillybus_core.c as follows:

* is_writebuf: The pipe's direction. A non-zero value means it's an FPGA to
  host pipe (the FPGA "writes").

* channelnum: The pipe's identification number in communication between the
  host and FPGA.

* format: The underlying data width. See Data Granularity below.

* allowpartial: A non-zero value means that a read() or write() (whichever
  applies) may return with less than the requested number of bytes. The common
  choice is a non-zero value, to match standard UNIX behavior.

* synchronous: A non-zero value means that the pipe is synchronous. See
  Synchronization above.

* bufsize: Each DMA buffer's size. Always a power of two.

* bufnum: The number of buffers allocated for this pipe. Always a power of two.

* exclusive_open: A non-zero value forces exclusive opening of the associated
  device file. If the device file is bidirectional, and already opened only in
  one direction, the opposite direction may be opened once.

* seekable: A non-zero value indicates that the pipe is seekable. See
  Seekable pipes above.

* supports_nonempty: A non-zero value (which is typical) indicates that the
  hardware will send the messages that are necessary to support select() and
  poll() for this pipe.

Host never reads from the FPGA
------------------------------

Even though PCI Express is hotpluggable in general, a typical motherboard
doesn't expect a card to go away all of the sudden. But since the PCIe card
is based upon reprogrammable logic, a sudden disappearance from the bus is
quite likely as a result of an accidental reprogramming of the FPGA while the
host is up. In practice, nothing happens immediately in such a situation. But
if the host attempts to read from an address that is mapped to the PCI Express
device, that leads to an immediate freeze of the system on some motherboards,
even though the PCIe standard requires a graceful recovery.

In order to avoid these freezes, the Xillybus driver refrains completely from
reading from the device's register space. All communication from the FPGA to
the host is done through DMA. In particular, the Interrupt Service Routine
doesn't follow the common practice of checking a status register when it's
invoked. Rather, the FPGA prepares a small buffer which contains short
messages, which inform the host what the interrupt was about.

This mechanism is used on non-PCIe buses as well for the sake of uniformity.

Channels, pipes, and the message channel
----------------------------------------

Each of the (possibly bidirectional) pipes presented to the user is allocated
a data channel between the FPGA and the host. The distinction between channels
and pipes is necessary only because of channel 0, which is used for interrupt-
related messages from the FPGA, and has no pipe attached to it.

Data streaming
--------------

Even though a non-segmented data stream is presented to the user at both
sides, the implementation relies on a set of DMA buffers which is allocated
for each channel. For the sake of illustration, let's take the FPGA to host
direction: As data streams into the respective channel's interface in the
FPGA, the Xillybus IP core writes it to one of the DMA buffers. When the
buffer is full, the FPGA informs the host about that (appending a
XILLYMSG_OPCODE_RELEASEBUF message channel 0 and sending an interrupt if
necessary). The host responds by making the data available for reading through
the character device. When all data has been read, the host writes on the
FPGA's buffer control register, allowing the buffer's overwriting. Flow
control mechanisms exist on both sides to prevent underflows and overflows.

This is not good enough for creating a TCP/IP-like stream: If the data flow
stops momentarily before a DMA buffer is filled, the intuitive expectation is
that the partial data in buffer will arrive anyhow, despite the buffer not
being completed. This is implemented by adding a field in the
XILLYMSG_OPCODE_RELEASEBUF message, through which the FPGA informs not just
which buffer is submitted, but how much data it contains.

But the FPGA will submit a partially filled buffer only if directed to do so
by the host. This situation occurs when the read() method has been blocking
for XILLY_RX_TIMEOUT jiffies (currently 10 ms), after which the host commands
the FPGA to submit a DMA buffer as soon as it can. This timeout mechanism
balances between bus bandwidth efficiency (preventing a lot of partially
filled buffers being sent) and a latency held fairly low for tails of data.

A similar setting is used in the host to FPGA direction. The handling of
partial DMA buffers is somewhat different, though. The user can tell the
driver to submit all data it has in the buffers to the FPGA, by issuing a
write() with the byte count set to zero. This is similar to a flush request,
but it doesn't block. There is also an autoflushing mechanism, which triggers
an equivalent flush roughly XILLY_RX_TIMEOUT jiffies after the last write().
This allows the user to be oblivious about the underlying buffering mechanism
and yet enjoy a stream-like interface.

Note that the issue of partial buffer flushing is irrelevant for pipes having
the "synchronous" attribute nonzero, since synchronous pipes don't allow data
to lay around in the DMA buffers between read() and write() anyhow.

Data granularity
----------------

The data arrives or is sent at the FPGA as 8, 16 or 32 bit wide words, as
configured by the "format" attribute. Whenever possible, the driver attempts
to hide this when the pipe is accessed differently from its natural alignment.
For example, reading single bytes from a pipe with 32 bit granularity works
with no issues. Writing single bytes to pipes with 16 or 32 bit granularity
will also work, but the driver can't send partially completed words to the
FPGA, so the transmission of up to one word may be held until it's fully
occupied with user data.

This somewhat complicates the handling of host to FPGA streams, because
when a buffer is flushed, it may contain up to 3 bytes don't form a word in
the FPGA, and hence can't be sent. To prevent loss of data, these leftover
bytes need to be moved to the next buffer. The parts in xillybus_core.c
that mention "leftovers" in some way are related to this complication.

Probing
-------

As mentioned earlier, the number of pipes that are created when the driver
loads and their attributes depend on the Xillybus IP core in the FPGA. During
the driver's initialization, a blob containing configuration info, the
Interface Description Table (IDT), is sent from the FPGA to the host. The
bootstrap process is done in three phases:

1. Acquire the length of the IDT, so a buffer can be allocated for it. This
   is done by sending a quiesce command to the device, since the acknowledge
   for this command contains the IDT's buffer length.

2. Acquire the IDT itself.

3. Create the interfaces according to the IDT.

Buffer allocation
-----------------

In order to simplify the logic that prevents illegal boundary crossings of
PCIe packets, the following rule applies: If a buffer is smaller than 4kB,
it must not cross a 4kB boundary. Otherwise, it must be 4kB aligned. The
xilly_setupchannels() functions allocates these buffers by requesting whole
pages from the kernel, and diving them into DMA buffers as necessary. Since
all buffers' sizes are powers of two, it's possible to pack any set of such
buffers, with a maximal waste of one page of memory.

All buffers are allocated when the driver is loaded. This is necessary,
since large continuous physical memory segments are sometimes requested,
which are more likely to be available when the system is freshly booted.

The allocation of buffer memory takes place in the same order they appear in
the IDT. The driver relies on a rule that the pipes are sorted with decreasing
buffer size in the IDT. If a requested buffer is larger or equal to a page,
the necessary number of pages is requested from the kernel, and these are
used for this buffer. If the requested buffer is smaller than a page, one
single page is requested from the kernel, and that page is partially used.
Or, if there already is a partially used page at hand, the buffer is packed
into that page. It can be shown that all pages requested from the kernel
(except possibly for the last) are 100% utilized this way.

The "nonempty" message (supporting poll)
----------------------------------------

In order to support the "poll" method (and hence select() ), there is a small
catch regarding the FPGA to host direction: The FPGA may have filled a DMA
buffer with some data, but not submitted that buffer. If the host waited for
the buffer's submission by the FPGA, there would be a possibility that the
FPGA side has sent data, but a select() call would still block, because the
host has not received any notification about this. This is solved with
XILLYMSG_OPCODE_NONEMPTY messages sent by the FPGA when a channel goes from
completely empty to containing some data.

These messages are used only to support poll() and select(). The IP core can
be configured not to send them for a slight reduction of bandwidth.


code:
========================================
Writing Device Drivers for Zorro Devices
========================================

:Author: Written by Geert Uytterhoeven <geert@linux-m68k.org>
:Last revised: September 5, 2003

Introduction
------------

The Zorro bus is the bus used in the Amiga family of computers. Thanks to
AutoConfig(tm), it's 100% Plug-and-Play.

There are two types of Zorro buses, Zorro II and Zorro III:

  - The Zorro II address space is 24-bit and lies within the first 16 MB of the
    Amiga's address map.

  - Zorro III is a 32-bit extension of Zorro II, which is backwards compatible
    with Zorro II. The Zorro III address space lies outside the first 16 MB.

Probing for Zorro Devices
-------------------------

Zorro devices are found by calling ``zorro_find_device()``, which returns a
pointer to the ``next`` Zorro device with the specified Zorro ID. A probe loop
for the board with Zorro ID ``ZORRO_PROD_xxx`` looks like::

    struct zorro_dev *z = NULL;

    while ((z = zorro_find_device(ZORRO_PROD_xxx, z))) {
	if (!zorro_request_region(z->resource.start+MY_START, MY_SIZE,
				  "My explanation"))
	...
    }

``ZORRO_WILDCARD`` acts as a wildcard and finds any Zorro device. If your driver
supports different types of boards, you can use a construct like::

    struct zorro_dev *z = NULL;

    while ((z = zorro_find_device(ZORRO_WILDCARD, z))) {
	if (z->id != ZORRO_PROD_xxx1 && z->id != ZORRO_PROD_xxx2 && ...)
	    continue;
	if (!zorro_request_region(z->resource.start+MY_START, MY_SIZE,
				  "My explanation"))
	...
    }

Zorro Resources
---------------

Before you can access a Zorro device's registers, you have to make sure it's
not yet in use. This is done using the I/O memory space resource management
functions::

    request_mem_region()
    release_mem_region()

Shortcuts to claim the whole device's address space are provided as well::

    zorro_request_device
    zorro_release_device

Accessing the Zorro Address Space
---------------------------------

The address regions in the Zorro device resources are Zorro bus address
regions. Due to the identity bus-physical address mapping on the Zorro bus,
they are CPU physical addresses as well.

The treatment of these regions depends on the type of Zorro space:

  - Zorro II address space is always mapped and does not have to be mapped
    explicitly using z_ioremap().

    Conversion from bus/physical Zorro II addresses to kernel virtual addresses
    and vice versa is done using::

	virt_addr = ZTWO_VADDR(bus_addr);
	bus_addr = ZTWO_PADDR(virt_addr);

  - Zorro III address space must be mapped explicitly using z_ioremap() first
    before it can be accessed::

	virt_addr = z_ioremap(bus_addr, size);
	...
	z_iounmap(virt_addr);

References
----------

#. linux/include/linux/zorro.h
#. linux/include/uapi/linux/zorro.h
#. linux/include/uapi/linux/zorro_ids.h
#. linux/arch/m68k/include/asm/zorro.h
#. linux/drivers/zorro
#. /proc/bus/zorro

repo_name: angery/linux


code:
===========================================
Fault injection capabilities infrastructure
===========================================

See also drivers/md/md-faulty.c and "every_nth" module option for scsi_debug.

Available fault injection capabilities
--------------------------------------

- failslab

  injects slab allocation failures. (kmalloc(), kmem_cache_alloc(), ...)

- fail_page_alloc

  injects page allocation failures. (alloc_pages(), get_free_pages(), ...)

- fail_usercopy

  injects failures in user memory access functions. (copy_from_user(), get_user(), ...)

- fail_futex

  injects futex deadlock and uaddr fault errors.

- fail_sunrpc

  injects kernel RPC client and server failures.

- fail_make_request

  injects disk IO errors on devices permitted by setting
  /sys/block/<device>/make-it-fail or
  /sys/block/<device>/<partition>/make-it-fail. (submit_bio_noacct())

- fail_mmc_request

  injects MMC data errors on devices permitted by setting
  debugfs entries under /sys/kernel/debug/mmc0/fail_mmc_request

- fail_function

  injects error return on specific functions, which are marked by
  ALLOW_ERROR_INJECTION() macro, by setting debugfs entries
  under /sys/kernel/debug/fail_function. No boot option supported.

- NVMe fault injection

  inject NVMe status code and retry flag on devices permitted by setting
  debugfs entries under /sys/kernel/debug/nvme*/fault_inject. The default
  status code is NVME_SC_INVALID_OPCODE with no retry. The status code and
  retry flag can be set via the debugfs.

Configure fault-injection capabilities behavior
-----------------------------------------------

debugfs entries
^^^^^^^^^^^^^^^

fault-inject-debugfs kernel module provides some debugfs entries for runtime
configuration of fault-injection capabilities.

- /sys/kernel/debug/fail*/probability:

	likelihood of failure injection, in percent.

	Format: <percent>

	Note that one-failure-per-hundred is a very high error rate
	for some testcases.  Consider setting probability=100 and configure
	/sys/kernel/debug/fail*/interval for such testcases.

- /sys/kernel/debug/fail*/interval:

	specifies the interval between failures, for calls to
	should_fail() that pass all the other tests.

	Note that if you enable this, by setting interval>1, you will
	probably want to set probability=100.

- /sys/kernel/debug/fail*/times:

	specifies how many times failures may happen at most. A value of -1
	means "no limit".

- /sys/kernel/debug/fail*/space:

	specifies an initial resource "budget", decremented by "size"
	on each call to should_fail(,size).  Failure injection is
	suppressed until "space" reaches zero.

- /sys/kernel/debug/fail*/verbose

	Format: { 0 | 1 | 2 }

	specifies the verbosity of the messages when failure is
	injected.  '0' means no messages; '1' will print only a single
	log line per failure; '2' will print a call trace too -- useful
	to debug the problems revealed by fault injection.

- /sys/kernel/debug/fail*/task-filter:

	Format: { 'Y' | 'N' }

	A value of 'N' disables filtering by process (default).
	Any positive value limits failures to only processes indicated by
	/proc/<pid>/make-it-fail==1.

- /sys/kernel/debug/fail*/require-start,
  /sys/kernel/debug/fail*/require-end,
  /sys/kernel/debug/fail*/reject-start,
  /sys/kernel/debug/fail*/reject-end:

	specifies the range of virtual addresses tested during
	stacktrace walking.  Failure is injected only if some caller
	in the walked stacktrace lies within the required range, and
	none lies within the rejected range.
	Default required range is [0,ULONG_MAX) (whole of virtual address space).
	Default rejected range is [0,0).

- /sys/kernel/debug/fail*/stacktrace-depth:

	specifies the maximum stacktrace depth walked during search
	for a caller within [require-start,require-end) OR
	[reject-start,reject-end).

- /sys/kernel/debug/fail_page_alloc/ignore-gfp-highmem:

	Format: { 'Y' | 'N' }

	default is 'Y', setting it to 'N' will also inject failures into
	highmem/user allocations (__GFP_HIGHMEM allocations).

- /sys/kernel/debug/failslab/ignore-gfp-wait:
- /sys/kernel/debug/fail_page_alloc/ignore-gfp-wait:

	Format: { 'Y' | 'N' }

	default is 'Y', setting it to 'N' will also inject failures
	into allocations that can sleep (__GFP_DIRECT_RECLAIM allocations).

- /sys/kernel/debug/fail_page_alloc/min-order:

	specifies the minimum page allocation order to be injected
	failures.

- /sys/kernel/debug/fail_futex/ignore-private:

	Format: { 'Y' | 'N' }

	default is 'N', setting it to 'Y' will disable failure injections
	when dealing with private (address space) futexes.

- /sys/kernel/debug/fail_sunrpc/ignore-client-disconnect:

	Format: { 'Y' | 'N' }

	default is 'N', setting it to 'Y' will disable disconnect
	injection on the RPC client.

- /sys/kernel/debug/fail_sunrpc/ignore-server-disconnect:

	Format: { 'Y' | 'N' }

	default is 'N', setting it to 'Y' will disable disconnect
	injection on the RPC server.

- /sys/kernel/debug/fail_sunrpc/ignore-cache-wait:

	Format: { 'Y' | 'N' }

	default is 'N', setting it to 'Y' will disable cache wait
	injection on the RPC server.

- /sys/kernel/debug/fail_function/inject:

	Format: { 'function-name' | '!function-name' | '' }

	specifies the target function of error injection by name.
	If the function name leads '!' prefix, given function is
	removed from injection list. If nothing specified ('')
	injection list is cleared.

- /sys/kernel/debug/fail_function/injectable:

	(read only) shows error injectable functions and what type of
	error values can be specified. The error type will be one of
	below;
	- NULL:	retval must be 0.
	- ERRNO: retval must be -1 to -MAX_ERRNO (-4096).
	- ERR_NULL: retval must be 0 or -1 to -MAX_ERRNO (-4096).

- /sys/kernel/debug/fail_function/<function-name>/retval:

	specifies the "error" return value to inject to the given function.
	This will be created when the user specifies a new injection entry.
	Note that this file only accepts unsigned values. So, if you want to
	use a negative errno, you better use 'printf' instead of 'echo', e.g.:
	$ printf %#x -12 > retval

Boot option
^^^^^^^^^^^

In order to inject faults while debugfs is not available (early boot time),
use the boot option::

	failslab=
	fail_page_alloc=
	fail_usercopy=
	fail_make_request=
	fail_futex=
	mmc_core.fail_request=<interval>,<probability>,<space>,<times>

proc entries
^^^^^^^^^^^^

- /proc/<pid>/fail-nth,
  /proc/self/task/<tid>/fail-nth:

	Write to this file of integer N makes N-th call in the task fail.
	Read from this file returns a integer value. A value of '0' indicates
	that the fault setup with a previous write to this file was injected.
	A positive integer N indicates that the fault wasn't yet injected.
	Note that this file enables all types of faults (slab, futex, etc).
	This setting takes precedence over all other generic debugfs settings
	like probability, interval, times, etc. But per-capability settings
	(e.g. fail_futex/ignore-private) take precedence over it.

	This feature is intended for systematic testing of faults in a single
	system call. See an example below.

How to add new fault injection capability
-----------------------------------------

- #include <linux/fault-inject.h>

- define the fault attributes

  DECLARE_FAULT_ATTR(name);

  Please see the definition of struct fault_attr in fault-inject.h
  for details.

- provide a way to configure fault attributes

- boot option

  If you need to enable the fault injection capability from boot time, you can
  provide boot option to configure it. There is a helper function for it:

	setup_fault_attr(attr, str);

- debugfs entries

  failslab, fail_page_alloc, fail_usercopy, and fail_make_request use this way.
  Helper functions:

	fault_create_debugfs_attr(name, parent, attr);

- module parameters

  If the scope of the fault injection capability is limited to a
  single kernel module, it is better to provide module parameters to
  configure the fault attributes.

- add a hook to insert failures

  Upon should_fail() returning true, client code should inject a failure:

	should_fail(attr, size);

Application Examples
--------------------

- Inject slab allocation failures into module init/exit code::

    #!/bin/bash

    FAILTYPE=failslab
    echo Y > /sys/kernel/debug/$FAILTYPE/task-filter
    echo 10 > /sys/kernel/debug/$FAILTYPE/probability
    echo 100 > /sys/kernel/debug/$FAILTYPE/interval
    echo -1 > /sys/kernel/debug/$FAILTYPE/times
    echo 0 > /sys/kernel/debug/$FAILTYPE/space
    echo 2 > /sys/kernel/debug/$FAILTYPE/verbose
    echo Y > /sys/kernel/debug/$FAILTYPE/ignore-gfp-wait

    faulty_system()
    {
	bash -c "echo 1 > /proc/self/make-it-fail && exec $*"
    }

    if [ $# -eq 0 ]
    then
	echo "Usage: $0 modulename [ modulename ... ]"
	exit 1
    fi

    for m in $*
    do
	echo inserting $m...
	faulty_system modprobe $m

	echo removing $m...
	faulty_system modprobe -r $m
    done

------------------------------------------------------------------------------

- Inject page allocation failures only for a specific module::

    #!/bin/bash

    FAILTYPE=fail_page_alloc
    module=$1

    if [ -z $module ]
    then
	echo "Usage: $0 <modulename>"
	exit 1
    fi

    modprobe $module

    if [ ! -d /sys/module/$module/sections ]
    then
	echo Module $module is not loaded
	exit 1
    fi

    cat /sys/module/$module/sections/.text > /sys/kernel/debug/$FAILTYPE/require-start
    cat /sys/module/$module/sections/.data > /sys/kernel/debug/$FAILTYPE/require-end

    echo N > /sys/kernel/debug/$FAILTYPE/task-filter
    echo 10 > /sys/kernel/debug/$FAILTYPE/probability
    echo 100 > /sys/kernel/debug/$FAILTYPE/interval
    echo -1 > /sys/kernel/debug/$FAILTYPE/times
    echo 0 > /sys/kernel/debug/$FAILTYPE/space
    echo 2 > /sys/kernel/debug/$FAILTYPE/verbose
    echo Y > /sys/kernel/debug/$FAILTYPE/ignore-gfp-wait
    echo Y > /sys/kernel/debug/$FAILTYPE/ignore-gfp-highmem
    echo 10 > /sys/kernel/debug/$FAILTYPE/stacktrace-depth

    trap "echo 0 > /sys/kernel/debug/$FAILTYPE/probability" SIGINT SIGTERM EXIT

    echo "Injecting errors into the module $module... (interrupt to stop)"
    sleep 1000000

------------------------------------------------------------------------------

- Inject open_ctree error while btrfs mount::

    #!/bin/bash

    rm -f testfile.img
    dd if=/dev/zero of=testfile.img bs=1M seek=1000 count=1
    DEVICE=$(losetup --show -f testfile.img)
    mkfs.btrfs -f $DEVICE
    mkdir -p tmpmnt

    FAILTYPE=fail_function
    FAILFUNC=open_ctree
    echo $FAILFUNC > /sys/kernel/debug/$FAILTYPE/inject
    printf %#x -12 > /sys/kernel/debug/$FAILTYPE/$FAILFUNC/retval
    echo N > /sys/kernel/debug/$FAILTYPE/task-filter
    echo 100 > /sys/kernel/debug/$FAILTYPE/probability
    echo 0 > /sys/kernel/debug/$FAILTYPE/interval
    echo -1 > /sys/kernel/debug/$FAILTYPE/times
    echo 0 > /sys/kernel/debug/$FAILTYPE/space
    echo 1 > /sys/kernel/debug/$FAILTYPE/verbose

    mount -t btrfs $DEVICE tmpmnt
    if [ $? -ne 0 ]
    then
	echo "SUCCESS!"
    else
	echo "FAILED!"
	umount tmpmnt
    fi

    echo > /sys/kernel/debug/$FAILTYPE/inject

    rmdir tmpmnt
    losetup -d $DEVICE
    rm testfile.img

Tool to run command with failslab or fail_page_alloc
----------------------------------------------------
In order to make it easier to accomplish the tasks mentioned above, we can use
tools/testing/fault-injection/failcmd.sh.  Please run a command
"./tools/testing/fault-injection/failcmd.sh --help" for more information and
see the following examples.

Examples:

Run a command "make -C tools/testing/selftests/ run_tests" with injecting slab
allocation failure::

	# ./tools/testing/fault-injection/failcmd.sh \
		-- make -C tools/testing/selftests/ run_tests

Same as above except to specify 100 times failures at most instead of one time
at most by default::

	# ./tools/testing/fault-injection/failcmd.sh --times=100 \
		-- make -C tools/testing/selftests/ run_tests

Same as above except to inject page allocation failure instead of slab
allocation failure::

	# env FAILCMD_TYPE=fail_page_alloc \
		./tools/testing/fault-injection/failcmd.sh --times=100 \
		-- make -C tools/testing/selftests/ run_tests

Systematic faults using fail-nth
---------------------------------

The following code systematically faults 0-th, 1-st, 2-nd and so on
capabilities in the socketpair() system call::

  #include <sys/types.h>
  #include <sys/stat.h>
  #include <sys/socket.h>
  #include <sys/syscall.h>
  #include <fcntl.h>
  #include <unistd.h>
  #include <string.h>
  #include <stdlib.h>
  #include <stdio.h>
  #include <errno.h>

  int main()
  {
	int i, err, res, fail_nth, fds[2];
	char buf[128];

	system("echo N > /sys/kernel/debug/failslab/ignore-gfp-wait");
	sprintf(buf, "/proc/self/task/%ld/fail-nth", syscall(SYS_gettid));
	fail_nth = open(buf, O_RDWR);
	for (i = 1;; i++) {
		sprintf(buf, "%d", i);
		write(fail_nth, buf, strlen(buf));
		res = socketpair(AF_LOCAL, SOCK_STREAM, 0, fds);
		err = errno;
		pread(fail_nth, buf, sizeof(buf), 0);
		if (res == 0) {
			close(fds[0]);
			close(fds[1]);
		}
		printf("%d-th fault %c: res=%d/%d\n", i, atoi(buf) ? 'N' : 'Y',
			res, err);
		if (atoi(buf))
			break;
	}
	return 0;
  }

An example output::

	1-th fault Y: res=-1/23
	2-th fault Y: res=-1/23
	3-th fault Y: res=-1/12
	4-th fault Y: res=-1/12
	5-th fault Y: res=-1/23
	6-th fault Y: res=-1/23
	7-th fault Y: res=-1/23
	8-th fault Y: res=-1/12
	9-th fault Y: res=-1/12
	10-th fault Y: res=-1/12
	11-th fault Y: res=-1/12
	12-th fault Y: res=-1/12
	13-th fault Y: res=-1/12
	14-th fault Y: res=-1/12
	15-th fault Y: res=-1/12
	16-th fault N: res=0/12


code:
.. SPDX-License-Identifier: GPL-2.0

===============
fault-injection
===============

.. toctree::
    :maxdepth: 1

    fault-injection
    notifier-error-inject
    nvme-fault-injection
    provoke-crashes

.. only::  subproject and html

   Indices
   =======

   * :ref:`genindex`


code:
Notifier error injection
========================

Notifier error injection provides the ability to inject artificial errors to
specified notifier chain callbacks. It is useful to test the error handling of
notifier call chain failures which is rarely executed.  There are kernel
modules that can be used to test the following notifiers.

 * PM notifier
 * Memory hotplug notifier
 * powerpc pSeries reconfig notifier
 * Netdevice notifier

PM notifier error injection module
----------------------------------
This feature is controlled through debugfs interface

  /sys/kernel/debug/notifier-error-inject/pm/actions/<notifier event>/error

Possible PM notifier events to be failed are:

 * PM_HIBERNATION_PREPARE
 * PM_SUSPEND_PREPARE
 * PM_RESTORE_PREPARE

Example: Inject PM suspend error (-12 = -ENOMEM)::

	# cd /sys/kernel/debug/notifier-error-inject/pm/
	# echo -12 > actions/PM_SUSPEND_PREPARE/error
	# echo mem > /sys/power/state
	bash: echo: write error: Cannot allocate memory

Memory hotplug notifier error injection module
----------------------------------------------
This feature is controlled through debugfs interface

  /sys/kernel/debug/notifier-error-inject/memory/actions/<notifier event>/error

Possible memory notifier events to be failed are:

 * MEM_GOING_ONLINE
 * MEM_GOING_OFFLINE

Example: Inject memory hotplug offline error (-12 == -ENOMEM)::

	# cd /sys/kernel/debug/notifier-error-inject/memory
	# echo -12 > actions/MEM_GOING_OFFLINE/error
	# echo offline > /sys/devices/system/memory/memoryXXX/state
	bash: echo: write error: Cannot allocate memory

powerpc pSeries reconfig notifier error injection module
--------------------------------------------------------
This feature is controlled through debugfs interface

  /sys/kernel/debug/notifier-error-inject/pSeries-reconfig/actions/<notifier event>/error

Possible pSeries reconfig notifier events to be failed are:

 * PSERIES_RECONFIG_ADD
 * PSERIES_RECONFIG_REMOVE
 * PSERIES_DRCONF_MEM_ADD
 * PSERIES_DRCONF_MEM_REMOVE

Netdevice notifier error injection module
----------------------------------------------
This feature is controlled through debugfs interface

  /sys/kernel/debug/notifier-error-inject/netdev/actions/<notifier event>/error

Netdevice notifier events which can be failed are:

 * NETDEV_REGISTER
 * NETDEV_CHANGEMTU
 * NETDEV_CHANGENAME
 * NETDEV_PRE_UP
 * NETDEV_PRE_TYPE_CHANGE
 * NETDEV_POST_INIT
 * NETDEV_PRECHANGEMTU
 * NETDEV_PRECHANGEUPPER
 * NETDEV_CHANGEUPPER

Example: Inject netdevice mtu change error (-22 == -EINVAL)::

	# cd /sys/kernel/debug/notifier-error-inject/netdev
	# echo -22 > actions/NETDEV_CHANGEMTU/error
	# ip link set eth0 mtu 1024
	RTNETLINK answers: Invalid argument

For more usage examples
-----------------------
There are tools/testing/selftests using the notifier error injection features
for CPU and memory notifiers.

 * tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh
 * tools/testing/selftests/memory-hotplug/mem-on-off-test.sh

These scripts first do simple online and offline tests and then do fault
injection tests if notifier error injection module is available.


code:
NVMe Fault Injection
====================
Linux's fault injection framework provides a systematic way to support
error injection via debugfs in the /sys/kernel/debug directory. When
enabled, the default NVME_SC_INVALID_OPCODE with no retry will be
injected into the nvme_try_complete_req. Users can change the default status
code and no retry flag via the debugfs. The list of Generic Command
Status can be found in include/linux/nvme.h

Following examples show how to inject an error into the nvme.

First, enable CONFIG_FAULT_INJECTION_DEBUG_FS kernel config,
recompile the kernel. After booting up the kernel, do the
following.

Example 1: Inject default status code with no retry
---------------------------------------------------

::

  mount /dev/nvme0n1 /mnt
  echo 1 > /sys/kernel/debug/nvme0n1/fault_inject/times
  echo 100 > /sys/kernel/debug/nvme0n1/fault_inject/probability
  cp a.file /mnt

Expected Result::

  cp: cannot stat ‘/mnt/a.file’: Input/output error

Message from dmesg::

  FAULT_INJECTION: forcing a failure.
  name fault_inject, interval 1, probability 100, space 0, times 1
  CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.15.0-rc8+ #2
  Hardware name: innotek GmbH VirtualBox/VirtualBox,
  BIOS VirtualBox 12/01/2006
  Call Trace:
    <IRQ>
    dump_stack+0x5c/0x7d
    should_fail+0x148/0x170
    nvme_should_fail+0x2f/0x50 [nvme_core]
    nvme_process_cq+0xe7/0x1d0 [nvme]
    nvme_irq+0x1e/0x40 [nvme]
    __handle_irq_event_percpu+0x3a/0x190
    handle_irq_event_percpu+0x30/0x70
    handle_irq_event+0x36/0x60
    handle_fasteoi_irq+0x78/0x120
    handle_irq+0xa7/0x130
    ? tick_irq_enter+0xa8/0xc0
    do_IRQ+0x43/0xc0
    common_interrupt+0xa2/0xa2
    </IRQ>
  RIP: 0010:native_safe_halt+0x2/0x10
  RSP: 0018:ffffffff82003e90 EFLAGS: 00000246 ORIG_RAX: ffffffffffffffdd
  RAX: ffffffff817a10c0 RBX: ffffffff82012480 RCX: 0000000000000000
  RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
  RBP: 0000000000000000 R08: 000000008e38ce64 R09: 0000000000000000
  R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff82012480
  R13: ffffffff82012480 R14: 0000000000000000 R15: 0000000000000000
    ? __sched_text_end+0x4/0x4
    default_idle+0x18/0xf0
    do_idle+0x150/0x1d0
    cpu_startup_entry+0x6f/0x80
    start_kernel+0x4c4/0x4e4
    ? set_init_arg+0x55/0x55
    secondary_startup_64+0xa5/0xb0
    print_req_error: I/O error, dev nvme0n1, sector 9240
  EXT4-fs error (device nvme0n1): ext4_find_entry:1436:
  inode #2: comm cp: reading directory lblock 0

Example 2: Inject default status code with retry
------------------------------------------------

::

  mount /dev/nvme0n1 /mnt
  echo 1 > /sys/kernel/debug/nvme0n1/fault_inject/times
  echo 100 > /sys/kernel/debug/nvme0n1/fault_inject/probability
  echo 1 > /sys/kernel/debug/nvme0n1/fault_inject/status
  echo 0 > /sys/kernel/debug/nvme0n1/fault_inject/dont_retry

  cp a.file /mnt

Expected Result::

  command success without error

Message from dmesg::

  FAULT_INJECTION: forcing a failure.
  name fault_inject, interval 1, probability 100, space 0, times 1
  CPU: 1 PID: 0 Comm: swapper/1 Not tainted 4.15.0-rc8+ #4
  Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
  Call Trace:
    <IRQ>
    dump_stack+0x5c/0x7d
    should_fail+0x148/0x170
    nvme_should_fail+0x30/0x60 [nvme_core]
    nvme_loop_queue_response+0x84/0x110 [nvme_loop]
    nvmet_req_complete+0x11/0x40 [nvmet]
    nvmet_bio_done+0x28/0x40 [nvmet]
    blk_update_request+0xb0/0x310
    blk_mq_end_request+0x18/0x60
    flush_smp_call_function_queue+0x3d/0xf0
    smp_call_function_single_interrupt+0x2c/0xc0
    call_function_single_interrupt+0xa2/0xb0
    </IRQ>
  RIP: 0010:native_safe_halt+0x2/0x10
  RSP: 0018:ffffc9000068bec0 EFLAGS: 00000246 ORIG_RAX: ffffffffffffff04
  RAX: ffffffff817a10c0 RBX: ffff88011a3c9680 RCX: 0000000000000000
  RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
  RBP: 0000000000000001 R08: 000000008e38c131 R09: 0000000000000000
  R10: 0000000000000000 R11: 0000000000000000 R12: ffff88011a3c9680
  R13: ffff88011a3c9680 R14: 0000000000000000 R15: 0000000000000000
    ? __sched_text_end+0x4/0x4
    default_idle+0x18/0xf0
    do_idle+0x150/0x1d0
    cpu_startup_entry+0x6f/0x80
    start_secondary+0x187/0x1e0
    secondary_startup_64+0xa5/0xb0

Example 3: Inject an error into the 10th admin command
------------------------------------------------------

::

  echo 100 > /sys/kernel/debug/nvme0/fault_inject/probability
  echo 10 > /sys/kernel/debug/nvme0/fault_inject/space
  echo 1 > /sys/kernel/debug/nvme0/fault_inject/times
  nvme reset /dev/nvme0

Expected Result::

  After NVMe controller reset, the reinitialization may or may not succeed.
  It depends on which admin command is actually forced to fail.

Message from dmesg::

  nvme nvme0: resetting controller
  FAULT_INJECTION: forcing a failure.
  name fault_inject, interval 1, probability 100, space 1, times 1
  CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.2.0-rc2+ #2
  Hardware name: MSI MS-7A45/B150M MORTAR ARCTIC (MS-7A45), BIOS 1.50 04/25/2017
  Call Trace:
   <IRQ>
   dump_stack+0x63/0x85
   should_fail+0x14a/0x170
   nvme_should_fail+0x38/0x80 [nvme_core]
   nvme_irq+0x129/0x280 [nvme]
   ? blk_mq_end_request+0xb3/0x120
   __handle_irq_event_percpu+0x84/0x1a0
   handle_irq_event_percpu+0x32/0x80
   handle_irq_event+0x3b/0x60
   handle_edge_irq+0x7f/0x1a0
   handle_irq+0x20/0x30
   do_IRQ+0x4e/0xe0
   common_interrupt+0xf/0xf
   </IRQ>
  RIP: 0010:cpuidle_enter_state+0xc5/0x460
  Code: ff e8 8f 5f 86 ff 80 7d c7 00 74 17 9c 58 0f 1f 44 00 00 f6 c4 02 0f 85 69 03 00 00 31 ff e8 62 aa 8c ff fb 66 0f 1f 44 00 00 <45> 85 ed 0f 88 37 03 00 00 4c 8b 45 d0 4c 2b 45 b8 48 ba cf f7 53
  RSP: 0018:ffffffff88c03dd0 EFLAGS: 00000246 ORIG_RAX: ffffffffffffffdc
  RAX: ffff9dac25a2ac80 RBX: ffffffff88d53760 RCX: 000000000000001f
  RDX: 0000000000000000 RSI: 000000002d958403 RDI: 0000000000000000
  RBP: ffffffff88c03e18 R08: fffffff75e35ffb7 R09: 00000a49a56c0b48
  R10: ffffffff88c03da0 R11: 0000000000001b0c R12: ffff9dac25a34d00
  R13: 0000000000000006 R14: 0000000000000006 R15: ffffffff88d53760
   cpuidle_enter+0x2e/0x40
   call_cpuidle+0x23/0x40
   do_idle+0x201/0x280
   cpu_startup_entry+0x1d/0x20
   rest_init+0xaa/0xb0
   arch_call_rest_init+0xe/0x1b
   start_kernel+0x51c/0x53b
   x86_64_start_reservations+0x24/0x26
   x86_64_start_kernel+0x74/0x77
   secondary_startup_64+0xa4/0xb0
  nvme nvme0: Could not set queue count (16385)
  nvme nvme0: IO queues not created


code:
.. SPDX-License-Identifier: GPL-2.0

============================================================
Provoking crashes with Linux Kernel Dump Test Module (LKDTM)
============================================================

The lkdtm module provides an interface to disrupt (and usually crash)
the kernel at predefined code locations to evaluate the reliability of
the kernel's exception handling and to test crash dumps obtained using
different dumping solutions. The module uses KPROBEs to instrument the
trigger location, but can also trigger the kernel directly without KPROBE
support via debugfs.

You can select the location of the trigger ("crash point name") and the
type of action ("crash point type") either through module arguments when
inserting the module, or through the debugfs interface.

Usage::

	insmod lkdtm.ko [recur_count={>0}] cpoint_name=<> cpoint_type=<>
			[cpoint_count={>0}]

recur_count
	Recursion level for the stack overflow test. By default this is
	dynamically calculated based on kernel configuration, with the
	goal of being just large enough to exhaust the kernel stack. The
	value can be seen at `/sys/module/lkdtm/parameters/recur_count`.

cpoint_name
	Where in the kernel to trigger the action. It can be
	one of INT_HARDWARE_ENTRY, INT_HW_IRQ_EN, INT_TASKLET_ENTRY,
	FS_DEVRW, MEM_SWAPOUT, TIMERADD, SCSI_QUEUE_RQ, or DIRECT.

cpoint_type
	Indicates the action to be taken on hitting the crash point.
	These are numerous, and best queried directly from debugfs. Some
	of the common ones are PANIC, BUG, EXCEPTION, LOOP, and OVERFLOW.
	See the contents of `/sys/kernel/debug/provoke-crash/DIRECT` for
	a complete list.

cpoint_count
	Indicates the number of times the crash point is to be hit
	before triggering the action. The default is 10 (except for
	DIRECT, which always fires immediately).

You can also induce failures by mounting debugfs and writing the type to
<debugfs>/provoke-crash/<crashpoint>. E.g.::

  mount -t debugfs debugfs /sys/kernel/debug
  echo EXCEPTION > /sys/kernel/debug/provoke-crash/INT_HARDWARE_ENTRY

The special file `DIRECT` will induce the action directly without KPROBE
instrumentation. This mode is the only one available when the module is
built for a kernel without KPROBEs support::

  # Instead of having a BUG kill your shell, have it kill "cat":
  cat <(echo WRITE_RO) >/sys/kernel/debug/provoke-crash/DIRECT


code:
===========================
The Frame Buffer Device API
===========================

Last revised: June 21, 2011

0. Introduction
---------------

This document describes the frame buffer API used by applications to interact
with frame buffer devices. In-kernel APIs between device drivers and the frame
buffer core are not described.

Due to a lack of documentation in the original frame buffer API, drivers
behaviours differ in subtle (and not so subtle) ways. This document describes
the recommended API implementation, but applications should be prepared to
deal with different behaviours.

1. Capabilities
---------------

Device and driver capabilities are reported in the fixed screen information
capabilities field::

  struct fb_fix_screeninfo {
	...
	__u16 capabilities;		/* see FB_CAP_*			*/
	...
  };

Application should use those capabilities to find out what features they can
expect from the device and driver.

- FB_CAP_FOURCC

The driver supports the four character code (FOURCC) based format setting API.
When supported, formats are configured using a FOURCC instead of manually
specifying color components layout.

2. Types and visuals
--------------------

Pixels are stored in memory in hardware-dependent formats. Applications need
to be aware of the pixel storage format in order to write image data to the
frame buffer memory in the format expected by the hardware.

Formats are described by frame buffer types and visuals. Some visuals require
additional information, which are stored in the variable screen information
bits_per_pixel, grayscale, red, green, blue and transp fields.

Visuals describe how color information is encoded and assembled to create
macropixels. Types describe how macropixels are stored in memory. The following
types and visuals are supported.

- FB_TYPE_PACKED_PIXELS

Macropixels are stored contiguously in a single plane. If the number of bits
per macropixel is not a multiple of 8, whether macropixels are padded to the
next multiple of 8 bits or packed together into bytes depends on the visual.

Padding at end of lines may be present and is then reported through the fixed
screen information line_length field.

- FB_TYPE_PLANES

Macropixels are split across multiple planes. The number of planes is equal to
the number of bits per macropixel, with plane i'th storing i'th bit from all
macropixels.

Planes are located contiguously in memory.

- FB_TYPE_INTERLEAVED_PLANES

Macropixels are split across multiple planes. The number of planes is equal to
the number of bits per macropixel, with plane i'th storing i'th bit from all
macropixels.

Planes are interleaved in memory. The interleave factor, defined as the
distance in bytes between the beginning of two consecutive interleaved blocks
belonging to different planes, is stored in the fixed screen information
type_aux field.

- FB_TYPE_FOURCC

Macropixels are stored in memory as described by the format FOURCC identifier
stored in the variable screen information grayscale field.

- FB_VISUAL_MONO01

Pixels are black or white and stored on a number of bits (typically one)
specified by the variable screen information bpp field.

Black pixels are represented by all bits set to 1 and white pixels by all bits
set to 0. When the number of bits per pixel is smaller than 8, several pixels
are packed together in a byte.

FB_VISUAL_MONO01 is currently used with FB_TYPE_PACKED_PIXELS only.

- FB_VISUAL_MONO10

Pixels are black or white and stored on a number of bits (typically one)
specified by the variable screen information bpp field.

Black pixels are represented by all bits set to 0 and white pixels by all bits
set to 1. When the number of bits per pixel is smaller than 8, several pixels
are packed together in a byte.

FB_VISUAL_MONO01 is currently used with FB_TYPE_PACKED_PIXELS only.

- FB_VISUAL_TRUECOLOR

Pixels are broken into red, green and blue components, and each component
indexes a read-only lookup table for the corresponding value. Lookup tables
are device-dependent, and provide linear or non-linear ramps.

Each component is stored in a macropixel according to the variable screen
information red, green, blue and transp fields.

- FB_VISUAL_PSEUDOCOLOR and FB_VISUAL_STATIC_PSEUDOCOLOR

Pixel values are encoded as indices into a colormap that stores red, green and
blue components. The colormap is read-only for FB_VISUAL_STATIC_PSEUDOCOLOR
and read-write for FB_VISUAL_PSEUDOCOLOR.

Each pixel value is stored in the number of bits reported by the variable
screen information bits_per_pixel field.

- FB_VISUAL_DIRECTCOLOR

Pixels are broken into red, green and blue components, and each component
indexes a programmable lookup table for the corresponding value.

Each component is stored in a macropixel according to the variable screen
information red, green, blue and transp fields.

- FB_VISUAL_FOURCC

Pixels are encoded and  interpreted as described by the format FOURCC
identifier stored in the variable screen information grayscale field.

3. Screen information
---------------------

Screen information are queried by applications using the FBIOGET_FSCREENINFO
and FBIOGET_VSCREENINFO ioctls. Those ioctls take a pointer to a
fb_fix_screeninfo and fb_var_screeninfo structure respectively.

struct fb_fix_screeninfo stores device independent unchangeable information
about the frame buffer device and the current format. Those information can't
be directly modified by applications, but can be changed by the driver when an
application modifies the format::

  struct fb_fix_screeninfo {
	char id[16];			/* identification string eg "TT Builtin" */
	unsigned long smem_start;	/* Start of frame buffer mem */
					/* (physical address) */
	__u32 smem_len;			/* Length of frame buffer mem */
	__u32 type;			/* see FB_TYPE_*		*/
	__u32 type_aux;			/* Interleave for interleaved Planes */
	__u32 visual;			/* see FB_VISUAL_*		*/
	__u16 xpanstep;			/* zero if no hardware panning  */
	__u16 ypanstep;			/* zero if no hardware panning  */
	__u16 ywrapstep;		/* zero if no hardware ywrap    */
	__u32 line_length;		/* length of a line in bytes    */
	unsigned long mmio_start;	/* Start of Memory Mapped I/O   */
					/* (physical address) */
	__u32 mmio_len;			/* Length of Memory Mapped I/O  */
	__u32 accel;			/* Indicate to driver which	*/
					/*  specific chip/card we have	*/
	__u16 capabilities;		/* see FB_CAP_*			*/
	__u16 reserved[2];		/* Reserved for future compatibility */
  };

struct fb_var_screeninfo stores device independent changeable information
about a frame buffer device, its current format and video mode, as well as
other miscellaneous parameters::

  struct fb_var_screeninfo {
	__u32 xres;			/* visible resolution		*/
	__u32 yres;
	__u32 xres_virtual;		/* virtual resolution		*/
	__u32 yres_virtual;
	__u32 xoffset;			/* offset from virtual to visible */
	__u32 yoffset;			/* resolution			*/

	__u32 bits_per_pixel;		/* guess what			*/
	__u32 grayscale;		/* 0 = color, 1 = grayscale,	*/
					/* >1 = FOURCC			*/
	struct fb_bitfield red;		/* bitfield in fb mem if true color, */
	struct fb_bitfield green;	/* else only length is significant */
	struct fb_bitfield blue;
	struct fb_bitfield transp;	/* transparency			*/

	__u32 nonstd;			/* != 0 Non standard pixel format */

	__u32 activate;			/* see FB_ACTIVATE_*		*/

	__u32 height;			/* height of picture in mm    */
	__u32 width;			/* width of picture in mm     */

	__u32 accel_flags;		/* (OBSOLETE) see fb_info.flags */

	/* Timing: All values in pixclocks, except pixclock (of course) */
	__u32 pixclock;			/* pixel clock in ps (pico seconds) */
	__u32 left_margin;		/* time from sync to picture	*/
	__u32 right_margin;		/* time from picture to sync	*/
	__u32 upper_margin;		/* time from sync to picture	*/
	__u32 lower_margin;
	__u32 hsync_len;		/* length of horizontal sync	*/
	__u32 vsync_len;		/* length of vertical sync	*/
	__u32 sync;			/* see FB_SYNC_*		*/
	__u32 vmode;			/* see FB_VMODE_*		*/
	__u32 rotate;			/* angle we rotate counter clockwise */
	__u32 colorspace;		/* colorspace for FOURCC-based modes */
	__u32 reserved[4];		/* Reserved for future compatibility */
  };

To modify variable information, applications call the FBIOPUT_VSCREENINFO
ioctl with a pointer to a fb_var_screeninfo structure. If the call is
successful, the driver will update the fixed screen information accordingly.

Instead of filling the complete fb_var_screeninfo structure manually,
applications should call the FBIOGET_VSCREENINFO ioctl and modify only the
fields they care about.

4. Format configuration
-----------------------

Frame buffer devices offer two ways to configure the frame buffer format: the
legacy API and the FOURCC-based API.

The legacy API has been the only frame buffer format configuration API for a
long time and is thus widely used by application. It is the recommended API
for applications when using RGB and grayscale formats, as well as legacy
non-standard formats.

To select a format, applications set the fb_var_screeninfo bits_per_pixel field
to the desired frame buffer depth. Values up to 8 will usually map to
monochrome, grayscale or pseudocolor visuals, although this is not required.

- For grayscale formats, applications set the grayscale field to one. The red,
  blue, green and transp fields must be set to 0 by applications and ignored by
  drivers. Drivers must fill the red, blue and green offsets to 0 and lengths
  to the bits_per_pixel value.

- For pseudocolor formats, applications set the grayscale field to zero. The
  red, blue, green and transp fields must be set to 0 by applications and
  ignored by drivers. Drivers must fill the red, blue and green offsets to 0
  and lengths to the bits_per_pixel value.

- For truecolor and directcolor formats, applications set the grayscale field
  to zero, and the red, blue, green and transp fields to describe the layout of
  color components in memory::

    struct fb_bitfield {
	__u32 offset;			/* beginning of bitfield	*/
	__u32 length;			/* length of bitfield		*/
	__u32 msb_right;		/* != 0 : Most significant bit is */
					/* right */
    };

  Pixel values are bits_per_pixel wide and are split in non-overlapping red,
  green, blue and alpha (transparency) components. Location and size of each
  component in the pixel value are described by the fb_bitfield offset and
  length fields. Offset are computed from the right.

  Pixels are always stored in an integer number of bytes. If the number of
  bits per pixel is not a multiple of 8, pixel values are padded to the next
  multiple of 8 bits.

Upon successful format configuration, drivers update the fb_fix_screeninfo
type, visual and line_length fields depending on the selected format.

The FOURCC-based API replaces format descriptions by four character codes
(FOURCC). FOURCCs are abstract identifiers that uniquely define a format
without explicitly describing it. This is the only API that supports YUV
formats. Drivers are also encouraged to implement the FOURCC-based API for RGB
and grayscale formats.

Drivers that support the FOURCC-based API report this capability by setting
the FB_CAP_FOURCC bit in the fb_fix_screeninfo capabilities field.

FOURCC definitions are located in the linux/videodev2.h header. However, and
despite starting with the V4L2_PIX_FMT_prefix, they are not restricted to V4L2
and don't require usage of the V4L2 subsystem. FOURCC documentation is
available in Documentation/userspace-api/media/v4l/pixfmt.rst.

To select a format, applications set the grayscale field to the desired FOURCC.
For YUV formats, they should also select the appropriate colorspace by setting
the colorspace field to one of the colorspaces listed in linux/videodev2.h and
documented in Documentation/userspace-api/media/v4l/colorspaces.rst.

The red, green, blue and transp fields are not used with the FOURCC-based API.
For forward compatibility reasons applications must zero those fields, and
drivers must ignore them. Values other than 0 may get a meaning in future
extensions.

Upon successful format configuration, drivers update the fb_fix_screeninfo
type, visual and line_length fields depending on the selected format. The type
and visual fields are set to FB_TYPE_FOURCC and FB_VISUAL_FOURCC respectively.


code:
========================================
arkfb - fbdev driver for ARK Logic chips
========================================

Supported Hardware
==================

	ARK 2000PV chip
	ICS 5342 ramdac

	- only BIOS initialized VGA devices supported
	- probably not working on big endian

Supported Features
==================

	*  4 bpp pseudocolor modes (with 18bit palette, two variants)
	*  8 bpp pseudocolor mode (with 18bit palette)
	* 16 bpp truecolor modes (RGB 555 and RGB 565)
	* 24 bpp truecolor mode (RGB 888)
	* 32 bpp truecolor mode (RGB 888)
	* text mode (activated by bpp = 0)
	* doublescan mode variant (not available in text mode)
	* panning in both directions
	* suspend/resume support

Text mode is supported even in higher resolutions, but there is limitation to
lower pixclocks (i got maximum about 70 MHz, it is dependent on specific
hardware). This limitation is not enforced by driver. Text mode supports 8bit
wide fonts only (hardware limitation) and 16bit tall fonts (driver
limitation). Unfortunately character attributes (like color) in text mode are
broken for unknown reason, so its usefulness is limited.

There are two 4 bpp modes. First mode (selected if nonstd == 0) is mode with
packed pixels, high nibble first. Second mode (selected if nonstd == 1) is mode
with interleaved planes (1 byte interleave), MSB first. Both modes support
8bit wide fonts only (driver limitation).

Suspend/resume works on systems that initialize video card during resume and
if device is active (for example used by fbcon).

Missing Features
================
(alias TODO list)

	* secondary (not initialized by BIOS) device support
	* big endian support
	* DPMS support
	* MMIO support
	* interlaced mode variant
	* support for fontwidths != 8 in 4 bpp modes
	* support for fontheight != 16 in text mode
	* hardware cursor
	* vsync synchronization
	* feature connector support
	* acceleration support (8514-like 2D)

Known bugs
==========

	* character attributes (and cursor) in text mode are broken

--
Ondrej Zajicek <santiago@crfreenet.org>


code:
=================
What is aty128fb?
=================

.. [This file is cloned from VesaFB/matroxfb]

This is a driver for a graphic framebuffer for ATI Rage128 based devices
on Intel and PPC boxes.

Advantages:

 * It provides a nice large console (128 cols + 48 lines with 1024x768)
   without using tiny, unreadable fonts.
 * You can run XF68_FBDev on top of /dev/fb0
 * Most important: boot logo :-)

Disadvantages:

 * graphic mode is slower than text mode... but you should not notice
   if you use same resolution as you used in textmode.
 * still experimental.

How to use it?
==============

Switching modes is done using the  video=aty128fb:<resolution>... modedb
boot parameter or using `fbset` program.

See Documentation/fb/modedb.rst for more information on modedb
resolutions.

You should compile in both vgacon (to boot if you remove your Rage128 from
box) and aty128fb (for graphics mode). You should not compile-in vesafb
unless you have primary display on non-Rage128 VBE2.0 device (see
Documentation/fb/vesafb.rst for details).

X11
===

XF68_FBDev should generally work fine, but it is non-accelerated. As of
this document, 8 and 32bpp works fine.  There have been palette issues
when switching from X to console and back to X.  You will have to restart
X to fix this.

Configuration
=============

You can pass kernel command line options to vesafb with
`video=aty128fb:option1,option2:value2,option3` (multiple options should
be separated by comma, values are separated from options by `:`).
Accepted options:

========= =======================================================
noaccel   do not use acceleration engine. It is default.
accel     use acceleration engine. Not finished.
vmode:x   chooses PowerMacintosh video mode <x>. Deprecated.
cmode:x   chooses PowerMacintosh colour mode <x>. Deprecated.
<XxX@X>   selects startup videomode. See modedb.txt for detailed
	  explanation. Default is 640x480x8bpp.
========= =======================================================

Limitations
===========

There are known and unknown bugs, features and misfeatures.
Currently there are following known bugs:

 - This driver is still experimental and is not finished.  Too many
   bugs/errata to list here.

Brad Douglas <brad@neruo.com>


code:
============================================
Framebuffer driver for Cirrus Logic chipsets
============================================

Copyright 1999 Jeff Garzik <jgarzik@pobox.com>

.. just a little something to get people going; contributors welcome!

Chip families supported:
	- SD64
	- Piccolo
	- Picasso
	- Spectrum
	- Alpine (GD-543x/4x)
	- Picasso4 (GD-5446)
	- GD-5480
	- Laguna (GD-546x)

Bus's supported:
	- PCI
	- Zorro

Architectures supported:
	- i386
	- Alpha
	- PPC (Motorola Powerstack)
	- m68k (Amiga)

Default video modes
-------------------
At the moment, there are two kernel command line arguments supported:

- mode:640x480
- mode:800x600
- mode:1024x768

Full support for startup video modes (modedb) will be integrated soon.

Version 1.9.9.1
---------------
* Fix memory detection for 512kB case
* 800x600 mode
* Fixed timings
* Hint for AXP: Use -accel false -vyres -1 when changing resolution

Version 1.9.4.4
---------------
* Preliminary Laguna support
* Overhaul color register routines.
* Associated with the above, console colors are now obtained from a LUT
  called 'palette' instead of from the VGA registers.  This code was
  modelled after that in atyfb and matroxfb.
* Code cleanup, add comments.
* Overhaul SR07 handling.
* Bug fixes.

Version 1.9.4.3
---------------
* Correctly set default startup video mode.
* Do not override ram size setting.  Define
  CLGEN_USE_HARDCODED_RAM_SETTINGS if you _do_ want to override the RAM
  setting.
* Compile fixes related to new 2.3.x IORESOURCE_IO[PORT] symbol changes.
* Use new 2.3.x resource allocation.
* Some code cleanup.

Version 1.9.4.2
---------------
* Casting fixes.
* Assertions no longer cause an oops on purpose.
* Bug fixes.

Version 1.9.4.1
---------------
* Add compatibility support.  Now requires a 2.1.x, 2.2.x or 2.3.x kernel.

Version 1.9.4
-------------
* Several enhancements, smaller memory footprint, a few bugfixes.
* Requires kernel 2.3.14-pre1 or later.

Version 1.9.3
-------------
* Bundled with kernel 2.3.14-pre1 or later.


code:
==========================
Understanding fbdev's cmap
==========================

These notes explain how X's dix layer uses fbdev's cmap structures.

-  example of relevant structures in fbdev as used for a 3-bit grayscale cmap::

    struct fb_var_screeninfo {
	    .bits_per_pixel = 8,
	    .grayscale      = 1,
	    .red =          { 4, 3, 0 },
	    .green =        { 0, 0, 0 },
	    .blue =         { 0, 0, 0 },
    }
    struct fb_fix_screeninfo {
	    .visual =       FB_VISUAL_STATIC_PSEUDOCOLOR,
    }
    for (i = 0; i < 8; i++)
	info->cmap.red[i] = (((2*i)+1)*(0xFFFF))/16;
    memcpy(info->cmap.green, info->cmap.red, sizeof(u16)*8);
    memcpy(info->cmap.blue, info->cmap.red, sizeof(u16)*8);

-  X11 apps do something like the following when trying to use grayscale::

    for (i=0; i < 8; i++) {
	char colorspec[64];
	memset(colorspec,0,64);
	sprintf(colorspec, "rgb:%x/%x/%x", i*36,i*36,i*36);
	if (!XParseColor(outputDisplay, testColormap, colorspec, &wantedColor))
		printf("Can't get color %s\n",colorspec);
	XAllocColor(outputDisplay, testColormap, &wantedColor);
	grays[i] = wantedColor;
    }

There's also named equivalents like gray1..x provided you have an rgb.txt.

Somewhere in X's callchain, this results in a call to X code that handles the
colormap. For example, Xfbdev hits the following:

xc-011010/programs/Xserver/dix/colormap.c::

  FindBestPixel(pentFirst, size, prgb, channel)

  dr = (long) pent->co.local.red - prgb->red;
  dg = (long) pent->co.local.green - prgb->green;
  db = (long) pent->co.local.blue - prgb->blue;
  sq = dr * dr;
  UnsignedToBigNum (sq, &sum);
  BigNumAdd (&sum, &temp, &sum);

co.local.red are entries that were brought in through FBIOGETCMAP which come
directly from the info->cmap.red that was listed above. The prgb is the rgb
that the app wants to match to. The above code is doing what looks like a least
squares matching function. That's why the cmap entries can't be set to the left
hand side boundaries of a color range.


code:
===========
Deferred IO
===========

Deferred IO is a way to delay and repurpose IO. It uses host memory as a
buffer and the MMU pagefault as a pretrigger for when to perform the device
IO. The following example may be a useful explanation of how one such setup
works:

- userspace app like Xfbdev mmaps framebuffer
- deferred IO and driver sets up fault and page_mkwrite handlers
- userspace app tries to write to mmaped vaddress
- we get pagefault and reach fault handler
- fault handler finds and returns physical page
- we get page_mkwrite where we add this page to a list
- schedule a workqueue task to be run after a delay
- app continues writing to that page with no additional cost. this is
  the key benefit.
- the workqueue task comes in and mkcleans the pages on the list, then
  completes the work associated with updating the framebuffer. this is
  the real work talking to the device.
- app tries to write to the address (that has now been mkcleaned)
- get pagefault and the above sequence occurs again

As can be seen from above, one benefit is roughly to allow bursty framebuffer
writes to occur at minimum cost. Then after some time when hopefully things
have gone quiet, we go and really update the framebuffer which would be
a relatively more expensive operation.

For some types of nonvolatile high latency displays, the desired image is
the final image rather than the intermediate stages which is why it's okay
to not update for each write that is occurring.

It may be the case that this is useful in other scenarios as well. Paul Mundt
has mentioned a case where it is beneficial to use the page count to decide
whether to coalesce and issue SG DMA or to do memory bursts.

Another one may be if one has a device framebuffer that is in an usual format,
say diagonally shifting RGB, this may then be a mechanism for you to allow
apps to pretend to have a normal framebuffer but reswizzle for the device
framebuffer at vsync time based on the touched pagelist.

How to use it: (for applications)
---------------------------------
No changes needed. mmap the framebuffer like normal and just use it.

How to use it: (for fbdev drivers)
----------------------------------
The following example may be helpful.

1. Setup your structure. Eg::

	static struct fb_deferred_io hecubafb_defio = {
		.delay		= HZ,
		.deferred_io	= hecubafb_dpy_deferred_io,
	};

The delay is the minimum delay between when the page_mkwrite trigger occurs
and when the deferred_io callback is called. The deferred_io callback is
explained below.

2. Setup your deferred IO callback. Eg::

	static void hecubafb_dpy_deferred_io(struct fb_info *info,
					     struct list_head *pagelist)

The deferred_io callback is where you would perform all your IO to the display
device. You receive the pagelist which is the list of pages that were written
to during the delay. You must not modify this list. This callback is called
from a workqueue.

3. Call init::

	info->fbdefio = &hecubafb_defio;
	fb_deferred_io_init(info);

4. Call cleanup::

	fb_deferred_io_cleanup(info);


code:
==============
What is efifb?
==============

This is a generic EFI platform driver for systems with UEFI firmware. The
system must be booted via the EFI stub for this to be usable. efifb supports
both firmware with Graphics Output Protocol (GOP) displays as well as older
systems with only Universal Graphics Adapter (UGA) displays.

Supported Hardware
==================

- iMac 17"/20"
- Macbook
- Macbook Pro 15"/17"
- MacMini
- ARM/ARM64/X86 systems with UEFI firmware

How to use it?
==============

For UGA displays, efifb does not have any kind of autodetection of your
machine.

You have to add the following kernel parameters in your elilo.conf::

	Macbook :
		video=efifb:macbook
	MacMini :
		video=efifb:mini
	Macbook Pro 15", iMac 17" :
		video=efifb:i17
	Macbook Pro 17", iMac 20" :
		video=efifb:i20

For GOP displays, efifb can autodetect the display's resolution and framebuffer
address, so these should work out of the box without any special parameters.

Accepted options:

======= ===========================================================
nowc	Don't map the framebuffer write combined. This can be used
	to workaround side-effects and slowdowns on other CPU cores
	when large amounts of console data are written.
======= ===========================================================

Options for GOP displays:

mode=n
        The EFI stub will set the mode of the display to mode number n if
        possible.

<xres>x<yres>[-(rgb|bgr|<bpp>)]
        The EFI stub will search for a display mode that matches the specified
        horizontal and vertical resolution, and optionally bit depth, and set
        the mode of the display to it if one is found. The bit depth can either
        "rgb" or "bgr" to match specifically those pixel formats, or a number
        for a mode with matching bits per pixel.

auto
        The EFI stub will choose the mode with the highest resolution (product
        of horizontal and vertical resolution). If there are multiple modes
        with the highest resolution, it will choose one with the highest color
        depth.

list
        The EFI stub will list out all the display modes that are available. A
        specific mode can then be chosen using one of the above options for the
        next boot.

Edgar Hucek <gimli@dark-green.com>


code:
================================
Driver for EP93xx LCD controller
================================

The EP93xx LCD controller can drive both standard desktop monitors and
embedded LCD displays. If you have a standard desktop monitor then you
can use the standard Linux video mode database. In your board file::

	static struct ep93xxfb_mach_info some_board_fb_info = {
		.num_modes	= EP93XXFB_USE_MODEDB,
		.bpp		= 16,
	};

If you have an embedded LCD display then you need to define a video
mode for it as follows::

	static struct fb_videomode some_board_video_modes[] = {
		{
			.name		= "some_lcd_name",
			/* Pixel clock, porches, etc */
		},
	};

Note that the pixel clock value is in pico-seconds. You can use the
KHZ2PICOS macro to convert the pixel clock value. Most other values
are in pixel clocks. See Documentation/fb/framebuffer.rst for further
details.

The ep93xxfb_mach_info structure for your board should look like the
following::

	static struct ep93xxfb_mach_info some_board_fb_info = {
		.num_modes	= ARRAY_SIZE(some_board_video_modes),
		.modes		= some_board_video_modes,
		.default_mode	= &some_board_video_modes[0],
		.bpp		= 16,
	};

The framebuffer device can be registered by adding the following to
your board initialisation function::

	ep93xx_register_fb(&some_board_fb_info);

=====================
Video Attribute Flags
=====================

The ep93xxfb_mach_info structure has a flags field which can be used
to configure the controller. The video attributes flags are fully
documented in section 7 of the EP93xx users' guide. The following
flags are available:

=============================== ==========================================
EP93XXFB_PCLK_FALLING		Clock data on the falling edge of the
				pixel clock. The default is to clock
				data on the rising edge.

EP93XXFB_SYNC_BLANK_HIGH	Blank signal is active high. By
				default the blank signal is active low.

EP93XXFB_SYNC_HORIZ_HIGH	Horizontal sync is active high. By
				default the horizontal sync is active low.

EP93XXFB_SYNC_VERT_HIGH		Vertical sync is active high. By
				default the vertical sync is active high.
=============================== ==========================================

The physical address of the framebuffer can be controlled using the
following flags:

=============================== ======================================
EP93XXFB_USE_SDCSN0		Use SDCSn[0] for the framebuffer. This
				is the default setting.

EP93XXFB_USE_SDCSN1		Use SDCSn[1] for the framebuffer.

EP93XXFB_USE_SDCSN2		Use SDCSn[2] for the framebuffer.

EP93XXFB_USE_SDCSN3		Use SDCSn[3] for the framebuffer.
=============================== ======================================

==================
Platform callbacks
==================

The EP93xx framebuffer driver supports three optional platform
callbacks: setup, teardown and blank. The setup and teardown functions
are called when the framebuffer driver is installed and removed
respectively. The blank function is called whenever the display is
blanked or unblanked.

The setup and teardown devices pass the platform_device structure as
an argument. The fb_info and ep93xxfb_mach_info structures can be
obtained as follows::

	static int some_board_fb_setup(struct platform_device *pdev)
	{
		struct ep93xxfb_mach_info *mach_info = pdev->dev.platform_data;
		struct fb_info *fb_info = platform_get_drvdata(pdev);

		/* Board specific framebuffer setup */
	}

======================
Setting the video mode
======================

The video mode is set using the following syntax::

	video=XRESxYRES[-BPP][@REFRESH]

If the EP93xx video driver is built-in then the video mode is set on
the Linux kernel command line, for example::

	video=ep93xx-fb:800x600-16@60

If the EP93xx video driver is built as a module then the video mode is
set when the module is installed::

	modprobe ep93xx-fb video=320x240

==============
Screenpage bug
==============

At least on the EP9315 there is a silicon bug which causes bit 27 of
the VIDSCRNPAGE (framebuffer physical offset) to be tied low. There is
an unofficial errata for this bug at::

	https://marc.info/?l=linux-arm-kernel&m=110061245502000&w=2

By default the EP93xx framebuffer driver checks if the allocated physical
address has bit 27 set. If it does, then the memory is freed and an
error is returned. The check can be disabled by adding the following
option when loading the driver::

      ep93xx-fb.check_screenpage_bug=0

In some cases it may be possible to reconfigure your SDRAM layout to
avoid this bug. See section 13 of the EP93xx users' guide for details.


code:
=======================
The Framebuffer Console
=======================

The framebuffer console (fbcon), as its name implies, is a text
console running on top of the framebuffer device. It has the functionality of
any standard text console driver, such as the VGA console, with the added
features that can be attributed to the graphical nature of the framebuffer.

In the x86 architecture, the framebuffer console is optional, and
some even treat it as a toy. For other architectures, it is the only available
display device, text or graphical.

What are the features of fbcon?  The framebuffer console supports
high resolutions, varying font types, display rotation, primitive multihead,
etc. Theoretically, multi-colored fonts, blending, aliasing, and any feature
made available by the underlying graphics card are also possible.

A. Configuration
================

The framebuffer console can be enabled by using your favorite kernel
configuration tool.  It is under Device Drivers->Graphics Support->
Console display driver support->Framebuffer Console Support.
Select 'y' to compile support statically or 'm' for module support.  The
module will be fbcon.

In order for fbcon to activate, at least one framebuffer driver is
required, so choose from any of the numerous drivers available. For x86
systems, they almost universally have VGA cards, so vga16fb and vesafb will
always be available. However, using a chipset-specific driver will give you
more speed and features, such as the ability to change the video mode
dynamically.

To display the penguin logo, choose any logo available in Graphics
support->Bootup logo.

Also, you will need to select at least one compiled-in font, but if
you don't do anything, the kernel configuration tool will select one for you,
usually an 8x16 font.

GOTCHA: A common bug report is enabling the framebuffer without enabling the
framebuffer console.  Depending on the driver, you may get a blanked or
garbled display, but the system still boots to completion.  If you are
fortunate to have a driver that does not alter the graphics chip, then you
will still get a VGA console.

B. Loading
==========

Possible scenarios:

1. Driver and fbcon are compiled statically

	 Usually, fbcon will automatically take over your console. The notable
	 exception is vesafb.  It needs to be explicitly activated with the
	 vga= boot option parameter.

2. Driver is compiled statically, fbcon is compiled as a module

	 Depending on the driver, you either get a standard console, or a
	 garbled display, as mentioned above.  To get a framebuffer console,
	 do a 'modprobe fbcon'.

3. Driver is compiled as a module, fbcon is compiled statically

	 You get your standard console.  Once the driver is loaded with
	 'modprobe xxxfb', fbcon automatically takes over the console with
	 the possible exception of using the fbcon=map:n option. See below.

4. Driver and fbcon are compiled as a module.

	 You can load them in any order. Once both are loaded, fbcon will take
	 over the console.

C. Boot options

	 The framebuffer console has several, largely unknown, boot options
	 that can change its behavior.

1. fbcon=font:<name>

	Select the initial font to use. The value 'name' can be any of the
	compiled-in fonts: 10x18, 6x10, 6x8, 7x14, Acorn8x8, MINI4x6,
	PEARL8x8, ProFont6x11, SUN12x22, SUN8x16, TER16x32, VGA8x16, VGA8x8.

	Note, not all drivers can handle font with widths not divisible by 8,
	such as vga16fb.

2. fbcon=map:<0123>

	This is an interesting option. It tells which driver gets mapped to
	which console. The value '0123' is a sequence that gets repeated until
	the total length is 64 which is the number of consoles available. In
	the above example, it is expanded to 012301230123... and the mapping
	will be::

		tty | 1 2 3 4 5 6 7 8 9 ...
		fb  | 0 1 2 3 0 1 2 3 0 ...

		('cat /proc/fb' should tell you what the fb numbers are)

	One side effect that may be useful is using a map value that exceeds
	the number of loaded fb drivers. For example, if only one driver is
	available, fb0, adding fbcon=map:1 tells fbcon not to take over the
	console.

	Later on, when you want to map the console the to the framebuffer
	device, you can use the con2fbmap utility.

3. fbcon=vc:<n1>-<n2>

	This option tells fbcon to take over only a range of consoles as
	specified by the values 'n1' and 'n2'. The rest of the consoles
	outside the given range will still be controlled by the standard
	console driver.

	NOTE: For x86 machines, the standard console is the VGA console which
	is typically located on the same video card.  Thus, the consoles that
	are controlled by the VGA console will be garbled.

4. fbcon=rotate:<n>

	This option changes the orientation angle of the console display. The
	value 'n' accepts the following:

	    - 0 - normal orientation (0 degree)
	    - 1 - clockwise orientation (90 degrees)
	    - 2 - upside down orientation (180 degrees)
	    - 3 - counterclockwise orientation (270 degrees)

	The angle can be changed anytime afterwards by 'echoing' the same
	numbers to any one of the 2 attributes found in
	/sys/class/graphics/fbcon:

		- rotate     - rotate the display of the active console
		- rotate_all - rotate the display of all consoles

	Console rotation will only become available if Framebuffer Console
	Rotation support is compiled in your kernel.

	NOTE: This is purely console rotation.  Any other applications that
	use the framebuffer will remain at their 'normal' orientation.
	Actually, the underlying fb driver is totally ignorant of console
	rotation.

5. fbcon=margin:<color>

	This option specifies the color of the margins. The margins are the
	leftover area at the right and the bottom of the screen that are not
	used by text. By default, this area will be black. The 'color' value
	is an integer number that depends on the framebuffer driver being used.

6. fbcon=nodefer

	If the kernel is compiled with deferred fbcon takeover support, normally
	the framebuffer contents, left in place by the firmware/bootloader, will
	be preserved until there actually is some text is output to the console.
	This option causes fbcon to bind immediately to the fbdev device.

7. fbcon=logo-pos:<location>

	The only possible 'location' is 'center' (without quotes), and when
	given, the bootup logo is moved from the default top-left corner
	location to the center of the framebuffer. If more than one logo is
	displayed due to multiple CPUs, the collected line of logos is moved
	as a whole.

8. fbcon=logo-count:<n>

	The value 'n' overrides the number of bootup logos. 0 disables the
	logo, and -1 gives the default which is the number of online CPUs.

C. Attaching, Detaching and Unloading

Before going on to how to attach, detach and unload the framebuffer console, an
illustration of the dependencies may help.

The console layer, as with most subsystems, needs a driver that interfaces with
the hardware. Thus, in a VGA console::

	console ---> VGA driver ---> hardware.

Assuming the VGA driver can be unloaded, one must first unbind the VGA driver
from the console layer before unloading the driver.  The VGA driver cannot be
unloaded if it is still bound to the console layer. (See
Documentation/driver-api/console.rst for more information).

This is more complicated in the case of the framebuffer console (fbcon),
because fbcon is an intermediate layer between the console and the drivers::

	console ---> fbcon ---> fbdev drivers ---> hardware

The fbdev drivers cannot be unloaded if bound to fbcon, and fbcon cannot
be unloaded if it's bound to the console layer.

So to unload the fbdev drivers, one must first unbind fbcon from the console,
then unbind the fbdev drivers from fbcon.  Fortunately, unbinding fbcon from
the console layer will automatically unbind framebuffer drivers from
fbcon. Thus, there is no need to explicitly unbind the fbdev drivers from
fbcon.

So, how do we unbind fbcon from the console? Part of the answer is in
Documentation/driver-api/console.rst. To summarize:

Echo a value to the bind file that represents the framebuffer console
driver. So assuming vtcon1 represents fbcon, then::

  echo 1 > /sys/class/vtconsole/vtcon1/bind - attach framebuffer console to
					     console layer
  echo 0 > /sys/class/vtconsole/vtcon1/bind - detach framebuffer console from
					     console layer

If fbcon is detached from the console layer, your boot console driver (which is
usually VGA text mode) will take over.  A few drivers (rivafb and i810fb) will
restore VGA text mode for you.  With the rest, before detaching fbcon, you
must take a few additional steps to make sure that your VGA text mode is
restored properly. The following is one of the several methods that you can do:

1. Download or install vbetool.  This utility is included with most
   distributions nowadays, and is usually part of the suspend/resume tool.

2. In your kernel configuration, ensure that CONFIG_FRAMEBUFFER_CONSOLE is set
   to 'y' or 'm'. Enable one or more of your favorite framebuffer drivers.

3. Boot into text mode and as root run::

	vbetool vbestate save > <vga state file>

   The above command saves the register contents of your graphics
   hardware to <vga state file>.  You need to do this step only once as
   the state file can be reused.

4. If fbcon is compiled as a module, load fbcon by doing::

       modprobe fbcon

5. Now to detach fbcon::

       vbetool vbestate restore < <vga state file> && \
       echo 0 > /sys/class/vtconsole/vtcon1/bind

6. That's it, you're back to VGA mode. And if you compiled fbcon as a module,
   you can unload it by 'rmmod fbcon'.

7. To reattach fbcon::

       echo 1 > /sys/class/vtconsole/vtcon1/bind

8. Once fbcon is unbound, all drivers registered to the system will also
become unbound.  This means that fbcon and individual framebuffer drivers
can be unloaded or reloaded at will. Reloading the drivers or fbcon will
automatically bind the console, fbcon and the drivers together. Unloading
all the drivers without unloading fbcon will make it impossible for the
console to bind fbcon.

Notes for vesafb users:
=======================

Unfortunately, if your bootline includes a vga=xxx parameter that sets the
hardware in graphics mode, such as when loading vesafb, vgacon will not load.
Instead, vgacon will replace the default boot console with dummycon, and you
won't get any display after detaching fbcon. Your machine is still alive, so
you can reattach vesafb. However, to reattach vesafb, you need to do one of
the following:

Variation 1:

    a. Before detaching fbcon, do::

	vbetool vbemode save > <vesa state file> # do once for each vesafb mode,
						 # the file can be reused

    b. Detach fbcon as in step 5.

    c. Attach fbcon::

	vbetool vbestate restore < <vesa state file> && \
	echo 1 > /sys/class/vtconsole/vtcon1/bind

Variation 2:

    a. Before detaching fbcon, do::

	echo <ID> > /sys/class/tty/console/bind

	vbetool vbemode get

    b. Take note of the mode number

    b. Detach fbcon as in step 5.

    c. Attach fbcon::

	vbetool vbemode set <mode number> && \
	echo 1 > /sys/class/vtconsole/vtcon1/bind

Samples:
========

Here are 2 sample bash scripts that you can use to bind or unbind the
framebuffer console driver if you are on an X86 box::

  #!/bin/bash
  # Unbind fbcon

  # Change this to where your actual vgastate file is located
  # Or Use VGASTATE=$1 to indicate the state file at runtime
  VGASTATE=/tmp/vgastate

  # path to vbetool
  VBETOOL=/usr/local/bin

  for (( i = 0; i < 16; i++))
  do
    if test -x /sys/class/vtconsole/vtcon$i; then
	if [ `cat /sys/class/vtconsole/vtcon$i/name | grep -c "frame buffer"` \
	     = 1 ]; then
	    if test -x $VBETOOL/vbetool; then
	       echo Unbinding vtcon$i
	       $VBETOOL/vbetool vbestate restore < $VGASTATE
	       echo 0 > /sys/class/vtconsole/vtcon$i/bind
	    fi
	fi
    fi
  done

---------------------------------------------------------------------------

::

  #!/bin/bash
  # Bind fbcon

  for (( i = 0; i < 16; i++))
  do
    if test -x /sys/class/vtconsole/vtcon$i; then
	if [ `cat /sys/class/vtconsole/vtcon$i/name | grep -c "frame buffer"` \
	     = 1 ]; then
	  echo Unbinding vtcon$i
	  echo 1 > /sys/class/vtconsole/vtcon$i/bind
	fi
    fi
  done

Antonino Daplas <adaplas@pol.net>