First look at the Silicon Graphics Indy boot process

Posted May 19, 2018 under

I’ve been fascinated by Silicon Graphics hardware for a very long time. Growing up, I had owned or at least had good access to a decent number of Silicon Graphics machines from the Indy up to the Octane series. I loved the industrial design of the hardware itself, as well as how capable and bulletproof they seemed.

SGI Irix

Unfortunately time moves on and I no longer have access to any of this hardware. Consequently I’ve become more interested in trying to emulate the old hardware. There doesn’t seem to be much out there, in terms of Silicon Graphics emulation. There are a few half-completed projects, including one of my own.

Early boot procedure

The Indy is powered by a MIPS R4k series processor, or later an R5k processor. On power up, the processor will jump to an address known as the Boot Vector. This is located at the physical memory address 0x1FC00000. The MMU starts initialised, unlike the x86, and the boot vector address is therefore also mapped to the virtual address 0xBFC00000.

This code lies within a memory segment known as KSEG1, which is a non-cachable memory space.

When disassembling the firmware image, the first thing we come across is the start point of the binary. It consists of a jump table, and looks like the following. On power up, the first instruction is to jump over the rest of the jump table. The jump table consists of 120 jump and nop commands.

ROM:BFC00000 bootVectorStart:
ROM:BFC00000 j       realStart (0xBFC003C0)
ROM:BFC00004 nop
ROM:BFC00008 j       loc_BFC007C4
ROM:BFC0000C nop
ROM:BFC00008 j       loc_BFC007C4
ROM:BFC0000C nop
ROM:BFC00010 j       loc_BFC007C4
ROM:BFC00014 nop
ROM:BFC00018 j       loc_BFC007C4
ROM:BFC0001C nop
ROM:BFC00020 j       loc_BFC007C4
ROM:BFC00024 nop
ROM:BFC00028 j       loc_BFC007C4
ROM:BFC0002C nop
ROM:BFC00030 j       loc_BFC007C4
ROM:BFC00034 nop
ROM:BFC00038 j       loc_BFC007C4
ROM:BFC0003C nop
ROM:BFC00040 j       loc_BFC007C4
ROM:BFC00044 nop

The first real piece of code run does some basic system initialisation. Interrupts are disabled, memory refresh is enabled, memory parity errors are cleared, memory parity checking is enabled, and the GIO bus protocol is set.

Now the processor is in a know state, the firmware starts initialising the on-board hardware.

Hardware Initialisation

The first device to be initialised is the HPC3 chip. The HPC3 chip is designated the “High performance Peripheral Controller” by Silicon Graphics. It is a peripheral interconnect interface, which on one side speaks GIO64 (configured above), and on the other allows the connection of a number of IO devices. These IO devices include, but are not limited to, the

  • Ethernet interface
  • SCSI interfaces
  • Audio I/O
  • UARTs and Parallel ports
  • Keyboard/Mouse
  • Interrupt controllers
  • Floppy drive controllers
  • Real time clock

Power On Self Test

Power on self tests are driven by a set of power-on routines, executed after the hardware initialisation.

init_prom_ram - init stack and bss

sysinit - run c boot program