Difference between revisions of "Developer Manual/Super IO"

From coreboot
Jump to navigation Jump to search
 
(22 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) ==


=== Virtual 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.


Many Super I/O's use register 0x30 of one logical device number (LDN) for more than one function enable.
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).  
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.
I.e. In some Super I/Os, like the IT8728F, 0x05 and 0x06 are the LDNs respectively for the keyboard and the mouse.


Virtual LDN's 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.
Check your chip's datasheet to find the complete list.


Original LDN always just switch on or off bit0 of register 0x30, however a virtual LDN is created as follows.
== Configuration registers ==
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 LDN is 0x7 it will handle bit0 of register 0x30. If the (virtual) LDN is 0x107 it will handle bit1 of same register etc.


TODO: Improvements needed here for the layman.
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 37: 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 108: Line 175:
   [...]
   [...]
   w83627ehg_enable_dev(SERIAL_DEV, TTYS0_BASE);
   w83627ehg_enable_dev(SERIAL_DEV, TTYS0_BASE);
  uart_init();
   console_init();
   console_init();


Line 117: 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 190: Line 256:


  };
  };
== Additional resources ==
If you still have some problems these could come in handy:
* [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