Rabbit 2000™ Microprocessor Designer's Handbook

> ## 7. The System ID Block

> The BIOS supports a system identification block to be placed at the top of flash memory. Identification information for each device can be placed in it for access by the BIOS, flash driver, and users. This block will contain specific part numbers for the flash and RAM devices installed, the product's serial number, Media Access Control (MAC) address if an Ethernet device, and so on. In addition, the ID block is designed with future expansion in mind by including a table version number and storing the block's size in bytes within the block itself. Pointers for a "user block" of protected data exist as well, with the planned use for storage of calibration constants, etc., although the user may use it if desired.

> Note that version 1 of the ID block (tableVersion = 0x01) has only limited functionality. In particular, only the following parameters are valid: tableVersion, productID, timestamp, macAddr, idBlockSize, idBlockCRC, and marker. Version 2 and later ID blocks have all the values filled with the exception of the flash and RAM speed fields, and Dynamic C versions 7.04x2 and later support use of the user block.

> If Dynamic C does not find an ID block on a device, the compiler will assume that it is a Z-World BL1810 (Jackrabbit) board.

> ### 7.1 Definition of SysIDBlock

> The following global struct is defined in IDBLOCK.LIB and is loaded from the flash device during BIOS startup. Users can access this struct in RAM if they need information from it. The definition below is for a 128-byte ID block; the actual size can vary according to the value in idBlockSize. The reserved[] field will expand and/or shrink to compensate for the change in size.

>     typedef struct {
>        int  tableVersion;      // ver. num for this table layout
>        int  productID;         // Z-World part #
>        int  vendorID;          // 1 = Z-World
>        char timestamp[7];      // YY/M/D H:M:S
>        long flashID;           // Z-World part #
>        int  flashType;         // Write method
>        int  flashSize;         // in 1000h pages
>        int  sectorSize;        // size of flash sector in bytes
>        int  numSectors;        // number of sectors
>        int  flashSpeed;        // in nanoseconds
>        long flash2ID;          // Z-World part #, 2nd flash
>        int  flash2Type;        // Write method, 2nd flash
>        int  flash2Size;        // in 1000h pages, 2nd flash
>        int  sector2Size;       // byte size of 2nd flash's sectors
>        int  num2Sectors;       // number of sectors
>        int  flash2Speed;       // in nanoseconds, 2nd flash
>        long ramID;             // Z-World part #
>        int  ramSize;           // in 1000h pages
>        int  ramSpeed;          // in nanoseconds
>        int  cpuID;             // CPU type identification
>        long crystalFreq;       // in Hertz
>        char macAddr[6];        // Media Access Control (MAC) addr
>        char serialNumber[24];  // device serial number
>        char productName[30];   // NULL-terminated string
>        char reserved[1];       // reserved 4 later use - size can
>                                //   grow
>        long idBlockSize;       // size of the SysIDBlock struct
>        int  userBlockSize;     // size of user block (directly
>                                //   below ID block)
>        int  userBlockLoc;      // offset of start of user block
>                                //   from this block
>        int  idBlockCRC;        // CRC of this block (when this
>                                //   field is set to zero)
>        char  marker[6];        // should be 0x55 0xAA 0x55 0xAA
>                                //   0x55 0xAA
>     } SysIDBlock;

> ### 7.2 Access

> The BIOS will read the system ID block during startup, so all a user needs to do is access the system ID block struct SysIDBlock in memory. If the BIOS does not find an ID block, it sets all parameters in SysIDBlock to zero.

> #### 7.2.1 Reading the SystemID Block

> If the user desires to read the ID block off the flash, the following function (from IDBLOCK.LIB) should be called:

> ## _readIDBlock

>     int _readIDBlock(int flash_bitmap)

> #### Description:

> Attempts to read the system ID block from the highest flash quadrant and save it in the system ID block structure. It performs a CRC check on the block to verify that the block is valid. If an error occurs, SysIDBlock.tableVersion is set to zero.

> #### Parameter

>     flash_bitmap

> Bitmap of memory quadrants mapped to flash. Examples:
> 0x01 = quadrant 0 only
> 0x03 = quadrants 0 and 1
> 0x0C = quadrants 2 and 3

> #### Return value:

> 0: Successful
> -1: Error reading from flash
> -2: ID block missing
> -3: ID block invalid (failed CRC check)

> #### 7.2.2 Writing the SystemID Block

> The WriteFlash() function does not allow writing to the ID block. If the ID block needs to be rewritten, a utility to do so is available for download from the Z-World website:

>      http://www.zworld.com/support/feature_downloads.html

> or contact Rabbit Semiconductor's Technical Support.

> ### 7.3 Determining the Existence of the SystemID Block

> The following sequence of events can be used to determine if an ID block is present:

> 1. The top 16 bytes of the flash device are read (if a 256KB flash in stalled, 16 bytes starting at address 0x3FFF0 will be read) into a local buffer.
> 2. The top six bytes of the buffer (read from 0x3FFF8-0x3FFFF) are checked for an alternating sequence of 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA. If this is not found, the block does not exist and an error (-2) is returned.
> 3. The ID block size (=SIZE) is determined from the first 4 bytes of the 16-byte buffer.
> 4. A block of bytes containing all fields from the start of the SysIDBlock struct up to but not including the reserved field is read from flash at address 0x40000-SIZE, essentially filling the SysIDBlock struct except for the reserved field (since the top 16 bytes have been read earlier).
> 5. The CRC field is saved in a local variable, then set to 0x0000. A CRC check is then calculated for the entire ID block except the reserved field and compared to the saved value. If they do not match, the block is considered invalid and an error (-3) is returned. The CRC field is then restored.

> The reserved field is avoided in the CRC check since its size may vary, depending on the size of the ID block.

> Offset from start of block | Size (bytes) | Description
> 00h | 2 | ID block version number
> 02h | 2 | Product ID
> 04h | 2 | Vendor ID
> 06h | 7 | Timestamp (YY/MM/D/H/M/S)
> 0Dh | 4 | Flash ID
> 11h | 2 | Flash size (in 1000h pages)
> 13h | 2 | Flash sector size (in bytes)
> 15h | 2 | Number of sectors in flash
> 17h | 2 | Flash access time (nanoseconds)
> 19h | 4 | Flash ID, 2nd flash
> 1Dh | 2 | Flash size (in 1000h pages), 2nd flash
> 1Fh | 2 | Flash sector size, 2nd flash (in bytes)
> 21h | 2 | Number of sectors in 2nd flash
> 23h | 2 | Flash access time (nanoseconds), 2nd flash
> 25h | 4 | RAM ID
> 29h | 2 | RAM size (in 1000h pages)
> 2Bh | 2 | RAM access time (nanoseconds)
> 2Dh | 2 | CPU ID
> 2Fh | 4 | Crystal frequency (Hertz)
> 33h | 6 | Media Access Control (MAC) address
> 39h | 24 | Serial number (as a null-terminated string)
> 51h | 30 | Product name (as a null-terminated string)
> 6Fh | N | Reserved (variable size)
> SIZE - 10h | 4 | Size of this ID block
> SIZE - 0Ch | 2 | Size of user block
> SIZE - 0Ah | 2 | Offset of user block location from start of this block
> SIZE - 08h | 2 | CRC value of this block (when this field = 0000h)
> SIZE - 06h | 6 | Marker, should = 55h AAh 55h AAh 55h AAh
> Table 4. The System ID Block

Rabbit Semiconductor Corporation http://www.rabbitsemiconductor.com Voice: (530) 757-8400 Fax: (530) 757-8402