Linux on the NCD Explora 451
brad@heeltoe.com
12/02

Overview

This is an attempt to run Linux on the NCD Explora 451 X terminal. The 451 uses the 403GCX processor, which has an MMU. Note that the 450 uses a different 403 which does not have an MMU and this can't run normal linux (it could probably run uCLinux, but that's a different effort).

I've found these terminals for cheap money on ebay. I recently bought two for $20 each. I've heard others paying $15.

My goal is to boot a kernel image using the stock boot prom and run linux using either an NFS file system or a file system mounted on a local PCMCIA card.

Status

I've figured out how to craft an image which the boot loader will tftp and run. I've created a simple ram image which I can use to test out the various pieces of hardware. I've managed to figure out where the video display is and how to access the "SuperI/O" chip. The serial port is working fine.

I have a linux kernel which boots and nfs mounts a file system. The shell runs fine. There is no video or ps/2 keyboard yet, but the serial console works fine.

To do list: Fix DRAM Simm BR's at boot time to get all the memory S3 Trio 64 video chip support PS/2 keyboard & mouse support Figure out the "pc style" speaker Figure out the stereo audio output Figure out the pcmcia mapping

Specs

Connectors

Parts & Chips

Hardware Details

Memory

The 403GCX supports dual mapping of memory banks into cached and uncached regions. It looks like the hardware wants uncached accesses to be to the "low addresses" and cached accesses to be high. For example, when accessing the SuperI/O, use 0xf4000000 for cached and 0x74000000 for uncached. The 403GCX user manual has some detail about how this is intended to be used when the MMU is not enabled. I am assuming the boot rom runs with translation disabled.

Once linux is running the MMU is enabled and this is a mute point. We run the i/o portions of the memory map as "uncached and guarded".

The boot prom looks at the memory in the SIMMs and adjusts the BR4, BR5, BR6 and BR7 registers accordingly. It seems to discard the "on-board" 4mb of dram if the SIMMs have more than 4mb of ram on them. Since ram is free these days and old ram is worthless I put two 16mb 60ns EDO rams in the SIMMs and the boot eprom reported 32mb and only configured BR5 & BR7 (see below for details).

I recently added code to reorganize the BR's just before giving control to the kernel. It's a reasonable start but it currently leaves half (or more) of the memory unused. This need to be fixed. It should be easy to add some code to the kernel or copy code to the relocated SIM to move the remaining BR once the jump to the kernel has been made.

PCI, FPGA and GPIO's

The ethernet and video chips are PCI based chips and want to see different types of bus cycles depending on what is being done. There is a custom FPGA which appears to be minimal PCI bridge. The "super i/o" chip has 16 bits of GPIO which control various things, including (it appears) what type of cycle is run.

It looks like setting the right bits in the super i/o gpio's will allow configuration cycles to run when reads and writes are done to one section of memory.

Serial Port

The 403GCX internal serial port does not appear to be connected. The external RS232C Serial port is connected to a PC87306 "SuperI/O" chip which implements a 16550 uart. It also implements the PS/2 keyboard and mouse, parallel port, real time clock and a floppy controller.

The boot rom leaves BR3 pointing at the SuperI/O chip, but as a word access (not byte). This means all the accesses need to be offset by 2 (i.e. instead of [0],[1] for sequential accesses you need [0],[2]). I suspect BR3 could be reprogrammed as byte wide but I also suspect I'll discover why 16 bit accesses are better sometime in the future.

Accessing the SuperI/O using the uncached alias and the word access translation (i.e. port address * 2), the id comes back 0x75 which is correct.

Video memory

The boot rom programs the video controller to the resolution configured by the boot rom "SE" command. I set it to the lowest resolution and this leaves the video as a direct 8 bit deep bitmap starting at 0x70000000. I used a simple 8x8 font and colors 0x0 and 0x1 and this makes a nice simple display in 640x480 mode. This was helpful during early debugging/discovery.

Once the kernel boots the S3 chip is reset. I've had no luck getting either VGA or S3 code to init the chip. Nor can I find any docs on the chip. But I'm not giving up.

Ethernet

The network connection is an AM79C971 PCNet-FAST 10/100 PCI base ethernet chip connected (via MII) to a Micro Linear 6692 phy chip (see BCR 32). A small bit of hacking to the existing pcnet32.c driver got it working. There seems to be some issues with the phy still; I set it up to renagotiate when it boots and it works, but I think the renagotiatation is not needed. I have not tested 100 mbit or full duplex modes. 70840000[0x10] = 00000081 70840000[0x14] = 08800000

LEDS

Led's D15 & D16 are controlled via superi/o gpio2, D1 ethernet link D15 gpio2 0x20 - 0=on,1=off D16 gpio2 0x10 - 1=on,0=off gpio2 7 pci reset? 6 ethernet link enable? 5 D15 4 D16 3 2 1 pci access? 0 pci access? gpio1 7 x 6 x speaker? 5 x 4 3 2 1 pci config cycles? 0

Configuration Details

Memory Map

This is a guess:

The boot eprom programs the memory map as thing:

0x01000000 - 0x013fffff		On-board DRAM, 4MB
0x01400000 - 0x017fffff		SIMM 1 DRAM, 4MB?

0xf0000000 - 0xf01fffff		Video ram, 2MB (32-bit)

0xf3000000 - 0xf3ffffff		ethernet? (16-bit)			
0xf4000000 - 0xf4ffffff		SuperI/O chip (16-bit)

0xfff00000 - 0xffffffff		flash eprom, 1MB, (8-bit)

I changed the linux piggyback loader to change BR5 to move the high 16mb to 0x0, which is what the 4xx linux port expects. I need to devise a way to move the low 16mb back down later, perhaps early in the kernel boot.

Register Dump

