* ========== Copyright Header Begin ==========================================
* Hypervisor Software File: gen-seeprom.c
* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
* - Do no alter or remove copyright notices
* - Redistribution and use of this software in source and binary forms, with
* or without modification, are permitted provided that the following
* - Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistribution in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of Sun Microsystems, Inc. or the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* This software is provided "AS IS," without a warranty of any kind.
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
* MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
* OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
* FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
* DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
* ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
* SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* You acknowledge that this software is not designed, licensed or
* intended for use in the design, construction, operation or maintenance of
* ========== Copyright Header End ============================================
* id: @(#)gen-seeprom.c 1.12 05/11/15
* copyright: Copyright 2005 Sun Microsystems, Inc. All Rights Reserved
* copyright: Use is subject to license terms.
* Parse a config file and generate a binary file containing the cpu seeprom
int system_type
= EXCALIBUR
;
int system_type_init
= 0;
int config_type_init
= 0;
struct fixed_seeprom
*seeprom_data
;
char err_string
[MAXLINE
];
static int quiet
= 0, release
= 0;
static struct unique_functions seeprom_func
[] = {
SET_FUNC_ENTRY(cpu_dynamic
, check_cpu
, write_cpu
, dump_cpu
, reg_cpu
)
SET_FUNC_ENTRY(sys_dynamic
, check_sys
, write_sys
, dump_sys
, reg_sys
)
SET_FUNC_ENTRY(env_dynamic
, check_env
, write_env
, dump_env
, reg_env
)
SET_FUNC_ENTRY(mem_dynamic
, check_mem
, write_mem
, dump_mem
, reg_mem
)
SET_FUNC_ENTRY(cpu_dynamic
, check_cpu
, write_cpu
, dump_cpu
, reg_cpu
)
static struct tm tm_compiled
= { COMPILE_TIME
};
compiled
= mktime(&tm_compiled
);
expire
= compiled
+ ACTIVE_TIME
;
/* -q option is quiet mode, no processing messages. */
"%s: [ -q ] <config_filename>\n", name
);
fprintf(stderr
, " -q Suppresses config file processing messages.\n");
fprintf(stderr
, "\nTool will expire on %s\n", ctime(&expire
));
static struct tm tm_compiled
= { COMPILE_TIME
};
time_t compiled
, now
, expire
;
compiled
= mktime(&tm_compiled
);
expire
= compiled
+ ACTIVE_TIME
;
now
= mktime(gmtime(&now
));
print_error(char *string
)
fprintf(stderr
, "%s: ERROR: %s\n", config_file
, string
);
print_input_error(char *parameter
)
sprintf(err_string
, "Input error for %s", parameter
);
* Get seeprom parameter value from data structure
while ((parameter
= seeprom_data
[i
].name
) != NULL
) {
if (strcmp(parameter
, name
) == 0) {
return (seeprom_data
[i
].value
);
sprintf(err_string
, "Cannot find value of %s", name
);
update_reg(data_reg
*cpu_reg
, char *name
, unsigned long long new,
unsigned long long *reg
, int num_entries
)
while (!found
&& (i
< num_entries
)) {
if (strcmp(cpu_reg
[i
].name
, name
) == 0) {
bits
= cpu_reg
[i
].size
-1;
(0xffffffffffffffffLL
^ (mask
<< cpu_reg
[i
].pos
));
data
|= ((new & mask
) << cpu_reg
[i
].pos
);
* Set seeprom parameter value in data structure
update_seeprom(char *name
, unsigned long long value
)
char parameter
[MAXNAMESIZE
];
void (*notify
)(void *data
);
if ((s1
= strtok(parameter
, ".")) != NULL
) {
while ((seeprom_data
[i
].name
) != NULL
) {
if (strcmp(seeprom_data
[i
].name
, s1
) == 0) {
notify
= seeprom_data
[i
].notify
;
seeprom_data
[i
].value
= value
;
int (*funcp
)(), num_entries
;
funcp
= seeprom_func
[type
].reg_func
;
num_entries
= funcp(s1
, &cpu_reg
);
retval
= update_reg(cpu_reg
,
if (notify
!= NULL
) notify((void *) value
);
* Get one parameter value from config file
get_one_input(int num_input
, char *input_str
, unsigned long long *input_val
)
if ((strncmp(input_str
, "0x", 2) == 0) ||
(strncmp(input_str
, "0X", 2) == 0)) {
retval
= sscanf(input_str
, "%llx", input_val
);
retval
= sscanf(input_str
, "%d", input_val
);
* Check if parameter is from the fixed region
fixed_parameter(char *name
)
char *c
, parameter
[MAXNAMESIZE
];
if ((c
= strtok(parameter
, ".")) != NULL
) {
while (seeprom_data
[i
].name
!= NULL
) {
if (strcmp(seeprom_data
[i
++].name
, c
) == 0) {
char parameter
[MAXNAMESIZE
];
char input_str
[MAXNAMESIZE
];
num_scanned
= sscanf(line
, "%32s %32s", parameter
, input_str
);
"WARNING: Ignoring following line:\n%s\n",
if (strcmp(parameter
, "cfg_type") == 0) {
if (strcmp(input_str
, "cpu") == 0) {
seeprom_data
= &cpu_seeprom_data
[0];
} else if (strcmp(input_str
, "sys") == 0) {
seeprom_data
= &sys_seeprom_data
[0];
} else if (strcmp(input_str
, "env") == 0) {
seeprom_data
= &env_seeprom_data
[0];
} else if (strcmp(input_str
, "mem") == 0) {
seeprom_data
= &mem_seeprom_data
[0];
} else if (strcmp(input_str
, "cpu_rw") == 0) {
seeprom_data
= &cpu_rw_data
[0];
fprintf(stderr
, " invalid config type: %s\n",
fprintf(stderr
, "config type already initialized!\n");
if (strcmp(parameter
, "system") == 0) {
if (strcmp(input_str
, "fiesta") == 0) {
} else if (strcmp(input_str
, "gmfiesta") == 0) {
seeprom_data
= &gm_cpu_seeprom_data
[0];
} else if (strcmp(input_str
, "excalibur") == 0) {
} else if (strcmp(input_str
, "serrano") == 0) {
&serrano_cpu_seeprom_data
[0];
fprintf(stderr
, " invalid system type: %s\n",
fprintf(stderr
, "system type already initialized!\n");
if ((system_type
== FIESTA
|| system_type
== GMFIESTA
||
system_type
== SERRANO
) &&
seeprom_data
= &fiesta_sys_data
[0];
if (fixed_parameter(parameter
)) {
unsigned long long input_val
;
if (get_one_input(num_scanned
, input_str
, &input_val
)) {
if (update_seeprom(parameter
, input_val
)) {
funcp
= seeprom_func
[type
].dynamic_func
;
switch (funcp(parameter
, line
)) {
"WARNING: Unknown parameter: %s\n", parameter
);
print_input_error(parameter
);
while (seeprom_data
[i
].name
!= NULL
) {
if (strcmp(seeprom_data
[i
].name
, "pad")) {
string
= strdup(seeprom_data
[i
].name
);
string
= strcat(string
, ":");
printf(" 0x%llx\n", seeprom_data
[i
].value
);
funcp
= seeprom_func
[type
].dump_func
;
* Verify parameters are valid
funcp
= seeprom_func
[type
].check_func
;
* Write n bytes to string
store_bytes(unsigned short bytes
, unsigned long long data
,
unsigned char **store_ptr
)
byte
= data
>> ((count
-1)*8);
write_image(char *out_file
)
unsigned char *image
, *ptr
;
ptr
= image
= malloc(MAX_IMAGE
);
while (seeprom_data
[i
].name
!= NULL
) {
if (strcmp(seeprom_data
[i
].name
, "checksum")) {
checksum_offset
+= seeprom_data
[i
].size
;
if (do_checksum
&& seeprom_data
[i
].size
!= 2) {
fprintf(stderr
, "Cannot generate checksum,");
"checksum size must be 2 bytes!\n");
store_bytes(seeprom_data
[i
].size
, seeprom_data
[i
].value
, &ptr
);
funcp
= (void (*)()) seeprom_func
[type
].write_func
;
"SEEPROM image size of %d,"
"exceeds maximum size of %d bytes!",
if (fixed_parameter("checksum")) {
modify checksum for release images
so diff between debug and release
checksum((unsigned short *) image
, size
);
if (release
&& type
== CPU
)
image
[checksum_offset
] = (cksum
>> 8) & 0xff;
image
[checksum_offset
+1] = cksum
& 0xff;
file
= open(out_file
, O_CREAT
|O_TRUNC
|O_WRONLY
, 0666);
fprintf(stderr
, "Can't open output file %s\n",
int tmp
= write(file
, image
, size
);
fprintf(stderr
, "Short write on %s\n",
printf("Wrote %d bytes to %s\n",
main(int argc
, char **argv
)
char *output_file
, *endptr
;
fprintf(stderr
, "%s: tool expired. Need new copy.\n", argv
[0]);
while ((c
= getopt(argc
, argv
, "qr")) != EOF
)
/* r option will clear high bit of id_magic */
/* as well as muddle up checksum. */
config_file
= argv
[optind
];
printf("config_file: %s\n", config_file
);
if ((file
= fopen(config_file
, "r")) != NULL
) {
while (fgets(line
, MAXLINE
, file
)) {
if ((line
[0] != '\n') && (line
[0] != '#')) {
if (process_line(line
)) {
sprintf(err_string
, "Can't open config file %s!", config_file
);
fprintf(stderr
, "Config file error!\n");
output_file
= strdup(config_file
);
endptr
= strrchr(output_file
, '.');
if (endptr
!= NULL
) *endptr
= 0;
out_file
= strcat(output_file
, ".bin");
/* Debug images have the high bit of id_magic set */
if (type
== CPU
&& !release
) {
temp
= get_seeprom("id_magic");
update_seeprom("id_magic", temp
| 0x8000);
if (write_image(out_file
)) {
sprintf(err_string
, "Write to output file %s unsuccessful!",