Difference between revisions of "Developer Manual/Super IO"

From coreboot
Jump to navigation Jump to search
 
(24 intermediate revisions by 3 users not shown)
Line 5: Line 5:
[[Image:Ite it8705f.jpg|thumb|right|<small>ITE IT8705F Super&nbsp;I/O</small>]]
[[Image:Ite it8705f.jpg|thumb|right|<small>ITE IT8705F Super&nbsp;I/O</small>]]


= Super I/O bringup =


Adding support for a new Super I/O chip is usually not significantly hard once you have obtained the datasheet for your target chip. Herein we shall outline the steps usally taken for a bringup.
== Logical Devices (LDN) ==
 
Every Super I/O chip provides different kinds of functions to the computer, such as control over GPIOs, GAME port, MIDI port, fan controllers, infrared and more.
 
Each of these functions, inside a Super I/O, is split into its own logical device and everyone of these devices is identified by an hex number (starting from 0x0) called logical device number (LDN).
I.e. In some Super I/Os, like the IT8728F, 0x05 and 0x06 are the LDNs respectively for the keyboard and the mouse.
 
Check your chip's datasheet to find the complete list.
 
== Configuration registers ==
 
A Super I/O chip can be configured through the use of its configuration registers.
 
These registers can be divided into two classes:
* Super I/O control and configuration
* Logical Device control and configuration
 
The first class contains all the registers that have the same value no matter which LDN has been selected, a sort of "global" register.
An example of this class can be found in the LDN register (reg 0x7) which is used to select an LDN, the Super I/O ID register (reg 0x20) and the Revision ID register (reg 0x27) which contain respectively the ID and the revision number of your chip.
 
The second class includes all the registers that are relative to the LDN that has been previously selected.
Among these ones there is the Logical Device Control register (reg 0x30) which is used to enable or disable the functionality of that Logical Device, the I/O Address register (reg 0x60-0x61) which are used to access runtime registers, and others.
 
== Access by Index and Data ==
 
In order to access any configuration register you'll have to use two special registers:
* Index register (I/O port 0x2E or 0x4E, depending on the chip)
* Data register (I/O port 0x2F or 0x4F, obtained by adding 1 to the Index register)
 
The Index register is used to specify which of the configuration registers you want to access.
This is accomplished by writing a byte containing the desired register's number into the Index register.
 
The Data register is used to read or write a byte of data from/into the register pointed to by the Index register.
 
The next examples should clarify the configuration process.
 
  I.e. how to read the chip's index
 
  outb(0x20, index_reg); // Points the Index register to the ID register (reg 0x20)
  int id = inb(data_reg); // Reads the ID value from the Data register and stores it
 
  I.e. how to select a logical device
 
  outb(0x07, index_reg); // Points the Index register to the LDN register (0x07)
  outb(0x03, data_reg); // Selects the LDN 0x03
 
  I.e. how to enable a logical device (You have to first select a logical device)
 
  outb(0x30, index_reg); // Points the Index register to the logical device control register (0x30)
  outb(0x01, data_reg); // Turns on the first bit of the logical device control register
 
== Virtual Logical Device Number (vLDN) ==
 
