This chapter describes how to add flash memory to a configuration (components in particular), and how to extend the Simics database of flash models.
Almost all flashes in Simics use the same Simics class, generic-flash-memory
. This class has a number of attributes that controls the behavior of a specific flash model. Thus, one can create virtually any flash manually, by instantiating an object of this class, and configure the attributes.
Simics automates this with the functions flash_memory
.flash_create_memory
and flash_memory
.flash_create_memory_anon
.
flash_create_memory
creates named pre-objects, for use in legacy components, and flash_create_memory_anon
creates anonymous pre-objects, for use in new components. Details about these functions can be found in the API Reference Manual.
Example:
import flash_memory
([flash, flash_ram, flash_image], flash_size
) = flash_memory.flash_create_memory_anon(
'Am29LV641D', 1, 16, big_endian = 1)
self.add_slot('flash', flash)
self.add_slot('flash_image', flash_image)
self.add_slot('flash_ram', flash_ram)
This creates one Am29LV641D flash chip with no interleaving, a bus width of 16 bits, in big-endian mode. Finally, it creates slots for the flash objects.
To be able to instantiate a flash, the flash_memory
.flash_create_memory
and flash_memory
.flash_create_memory_anon
functions need to know the configuration specifics for that particular flash.
This information is stored in an internal database. It is possible to add additional flash models to this database. To do this, you need to provide a flash name, the configuration specifics, and a finalize function.
Underscores in the flash name act as a wild card and will match any character. This can be used in combination with the finalize method to e.g., modify the CFI data for a given instance of the flash.
The configuration details is a single parameter (a dictionary). All the keys in it are attribute names from the generic-flash-memory
class. See the API Reference Manual for available attributes and valid values.
Example of a typical IntelĀ® flash:
import flash_memory
def finish_config_28F___S3(product_no, config):
# set size-dependent parameters
if product_no[3:6] == "160": # 16Mbit
device_geometry_definition = [0x15, 0x02, 0x00, 0x05, 0x00,
0x01, 0x1f, 0x00, 0x00, 0x01]
config['device_id'] = 0xd0
blocks = 32
elif product_no[3:6] == "320": # 32Mbit
device_geometry_definition = [0x16, 0x02, 0x00, 0x05, 0x00,
0x01, 0x3f, 0x00, 0x00, 0x01]
config['device_id'] = 0xd4
blocks = 64
else:
return ("The product no (" + product_no + ") should contain a valid "
"size (160 or 320), not '" + product_no[3:6] + "'")
# size
size = 1 << device_geometry_definition[0]
# cfi_query
for i in range(0x27, 0x31):
config["cfi_query"][i] = device_geometry_definition[i - 0x27]
config['unit_size'] = [0x10000 for i in range(blocks)]
return (config, size)
flash_memory.flash_add_model(
"copyof28F___S3",
{"cfi_query" : [0xb0, 0x00, 0x00, 0x00, # 0x00 Sharp Manufacturer ID
0x00, 0x00, 0x00, 0x00, # 0x04
0x00, 0x00, 0x00, 0x00, # 0x08
0x00, 0x00, 0x00, 0x00, # 0x0C
0x51, 0x52, 0x59, 0x01, # 0x10
0x00, 0x31, 0x00, 0x00, # 0x14 Pointer to Extended Query
0x00, 0x00, 0x00, 0x27, # 0x18
0x55, 0x27, 0x55, 0x03, # 0x1C
0x06, 0x0A, 0x0f, 0x04, # 0x20
0x04, 0x04, 0x04, None, # 0x24
None, None, None, None, # 0x28
None, None, None, None, # 0x2C
None,
0x50, 0x52, 0x49, 0x31, # 0x31 Extended Query
0x30, 0x0f, 0x00, 0x00, # 0x35
0x00, 0x01, 0x03, 0x00, # 0x39
0x50, 0x50], # 0x3D
"device_id" : None, #
"manufacturer_id" : 0x00b0, # Sharp Manufacturer ID is verbatim
# from IntelĀ® docs.
"max_chip_width" : 16, # 16-bits chips
"unit_size" : None,
"intel_write_buffer" : 1,
"intel_protection_program" : 0, # No protection command on S3
"intel_configuration" : 1,
"intel_lock" : 1 # Simple locking
},
finish_config_28F___S3)
Example of typical AMD* flash:
import flash_memory
flash_memory.flash_add_model(
"copyofAm29LV64_D",
{"cfi_query" : [0x01, 0x00, 0x00, 0x00, # 0x00
0x00, 0x00, 0x00, 0x00, # 0x04
0x00, 0x00, 0x00, 0x00, # 0x08
0x00, 0x00, 0x00, 0x00, # 0x0C
0x51, 0x52, 0x59, 0x02, # 0x10
0x00, 0x40, 0x00, 0x00, # 0x14
0x00, 0x00, 0x00, 0x27, # 0x18
0x36, 0x00, 0x00, 0x04, # 0x1C
0x00, 0x0A, 0x00, 0x05, # 0x20
0x00, 0x04, 0x00, 0x17, # 0x24
0x01, 0x00, 0x00, 0x00, # 0x28
0x01, 0x7F, 0x00, 0x00, # 0x2C
0x01, 0x00, 0x00, 0x00, # 0x30
0x00, 0x00, 0x00, 0x00, # 0x34
0x00, 0x00, 0x00, 0x00, # 0x38
0x00, 0x00, 0x00, 0x00, # 0x3C
0x50, 0x52, 0x49, 0x31, # 0x40
0x33, 0x00, 0x02, 0x04, # 0x44
0x01, 0x04, 0x00, 0x00, # 0x48
0x00, 0xB5, 0xC5, 0x05],# 0x4C
"device_id" : 0x22D7,
"manufacturer_id" : 0x01, # AMD
"max_chip_width" : 16, # 16-bits chip
"unit_size" : [0x10000 for i in range(128)],
},
flash_memory.finish_default)
* Other names and brands may be claimed as the property of others.