Git Product home page Git Product logo

c1600re's Introduction

Cisco 1600R Series Reverse Engineering

Documented here is my effort to reverse engineer enough detail about the Cisco 1600R series router platform in order to be able to run my own code.

Rationale

This was an extension of my Cisco 2500 reverse engineering effort, something which I took up while waiting for some PCBs to arrive to test out an idea for providing IO via one of the Flash sockets.

Platform Brief

The 1600R series is interesting due to the use of a Motorola 68360, which is somewhat like a microcontroller featuring a CPU32 core (similar to a 68020) and many built in peripherals. My work was done using a 1603R, and a summary of its most notable features is:

  • Motorola 68360 clocked at 33MHz (some models may be 25MHz?)
  • Built-in timers, UART, ethernet controller and DMA channels
  • 8MB on-board RAM
  • 72 pin SIMM slot accepting an additional 16MB of DRAM
  • 4 boot ROM sockets
  • 1 WIC slot for I/O
  • PCMCIA socket for non-volatile storage
  • 8KByte EEPROM (NVRAM) storing the routers configuration and other information

These features will be addressed in more detail in their respective sections below.

A nice feature about the 1600R is that they are a fanless device, which may be more appealing to some people. A downside is that they use an external power brick.

There are no significant proprietary chips on the board this time, but there are two large Altera EPM7000 series CPLDs which do integrate some functionality. With most peripherals being contained within the 68360, documentation is readily available, and only a few other details are required to interact with the rest of the hardware.

Conventions

I use the following conventions in my documentation:

  • A forward slash (/) after a signal name indicates that the signal is active low, or negative logic
  • In register bit tables:
    • R indicates that a register is readable
    • W indicates that a register is writable, and will read back the same value written
    • w indicates that a register is writable, but the value read back may not represent what was written, or the register is write-once
    • -0 indicates the bit reads as 0 on reset, and -1 reads as a 1. -? means the bit value is indeterminate on reset (e.g. influenced externally).

Memories

A notable feature of the 68360 is that it can generate chip select signals internally, with fully programmable base addresses and address masks. This means that the memory map is not strictly fixed, and memories can thus be located anywhere the programmer wishes them to be.

In this document I will indicate the "default" positioning of the various memories (according to the disassembly of the boot ROMs) and the chip select they are connected to (which will correspond to a particular pair of BR and OR registers). While the chip selects cannot be modified as they are fixed by the hardware design, the memory map can be customised as you see fit.

Boot ROMs

The 1600R has four PLCC32 sockets for holding boot ROMs. The boot ROM code comprises a monitor (ROMmon) and a basic IOS.

Once again, the ROMs were found to be 8Mbit in size, and are arranged as such in the 4 sockets:

  • FW1 and FW3 even bytes
  • FW2 and FW4 odd bytes

FW1 and FW2 form a pair, as do FW3 and FW4.

The boot ROMs present a 16 bit port to the CPU.

Bit order in the boot ROMs is "natural" on the 1600R, unlike the 2500 series where it was mirrored. One thing I did notice, however, is that the ROMs were split down the middle and the two halves swapped, indicating that the most significant address bit (A19) may be inverted. This theory was tested and confirmed - when using 4Mbit ROMs I had to swap the two 2Mbit halves of the image in order to function correctly. A19 is supplied by one of the CPLDs, so it is probable the inversion is being applied in there.

Boot ROMs are mirrored at addresses 0 and 0x04000000, although this is not a strict requirement. FW1 and FW2 can cover the address range 0-XX1FFFFF, while FW3 and FW4 then cover 0xXX200000-XX3FFFFF within these windows. Boot ROMs use CS0/, which at reset begins at address 0 and covers the entire address space allowing the reset vector to be read by the CPU. This window may then be closed up by modifying the OR0 and BR0 registers appropriately.

Due to the ROMs being 8Mbit in size, smaller ROMs will once again encounter an issue with the WE/ pin being driven by an address signal. Unlike the 2500 series, there are no pre-existing jumpers to address this, so a hardware mod is required to be implemented by the user. This requires some fine and delicate soldering, so unfortunately will not be accessible to everyone. None the less, details are provided here for anyone that wishes to attempt it.

The jumper can then be added to run the factory boot ROMs, or removed for 1, 2 or 4Mbit ROMs.