Some Super I/O's use register 0x30 of one of the logical device numbers (LDN) to also enable other logical device's functions.
For example, in the case of the [http://media.digikey.com/pdf/Data%20Sheets/Nuvoton%20PDFs/W83627EHx_EG_EFc.pdf W83627EHF chip], register 0x30 of LDN 0x9 was used to enable multiple devices (GPIO2 = bit0, GPIO3 = bit1, GPIO4 = bit2 and GPIO5 = bit3). To overcome this issue a concept of virtual LDN has been [https://www.coreboot.org/pipermail/coreboot/2008-February/030912.html introduced].
 
Virtual LDN's can be used in Coreboot to uniquely map the enable bit position in register 0x30 of an LDN, this allows to use a general way to handle any bit enable operation required without special cases.
 
Originally, except in cases such as the W83627EHF's, to enable or disable an LDN's functionality you only had to just switch on or off bit0 of the register 0x30, however a virtual LDN is created as follows:
* Low [7:0] bits are used to describe the original LDN.
* High [10:8] bits select the position of the bit enable in the register 0x30.
 
Note: the bit positions are in hex.
 
I.e. W83627EHF chip
 
In order to enable the GPIO5 (bit3 of register 0x30) this is what the virtual LDN has to look like this:
 
  [0000 0011] [0000 1001] = 0x309
    ^^^^^^^^^  ^^^^^^^^^
        |          |
        |          +------- Original LDN
        |
        |
        +------- Position inside register 0x30
 
 
Note: if the virtual LDN is 0x7 it will handle bit0 of register 0x30.
 
= Super I/O bring-up =
 
Adding support for a new Super I/O chip is usually not significantly hard once you have obtained the datasheet for your target chip. Herein we shall outline the steps usually taken for a bring-up.


== Source layout ==
== Source layout ==
Line 24: Line 104:
== device.h, (e.g., w83627ehg.h) ==
== device.h, (e.g., w83627ehg.h) ==


The '''src/superio/''vendor''/''device'''''/''device.h'' header should contain the Super I/O supported Logical Device Numbers (LDN) (see below) and the early_serial enabling function prototype.
The '''src/superio/''vendor''/''device'''''/''device.h'' header should contain the Super I/O supported [[#Logical Device Numbers|Logical Device Numbers]] (LDN) and the early_serial enabling function prototype.


For example, for '''f71869ad.h''' we have:
For example, for '''f71869ad.h''' we have:
Line 95: Line 175:
   [...]
   [...]
   w83627ehg_enable_dev(SERIAL_DEV, TTYS0_BASE);
   w83627ehg_enable_dev(SERIAL_DEV, TTYS0_BASE);
  uart_init();
   console_init();
   console_init();


Line 104: Line 183:


  /*
  /*
   * io_info contains the mask 0x07f8. Given 16 register, each 8 bits wide of a
   * io_info contains the mask 0x07f8. Given 8 register, each 8 bits wide of a
   * logical device we need a mask of the following form:
   * logical device we need a mask of the following form:
   *
   *
Line 121: Line 200:
   */
   */


=== Virtual logical devices ===
A typical superio.c would look like this:
 
#include <arch/io.h>
#include <device/device.h>
#include <device/pnp.h>
#include <superio/conf_mode.h>
#include <console/console.h>
#include <stdlib.h>
#include "f71869ad.h"
static void f71869ad_init(device_t dev)
{
= dev->chip_info;
}
static struct device_operations ops = {
= pnp_read_resources,
= pnp_set_resources,
= pnp_enable_resources,
= pnp_alt_enable,
};
static struct pnp_info pnp_dev_info[] = {
};
static void enable_dev(device_t dev)
{
}
struct chip_operations superio_fintek_f71869ad_ops = {
};


Some Super I/Os use register 0x30 of one logical device number (LDN) for more than one function enable. For example, it can be used to enable some GPIOs, GAME, MIDI etc. To overcome this issue a concept of virtual LDN has been introduced. Virtual LDNs can be used in coreboot to map the enable bit position in register 0x30 to virtual LDN, which will just enable the functionality map to that bit.
== Additional resources ==


Original LDN always just switch on or off bit0 of register 0x30. Virtual LDN is created as follows. Low [7:0] bits are used to describe the original LDN. High [10:8] bits select the position of the bit enable in the register 0x30.
If you still have some problems these could come in handy:


If LDN is 0x7 it will handle bit0 of register 0x30. If the (virtual) LDN is 0x107 it will handle bit1 of same register etc.
* [https://www.usbid.com/datasheets/usbid/2000/2000-q3/pc87393_bios.pdf Porting a BIOS to the pc87393 chip]
* [http://pdf.datasheetcatalog.com/datasheet/nationalsemiconductor/PC87393.pdf pc87393 datasheet]
* [ftp://download.intel.com/support/motherboards/desktop/sb/pnpbiosspecificationv10a.pdf PNP 1.0a specification]

Latest revision as of 13:07, 3 March 2016