Difference between revisions of "Developer Manual/Super IO"
Jump to navigation
Jump to search
Eocallaghan (talk | contribs) |
AvengerF12 (talk | contribs) |
||
(24 intermediate revisions by 3 users not shown) | |||
Line 5: | Line 5: | ||
[[Image:Ite it8705f.jpg|thumb|right|<small>ITE IT8705F Super I/O</small>]] | [[Image:Ite it8705f.jpg|thumb|right|<small>ITE IT8705F Super I/O</small>]] | ||
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 | == 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 | 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); | ||
console_init(); | console_init(); | ||
Line 104: | Line 183: | ||
/* | /* | ||
* io_info contains the mask 0x07f8. Given | * 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: | ||
*/ | */ | ||
=== | 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 = { | |||
}; | |||
== 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] |