From the ROM monitor "dr" command, it is possible to determine some details of the memory map of the X-terminal.

It looks

Bank Register values are:

BR0 - 0xFF1804f2: EPROM @ 0xfff00000, 1MB, r/w, 8-bit 
BR1 - 0x00bf4002: VRAM @ 0xf0000000, 16MB, r/w, 32-bit 
0000 0000 1011 1111 0100 0000 0000 0010
               1    1
               2345 6789

BR2 - 0x3098cab2: @ 0xf3000000, 16MB, r/w, 16-bit 
0011 0000 1001 1000 1100 1010 1011 0010
               1    111     2 2222 2
               2345 678     3 4567 8
Address F3xx xxxx
16mb bank
r/w
line fills are target word first
bursting disabled
16 bit
ready pin input enabled
transfer wait = 0xa, 10
cs on
oe valid off
wb ena on
wb ena off
transfer hold = 2

BR3 - 0x4098c4f2: @ 0xf4000000, 16MB, r/w, 8-bit 
0100 0000 1001 1000 1100 0100 1111 0010
Address F3xx xxxx
16mb bank
r/w
line fills are target word first
bursting disabled
16 bit
ready pin input enabled
transfer wait = 0x4, 4
cs on
oe valid on
wb ena on
wb ena off
transfer hold = 2

 BR4 - on board
 BR5 - simm 2
 BR6 - on board
 BR7 - simm 1

** onboard + 4mb simm in j9 (8mb total):
 BR4 - 0x00000000
 BR5 - 0x00000000

 BR6 - 0x14594a2e: on-board @ 0x01400000, 4MB, r/w, 32-bit 
 0001 0100 0101 1001 0100 1010 0010 1110

 BR7 - 0x10594a2e: simm 1 @ 0x01000000, 4MB, r/w, 32-bit 
 0001 0000 0101 1001 0100 1010 0010 1110
 0    4    8    1    1
                2    6

** onboard + 4mb simm in j10 (8mb total):
 BR4 - 0x14594a2e: on-board? @ 0x01400000, 4MB, r/w, 32-bit 
 BR5 - 0x10594a2e: simm 2 @ 0x01000000, 4MB, r/w, 32-bit 
 BR6 - 0x00000000
 BR7 - 0x00000000

** onboard + 2 x 4mb simm (16mb total?):
 BR4 - 0x1c594a2e: on-board? @ 0x01c00000, 4mb, r/w, 32-bit 
 BR5 - 0x18594a2e: simm 2 @ 0x01800000, 4mb, r/w, 32-bit 
 BR6 - 0x14594a2e: on-board @ 0x01400000, 4MB, r/w, 32-bit 
 BR7 - 0x10594a2e: simm 1 @ 0x01000000, 4MB, r/w, 32-bit 

** one 16mb simm in j9 (16mb total):
 BR4 - 0x00000000
 BR5 - 0x00000000
 BR6 - 0x00000000
 BR7 - 0x10994a2e: SIMM 1 DRAM @ 0x01000000, 16MB, r/w, 32-bit 

** one 16mb simm in j10 (16mb total):
 BR4 - 0x00000000
 BR5 - 0x10994a2e: SIMM 1 DRAM @ 0x01000000, 16MB, r/w, 32-bit 
 BR6 - 0x00000000
 BR7 - 0x00000000

** two 16mb summ (32mb total):
 BR4 - 0
 BR5 - 0x20994a2e: SIMM 2 DRAM @ 0x02000000, 16MB, r/w, 32-bit 
 0010 0000 1001 1001 0100 1010 0010 1110

 BR6 - 0x00000000: On-board DRAM, 4MB, r/w, 32-bit 
 disabled

 BR7 - 0x10994a2e: SIMM 1 DRAM @ 0x01000000, 16MB, r/w, 32-bit 
 0001 0000 1001 1001 0100 1010 0010 1110

-----

PCI

found S3; [70820000] = 00003353
[70820000] = 00003353 (BESR=00000000)
[70820002] = 00000189 (BESR=00000000)
[70820004] = 00000300 (BESR=00000000)
[70820006] = 00000002 (BESR=00000000)
[70820008] = 00001400 (BESR=00000000)
[7082000A] = 00000003 (BESR=00000000)
[7082000C] = 00000000 (BESR=00000000)
[7082000E] = 00000000 (BESR=00000000)
[70820010] = 00000000 (BESR=00000000)
[70820012] = 00000000 (BESR=00000000)
[70820014] = 00000000 (BESR=00000000)
[70820016] = 00000000 (BESR=00000000)
[70820018] = 00000000 (BESR=00000000)
[7082001A] = 00000000 (BESR=00000000)
[7082001C] = 00000000 (BESR=00000000)
[7082001E] = 00000000 (BESR=00000000)
found PC-FAST [70840000] = 00002210
[70840000] = 00002210 (BESR=00000000)
[70840002] = 00000020 (BESR=00000000)
[70840004] = 00000600 (BESR=00000000)
[70840006] = 00008082 (BESR=00000000)
[70840008] = 00002500 (BESR=00000000)
[7084000A] = 00000002 (BESR=00000000)
[7084000C] = 00000000 (BESR=00000000)
[7084000E] = 00000000 (BESR=00000000)
[70840010] = 00008100 (BESR=00000000)
[70840012] = 00000000 (BESR=00000000)
[70840014] = 00000000 (BESR=00000000)
[70840016] = 00008008 (BESR=00000000)
[70840018] = 00000000 (BESR=00000000)
[7084001A] = 00000000 (BESR=00000000)
[7084001C] = 00000000 (BESR=00000000)
[7084001E] = 00000000 (BESR=00000000)
0x10 = 00000081
0x14 = 08800000 -> 70800000 for memory?
Done!