As with the 2500, it should be possible to utilise the full capacity of 4Mbit ROMs by arranging the contents appropriately, taking into account the inverted nature of A19 (assuming base address of 0):

  • FW1/FW2
    • CPU 0x0-3FFFF/ROM 0x40000-7FFFF when CPU A19/ROM A18 is high
    • CPU 0x80000-BFFFF/ROM 0x0-3FFFF when CPU A19/ROM A18 is low
  • FW3/FW4
    • CPU 0x200000-23FFFF/ROM 0x40000-7FFFF when CPU A19/ROM A18 is high
    • CPU 0x280000-2BFFFF/ROM 0x0-3FFFF when CPU A19/ROM A18 is low

NVRAM

NVRAM is a 8Kbyte EEPROM, part number X28HC64J, which holds the routers configuration register (ala 0x2102) and configuration (startup-config), along with some other data known as a "cookie" which contains the routers Ethernet MAC address.

The NVRAM is soldered to the board as opposed to being socketed. For your own purposes, you might completely ignore this chip, or you might write code to erase and re-program it yourself.

NVRAM is located at address 0x0E000000, and uses CS7/.

The NVRAM presents an 8 bit port to the CPU.

EEPROMs are not directly writable, and usually require some form of erase operation before data can be written back. Therefore the correct sequence of operations needs to be established before this can function as a form of non-volatile storage. Code execution from this ROM has not yet been tested.

As mentioned, the cookie contains the MAC address assigned to the router. The cookie is duplicated within the NVRAM at two addresses: 0x0E000000 and 0x0E000280

rommon 8 > cookie ?

cookie:
01 01 00 05 32 4a 2c 9c 09 00 00 00 03 07 00 00
26 60 62 56 00 00 00 00 00 00 00 00 00 00 00 00

