ucostyio

First look at the Silicon Graphics Indy boot process

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.

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
...
graph LR; power[Power Up] --> bootVectorStart[bootVectorStart
0xBFC00000] bootVectorStart --> realStart[realStart
0xBFC003C0]

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
graph TD; realStart --> init_hpc3[init_hpc3
0xBFC00A3C] realStart --> start_aes_tx[start_aes_tx
0xBFC00BD0] realStart --> init_scsi[init_scsi
0xBFC00DCC] realStart --> init_intX[init_intX
0xBFC00D58] realStart --> pon_initio[pon_initio
0xBFC039E0]

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

Comments

comments powered by Disqus
Powered by Disqus