Cyrix/IBM 6x86 CPUs have 24 configuration registers, divided in 4 functional groups, that are used to set various performance features. The 4 functional groups are:
All registers are single byte, except for the Address Region Registers (ARRs) which are 3 bytes wide. Each register (and each byte in the ARRs) is identified by an index, used to read or write to it.
To access one of the registers, a write must be done to I/O port 22h, with the index as the value of the data written. The following instruction must be a read or a write to I/O port 23h, which will then transfer the data from/to the specified configuration register. Additionally, to access ARR0-ARR7, RCR0-RCR7, CCR4 and CCR5, bits (7-4) of CCR3 must be set to 0001b (these bits are called MAPEN(3-0) in the Cyrix/IBM docs). The mechanism seems complicated but in practice it is relatively simple, even if a little awkward. The actual code for the kernel patches is the following:
(This macro defines a mechanism for setting a register with index reg to a given value val)
#define setCx86(reg, val) \
movb reg,%ax; \
outb %ax,$0x22; \
movb val,%ax; \
outb %ax,$0x23
(This macro defines a mechanism for reading a register with index reg to AX)
#define getCx86(reg) \
movb reg,%ax; \
outb %ax,$0x22; \
inb $0x23,%ax
And this is an example of using the above macros:
cli # disable interrupts
getCx86($0xc3) # get CCR3
movb %ax,%cx # Save old value in register ECX
movb %ax,%bx
andb $0x0f,%bx # Enable access to all config registers
orb $0x10,%bx # by setting bits 7-4 to 0001
setCx86($0xc3,%bx)
# ... do something
setCx86($0xc3,%cx) # reset CCR3 to previous state
sti # enable interrupts
Note that this short routine must run with interrupts disabled. In the ...do something part one could for example setup ARRs for specific memory regions in one's system.
Configuring ARRs is the most important, but also the most involved operation to improve the performance of any Linux system with a 6x86 family CPU. It can be done quite simply with set6x86, but one should at least read the ARR description in the relevant Application Notes (e.g. IBM Application Note 40205) or in the 6x86 Data Book. Usually, ARRs 0 to 3 and ARR7 will have been setup by the BIOS, taking care of setting up the 6x86 for your main memory. All that one will have to do to optimize performance is to setup a separate ARR for the video card(s).
Assuming you have set6x86 version 1.3 or later installed on your system, the actual procedure to setup an ARR is not too complicated:
This seems very theoretical so let's see an example configuration:
Step 1 - Finding an unused ARR.
6x86_arr reports the following on my system:
As we can see, ARRs 4, 5 and 6 are free. Let's setup ARR6.
Step 2 - Find the size and address of the memory region we want to setup an ARR for.
In this example, we want to setup an ARR for the Linear Video Frame Buffer of a standard S3 Trio64 V2 video card with 2Mb of EDO video DRAM.We simply type X > -probeonly and this reports various lines on the screen, one of which reads: (--) S3: PCI: Trio64V2 rev 14, Linear FB @ 0xe0000000.
Step 3 - Determine RCR settings.
Usually this is the simplest possible setting: not cached, write gathering enabled. This results in an RCR value of 0x09.
Step 4 - Setup the four calls to set6x86.
In this example, D6, D7 and D8 are indexes to ARR6, and E2 is the index to RCR6.
D6 and D7 must be loaded with the two most significant bytes of my Linear Video Frame Buffer address 0xE0 and 0x00 respectively.
D8 is setup with a value (0x0A) that corresponds to the size of the memory region being setup, in this case 2Mb. If I had 4Mb on my video card, this value would be 0x0B. If I had 1Mb, it would be 0x09; adjust accordingly.
Finally, RCR6 is loaded with 0x09, resulting in a non-cached memory region with write gathering enabled.
Step 5 - Include the above sequence in rc.local or rc.cyrix, in the part that has MAPEN enabled.
Step 6 - Reboot and check that the new ARR is correctly configured by running 6x86_arr again:
Step 7 - Test with an adequate benchmark (dga, Xmark, xbench, xengine, Doom, Quake or anything else that measures video memory bandwidth).
In case your system has12Mb, 24Mb, 48Mb or 96Mb of total DRAM installed, you will notice that ARR6 has already been setup by the BIOS for an unused memory region. This is OK, but now you will have to setup ARR5 instead of ARR6 for your LVFB.
In step 4 above, replace the D6, D7, D8 and E2 indexes by D3, D4, D5 and E1 respectively.
If your system also has ARR5 used by the BIOS, you will have to use ARR4. The indexes to setup will be D0, D1, D2 and E0 respectively.
Last updated on January 4, 1998.
Copyright 1997 Andrew D. Balsa