Router(boot)#show memory 0x0e000000
0E000000: 8D740101 0005324A 2C9C0900 00000307  .t....2J,.......
0E000010: 00002660 62560000 00000000 00000000  ..&`bV..........
0E000020: 0000821D                             ....

In this example, 00 05 32 4a 2c 9c is the MAC address.

The cookie starts with a "magic number" of 0x8D74, and is followed by a checksum value (0x821D in this case). The checksum is calculated by adding up the value of all words (17, exclude the checksum itself) into an unsigned 16 bit variable, Python e.g.:

cookie = [
    0x8D74, 0x0101, 0x0005, 0x324A, 0x2C9C, 0x0900, 0x0000, 0x0307,
    0x0000, 0x2660, 0x6256, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000
]

cksum = 0

for word in cookie:
    cksum += word

cksum &= 0xFFFF

print(f'0x{cksum:04X}')  # Result: 0x821D

DRAM

8Mbyte of DRAM is soldered onto the board.

  • 0x02000000-023FFFFF (4MB) utilising "CS5/"
  • 0x02400000-027FFFFF (4MB) utilising "CS6/"

Although the BR/OR 5 and 6 registers are used, the CS pin actually functions as a RAS signal instead.

A 72 pin SIMM socket supports a maximum of 16Mbyte of DRAM, allowing for a total of 24Mbyte of RAM in total. The 68360 can be configured to provide the DRAM refreshing.

The PEPAR and GMR registers must be appropriately initialised before DRAM can be utiliised.

Flash

Flash storage is via a PCMCIA socket, and the routers datasheet claims a maximum of 16Mbyte of storage.

Flash is located at 0x08000000, and uses CS4/.

The total address space mapped to CS4/ is 32Mbyte, with the Flash card visible in the first half, and some information about the card itself visible from address 0x09000000 and repeating every 4Kbyte.

During boot, the boot ROM makes mention of initialising a PCMCIA controller. I believe this may be contained within one of the Altera CPLDs, and attempting to read from the flash memory range before the controller has been initialised will result in a bus error exception.

Once again it seems that there is some kind of proprietary pinout being used on the flash card. Comparing some signals like chip enables, data lines etc do not produce activity when you would expect to see it. I dont know how important it is to know the pinout, except to be aware that a standard PCMCIA memory card may not work in a Cisco router.

There are 4 byte sized registers associated with the PCMCIA controller, and based on initial experiments I have determined likely functions for some of the bits within:

Socket Power Control Register 0x0D030000

Bit 7Bit 0
R/W-0 R-0
EN PWR

Bit 3: EN: Power delivery control
    0: Disabled
    1: Enabled
Bit 2: PWR: Power delivery status
    0: Card is not powered
    1: Card is powered

Socket Status Register 0x0D030001

Bit 7Bit 0
R-? R-? R-1 R-1 R-0
CD READY

Bits 7-6: CD: Flash card presence detection
    00: Card is present
    xx: Card is not present
Bit 0: READY: Flash card readiness
    0: Card is not ready
    1: Card is ready

Socket Status Change Register 0x0D030002

Bit 7Bit 0
R-?
CD

Bit 7: CD: Flash card presence
    0: No change
    1: Change detected

Socket Access Control Register 0x0D030003

Bit 7Bit 0
R/W-0 R/W-1 R/W-1 R/W-1
RD WAIT

Bit 6: RD: Read access
    0: Disabled
    1: Enabled
Bits 2-0: WAIT: Wait states for access
    000: 4 clocks
    001: 5 clocks
    010: 7 clocks
    011: 9 clocks
    1xx: 10 clocks

Initialisation of the PCMCIA controller can be achieved using the following process (preliminary, see notes here):

  1. Check if (as a long) the registers of the PCMCIA controller are 0, if they are, skip initialisation
  2. Read the Socket Status Register, AND the value with 0xC0, and if the result is 0 then a flash card is present
  3. Write 0 to the Socket Access Control Register
  4. Write 0x08 to the Socket Power Control Register to enable power to the socket
  5. Write 0xC7 to the Socket Access Control Register
  6. Write 0x47 to the Socket Access Control Register
  7. Wait for the READY bit of the Socket Status Register to be set

Example in C:

uint8_t
is_flash_card_present(void)
{
    /* Perhaps a check if the PCMCIA controller exists? */
    if (*(uint32_t *)(PERIPHERAL_BASE + 0x30000) != 0) {
        /* Is a PCMCIA card present? */
        if (SSTRbits.CD == 0) {
            /* Card detected */
            return 1;
        }
    }

    /* No controller, or card not detected */
    return 0;
}

void
delay_loop(void)
{
    uint16_t ctr;

    for (ctr = 1000; ctr > 0; ctr--);
}

void
init_pcmcia_controller(void)
{
    uint8_t ctr;

    if (is_flash_card_present() != 0) {
        if (SPCRbits.EN == 0) {
            /* Card is not yet powered up, initialise controller */

            /* Clear access control register */
            SACR = 0;
            delay_loop();

            /* Enable power to socket */
            SPCRbits.EN = 1;
            delay_loop();

            /* Configure read access bit and wait states */
            SACR = 0xC7;
            delay_loop();
            SACR = 0x47;

            for (ctr = 100; ctr > 0; ctr--) {
                /* Loop for a little while waiting for READY bit to be set */
                if (SSTRbits.READY != 0) {
                    break;
                }

                delay_loop();
            }
        }
    }
}

If the initialisation completes successfully, the card is now readable.

Write access is still a work in progress. TODO

Peripherals

UART

The UART for the Console port is integrated into the 68360, and is provided by SMC1.

The SMC hardware is quite simple, and does not provide hardware flow control. The DTR and DSR signals are routed to some IO pins of the 68360, so flow control could be implemented in software.

Full documentation for the SMC is provided in the 68360 User Manual.

See GPIO for details about which pins are allocated to which signals/functions.

Also see some notes in DMA about how data is sent and received using on-chip peripherals.

Timers

The 68360 contains 4x 16 bit timer channels, which can be chained to create a maximum of two 32 bit timers.

In addition to these timer channels, there is also a "Periodic Interrupt Timer".

The interrupt priority of the PIT is independent of the general purpose timers. The general purpose timers all share the same IPL but have their own vector as an offset from the CPM vector base.

Full documentation is provided in the 68360 User Manual.

Watchdog

A watchdog is provided internally by the 68360.

The watchdog configuration is much more flexible compared to the 2500, with the period being more widely adjustable from miliseconds to several seconds being a notable mention. It is also possible to have the watchdog fire an interrupt rather than causing a reset.

Full documentation is provided in the 68360 User Manual.

Ethernet Controller

The 68360 has a built-in ethernet controller utilising the SCC1 peripheral, but at time of writing not many details are known about it.

See GPIO for details about which pins are allocated to which signals/functions.

Also see some notes in DMA about how data is sent and received using on-chip peripherals.

GPIO

The 68360 also has 3 banks of GPIO pins many of which are bidir, tri-state, open drain, etc. Several of these are pre-assigned for various functions. PORTC pins in particular have the notable feature of "interrupt on change".

The following GPIO pins are known to be used for the noted purposes, based on the peripherals that are configured and buzzing signals out manually:

  • PORTA
    • PA0 - Ethernet RXD (SCC1)
    • PA1 - Ethernet TXD (SCC1)
    • PA3 - WIC pin 63
    • PA4 - WIC pin 40
    • PA5 - WIC pin 7
    • PA9 - connected to an external 8.064MHz oscillator (aka CLK2 - can be supplied to a BRG)
    • PA10 - Ethernet TCLK
    • PA11 - Ethernet RCLK
    • PA12 - WIC pin 5
    • PA13 - WIC pin 38
  • PORTB
    • PB1 - WIC EEPROM SK (SPICLK)
    • PB2 - WIC EEPROM DI (SPIMOSI)
    • PB3 - WIC EEPROM DO (SPIMISO)
    • PB4 - WIC pin 16
    • PB5 - WIC EEPROM CS
    • PB6 - TXD (SMC1) - console pin 3
    • PB7 - RXD (SMC1) - console pin 6
    • PB8 - console pin 2 - DTR (s/w control only)
    • PB9 - console pin 7 - DSR (s/w control only)
    • PB10 - Ethernet JAB
    • PB12 - Ethernet TEN
    • PB13 - Ethernet LBK
    • PB14 - Ethernet AUTOSEL
    • PB16 - WIC pin 36 - pin is pulled up via resistor, and on a selection of WICs I have is pulled down via a 0 ohm resistor, so probably something like a presence detect function
  • PORTC
    • PC2 - WIC pin 42
    • PC4 - Ethernet COL
    • PC5 - Ethernet CD
    • PC6 - WIC pin 41
    • PC7 - WIC pin 8
    • PC8 - WIC pin 43
    • PC9 - WIC pin 9
  • PORTE
    • Port E pins are largely used for DRAM memory interface signals (RAS, CAS etc)

DMA

Most peripherals within the 68360 contain dedicated DMA (SDMA) channels for TX and RX operations, but two other general purpose DMA channels are also provided (yay!).

Data is not written to or read from peripherals in the usual way, e.g. writing or reading FIFO registers. Instead, all TX and RX operations are handled by configuring SDMA channels to send and receive from/to buffers in memory using Buffer Descriptors that specify the address and size of the buffer to send or receive.

The result of this is that your software will likely become more heavily interrupt driven, whether they are handled via ISRs or in polled mode.

Full documentation is provided in the 68360 User Manual.

Peripherals and External Registers

Peripheral and registers external to the 68360 itself are mapped at locations in the 0x0D0XXXXX address space. Registers within this address space use CS3/.

Important Notes: Further experimentation has revealed that only the 0x0D08XXXX window is enabled by default. While investigating the PCMCIA controller, and using my own monitor, I was unable to read any of the PCMCIA controller registers located at 0x0D030000, simply resulting in a bus error. Therefore I believe that there is more initialisation work to be done to enable additional windows. TODO

WIC Slot

WAN Interface Cards (WICs) are Cisco proprietary modules that provide various different .. WAN interfaces. These would traditionally have been serial for frame relay, ISDN, DSL, modem, etc.

The 1600R has one WIC slot accessible at address 0x0D050000, which is part of an address range configured on CS3/.

Through buzzing out the connectivity to the WIC slot I identified 8 address bits and 8 data bits.

The following signals were identified, and alone are likely to be sufficient for creating your own cards to plug into the WIC slot and provide additional IO and periperhals:

  • Address pins A7..0
  • Data pins D7..0
  • DS/ (data strobe)
  • CS/ (chip select)
  • R or W/ (read or write - write being active low)
  • EEPROM CS, DI, DO, SK (SPI interface to a small inventory EEPROM)
  • Power supply pins - 2x +5V, 1x -5V, 1x +12V, 1x -12V, numerous GND

Try as I might, at the time of writing I had not yet been able to positively identify any kind of "official" interrupt or reset pin on the WIC slot. That said, several pins of the WIC slot are routed to various PORTA, PORTB and PORTC pins on the CPU, so it is very likely that you could take your pick of these to provide this functionality as required. Some of these pins are associated with further Serial Communication Controllers in the 68360, enabling access to higher speed serial interfaces supporting various protocols.

Pinout for the WIC slot identified so far is as follows. Orientation of the WIC connector should be view from the rear of the card looking into the connector, with the notches on the sides of the connector arranged as ] on the left and L on the right. In this orientation, pin 1 is top right, pin 34 is top left, pin 35 is bottom right and pin 68 bottom left.

WIC Socket Pinout

PinSignalPinSignal PinSignalPinSignal
1-12V18A035+5V52A1
2GND19A236PD53A3
320A437GND54A5
4GND21A638CPU PA1355A7
5CPU PA1222EEPROM DO39GND56
6GND23EEPROM DI40CPU PA457
7CPU PA524GND41CPU PC658EEPROM SK
8CPU PC725CS/42CPU PC259R or W/
9CPU PC92643CPU PC860
102744GND61
11D02845D162
12D229GND46D363CPU PA3
13D43047D564GND
14D631GND48D765
15DS/3249EEPROM CS66GND
16CPU PB433GND50CPLD 01 pin 4967CPLD 01 pin 71
17-5V34+12V51GND68+5V

On-board ISDN Controller

My router model, a 1603R, has a built-in ISDN controller. I dont plan to do anything with this so I wont document much about it, but this controller is accessible at address 0x0D060000 as part of the address space covered by CS3/.

System Option Register

This is a name I came up with based on initial discovery, it is a byte sized read-only register which seems to describe some properties about the router platform.

This register is located at 0x0D080000 as part of the address space covered by CS3/.

The initial purpose discovered is that it indicates whether the CPU speed is 25MHz or 33MHz, which then allows the PLL and other peripherals (with baud rate generators for example) to be configured appropriately. The register itself is a buffer whos input pins are tied to either +5v or GND via some resistors.

The upper nibble of this register indicates the hardware revision.

System Option Register 0x0D080000

Bit 7Bit 0
R-? R-? R-? R-? R-?
HWREV SPEED

Bit 7-4: HWREV: Hardware revision
Bit 3: SPEED: CPU speed strap
    0: 33MHz
    1: 25MHz

The HWREV field is treated as a literal, and does not encode any information.

LED Control Register

Another name that I have come up with, this byte size register enables 5 LEDS to be controlled - even more blinkenlights!

This register is located at 0x0D080001 as part of the address space covered by CS3/.

The outputs of the register are used to sink current via the LEDs, so the logic to control them is inverted.

LED Control Register 0x0D080001

Bit 7Bit 0
R/W-0 R/W-0 R/W-0 R/W-0 R/W-0
OK LED1 LED2 LED3 LED4

Bit 7: OK: OK LED
    0: LED is on
    1: LED is off
Bit 6: LED1: Multi-purpose LED 1
    0: LED is on
    1: LED is off
Bit 5: LED2: Multi-purpose LED 2
    0: LED is on
    1: LED is off
Bit 4: LED3: Multi-purpose LED 3
    0: LED is on
    1: LED is off
Bit 3: LED4: Multi-purpose LED 4
    0: LED is on
    1: LED is off

Due to there being a variety of different 1600R models, 4 of the LEDs are effectively "multi-purpose" in that depending on the router model, they may indicate something slightly different. The physical layout of the LEDs is the same regardless of the router, so refer to the table below for a hint as to which LED is located where.

LED1 LED3
OK
LED2 LED4

Other

Minimal Startup Code

Getting a 68360 up and running is a bit involved. My best suggestion would be to look at the source for the serial bootloader or sample FreeRTOS applications as working examples to build on.

Across these two examples you will find code to:

  • Perform the bare minimum system configuration to jump to main()
  • Initialise OR and BR registers to map chip selects to memory windows
  • Configure DRAM interfaces and refreshing
  • Configure the PLL to reach a target operating frequency
  • Copy intitialised data from ROM to RAM and clear the BSS area
  • Initialise the SMC1 to provide UART for serial communications
  • Configure some interrupts

The serial bootloader in particular is an example of using SDAM channels and buffer descriptors to send and receive data over the UART.

Reset Button Modification

The hardware as supplied does not include a reset button, but one can be added very easily.

The mod will bridge the RESETH/ pin to ground when the button is pressed, causing a full reset of the CPU and all internal peripherals. The user may want to execute a RESET instruction at boot to cause external peripherals to be reset, as these seem to be tied to the RESETS/ signal, and this is not asserted when RESETH/ is.

Overclocking

The CPU features a PLL which takes input from a (as manufactured) 4MHz crystal. This is then divided by 128 (as determined by the MODCK1-0 settings), and then multiplied up to the target operating frequency via the MF field of the PLLCR register.

I did some quick testing and it seems like you can quite easily push the CPU (33MHz rated part in my case) to at least 50MHz. I didnt run it for more than a minute or so, so long term stability is unknown, and depending on just how far you take it, maybe some additional cooling may be required, and wait states for memories may need to be adjusted as well.

c1600re's People

Contributors

tomstorey avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.