Linux on the NCD Explora 451 brad@heeltoe.com 12/02
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.
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
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.
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.
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.
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.
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.
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!