summaryrefslogtreecommitdiff
path: root/GraphicStackOverview.mdwn
diff options
context:
space:
mode:
authorJoe Rayhawk <jrayhawk@freedesktop.org>2013-05-13 18:25:07 -0700
committerJoe Rayhawk <jrayhawk@freedesktop.org>2013-05-13 18:25:07 -0700
commit90e80bb00190f350a4b8419bf71ad8e8a96a81d2 (patch)
treef27462e532760ae521fefdc29aff8b64c4e29871 /GraphicStackOverview.mdwn
parent40f6ce4deb371f995f3ad9351f5ffafb9487ae07 (diff)
moin2mdwn: convert page GraphicStackOverview
Diffstat (limited to 'GraphicStackOverview.mdwn')
-rw-r--r--GraphicStackOverview.mdwn73
1 files changed, 73 insertions, 0 deletions
diff --git a/GraphicStackOverview.mdwn b/GraphicStackOverview.mdwn
new file mode 100644
index 0000000..1e84b61
--- /dev/null
+++ b/GraphicStackOverview.mdwn
@@ -0,0 +1,73 @@
+
+Most of the time, when you want to help or contribute to a "libre" project, you are lost. This page will try to help new developers getting up to speed on nouveau development by overviewing some base concepts and giving some code and web pointers.
+
+
+### The Memory
+
+[[!wikipedia X86_architecture desc="x86 architecture"]] has 3 memory address spaces:
+
+* The [[!wikipedia Physical_address desc="physical memory address space"]] is used for communication with the [[!wikipedia Memory_controller desc="memory controller"]]. That's the one mainly used for driver development. You can access it with the `/dev/mem` device node.
+* The [[!wikipedia Virtual_address desc="virtual memory address space"]] is what a process sees. It's managed by [[!wikipedia Memory_management_unit desc="memory management unit"]] inside the [[!wikipedia Microprocessor desc="microprocessor"]].
+* The [[!wikipedia Memory-mapped_I/O desc="I/O (Input/Output) ports space"]]. It is an address space on its own, namely it does not have any connection with the 2 previous address spaces. It's used for VGA hardware programming.
+On [[!wikipedia X86_architecture desc="x86 architecture"]], the [[physical<->virtual(logical) memory mapping|http://www.bertolinux.com/kernel/english/KernelAnalysis-HOWTO-7.html#ss7.3]] is done using the [[!wikipedia Page_table desc="pagination"]] mechanism.
+
+
+### PCI (Peripheral Component Interconnect)
+
+Your are going to plug your graphic cards into [[!wikipedia Peripheral_Component_Interconnect desc="PCI"]] slots on your [[!wikipedia Motherboard desc="motherboard"]]. [[!wikipedia Peripheral_Component_Interconnect desc="PCI"]] specifications are not freely available to the public :( . But in our case, we will only want to have an overall understanding of the programming model. The programming entry point for this computer [[!wikipedia Bus_(computing) desc="bus"]] is the [[!wikipedia Peripheral_Component_Interconnect desc="PCI"]] [[!wikipedia PCI_Configuration_Space desc="configuration space"]]. It is accessed with the `0xCF8` and `0xCFC` I/O ports in the [[!wikipedia X86_architecture desc="x86 architecture"]] I/O ports address space. To be a bit more specific `0xCF8` is the address port, and the `0xCFC` the data port. Each [[!wikipedia Peripheral_Component_Interconnect desc="PCI"]] entity (minimal addressable unit on the [[!wikipedia Bus_(computing) desc="bus"]] like the byte in memory) has its own [[!wikipedia PCI_Configuration_Space desc="configuration space"]]. You can have a look at some code in the [[Linux|http://www.kernel.org]] kernel source code to have a deeper understanding. Check out <small>_linux_kernel_source_</small>`/arch/i386/pci/direct.c` source file. In the case of the [[XORG|http://www.x.org/]] server, you have a [[!wikipedia Peripheral_Component_Interconnect desc="PCI"]] programming module which write accesses `/dev/mem` (that's one of the reasons why the [[XORG|http://www.x.org/]] server must run with root privileges). Have a look at <small>_xorg-server_source_</small>`/hw/xfree86/os-support/bus/Pci.c` source file and <small>_xorg-server_source_</small>`/hw/xfree86/doc/devel/RAC.notes`. You can play with the [[!wikipedia Peripheral_Component_Interconnect" desc="PCI"]] system using the [[pciutils|http://mj.ucw.cz/pciutils.shtml]] or directly with the [[Linux|http://www.kernel.org/]] kernel sysfs (system file system) file in `/sys/bus/pci/devices`. Both methods will interpret the content of the [[!wikipedia PCI_Configuration_Space desc="configuration space"]]. An entity will have in its [[!wikipedia PCI_Configuration_Space desc="configuration space"]] 3 types of resources:
+
+* I/O memory. This is a chunk of physical memory which is decoded by the entity. Checkout the content of the `/proc/iomem`.
+* I/O ports. Those from the [[!wikipedia Memory-mapped_I/O desc="I/O ports space"]] that will be decoded by the entity. Checkout the content of the `/proc/ioports` file.
+* IRQs (Interrupt ReQuests). Checkout the content of the `/proc/irq` directory.
+The configuration of such resources is done using 2 systems:
+
+* [[!wikipedia Peripheral_Component_Interconnect desc="PCI"]] [[PNP|http://tldp.org/HOWTO/Plug-and-Play-HOWTO.html]] (Plug-aNd-Play) which is obsolete.
+* ACPI (Advanced Configuration and Power Interface) which is the current way to do it, see [[below|GraphicStackOverview]].
+[[!wikipedia Peripheral_Component_Interconnect" desc="PCI"]] programming using the [[XORG|http://www.x.org/]] server is ugly. It is a task which is meant to be done by the OS (Operating System) kernel.
+
+
+### AGP (Accelerated Graphic Port), PCI Express cards
+
+A graphic card plugged into an [[!wikipedia Accelerated_Graphics_Port desc="AGP"]] slot or a [[!wikipedia PCI_Express desc="PCI Express"]] slot will be seen by the system like a [[!wikipedia Peripheral_Component_Interconnect desc="PCI"]] device. <a name="ACPI"></a>
+
+
+### ACPI (Advanced Configuration and Power Interface)
+
+Today, computers are [[ACPI|http://en.wikipedia.org/wiki/Advanced_Configuration_and_Power_Interface]] capable. [[!wikipedia Advanced_Configuration_and_Power_Interface desc="ACPI"]] replaces [[!wikipedia Peripheral_Component_Interconnect desc="PCI"]] [[PNP|http://tldp.org/HOWTO/Plug-and-Play-HOWTO.html]] for of entity configuration and adds power management, multiprocessors sweet, and other things to the lot. Unlike [[!wikipedia Peripheral_Component_Interconnect desc="PCI"]], [[!wikipedia Advanced_Configuration_and_Power_Interface desc="ACPI"]] [[specification|http://www.acpi.info/]] is freely available. [[!wikipedia Advanced_Configuration_and_Power_Interface desc="ACPI"]] is memory table based: at computer boot time, the OS must find the RSDP (Root System Description Pointer) in physical memory. On [[!wikipedia X86_architecture desc="x86 architecture"]], it is a matter of finding the "RSD PTR" string in specific physical memory regions. Checkout the Intel Architecture - Personal Computer (IA-PC) section in the [[specification|http://www.acpi.info/]] and the `acpi_scan_rsdp` function in <small>_linux_kernel_source_</small>`/arch/i386/kernel/acpi/boot.c`.
+
+
+### XORG, DDX (Device Dependent X) and DIX (Device Independent X)
+
+* [[XORG|http://www.x.org/]] is the lot, the entire project, the reference implementation of the client libs and servers of the [[!wikipedia X_Window_System_protocols_and_architecture desc="X Window System"]]. You need to understand the [[!wikipedia X_Window_core_protocol desc="X Window core protocol"]]. Keep in mind that [[XORG|http://www.x.org/]] has more than one server like the DMX (Distributed Multihead X) server, the kdrive server or the famous XGL server.
+* DIX is the part of [[XORG|http://www.x.org/]] which deals with the clients, network transparency and software rendering. In the [[XORG|http://www.x.org/]] source package layout, it's almost everything except the <small>_xorg-server_source_</small>`/hw` directory. You will find the **`main`** function, in <small>_xorg-server_source_</small>`/dix/main.c` source file.
+* DDX is the part of [[XORG|http://www.x.org/]] dealing with the hardware (and with the OSes to a certain extend). There are several DDX in the <small>_xorg-server_source_</small>`/hw` directory of the [[XORG|http://www.x.org/]] source package: XGL, kdrive, xfree86 etc... The one we are interested in is of course the xfree86 one since nouveau is a set of hardware drivers for this DDX. Indeed, each DDX comes with its hardware drivers. Have a look in <small>_xorg-server_source_</small>`/hw/kdrive`, there you will find drivers for several cards for the kdrive X server.
+The assembly of the xfree86 DDX with the DIX part shape the famous [[XORG|http://www.x.org/]] server.
+
+
+### XORG server design
+
+One of the first things the [[XORG|http://www.x.org/]] server will do is to load the nouveau video driver module. The xfree86 DDX implements a dynamic module loading system which is just a wrapper around the [[libc|http://www.gnu.org/software/libc/libc.html]] dynamic loader. The dynamic loader is based on symbols, namely function entry points or data pointers which are resolved or not at runtime. To understand the document below, you must know what is a _server generation_. When you start the [[XORG|http://www.x.org/]] server, the first _server generation_ is generated. When the last client goes away, then a new _server generation_ will start. You will see in the DIX and DDX code that there is a significant difference between the first _server generation_ and subsequent _server generation_s because some operations are useless to be performed several times, for instance sockets creation. To understand the [[XORG|http://www.x.org/]] server design, read ******very****** carefully ******[[the xfree86 DDX DESIGN document|http://webcvs.freedesktop.org/xorg/xc/programs/Xserver/hw/xfree86/doc/DESIGN?view=markup]]******. [[!wikipedia X_Window_System_protocols_and_architecture desc="X Window System"]] model revolves around the _screen_ object, and the previous document states that one _screen_ is managed by one video driver only in the xfree86 DDX. Moreover don't forget that a _screen_ has a xfree86 DDX structure (`ScrnInfoRec` living for the entire server life) and DIX structure (`ScreenRec` living for only one server generation), both embedding some per _screen_ video driver private data. Of course, there is also [[in depth documentation|http://gitweb.freedesktop.org/?p=xorg/doc/xorg-docs.git;a=tree]].
+
+
+### Video mode setting and RandR (the X Resize, Rotate and Reflect Extension in short) 1.2 extension
+
+One of latest big improvements in [[XORG|http://www.x.org/]] is the [[RandR 1.2 extension|http://gitweb.freedesktop.org/?p=xorg/proto/randrproto.git;a=blob;h=345ef4eca0f58b7c98b45d51d114dbb4b6d09e02;hb=aada204b1fc9ba6461efad3fe6bd032ee98536e1;f=randrproto.txt]]. It's a system that allows fine grained control of video mode setting. The RandR model deals with outputs and CRTCs (Cathode Ray Tube Controllers). CRTC is a legacy name from the past when all display devices were Cathode Ray Tubes. Today, a CRTC can drive flat displays. Typical nvidia chips embed 2 CRTCs, and the cards which host those chips have typically a [[!wikipedia S-video desc="S-Video"]] (Separate Video) connector which outputs [[!wikipedia PAL desc="PAL"]] (Phase Alternating Line) or [[!wikipedia NTSC desc="NTSC"]] (National Television System(s) Committee) video signal, have a [[!wikipedia VGA_connector desc="VGA"]] (Video Graphics Array) connector which outputs a VGA signal, a [[!wikipedia Digital_Visual_Interface desc="DVI"]] (Digital Visual Interface) connector which outputs a VGA signal and/or a single/dual [[!wikipedia TMDS desc="TMDS"]] (Transition Minimized Differential Signaling) digital signal. On mobile editions of nvidia chips, you will have pins outputting [[!wikipedia Low_voltage_differential_signaling desc="LVDS"]] (Low Voltage Differential Signaling) in order to drive a LDFP (Local Digital Flat Panel). There is a [[GIT|http://git.or.cz]] [[RandR-1.2 branch|http://gitweb.freedesktop.org/?p=nouveau/xf86-video-nouveau.git;a=shortlog;h=randr-1.2]] for the nouveau video driver.
+
+
+### The nouveau xfree86 DDX video driver module
+
+If you read **properly** the ******[[the xfree86 DDX DESIGN document|http://webcvs.freedesktop.org/xorg/xc/programs/Xserver/hw/xfree86/doc/DESIGN?view=markup]]******, and in particular its latest section, you will look for the `nouveauModuleData` structure in <small>_xf86-video-nouveau_</small>`/src/nv_driver.c` source file from the nouveau xfree86 DDX video driver source package directory layout. This structure will tell you there is only a setup function for this driver called right after the module is loaded in the [[XORG|http://www.x.org/]] server address space, called `nouveauSetup` in <small>_xf86-video-nouveau_source_</small>`/src/nv_driver.c` source file. `nouveauSetup` will register the nouveau `DriverRec` structure that will points to the `NVIdentify`, `NVProbe` and `NVAvailableOptions` functions, still in <small>_xf86-video-nouveau_source_</small>`/src/nv_driver.c`. During the probe phase of the [[XORG|http://www.x.org/]] server done using the `NVProbe` function of the video driver module, driver hooks in the xfree86 DDX `ScrnInfoRec` will be filled in. Here come, `NVPreInit`, `NVScreenInit`, `NVSwitchMode`, `NVAdjustFrame`, `NVEnterVT`, `NVLeaveVT`, `NVFreeScreen`, `NVValidMode` driver functions.
+
+* `NVIdentify` from the `DriverRec` structure named `NV` prints information about the chipsets handled by the driver. In <small>_xf86-video-nouveau_source_</small>`/src/nv_driver.c` this function logs the chipsets families supported and in <small>_xf86-video-nv_source_</small>/src/nv_driver.c` this function logs all of the chipsets supported with their [[!wikipedia Peripheral_Component_Interconnect desc="PCI"]] ids (identifiers).
+* `NVAvailableOptions` from the `DriverRec` structure named `NV` provides the initialized `OptionInfoRec` structure which will describe the various configuration options for this driver. Yes, those options which can be set in the device section of the famous <small>_xorg.conf_</small> file. In <small>_xf86-video-nouveau_source_</small>`/src/nv_driver.c`, those options are statically defined in the `OptionInfoRec` structure named `NVOptions` in <small>_xf86-video-nouveau_source_</small>`/src/nv_const.h`. `NVAvailableOptions` from <small>_xf86-video-nv_source_</small>`/src/nv_driver.c` is the same, except that there is a special `OptionInfoRec` structure for the riva 128 chip the riva driver files (for chipset archaeologists) and the common `OptionInfoRec` structure lies into <small>_xf86-video-nouveau_source_</small>`/src/nv_driver.c`.
+* `NVProbe` looks for the supported chipsets on the [[!wikipedia Peripheral_Component_Interconnect desc="PCI"]] bus and match them with the enabled device sections from the X server configuration. If the PROBE_DETECT flag is passed to this probe function, only detection is performed, no [[!wikipedia Peripheral_Component_Interconnect desc="PCI"]] resources are claimed by the driver. There is a special detection for some _bridged_ [[!wikipedia Accelerated_Graphics_Port desc="AGP"]]/[[!wikipedia PCI_Express desc="PCI Express"]] chipsets. Those [[!wikipedia Accelerated_Graphics_Port desc="AGP"]] chipsets _bridged_ to [[!wikipedia PCI_Express desc="PCI Express"]] have special [[!wikipedia Peripheral_Component_Interconnect desc="PCI"]] ids. The real [[!wikipedia Peripheral_Component_Interconnect desc="PCI"]] ids of the chipset for programming purpose is stored in the chipset [[!wikipedia Peripheral_Component_Interconnect desc="PCI"]] [[!wikipedia Memory-mapped_I/O desc="mmio"]] (Memory Mapped Input Output). Indeed, this is an ugly hack.
+* `NVPreInit` is `NVProbe` on steroids. It will determine the amount of video ram, will validate video modes, etc... One thing the driver will do is to determine the chipset architecture from the ids calling `NVDetermineChipsetArch` (inline for the NV driver). It checks for 32 bpp (bits per pixel) support and that the color depth is 8,15,16 or 24 bits. It shows that there are at most 2 CRTCs. The NV driver supports Dual``Head which seems to be configured only through the xfree86 DDX vbe module and implies no hardware cursor and the following new event handling functions: `NVSwitchModeVBE`, `NVEnterVTVBE` and `NVLeaveVTVBE`. Locating the VRAM mapping base physical address implies to mask the [[!wikipedia Peripheral_Component_Interconnect desc="PCI"]] entity second memory base address with the 0xFF800000 value. Same thing for the MMIO registers base physical address (first [[!wikipedia Peripheral_Component_Interconnect desc="PCI"]] entity memory base address) with the 0xFFFFC000 value.
+
+#### EXA
+
+EXA is not an acronym. It is an [[!wikipedia Application_programming_interface desc="API"]] for [[XORG|http://www.x.org/]] acceleration. The xfree86 DDX is the only DDX to implement it. EXA acceleration is initialized (if enabled) each time a _screen_ is initialized (for instance at the start of a new _server generation_), hence checkout the `NVScreenInit` function in <small>_xf86-video-nouveau_source_</small>`/src/nv_driver.c`. In the case EXA is enabled in the configuration file, you will be routed to `NVExaInit` in <small>_xf86-video-nouveau_source_</small>`/src/nv_exa.c` source file. In this function, all the EXA hooks will be sent to the [[XORG|http://www.x.org/]] EXA module and initialized with the `exaDriverInit` EXA module function, namely: `NVDownloadFromScreen`, `NVUploadToScreen`, `NVExaPrepareCopy`, `NVExaCopy`, `NVExaDoneCopy`, `NVExaPrepareSolid`, `NVExaSolid`, `NVExaDoneSolid`, `NVCheckComposite`, `NVPrepareComposite`, `NVComposite`, `NVDoneComposite`, all those functions are in <small>_xf86-video-nouveau_source_</small>`/src/nv_exa.c`. More on EXA on [[freedesktop wiki|http://wiki.x.org/wiki/ExaStatus]] and in <small>_xorg-server_source_</small>`/hw/xfree86/doc/devel/exa-driver.txt`
+
+
+#### DRI (Direct Rendering Infrastructure) and its kernel counterpart, the DRM (Direct Rendering Manager)
+
+The [[!wikipedia Direct_Rendering_Infrastructure desc="DRI"]] and the [[!wikipedia Direct_Rendering_Manager desc="DRM"]] are the plumbing for programming the graphic card hardware. It is mainly used by [[mesa|http://www.mesa3d.org/]], the "libre" opengl implementation, but since the access to the hardware must be synchronized among all graphic card hardware clients, the xfree86 DDX video driver module has to cope with it since itself is such client. Then when EXA will want to perform accelerated operations, it will have to _DRI dialog_ with the hardware. You have a [[!wikipedia Direct_Rendering_Infrastructure desc="DRI"]] xfree86 DDX module in <small>_xorg-server_source_</small>`/hw/xf86/dri` for xfree86 DDX code which wants hardware access the [[!wikipedia Direct_Rendering_Infrastructure desc="DRI"]] way. This module and the related xfree86 DDX code will use the DRM user level interface library, [[libdrm|http://dri.freedesktop.org/libdrm/]]. In theory, future DRM evolution will allow us to get rid of the [[!wikipedia Peripheral_Component_Interconnect desc="PCI"]] programming code from [[XORG|http://www.x.org/]] server.